Оглавление:

Удовольствие от гироскопа с неопиксельным кольцом: 4 шага (с изображениями)
Удовольствие от гироскопа с неопиксельным кольцом: 4 шага (с изображениями)

Видео: Удовольствие от гироскопа с неопиксельным кольцом: 4 шага (с изображениями)

Видео: Удовольствие от гироскопа с неопиксельным кольцом: 4 шага (с изображениями)
Видео: Дедушка не выдержал и дал ответ за Украинский флаг 2024, Ноябрь
Anonim
Image
Image

В этом уроке мы воспользуемся гироскопом MPU6050, неопиксельным кольцом и Arduino для создания устройства, которое зажигает светодиоды, соответствующие углу наклона.

Это простой и увлекательный проект, который будет собран на макете. Если вы будете следовать инструкциям, вы создадите то, что видели в видео. Это хорошее руководство для изучения гироскопа и неопиксельного кольца.

Я создаю это руководство из-за интереса, который я проявил к моему первому инструктажу здесь (Управление светодиодом гироскопа с Arduino). В этом руководстве я заменил простые светодиоды на неопиксельное кольцо. Кольцо проще использовать через библиотеку Adafruit, и оно определенно более эффектно.

Так что, если у вас есть эти компоненты, это отличный способ их использовать, я постараюсь шаг за шагом провести вас через создание устройства, а также объяснить, как оно работает, на последнем этапе.

Шаг 1: необходимые вещи

сборка
сборка

Запчасти

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

2. Макетная плата

3. Гироскоп MPU6050 (eBay) 1.2 $

4. 24 neopixel led кольцо (Adafruit) 17 $

5. 4 батарейных блока AA с 4 батареями

6. П-образные соединительные кабели (опция). Я использовал эти соединительные кабели, потому что они лучше смотрятся на макетной плате, и светодиоды в этом случае лучше видны. Вы можете найти коробку 140 на ebay примерно за 4 доллара. Если у вас нет этих кабелей, вы можете заменить их проводами Dupont.

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

1. Переходник с USB на последовательный FTDI FT232RL для программирования arduino pro mini

2. Arduino IDE

Навыки: 1. Пайка, проверьте этот учебник

3. Основы программирования на Arduino, это руководство может быть полезно

Шаг 2: Сборка

сборка
сборка

Я приложил схему фритзинга в формате fzz и ее изображение для облегчения визуализации соединений.

1. Вам нужно припаять 3 штыря к задней части кольца neopixel, как показано на картинке.

- припаять плюсовой вывод

- припаять землю

- припаять контакт ввода данных

2. Затем у держателя 4х батарей должен быть способ подключения к макетной плате, простое решение - припаять два штыревых провода Dupont к его клеммам.

3. Подготовьте макетную плату.

- поместите неопиксельное кольцо, микроконтроллер и гироскоп на макетную плату, как на изображении

- разместить все отрицательные провода: к микроконтроллеру, неопиксельному кольцу, гироскопу

- разместить все плюсовые провода: к микроконтроллеру, неопиксельному кольцу, гироскопу

- разместить все провода данных:

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

* вывод D6 от микроконтроллера к неопиксельному кольцу

- дважды проверьте все соединения перед включением

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

Шаг 3: Код и калибровка

Для начала нужно скачать и установить две библиотеки:

1. Библиотека Adafruit neopixel для управления neopixel

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); беззнаковый длинный lastPrintTime = 0; bool initialization = false; // устанавливаем истину, если инициализация DMP прошла успешно 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 gravity; // [x, y, z] вектор гравитации float ypr [3]; // [рыскание, тангаж, крен] yaw / pitch / roll контейнер и вектор силы тяжести volatile bool mpuInterrupt = false; // указывает, перешел ли вывод прерывания MPU в высокий уровень

установка void ()

{Serial.begin (9600); Serial.println («Программа запущена»); инициализация = initializeGyroscope (); strip.begin (); } void loop () {если (! инициализация) {возврат; } mpuInterrupt = false; mpuIntStatus = mpu.getIntStatus (); fifoCount = mpu.getFIFOCount (); если (hasFifoOverflown (mpuIntStatus, fifoCount)) {mpu.resetFIFO (); возвращение; } если (mpuIntStatus & 0x02) {в то время как (fifoCount <размер пакета) {fifoCount = mpu.getFIFOCount (); } mpu.getFIFOBytes (fifoBuffer, packetSize); fifoCount - = размер пакета; mpu.dmpGetQuaternion (& q, fifoBuffer); mpu.dmpGetGravity (& gravity, & 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) {return mpuIntStatus & 0x10 || fifoCount == 1024; } void redrawLeds (int x, int y, int z) {x = constrain (x, -1 * MAX_ANGLE, MAX_ANGLE); y = ограничение (y, -1 * MAX_ANGLE, MAX_ANGLE); если (у 0) {светодиоды (у, z, 0, 5, 0, 89); } else if (y <0 и z 0 и z 0 и z> 0) {светодиоды (y, z, 20, 24, 89, 0); }} void lightLeds (int x, int y, int fromLedPosition, int toLedPosition, int fromAngle, int toAngle) {двойной угол = (atan ((double) abs (x) / (double) abs (y)) * 4068) / 71; int ledNr = map (угол, fromAngle, toAngle, fromLedPosition, toLedPosition); printDebug (x, y, ledNr, угол); uint32_t color; for (int i = 0; i позиция + LED_OFFSET) {вернуть позицию + LED_OFFSET; } позиция возврата + LED_OFFSET - NUM_LEDS; } void printDebug (int y, int z, int lightLed, int angle) {if (millis () - lastPrintTime <500) {return; } Serial.print ("a ="); Serial.print (угол); Serial.print (";"); Serial.print ("ll ="); Serial.print (светодиоды); Serial.print (";"); Serial.print ("y ="); Serial.print (y); Serial.print (";"); Serial.print ("z ="); Serial.print (z); Serial.println (";"); lastPrintTime = миллис (); } 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 (код")); 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 (); return true;} void dmpDataReady () {mpuInterrupt = true;}

Загрузите код:

Используя адаптер FTDI, загрузите код в Arduino.

Подключите блок питания (аккумуляторы)

Калибровка:

Здесь самое важное, что нужно откалибровать, - это константа LED_OFFSET. В моем примере - 12. Вам нужно отрегулировать это значение от 0 до 23, чтобы после подачи питания на плату светодиод загорался в том направлении, в котором вы наклоняете плату.

Если вы хотите узнать больше о том, как это работает, посмотрите последний шаг

Шаг 4: Как это работает (необязательно)

Как это работает (необязательно)
Как это работает (необязательно)

Для начала немного информации о гироскопе MPU6050. Это гироскоп MEMS (MEMS расшифровывается как Microelectromechanical systems).

Каждый тип гироскопа MEMs имеет некоторую форму колеблющегося компонента, откуда можно обнаружить акклерацию и, следовательно, изменение направления. Это связано с тем, что согласно закону сохранения движения, вибрирующий объект любит продолжать вибрировать в той же плоскости, и любое колебательное отклонение можно использовать для изменения направления.

Гироскоп также содержит собственный микроконтроллер для вычисления крена, тангажа и рыскания с помощью причудливой математики.

Но необработанные данные гироскопа страдают от шума и дрейфа, поэтому мы использовали внешнюю библиотеку, чтобы сгладить ситуацию и предоставить нам чистые данные, пригодные для использования.

Neopixel - это светодиоды RGB с индивидуальной адресацией, соединенные цепями и кольцами. Они работают от 5 В и содержат собственные схемы, поэтому вам нужно только запитать неопиксели и связаться с ними по линии передачи данных. Связь осуществляется с помощью одной линии данных, содержащей часы и данные (подробнее здесь). 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

* …так далее

- внутри функции светодиоды

* я вычисляю угол на основе двух осей, используя арктангенс (проверьте прикрепленное изображение)

* я вычисляю, что привело к отображению, используя функцию карты arduino

* Я сбрасываю светодиодную полосу для всех светодиодов, кроме двух, один из которых соответствует положению светодиода, которое я рассчитал ранее, и положению светодиода до (чтобы показать эффект затухания)

* Я использую функцию normalizeLedPosition (), чтобы учесть калибровку неопикселей. Калибровка полезна, потому что неопиксельное кольцо можно вращать по своему усмотрению, и его следует выровнять с гироскопом.

* Я также печатаю ось буксировки, какой светодиод имеет свет и угол

Математика

Я прикрепил картинку со светодиодным кольцом и тригонометрической функцией, используемой для определения угла.

Рекомендуемые: