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

Как сделать дома робота для управления жестами

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

Arduino UNO
× 1
Arduino Nano R3
× 1
Модуль Bluetooth HC-05
× 2
Трехосевой акселерометр и гироскоп SparkFun - MPU-6050
× 1
Двигатель постоянного тока, 12 В
× 2
резиновые колеса
× 1
Драйверы двигателей Texas Instruments Dual H-Bridge L293D
× 1
Батарея 9 В (стандартная)
× 2

Необходимые инструменты и машины

Паяльник (общий)
Проволока для припоя, без свинца
Лента, пена
Мультитул, отвертка

Приложения и онлайн-сервисы

IDE Arduino

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


Речь идет о том, как самому сделать машину, управляемую жестами. По сути, это простое приложение трехосного гироскопа и акселерометра MPU-6050. Вы можете делать гораздо больше. понимая, как его использовать, как взаимодействовать с Arduino и как передавать его данные через модули Bluetooth. В этой статье я сосредоточусь на связи Bluetooth-Bluetooth между двумя модулями Bluetooth HC-05.

Посмотрите видео, чтобы построить тело робота и соединения для этого проекта.

Схема подключения робота и блока передатчика приведена ниже, вы можете обратиться к ним.

Печатная плата прямого заказа, используемая в этом проекте от PCBway:https://www.pcbway.com/project/shareproject/How_to_Make_Arduino_Based_Edge_Avoiding_Robot.html

Теперь поговорим о настройке модуля Bluetooth. По сути, модуль Bluetooth HC-05 поставляется с заводскими настройками ведомого модуля. это означает, что мы можем отправлять данные в модуль jus, подключив его. Нет необходимости делать какие-либо другие настройки для отправки данных с мобильных устройств в модуль HC-05. просто введите пароль по умолчанию (1234/0000), чтобы подключиться к нему. но что, если мы хотим отправить данные с помощью этого модуля в какой-то другой тот же модуль или на мобильное устройство.

В этом проекте мы делаем то же самое, отправляя данные через модуль Bluetooth. собранные гироскопическим датчиком mpu-6050 к другому модулю Bluetooth.

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

Поэтому сначала настройте первый модуль Bluetooth как ведомое устройство. для этого подключите его к Arduino согласно этой электрической схеме.

И загрузите код по имени configure.

  #include  
SoftwareSerial BTSerial (10, 11); // RX | TX
void setup ()
{
Serial.begin (9600);
Serial.println ("Введите AT-команды:");
BTSerial.begin (38400 ); // Скорость по умолчанию HC-05 в команде AT подробнее
}
void loop ()
{
// Продолжаем чтение из HC-05 и отправляем в Arduino Serial Monitor
if (BTSerial.available ())
Serial.write (BTSerial.read ());
// Продолжаем чтение из последовательного монитора Arduino и отправляем на HC-05
if (Serial. available ())
BTSerial.write (Serial.read ());
}

Отсоедините модуль. Нажмите и удерживайте кнопку ky на модуле и подключите его обратно. Вы увидите, что светодиод на модуле мигает медленнее. Раз в 2 секунды. Это означает, что HC-05 находится в командном режиме AT. Теперь откройте последовательный монитор, измените скорость передачи на 9600 и тип вывода как NL и CR. Теперь введите AT в поле отправки и отправьте его. если он отвечает "ОК", значит, все в порядке. Но если это не так и отвечает с ошибкой, отправьте AT еще раз. Пока он не ответит оком или проверьте соединения и снова не отправит AT…

после получения ответа OK от модуля введите следующие команды одну за другой:

AT + ORGL и отправьте его. эта команда установит для модуля заводские настройки.

AT + RMAAD эта команда освободит модуль от любой предыдущей пары

AT + UART? проверить текущую скорость передачи модуля

AT + UART =38400, 0, 0 установить скорость передачи как 38400

В + РОЛЬ? проверьте роль, является ли она подчиненной или главной. он отвечает 0 или 1. если модуль является подчиненным, он отвечает 0, а если это главное устройство, то он ответит 1

установить роль как ведомое устройство. введите AT + ROLE =0

AT + ADDR? проверьте адрес модуля.

Запишите этот адрес. ответил модуль. после получения этого адреса настройка подчиненного модуля завершена.

Пришло время настроить второй модуль Bluetooth как ведущее устройство. Подключите этот модуль к плате Arduino и войдите в режим AT. как мы сделали с предыдущим.

Введите эти AT-команды в заданной последовательности.

AT + ORGL

AT + RMAAD

AT + UART?

AT + UART =38400, 0, 0

AT + РОЛЬ?

установите роль этого модуля в качестве ведущего устройства. AT + ROLE =1

AT + CMODE =0, чтобы модуль подключал только одно устройство. настройка по умолчанию - 0

теперь свяжите этот модуль с ведомым устройством, чтобы выполнить этот ввод,

AT + BIND ="адрес подчиненного модуля" и все готово

Теперь установите библиотеки для датчика MPU-6050 и связи I2C. Так как гироскоп MPU-6050 имеет интерфейс I2C. скачать библиотеки и исходный код отсюда:http://www.mediafire.com/file/l8mru5emulb8x93/gesture_control_robot.rar/file

если вы предварительно установили эти библиотеки, пропустите это.

Теперь подключите автомобильный блок к ПК с помощью USB-кабеля. выберите правильный com-порт и тип платы. И загрузите программу с именем "Gesture_controled_Robot__car_unit_". Во время загрузки программы убедитесь, что аккумулятор и модуль Bluetooth не подключены к автомобилю.

  // программа Шубхама Шинганапуре от 3-10-2019 
//
// для роботизированной машины, управляемой жестами
int lm1 =8; // выход левого мотора 1
int lm2 =9; // выход левого мотора 2
int rm1 =10; // правый вывод двигателя 1
int rm2 =11; // выход правого двигателя 2
char d =0;
void setup ()
{
pinMode (lm1, OUTPUT);
pinMode (lm2, OUTPUT);
pinMode (rm1, OUTPUT);
pinMode (rm2, OUTPUT);
Serial.begin (38400);
sTOP ();
}
void loop ()
{
if (Serial.available ()> 0)
{
d =Serial.read ();
if (d ==' F ')
{
ForWard ();
}
if (d ==' B ')
{
BackWard ();
}
if (d =='L')
{
Left ();
}
if (d =='R')
{
Вправо ();
}
if (d =='S')
{
sTOP ();
}
}
}
void ForWard ()
{
digitalWrite (lm1, HIGH);
digitalWrite (lm2, LOW);
digitalWrite (rm1, HIGH);
digitalWrite (rm2, LOW);
}
void BackWard ()
{
digitalWrite (lm1, LOW);
digitalWrite (lm2, HIGH );
digitalWrite (rm1, LOW);
digitalWrite (rm2, HIGH);
}
void Left ()
{
digitalWrite (lm1, LOW);
digitalWrite (lm2, HIGH);
digitalWrite (rm1, HIGH);
digitalWrite (rm2, LOW);
}
void Right ()
{
digitalWrite (lm1, HIGH);
digitalWrite (lm2, LOW);
digitalWrite (rm1, LOW);
digitalWrite (rm2, HIGH);
}
void sTOP ()
{
digitalWrite (lm1, LOW);
digitalWrite (lm2, LOW);
digitalWrite (rm1, LOW);
digitalWrite ( rm2, LOW);
}

Сделайте то же самое с удаленным блоком. открыть программу по имени удаленно. и загрузите его в удаленное устройство.

  // программа изменена 10.03.19 // Шубхамом Шинганапуре. 
//
// для роботизированной машины, управляемой жестами (удаленная)
#include " I2Cdev.h "
#include" MPU6050_6Axis_MotionApps20.h "
// # include" MPU6050.h "// не требуется при использовании файла включения MotionApps
// Библиотека Arduino Wire требуется, если I2Cdev Реализация I2CDEV_ARDUINO_WIRE
// используется в I2Cdev.h
#if I2CDEV_IMPLEMENTATION ==I2CDEV_ARDUINO_WIRE
#include "Wire.h"
#endif
// класс по умолчанию I2C адрес 0x68
// здесь в качестве параметра могут быть переданы конкретные адреса I2C
// AD0 low =0x68 (по умолчанию для SparkFun Breakout и оценочной платы InvenSense)
// AD0 high =0x69
MPU6050 mpu;
#define OUTPUT_READABLE_YAWPITCHROLL
// переменные управления / состояния MPU
bool dmpReady =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
VectorFloat gravity;
Quaternion q;
float ypr [3]; // [рыскание, тангаж, крен] контейнер рыскания / тангажа / крена и вектор силы тяжести
uint8_t teapotPacket [14] ={'$', 0x02, 0,0, 0,0, 0,0, 0,0 , 0x00, 0x00, '\ r', '\ n'};
volatile bool mpuInterrupt =false; // указывает, перешел ли вывод прерывания MPU на высокий уровень
void dmpDataReady () {
mpuInterrupt =true;
}
#include
SoftwareSerial BTSerial ( 10, 11); // RX | TX
int bt =8;
int x =1;
void setup () {
#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 Demo, но
// это действительно зависит от вашего проекта)
Serial.begin (115200);
BTSerial.begin (38400);
// while (! Serial); // ждем перечисления Леонардо, остальные немедленно продолжат
Serial.println (F ("Инициализация устройств I2C ..."));
mpu.initialize ();
// проверяем соединение
Serial.println(F("Testing device connections ... "));
Serial.println (mpu.testConnection ()? F (" Соединение MPU6050 выполнено успешно "):F (" Соединение MPU6050 не выполнено " ));
// ждем готовности
// загружаем и настраиваем DMP
Serial.println (F ("Initializing DMP ..."));
devStatus =mpu .dmpInitialize ();
// укажите здесь свои собственные смещения гироскопа, масштабированные для минимальной чувствительности
mpu.setXGyroOffset (220);
mpu.setYGyroOffset (76);
mpu. setZGyroOffset (-85);
mpu.setZAccelOffset (1788);
// убедитесь, что это сработало (возвращает 0, если да)
if (devStatus ==0) {
/ / включаем DMP, теперь, когда он готов
Serial.println (F ("Включение DMP ..."));
mpu.setDMPEnabled (true);
// разрешаем прерывание Arduino обнаружение
Serial.println (F ("Включение обнаружения прерывания (внешнее прерывание Arduino 0) ..."));
a ttachInterrupt (0, dmpDataReady, RISING);
mpuIntStatus =mpu.getIntStatus ();
// устанавливаем наш флаг готовности DMP, чтобы функция main loop () знала, что его можно использовать
Последовательный .println (F ("DMP готов! Ожидание первого прерывания ... "));
dmpReady =true;
// получаем ожидаемый размер пакета DMP для последующего сравнения
packetSize =mpu.dmpGetFIFOPacketSize ();
} else {
// ОШИБКА!
// 1 =начальная загрузка памяти не удалась
// 2 =не удалось обновить конфигурацию DMP
// (если что-то сломается, обычно код будет 1)
Serial.print (F ("Ошибка инициализации DMP (код"));
Serial.print (devStatus);
Serial.println (F (")"));
}
// настраиваем светодиод для вывода
pinMode (bt, INPUT);
}
// ================================================================
// ===ОСНОВНОЙ ЦИКЛ ПРОГРАММЫ ===
// ================================================================
void loop () {
if (digitalRead (bt) ==HIGH)
{
x ++;
задержка (150);
}
if ((x% 2) ==0) {
// если программирование не удалось, не пытайтесь ничего делать
if (! dmpReady) return;
// ждем прерывания MPU или доступных дополнительных пакетов
while (! mpuInterrupt &&fifoCount // здесь другое поведение программы
//.
//.
//.
// если вы действительно параноик, вы можете часто тестировать между другими
// вещами, чтобы узнать, истинно ли mpuInterrupt, и если да, то «break;» из цикла
// while () для немедленной обработки данных MPU
//.
//.
//.
}
// сбрасываем флаг прерывания и получаем байт INT_STATUS
mpuInterrupt =false;
mpuIntStatus =mpu.getIntStatus ( );
// получаем текущий счетчик FIFO
fifoCount =mpu.getFIFOCount ();
// проверяем переполнение (этого никогда не должно происходить, если наш код не слишком неэффективен)
если ((mpuIntStatus &0x10) || fifoCount ==1024) {
// сбрасываем, чтобы можно было продолжить работу.
mpu.resetFIFO ();
Serial.println (F ("FIFO overflow!"));
// в противном случае проверяем наличие прерывания готовности данных DMP (это должно происходить часто)
} else if (mpuIntStatus &0x02) {
// ждать правильной доступной длины данных, должно быть ОЧЕНЬ короткое ожидание
while (fifoCount // читать пакет из FIFO
mpu.getFIFOBytes (fifoBuffer, packetSize);
// отслеживать здесь количество FIFO в случае наличия> 1 доступного пакета
// (это позволяет нам немедленно прочитать больше, не дожидаясь прерывания)
fifoCount - =packetSize;
#ifdef OUTPUT_READABLE_YAWPITCHROLL
// отображение Углы Эйлера в градусах
mpu.dmpGetQuaternion (&q, fifoBuffer);
mpu.dmpGetGravity (&gravity, &q);
mpu.dmpGetYawPitchRoll (ypr, &q, &gravity);
Последовательный .print ("ypr \ t");
Serial.print (ypr [0] * 180 / M_PI);
Serial.print ("\ t");
Serial.print ( ypr [1] * 180 / M_PI);
Последовательный .print ("\ t");
Serial.println (ypr [2] * 180 / M_PI);
if ((ypr [1] * 180 / M_PI) <=-25)
{BTSerial.write('F ');
}
else if ((ypr [1] * 180 / M_PI)> =25)
{BTSerial.write (' B ' );
}
else if ((ypr [2] * 180 / M_PI) <=-25)
{BTSerial.write('L ');
}
else if ((ypr [2] * 180 / M_PI)> =20)
{BTSerial.write ('R');
}
else {
BTSerial. write ('S');
}
#endif
}
}
else {
BTSerial.write ('S');
}
}

Вставьте подчиненный модуль Bluetooth в автомобильный блок и ведущий модуль Bluetooth в удаленном блоке. И все готово.

Включите его, и он готов к игре …….



Надеюсь, вы найдете это полезным. если да, нравится, поделитесь, прокомментируйте свои сомнения. Чтобы увидеть больше таких проектов, подписывайтесь на меня! Поддержите мою работу и подпишитесь на мой канал на YouTube.

Спасибо!

Код

  • Робот, управляемый жестами (удаленное устройство)
Робот, управляемый жестами (удаленный блок) Arduino
 // программа изменена 10.03.19 // Шубхамом Шинганапуре. //// для управляемой жестами роботизированной машины (удаленно) #include "I2Cdev.h" #include "MPU6050_6Axis_MotionApps20.h" // # include "MPU6050.h" // не требуется при использовании файла включения MotionApps // Библиотека Arduino Wire требуется, если реализация I2Cdev I2CDEV_ARDUINO_WIRE // используется в I2Cdev.h # if I2CDEV_IMPLEMENTATION ==I2CDEV_ARDUINO_WIRE #include "Wire.h" # endif // Адрес I2C по умолчанию для класса 0x68 // здесь могут быть переданы конкретные адреса I2C в качестве параметра // AD0 low =0x68 (по умолчанию для SparkFun Breakout и оценочной платы InvenSense) // AD0 high =0x69MPU6050 mpu; #define OUTPUT_READABLE_YAWPITCHROLL // Управление 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-память bufferVectorFloat gravity; Quaternion q; float ypr [3]; // [рыскание, тангаж, крен] контейнер рыскания / тангажа / крена и вектор силы тяжести uint8_t teapotPacket [14] ={'$', 0x02, 0,0, 0,0, 0,0, 0,0, 0x00, 0x00, '\ r', '\ n'}; изменчивый bool mpuInterrupt =false; // указывает, перешел ли вывод прерывания MPU в состояние highvoid dmpDataReady () {mpuInterrupt =true;} # include  SoftwareSerial BTSerial (10, 11); // RX | TXint bt =8; int x =1; void setup () {#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); BTSerial.begin (38400); // while (! Serial); // ждем перечисления Леонардо, остальные немедленно продолжат Serial.println (F ("Инициализация устройств I2C ...")); mpu.initialize (); // проверяем соединение Serial.println (F ("Проверка соединения устройства ...")); Serial.println (mpu.testConnection ()? F («Соединение MPU6050 выполнено успешно»):F («Соединение MPU6050 не удалось»)); // ждем готовности // загружаем и настраиваем DMP Serial.println (F ("Initializing DMP ...")); devStatus =mpu.dmpInitialize (); // укажите здесь свои собственные смещения гироскопа, масштабированные для минимальной чувствительности mpu.setXGyroOffset (220); mpu.setYGyroOffset (76); mpu.setZGyroOffset (-85); mpu.setZAccelOffset (1788); // убеждаемся, что он сработал (если да, то возвращает 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 (bt, INPUT); } // ================================================================// ===ОСНОВНОЙ ЦИКЛ ПРОГРАММЫ ===// ================================================================void loop () {if (digitalRead (bt) ==ВЫСОКИЙ) {x ++; задержка (150); } if ((x% 2) ==0) {// если программирование не удалось, не пытайтесь ничего делать if (! dmpReady) return; // ждем прерывания MPU или доступных дополнительных пакетов while (! mpuInterrupt &&fifoCount  1 пакета // (это позволяет нам немедленно читать больше, не дожидаясь прерывания) fifoCount - =packetSize; #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); если ((ypr [1] * 180 / M_PI) <=-25) {BTSerial.write ('F'); } иначе, если ((ypr [1] * 180 / M_PI)> =25) {BTSerial.write ('B'); } иначе, если ((ypr [2] * 180 / M_PI) <=-25) {BTSerial.write ('L'); } иначе, если ((ypr [2] * 180 / M_PI)> =20) {BTSerial.write ('R'); } еще {BTSerial.write ('S'); } #endif}} еще {BTSerial.write ('S'); }} 

Схема


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

  1. Как создать платформу для роботов Arduino + Raspberry Pi
  2. Сделайте машинку для письма домашнего задания дома
  3. Робот с сервомотором избегает препятствий
  4. Робот-последователь линии
  5. Как создать настраиваемую перфорированную кнопку клавиатуры
  6. Автономный домашний робот-помощник
  7. Как создавать музыку с помощью Arduino
  8. Как сделать автоматическое открывание дверей на базе Arduino
  9. Управление манипулятором Arduino с помощью приложения для Android
  10. Робот для супер-крутой навигации внутри помещений