Съдържание:

Забавление с жироскоп с пръстен от неопиксел: 4 стъпки (със снимки)
Забавление с жироскоп с пръстен от неопиксел: 4 стъпки (със снимки)

Видео: Забавление с жироскоп с пръстен от неопиксел: 4 стъпки (със снимки)

Видео: Забавление с жироскоп с пръстен от неопиксел: 4 стъпки (със снимки)
Видео: Прохождение God of War (2022) PC – 18: Бог из малахита 2024, Ноември
Anonim
Image
Image

В този урок ще използваме жироскопа MPU6050, неопикселов пръстен и arduino за изграждане на устройство, което осветява светодиодите, съответстващи на ъгъла на наклона.

Това е прост и забавен проект и ще бъде сглобен на макет. Ако следвате стъпките, ще изградите това, което сте видели във видеото. Това е добър урок за изучаване на жироскопа и неопикселовия пръстен.

Изграждам този урок поради интереса, който видях при първата си инструкция тук (Gyroscope Led Control With Arduino). В тази инструкция замених обикновените светодиоди с неопикселов пръстен. Пръстенът е по -прост за използване чрез библиотека на Adafruit и определено е по -грандиозен.

Така че, ако разполагате с тези компоненти, това е чудесен начин да ги използвате, ще се опитам да ви преведа стъпка по стъпка през изграждането на устройството и също така да обясня как работи в последната стъпка.

Стъпка 1: Необходими неща

Монтаж
Монтаж

Части

1. Arduino pro mini 328p (eBay) 2 $

2. Платформа

3. Жироскоп MPU6050 (eBay) 1,2 $

4. 24 неопикселов светодиоден пръстен (Adafruit) 17 $

5. 4 x AA батерии с 4 батерии

6. Кабелни джъмпери с U-образна форма (по избор). Използвал съм тези джъмпер кабели, защото изглеждат по -добре на макета, а светодиодите са по -видими по този начин. Можете да намерите кутия от 140 в ebay на около 4 $. Ако нямате тези кабели, можете да ги замените с кабели dupont.

Инструменти:

1. USB към сериен FTDI адаптер FT232RL за програмиране на arduino pro mini

2. Arduino IDE

Умения: 1. Запояване, проверете този урок

3. Основно arduino програмиране, този урок може да бъде полезен

Стъпка 2: Монтаж

Монтаж
Монтаж

Прикачих схемата за фризиране във формат fzz и снимка от нея за лесна визуализация на връзките

1. Трябва да запоите 3 мъжки щифта на гърба на неопикселовия пръстен, както е показано на снимката

- запоявайте положителния щифт

- запоявайте земята

- запоявайте щифта за въвеждане на данни

2. Тогава 4x държачът на батерията трябва да има начин за свързване към макетната платка, лесното решение е да се запоят два мъжки проводника dupont към неговите клеми.

3. Подгответе дъската.

- поставете неопикселовия пръстен, микроконтролера и жироскопа върху чертежа, както е на изображението

- поставете всички отрицателни проводници: към микроконтролера, неопикселов пръстен, жироскоп

- поставете всички положителни проводници: към микроконтролера, неопикселов пръстен, жироскоп

- поставете всички кабели за данни:

* SDA и SCL от микроконтролера до жироскопа

* щифт D6 от микроконтролера към неопикселовия пръстен

- проверете отново всички връзки преди захранването

- по желание с тиксо, залепете батерията на гърба на таблото, за да я задържите на място и да я направите по -преносима

Стъпка 3: Кодът и калибрирането

Първо трябва да изтеглите и инсталирате две библиотеки:

1. Адапрут библиотека за неопиксели, контролираща неопиксела

2. Библиотека MPU6050 за жироскопа

3. Източник на библиотека I2CDev

Те са две страхотни библиотеки, които ще се справят тежко!

Повече подробности за неопикселите тук

След това изтеглете и инсталирайте моята библиотека от тук или я копирайте отдолу:

#include "I2Cdev.h"

#include #include "MPU6050_6Axis_MotionApps20.h" #include "Wire.h" #define NEOPIXED_CONTROL_PIN 6 #define NUM_LEDS 24 const int MAX_ANGLE = 45; const int LED_OFFSET = 12; MPU6050 mpu; Adafruit_NeoPixel strip = Adafruit_NeoPixel (NUM_LEDS, NEOPIXED_CONTROL_PIN, NEO_RBG + NEO_KHZ800); unsigned long lastPrintTime = 0; bool инициализация = false; // задайте true, ако DMP init е успешен uint8_t mpuIntStatus; // съдържа действителен байт за състояние на прекъсване от MPU uint8_t devStatus; // връщане на състоянието след всяка операция на устройството (0 = успех,! 0 = грешка) uint16_t packetSize; // очакван размер на DMP пакет (по подразбиране е 42 байта) uint16_t fifoCount; // преброяване на всички байтове в момента във FIFO uint8_t fifoBuffer [64]; // FIFO буфер за съхранение Quaternion q; // [w, x, y, z] кватернион контейнер VectorFloat гравитация; // [x, y, z] гравитационен вектор поплавък ypr [3]; // [криволичене, стъпка, търкаляне] съхранение/терена/ролка контейнер и гравитационен вектор летливи bool mpuInterrupt = false; // показва дали прекъсващият щифт на MPU е станал висок

void setup ()

{Serial.begin (9600); Serial.println ("Програмата стартира"); initialization = initializeGyroscope (); strip.begin (); } void loop () {if (! инициализация) {return; } mpuInterrupt = false; mpuIntStatus = mpu.getIntStatus (); fifoCount = mpu.getFIFOCount (); if (hasFifoOverflown (mpuIntStatus, fifoCount)) {mpu.resetFIFO (); връщане; } if (mpuIntStatus & 0x02) {while (fifoCount <packetSize) {fifoCount = mpu.getFIFOCount (); } mpu.getFIFOBytes (fifoBuffer, packetSize); fifoCount -= размер на пакета; mpu.dmpGetQuaternion (& q, fifoBuffer); mpu.dmpGetGravity (& гравитация, & q); mpu.dmpGetYawPitchRoll (ypr, & q, & gravity); redrawLeds (ypr [0] * 180/M_PI, ypr [1] * 180/M_PI, ypr [2] * 180/M_PI); }} логическо hasFifoOverflown (int mpuIntStatus, int fifoCount) {връщане mpuIntStatus & 0x10 || fifoCount == 1024; } void redrawLeds (int x, int y, int z) {x = ограничение (x, -1 * MAX_ANGLE, MAX_ANGLE); y = ограничение (y, -1 * MAX_ANGLE, MAX_ANGLE); if (y 0) {lightLeds (y, z, 0, 5, 0, 89); } иначе ако (y <0 и z 0 и z 0 и z> 0) {lightLeds (y, z, 20, 24, 89, 0); }} void lightLeds (int x, int y, int fromLedPosition, int toLedPosition, int fromAngle, int toAngle) {двоен ъгъл = (atan ((двоен) abs (x) / (двоен) abs (y)) * * 4068) / 71; int ledNr = карта (ъгъл, отAngle, toAngle, fromLedPosition, toLedPosition); printDebug (x, y, ledNr, ъгъл); uint32_t цвят; for (int i = 0; i позиция + LED_OFFSET) {позиция за връщане + LED_OFFSET; } позиция за връщане + LED_OFFSET - NUM_LEDS; } void printDebug (int y, int z, int lightLed, int ъгъл) {if (millis () - lastPrintTime <500) {return; } Serial.print ("a ="); Serial.print (ъгъл); Serial.print (";"); Serial.print ("ll ="); Serial.print (lightLed); Serial.print (";"); Serial.print ("y ="); Serial.print (y); Serial.print (";"); Serial.print ("z ="); Serial.print (z); Serial.println (";"); lastPrintTime = millis (); } bool initializeGyroscope () {Wire.begin (); TWBR = 24; mpu.initialize (); Serial.println (mpu.testConnection ()? F ("MPU6050 връзката е успешна"): F ("MPU6050 връзката е неуспешна")); Serial.println (F ("Инициализиране на DMP …")); devStatus = mpu.dmpInitialize (); mpu.setXGyroOffset (220); mpu.setYGyroOffset (76); mpu.setZGyroOffset (-85); mpu.setZAccelOffset (1788); if (devStatus! = 0) {Serial.print (F ("DMP Initialization failed (code")); Serial.println (devStatus); return false;} mpu.setDMPEnabled (true); Serial.println (F ("Активиране откриване на прекъсване (Arduino външно прекъсване 0) … ")); attachInterrupt (0, dmpDataReady, RISING); mpuIntStatus = mpu.getIntStatus (); Serial.println (F (" DMP готов! Изчакване на първото прекъсване … ")); packetSize = mpu.dmpGetFIFOPacketSize (); връщане true;} void dmpDataReady () {mpuInterrupt = true;}

Качете кода:

С помощта на адаптера FTDI качете кода в arduino.

Свържете захранването (батерии)

Калибриране:

Най -важното нещо за калибриране тук е константата "LED_OFFSET". В моя пример е 12. Трябва да регулирате това от 0 до 23, така че след захранването на платката светодиодът да светне в посоката, в която накланяте дъската.

Ако искате да научите повече подробности за това как работи, вижте последната стъпка

Стъпка 4: Как работи (по избор)

Как работи (по избор)
Как работи (по избор)

Първо малко информация за жироскопа MPU6050. Това е MEMS жироскоп (MEMS означава микроелектромеханични системи).

Всеки тип MEMs жироскоп има някаква форма на осцилиращ компонент, откъдето може да се открие аккрелацията и следователно промяната на посоката. Това е така, защото според закона за запазване на движението вибриращият обект обича да продължава да вибрира в същата равнина и всяко вибрационно отклонение може да се използва за извличане на промяна в посоката.

Жироскопът също така съдържа свой собствен микроконтролер за изчисляване на хвърлянето, наклона и промяната чрез някои фантастични математики.

Но суровите жироскопични данни страдат от шум и отклонение, затова използвахме външна библиотека, за да изгладим нещата и да ни дадем чисти използваеми данни.

Neopixel са RGB светодиоди, индивидуално адресирани и оковани в ленти и пръстени. Те работят на 5V и съдържат собствена схема, така че трябва само да захранвате неопикселите и да комуникирате с тях, използвайки линията за данни. Комуникацията се осъществява с един ред данни, съдържащ часовник и данни (повече подробности тук). Adafruit осигурява чиста библиотека за взаимодействие с неопикселовите пръстени.

Кодът

Вътре във функцията l oop () се извиква библиотеката MPU6050_6Axis_MotionApps20. Когато библиотеката има нови данни от жироскопа, тя извиква redrawLeds (x, y, z) с 3 аргумента, представляващи криволичене, височина и въртене

Вътре в redrawLeds ():

- ние се фокусираме върху две оси: y, z

- ние ограничаваме двете оси от -MAX_ANGLE до +MAX_ANGLE, дефинирахме макс ъгъл до 45 и той може да се променя

- разделяме 360 градуса на 4 квадранта и извикваме функции lightLeds () за всеки, както следва:

* y отрицателен, z положителен първи квадрант ще контролира светодиодите от 0 до 5, ъгълът ще бъде от 0 до 89

* y отрицателен, z отрицателен втори квадрант контролира светодиодите от 6 до 12, ъгълът ще бъде от 89 до 0

* … и т.н.

- вътре във функцията lightLeds

* изчислявам ъгъл въз основа на двете оси, използвайки арктангенс (проверете приложената снимка)

* изчислявам какво е довело до показване с помощта на функцията arduino map

* възстановявам всички светодиодни ленти, с изключение на два светодиода, този, който съответства на позицията на светодиода, която съм изчислил преди, и позиция на светодиода преди (за показване на ефект на затихване)

* Използвам функция, наречена normalizeLedPosition (), за да взема предвид неопикселовото калибриране. Калибрирането е полезно, тъй като неопикселовият пръстен може да се завърта както желае и трябва да бъде подравнен с жироскопа

* аз също отпечатвам оста на теглене, това, което води светлината и ъгъла

Математиката

Прикачих снимка с LED пръстена и тригонометричната функция, използвана за определяне на ъгъла.

Препоръчано: