Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Manufacturing Technology >> Производственный процесс

Начало работы с датчиком движения IMU (6 DOF)

Компоненты и расходные материалы

Arduino UNO
× 1
Единица инерциального измерения (IMU) (6 градусов свободы)
× 1

Об этом проекте

Сегодня мы изучим лучший доступный датчик IMU (Inertia Measurement Unit) и узнаем, как его можно связать с Arduino. Позже в нашем следующем уроке мы попытаемся визуализировать обнаружение движения в 3D.

Модуль датчика IMU, который мы будем использовать, сконцентрирован вокруг датчика MPU-6050.

Устройства MPU-6050 объединяют в себе 3-осевой гироскоп . и 3-осевой акселерометр на том же кремниевом кристалле вместе со встроенным процессором Digital Motion Processor ™ (DMP ™) , который обрабатывает сложные 6-осевые алгоритмы MotionFusion.

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

Что вам нужно:

АППАРАТНОЕ ОБЕСПЕЧЕНИЕ:

1) Arduino UNO

2) Датчик MPU 6050

3) Соединительные провода

ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ: IDE Arduino

Протокол связи: Этот датчик IMU обменивается данными с Arduino по протоколу шины I2C.

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

Теперь перейдем к схеме подключения и профилю подключения.

Для подключения обратитесь к одному из этих двух рисунков ниже.

Если у вас возникли проблемы с приведенными выше цифрами, не паникуйте .....

Просмотрите профиль контактов подключения ниже:

Подключите 5 В [IMU MPU-6050] к VCC [ARDUINO]

Подключите SDA [IMU MPU-6050] к аналоговому входу (A4) [ARDUINO]

Подключите SCL [IMU MPU-6050] к аналоговому входу (A5) [ARDUINO]

Подключите GND [IMU MPU-6050] к GND [ARDUINO]

Подключите INTPIN [IMU MPU-6050] к контакту 2 (контакт цифрового ШИМ) [ARDUINO]

Здесь, если ваш модуль MPU 6050 имеет вывод 5V, вы можете подключить его к выводу 5V вашего Arduino. В противном случае вам придется подключить его к выводу 3,3 В, чтобы избежать проблем с перенапряжением.

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

Во-первых, чтобы протестировать MPU 6050, щелкните по этой ссылке и загрузите библиотеку arduino для MPU 6050. Там есть zip-папка с именем «MPU6050.zip». Загрузите папку и извлеките ее содержимое. После этого скопируйте папку библиотеки «MPU6050» и вставьте ее в папку библиотеки Arduino. То есть вам нужно перейти в то место, где находится папка «библиотеки» Arduino, а затем просто вставить в нее эту папку «MPU6050».

Затем вам нужно загрузить другую библиотеку с именем «I2Cdev.zip» (если она не была установлена ​​ранее) и вставить ее в библиотеку Arduino так же, как и предыдущую.

Итак, теперь в папке «библиотеки» Arduino у нас есть два новых объекта. (Рис:8)

Теперь щелкните IDE arduino и посмотрите, видны ли эти новые библиотеки (рис. (9).

Прежде чем включать эти библиотеки в свой скетч, вам необходимо получить код для MPU6050. См. Рис. (10)

(Файл> Примеры> MPU6050> Примеры> MPU6050_DMP6). Щелкните этот файл "MPU6050_DMP6".

Затем включите библиотеки «I2Cdev» и «MPU6050» в этот скетч [Рис (11)].

Выполнив все шаги, СОБИРАЙТЕ эскиз [Рис (12)].

Остается последний шаг ...

Если вы заметили, что в правом нижнем углу этого окна отображается сообщение «Arduino / Genuino Uno на COM1», убедитесь, что это правильно. Если нет, обратитесь к [Рис. (14)]. Не нажимайте сейчас Serial Monitor. Только после загрузки скетча [как на Рис. (13)] переходите к следующим шагам.

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

Смущает это новое окно ?? Что ж, это ваш экран вывода. С технической точки зрения мы называем это последовательным монитором. Здесь мы считываем наши значения с разных датчиков.

ШАГ:Инструменты> Последовательный монитор или, горячая клавиша (Ctrl + Shift + M)

Если у вас возникнут проблемы с загрузкой скетча, даже если вы выбрали правильные порты. Щелкните по этой ссылке (для пользователей Windows). Для пользователей Mac см. Руководство. Пользователи Linux могут обратиться к этой веб-странице за инструкциями.

После загрузки кода откройте монитор последовательного порта и измените «скорость передачи» на 115200. Если вы выберете любую другую скорость передачи, вы увидите ненужные комментарии, потому что они не будут синхронизироваться. ПРИМЕЧАНИЕ. Хост-процессоры с тактовой частотой 8 МГц или медленнее, такие как Teensy @ 3,3 В или Ardunio Pro Mini, работающие при 3,3 В, не могут надежно обрабатывать эту скорость передачи данных из-за того, что синхронизация передачи слишком не совпадает с тактами процессора. В этих случаях необходимо использовать 38400 или медленнее, либо использовать какой-либо внешний отдельный кристалл для таймера UART.

Если вы не видите на экране сообщение «Инициализация устройств I2C…», нажмите кнопку «СБРОС». Теперь он должен работать. [Рис. (15)]


ЗНАЮЩИЙ>> Вы увидите строку «Отправьте любой символ, чтобы начать программирование и демонстрацию DMP:» Что такое DMP ??

Ответ: DMP - это цифровая обработка движения . . MPU 6050 Invense имеет встроенный процессор движения. Он обрабатывает значения акселерометра и гироскопа, чтобы дать нам точные трехмерные значения; т.е. рыскание, наклон и крен. [Рис. (16)]


ЗНАЮЩИЙ>> Мы видели, что связь между датчиком и Arduino основана на протоколе шины I2C. Точно так же мы также включили в этот проект библиотеку I2C. вы знаете, что означает I2C?

Ответ: Шина I2C физически состоит из 2 активных проводов и заземления. Активные провода, называемые SDA и SCL , оба являются двунаправленными. SDA - это строка последовательного DAta, а SCL - это строка последовательного CLock. Каждое устройство, подключенное к шине, имеет свой собственный уникальный адрес, независимо от того, является ли он микроконтроллером, драйвером ЖК-дисплея, памятью или ASIC. Каждый из этих чипов может действовать как приемник и / или передатчик, в зависимости от функциональности. Очевидно, что драйвер ЖК-дисплея - это только приемник, тогда как микросхема памяти или ввода-вывода может быть и передатчиком, и приемником. Шина I2C - это шина с несколькими мастерами. Это означает, что к нему может быть подключено более одной ИС, способной инициировать передачу данных. В спецификации протокола I2C указано, что ИС, которая инициирует передачу данных по шине, считается мастером шины. Следовательно, в то время все остальные ИС рассматриваются как ведомые шины. Поскольку мастерами шины обычно являются микроконтроллеры, здесь, например, мастером шины является ArduinoUno. Точно так же датчик MPU является ведомым устройством шины.


Визуализируйте движение в 3D в моем следующем уроке. Нажмите здесь




Код

  • Код Arduino для датчика MPU
Код Arduino для датчика MPU Arduino
 * /// I2Cdev и MPU6050 должны быть установлены как библиотеки, иначе файлы .cpp / .h // для обоих классов должны находиться в пути включения вашего проекта # include "I2Cdev.h" #include "MPU6050_6Axis_MotionApps20 .h "// # include" MPU6050.h "// необязательно при использовании файла включения MotionApps // библиотека Arduino Wire требуется, если I2Cdev реализация I2CDEV_ARDUINO_WIRE // используется в I2Cdev.h # если I2CDEV_IMPLEMENTATION ==I2CDEV_ARDUINO_WIRE #include" Wire .h "# endif // адрес I2C по умолчанию для класса 0x68 // здесь в качестве параметра могут быть переданы конкретные адреса I2C // AD0 low =0x68 (по умолчанию для SparkFun Breakout и оценочной платы InvenSense) // AD0 high =0x69MPU6050 mpu; / / MPU6050 mpu (0x69); // <- использовать для AD0 high / * =========================================================================ПРИМЕЧАНИЕ. В дополнение к подключению 3,3 В, GND, SDA и SCL, этот скетч зависит от того, подключен ли вывод INT MPU-6050 к выводу №0 внешнего прерывания Arduino. На Arduino Uno и Mega 2560 это цифровой вывод 2 ввода / вывода * =========================================================================* // * =========================================================================ПРИМЕЧАНИЕ:Arduino v1.0.1 с платой Leonardo генерирует ошибку компиляции при использовании Serial.write (buf, len). Выходные данные Teapot используют этот метод. Решение требует модификации файла Arduino USBAPI.h, что, к счастью, просто, но раздражает. Это будет исправлено в следующем выпуске IDE. Для получения дополнительной информации перейдите по этим ссылкам:http://arduino.cc/forum/index.php/topic,109987.0.html http://code.google.com/p/arduino/issues/detail?id=958 * =========================================================================* /// раскомментируйте "OUTPUT_READABLE_QUATERNION", если вы хотите увидеть фактические // компоненты кватерниона в [w, x, y, z] формат (не лучший для синтаксического анализа // на удаленном хосте, таком как Processing или что-то в этом роде) // # определить OUTPUT_READABLE_QUATERNION // раскомментировать «OUTPUT_READABLE_EULER», если вы хотите видеть углы Эйлера // (в градусах), вычисленные по приходящим кватернионам из FIFO .// Обратите внимание, что углы Эйлера страдают от блокировки кардана (дополнительную информацию см. // http://en.wikipedia.org/wiki/Gimbal_lock) //#define OUTPUT_READABLE_EULER // раскомментируйте "OUTPUT_READABLE_YAWPITCHROLL", если хотите чтобы увидеть углы рыскания /// тангажа / крена (в градусах), вычисленные по кватернионам, // поступающим из FIFO. Обратите внимание, что для этого также требуются вычисления вектора силы тяжести. // Также обратите внимание, что углы рыскания / тангажа / крена страдают от блокировки кардана (// дополнительную информацию см .:http://en.wikipedia.org/wiki/Gimbal_lock )#define OUTPUT_READABLE_YAWPITCHROLL / / uncomment "OUTPUT_READABLE_REALACCEL", если вы хотите видеть компоненты ускорения // без гравитации. Этот опорный кадр ускорения // не компенсируется ориентацией, поэтому + X всегда равно + X согласно // датчику, просто без влияния силы тяжести. Если вы хотите, чтобы ускорение // компенсировалось для ориентации, используйте вместо него OUTPUT_READABLE_WORLDACCEL. //#Define OUTPUT_READABLE_REALACCEL // раскомментируйте «OUTPUT_READABLE_WORLDACCEL», если вы хотите видеть компоненты ускорения // с удалением силы тяжести и корректировкой для мировой системы // отсчета (рыскание относительно исходной ориентации, поскольку // магнитометра в этом случае нет). В некоторых случаях это может быть весьма удобно. //#Define OUTPUT_READABLE_WORLDACCEL // раскомментируйте «OUTPUT_TEAPOT», если вы хотите, чтобы вывод соответствовал формату, // использованному для демонстрации чайника InvenSense // # define OUTPUT_TEAPOT #define LED_PIN 13 // (Arduino - 13 , Teensy - 11, Teensy ++ - 6) bool blinkState =false; // Управление / статус MPU varsbool dmpReady =false; // устанавливаем истину, если инициализация DMP прошла успешно uint8_t mpuIntStatus; // содержит текущий байт состояния прерывания из MPUuint8_t devStatus; // возвращаем статус после каждой операции с устройством (0 =успех,! 0 =ошибка) uint16_t packetSize; // ожидаемый размер пакета DMP (по умолчанию 42 байта) uint16_t fifoCount; // подсчет всех байтов, находящихся в данный момент в FIFOuint8_t fifoBuffer [64]; // буфер памяти FIFO // ориентация / движение varsQuaternion q; // [w, x, y, z] кватернион containerVectorInt16 aa; // [x, y, z] измерения датчика ускоренияVectorInt16 aaReal; // [x, y, z] измерения датчика ускорения без гравитацииVectorInt16 aaWorld; // [x, y, z] измерения датчика ускорения в мировом фрейме VectorFloat gravity; // [x, y, z] вектор гравитации float euler [3]; // [psi, theta, phi] Угол Эйлера containerfloat ypr [3]; // [рыскание, тангаж, крен] контейнер рыскания / тангажа / крена и вектор силы тяжести // структура пакета для чайника InvenSense demouint8_t teapotPacket [14] ={'$', 0x02, 0,0, 0,0, 0,0, 0,0, 0x00, 0x00, '\ r', '\ n'}; // ================================================================// ===ПРОЦЕДУРА ОБНАРУЖЕНИЯ ПРЕРЫВАНИЯ ===// ================================================================volatile bool mpuInterrupt =false; // указывает, перешел ли вывод прерывания MPU на высокий уровень dmpDataReady () {mpuInterrupt =true;} // ==================================================================// ===НАЧАЛЬНАЯ НАСТРОЙКА ===// ================================================================void setup () {// подключаемся к шине I2C (библиотека I2Cdev не делает этого автоматически) #if I2CDEV_IMPLEMENTATION ==I2CDEV_ARDUINO_WIRE Wire.begin (); TWBR =24; // Тактовая частота I2C 400 кГц (200 кГц, если процессор 8 МГц) #elif I2CDEV_IMPLEMENTATION ==I2CDEV_BUILTIN_FASTWIRE Fastwire ::setup (400, true); #endif // инициализировать последовательную связь // (выбрано 115200, потому что это требуется для вывода демо-версии Teapot, но // это действительно зависит от вас, в зависимости от вашего проекта) Serial.begin (115200); в то время как (! серийный); // ждем перечисления Леонардо, другие немедленно продолжат // ПРИМЕЧАНИЕ:хост-процессоры с тактовой частотой 8 МГц или медленнее, такие как Teensy @ 3,3 В или Ardunio // Pro Mini, работающие на 3,3 В, не могут надежно справиться с этой скоростью передачи // из-за временной синхронизации. слишком рассогласован с тактами процессора. В этих случаях вы должны использовать // 38400 или медленнее, или использовать какое-то внешнее // решение на отдельном кристалле для таймера UART. // инициализируем устройство Serial.println (F ("Инициализация устройств I2C ...")); mpu.initialize (); // проверяем соединение Serial.println (F ("Проверка соединения устройства ...")); Serial.println (mpu.testConnection ()? F («Соединение MPU6050 выполнено успешно»):F («Соединение MPU6050 не удалось»)); // ждем готовности Serial.println (F ("\ nОтправьте любой символ, чтобы начать программирование и демонстрацию DMP:")); while (Serial.available () &&Serial.read ()); // пустой буфер while (! Serial.available ()); // ждем данных while (Serial.available () &&Serial.read ()); // снова пустой буфер // загрузка и настройка DMP Serial.println (F ("Initializing DMP ...")); devStatus =mpu.dmpInitialize (); // укажите здесь свои собственные смещения гироскопа, масштабированные для минимальной чувствительности mpu.setXGyroOffset (220); mpu.setYGyroOffset (76); mpu.setZGyroOffset (-85); mpu.setZAccelOffset (1788); // Заводская установка по умолчанию 1688 для моего тестового чипа // Убедитесь, что он работает (если да, то возвращает 0) if (devStatus ==0) {// включите DMP, теперь, когда он готов Serial.println (F ("Включение DMP. .. ")); mpu.setDMPEnabled (правда); // включить обнаружение прерывания Arduino Serial.println (F ("Включение обнаружения прерывания (внешнее прерывание Arduino 0) ...")); attachInterrupt (0, dmpDataReady, RISING); mpuIntStatus =mpu.getIntStatus (); // устанавливаем наш флаг готовности DMP, чтобы функция main loop () знала, что его можно использовать Serial.println (F («DMP готов! Ожидание первого прерывания ...»)); dmpReady =true; // получить ожидаемый размер пакета DMP для последующего сравнения packetSize =mpu.dmpGetFIFOPacketSize (); } else {// ОШИБКА! // 1 =начальная загрузка памяти не удалась // 2 =не удалось обновить конфигурацию DMP // (если она выйдет из строя, обычно код будет 1) Serial.print (F («Ошибка инициализации DMP (код»)); Serial. печать (devStatus); Serial.println (F (")")); } // настраиваем светодиод для вывода pinMode (LED_PIN, OUTPUT);} // ================================================================// ===ГЛАВНЫЙ ЦИКЛ ПРОГРАММЫ ===// ================================================================void loop () {// если программирование не удалось, не пытайтесь ничего делать if (! dmpReady) return; // ждем прерывания MPU или доступных дополнительных пакетов while (! mpuInterrupt &&fifoCount  1 пакета // (это позволяет нам немедленно читать больше, не дожидаясь прерывания) fifoCount - =packetSize; #ifdef OUTPUT_READABLE_QUATERNION // отображение значений кватернионов в простой матричной форме:w x y z mpu.dmpGetQuaternion (&q, fifoBuffer); Serial.print ("quat \ t"); Серийный отпечаток (q.w); Serial.print ("\ t"); Серийная печать (q.x); Serial.print ("\ t"); Серийный отпечаток (q.y); Serial.print ("\ t"); Serial.println (q.z); #endif #ifdef OUTPUT_READABLE_EULER // отображение углов Эйлера в градусах mpu.dmpGetQuaternion (&q, fifoBuffer); mpu.dmpGetEuler (Эйлер, &q); Serial.print ("Эйлер \ т"); Serial.print (euler [0] * 180 / M_PI); Serial.print ("\ t"); Serial.print (euler [1] * 180 / M_PI); Serial.print ("\ t"); Serial.println (Эйлер [2] * 180 / M_PI); #endif #ifdef OUTPUT_READABLE_YAWPITCHROLL // отображение углов Эйлера в градусах mpu.dmpGetQuaternion (&q, fifoBuffer); mpu.dmpGetGravity (&gravity, &q); mpu.dmpGetYawPitchRoll (ypr, &q, &gravity); Serial.print ("ypr \ t"); Serial.print (ypr [0] * 180 / M_PI); Serial.print ("\ t"); Serial.print (ypr [1] * 180 / M_PI); Serial.print ("\ t"); Serial.println (ypr [2] * 180 / M_PI); #endif #ifdef OUTPUT_READABLE_REALACCEL // отображение реального ускорения, скорректированного для удаления гравитации mpu.dmpGetQuaternion (&q, fifoBuffer); mpu.dmpGetAccel (&aa, fifoBuffer); mpu.dmpGetGravity (&gravity, &q); mpu.dmpGetLinearAccel (&aaReal, &aa, &gravity); Serial.print ("площадь \ т"); Serial.print (aaReal.x); Serial.print ("\ t"); Serial.print (aaReal.y); Serial.print ("\ t"); Serial.println (aaReal.z); #endif #ifdef OUTPUT_READABLE_WORLDACCEL // отображение начального ускорения мирового кадра, скорректированного для удаления гравитации // и повернутого на основе известной ориентации из кватерниона mpu.dmpGetQuaternion (&q, fifoBuffer); mpu.dmpGetAccel (&aa, fifoBuffer); mpu.dmpGetGravity (&gravity, &q); mpu.dmpGetLinearAccel (&aaReal, &aa, &gravity); mpu.dmpGetLinearAccelInWorld (&aaWorld, &aaReal, &q); Serial.print ("мир \ т"); Serial.print (aaWorld.x); Serial.print ("\ t"); Serial.print (aaWorld.y); Serial.print ("\ t"); Serial.println (aaWorld.z); #endif #ifdef OUTPUT_TEAPOT // отображение значений кватернионов в демонстрационном формате InvenSense Teapot:teapotPacket [2] =fifoBuffer [0]; teapotPacket [3] =fifoBuffer [1]; teapotPacket [4] =fifoBuffer [4]; teapotPacket [5] =fifoBuffer [5]; teapotPacket [6] =fifoBuffer [8]; teapotPacket [7] =fifoBuffer [9]; teapotPacket [8] =fifoBuffer [12]; teapotPacket [9] =fifoBuffer [13]; Serial.write (teapotPacket, 14); чайникPacket [11] ++; // packetCount, намеренно зацикливается на 0xFF #endif // мигает светодиод, чтобы указать активность blinkState =! blinkState; digitalWrite (LED_PIN, blinkState); }} 

Схема


Производственный процесс

  1. Датчик отслеживания линии с RPi
  2. API датчика окружающей среды с RPi
  3. Датчик движения с использованием Raspberry Pi
  4. Raspberry Pi GPIO с датчиком движения PIR:Лучшее руководство
  5. Взаимодействие датчика движения HC-SR501 PIR с Raspberry Pi
  6. Начало работы с TJBot
  7. Начало работы с RAK 831 Lora Gateway и RPi3
  8. Начало работы со шлюзом RAK831 LoRa и RPi3
  9. Начало работы с ИИ в страховании:вводное руководство
  10. Учебник по Arduino 01:Начало работы