Arduino – машинка на управлении по bluetooth 4.0 (ble) со смартфона
Всем привет.
Делюсь с вами своим небольшим проектом bluetooth машинки.
Проект сделан для обкатки технологии передачи данных со смартфона на Arduino по протоколу BLE (bluetooth 4.0)
Так как тема РУ моделей мне очень близка и в коробке завалялась старинная, нерабочая машинка на 433 МГц, было решено дать ей вторую жизнь.
Собственно проект состоит из 2 софтверных частей.
- Приложение на Android, работающее по протоколу BLE.
- Собственно код на Arduino
Приложение на мобилку написано на C#, с использованием фреймворка Xamarin.
Приложение не претендует на релизную версию для выкладывания в Play Market, так что не обессудьте.
Если кто-то захочет ознакомиться с кодом или внести новый функционал для своего проекта, прошу, используйте по ссылке
Проект управления по bluetooth 4.0
Для тех, кто хочет использовать приложение “как есть” вот ссылка
Joystick
.
Сразу скажу, приложение точно работает на android 6.0 и выше, с разрешением 1980×1020 (другие не тестил), только для устройств с поддержкой BLE (как проверить, ищите в интернете), так что не пинайте.
Вкратце расскажу по работе с текущей версией.
Так-как я любитель квадрокоптеров, то и управление делал схожим.
- Два стика – левый газ, правый поворот колес.
- По нажатию на кнопку BLUETOOTH – окно с поиском устройств и подключением.
- По нажатию на кнопку НАСТРОЙКИ – окно с конечными точками и интервалом отправки данных на Arduino ( сделано для универсального использования с любой конфигурацией машинки)
- Главное окно с индикатором подключения и стиками.
Ну а теперь кусок кода на Arduino.
#include <SoftwareServo.h>
#include <timer-api.h>
#include <timer_setup.h>
#include <SoftwareSerial.h>
const int FwdPin = 5; //Forward Motor Pin
const int BwdPin = 6; //Backward Motor Pin
const int ServoPin = 9; // Servo Pin
SoftwareSerial mySerial(11, 12); // RX, TX - Порт bluetooth
SoftwareServo servo; //Сервопривод
byte data[5]; // Массив, куда кладутся принятые данные
short prevXPos, prevYPos, xPos, yPos; //Переменные позиции газа и серво
bool light; // Индикатор включения фар или иного света (у меня не задействован)
void setup()
{
mySerial.begin(9600);
sendCommand("AT");
sendCommand("AT ROLE0");
sendCommand("AT NAMEbluino");
servo.attach(ServoPin);
servo.setMaximumPulse(2200);
pinMode(FwdPin, OUTPUT);
pinMode(BwdPin, OUTPUT);
timer_init_ISR_500Hz(TIMER_DEFAULT); // запускаем таймер прерываний (частота подбирается индивидуально)
}
/**
* Метод отправки команд на bluetooth модуль
*/
void sendCommand(const char * command){
mySerial.println(command);
delay(100);
byte reply[100];
int i = 0;
while (mySerial.available()) {
reply[i] = mySerial.read();
i = 1;
}
}
void loop()
{
int i = 0;
//Ждем, пока не придет 5 байтов в соответсвии с протоколом (протокол описан в приложении на мобилу)
while (i != 5){
while (mySerial.available()) {
data[i] = mySerial.read();
i = 1;
}
}
//Десериализации полученных данных
xPos = (data[1] << 8) | (data[0]);
yPos = (data[3] << 8) | (data[2]);
light = data[4];
//Пинаем серву
SoftwareServo :: refresh ();
}
/**
* Обработчик прерываний
*/
void timer_handle_interrupts(int timer) {
if(xPos < 0){
xPos = xPos * -1;
}
//Собственно задаем скорость и направление мотору
if(yPos < 0){
yPos = yPos * -1;
if(prevYPos != yPos){
prevYPos = yPos;
analogWrite(FwdPin, 0);
analogWrite(BwdPin, yPos);
}
}
else{
if(prevYPos != yPos){
prevYPos = yPos;
analogWrite(FwdPin, yPos);
analogWrite(BwdPin, 0);
}
}
//Задаем угол поворота серве
if(prevXPos != xPos)
{
prevXPos = xPos;
servo.write(xPos);
}
}
Ссылки на использованные в этой машинке китайские модули.
Еще нужна сама Arduino (у меня UNO), выбрал её, потому что все питание у меня идет от 2s Li-po, а она может питаться до 10В.
Коллекторный двигатель и корпус (как писал выше, у меня от старинной модели вместе с движком). Можно заменить драйвер на ESC с б/к двигателем.
Схему рисовать не буду (посмотрев в редактор, половину устройств нет, искать их лень).
Подключается все не сложно. По пинам скажу на bluetooth RXD -> pin 12, TXD -> pin 11, остальное понятно по коду.
Пример работы ожившей машинки из прошлого с новым железом
Здесь
§
Всем привет.
Делюсь с вами своим небольшим проектом bluetooth машинки.
Проект сделан для обкатки технологии передачи данных со смартфона на Arduino по протоколу BLE (bluetooth 4.0)
Так как тема РУ моделей мне очень близка и в коробке завалялась старинная, нерабочая машинка на 433 МГц, было решено дать ей вторую жизнь.
Собственно проект состоит из 2 софтверных частей.
- Приложение на Android, работающее по протоколу BLE.
- Собственно код на Arduino
Приложение на мобилку написано на C#, с использованием фреймворка Xamarin.
Приложение не претендует на релизную версию для выкладывания в Play Market, так что не обессудьте.
Если кто-то захочет ознакомиться с кодом или внести новый функционал для своего проекта, прошу, используйте по ссылке
Проект управления по bluetooth 4.0
Для тех, кто хочет использовать приложение “как есть” вот ссылка
Joystick
.
Сразу скажу, приложение точно работает на android 6.0 и выше, с разрешением 1980×1020 (другие не тестил), только для устройств с поддержкой BLE (как проверить, ищите в интернете), так что не пинайте.
Вкратце расскажу по работе с текущей версией.
Так-как я любитель квадрокоптеров, то и управление делал схожим.
- Два стика – левый газ, правый поворот колес.
- По нажатию на кнопку BLUETOOTH – окно с поиском устройств и подключением.
- По нажатию на кнопку НАСТРОЙКИ – окно с конечными точками и интервалом отправки данных на Arduino ( сделано для универсального использования с любой конфигурацией машинки)
- Главное окно с индикатором подключения и стиками.
Ну а теперь кусок кода на Arduino.
#include <SoftwareServo.h>
#include <timer-api.h>
#include <timer_setup.h>
#include <SoftwareSerial.h>
const int FwdPin = 5; //Forward Motor Pin
const int BwdPin = 6; //Backward Motor Pin
const int ServoPin = 9; // Servo Pin
SoftwareSerial mySerial(11, 12); // RX, TX - Порт bluetooth
SoftwareServo servo; //Сервопривод
byte data[5]; // Массив, куда кладутся принятые данные
short prevXPos, prevYPos, xPos, yPos; //Переменные позиции газа и серво
bool light; // Индикатор включения фар или иного света (у меня не задействован)
void setup()
{
mySerial.begin(9600);
sendCommand("AT");
sendCommand("AT ROLE0");
sendCommand("AT NAMEbluino");
servo.attach(ServoPin);
servo.setMaximumPulse(2200);
pinMode(FwdPin, OUTPUT);
pinMode(BwdPin, OUTPUT);
timer_init_ISR_500Hz(TIMER_DEFAULT); // запускаем таймер прерываний (частота подбирается индивидуально)
}
/**
* Метод отправки команд на bluetooth модуль
*/
void sendCommand(const char * command){
mySerial.println(command);
delay(100);
byte reply[100];
int i = 0;
while (mySerial.available()) {
reply[i] = mySerial.read();
i = 1;
}
}
void loop()
{
int i = 0;
//Ждем, пока не придет 5 байтов в соответсвии с протоколом (протокол описан в приложении на мобилу)
while (i != 5){
while (mySerial.available()) {
data[i] = mySerial.read();
i = 1;
}
}
//Десериализации полученных данных
xPos = (data[1] << 8) | (data[0]);
yPos = (data[3] << 8) | (data[2]);
light = data[4];
//Пинаем серву
SoftwareServo :: refresh ();
}
/**
* Обработчик прерываний
*/
void timer_handle_interrupts(int timer) {
if(xPos < 0){
xPos = xPos * -1;
}
//Собственно задаем скорость и направление мотору
if(yPos < 0){
yPos = yPos * -1;
if(prevYPos != yPos){
prevYPos = yPos;
analogWrite(FwdPin, 0);
analogWrite(BwdPin, yPos);
}
}
else{
if(prevYPos != yPos){
prevYPos = yPos;
analogWrite(FwdPin, yPos);
analogWrite(BwdPin, 0);
}
}
//Задаем угол поворота серве
if(prevXPos != xPos)
{
prevXPos = xPos;
servo.write(xPos);
}
}
Ссылки на использованные в этой машинке китайские модули.
Еще нужна сама Arduino (у меня UNO), выбрал её, потому что все питание у меня идет от 2s Li-po, а она может питаться до 10В.
Коллекторный двигатель и корпус (как писал выше, у меня от старинной модели вместе с движком). Можно заменить драйвер на ESC с б/к двигателем.
Схему рисовать не буду (посмотрев в редактор, половину устройств нет, искать их лень).
Подключается все не сложно. По пинам скажу на bluetooth RXD -> pin 12, TXD -> pin 11, остальное понятно по коду.
Пример работы ожившей машинки из прошлого с новым железом
Здесь
Исходный код программы
В программе первым делом необходимо инициализировать выходные контакты для подключения двигателей (через драйвер мотора).
Затем в функции setup задать направление работы для этих контактов (на вывод данных).
После этого мы будем считывать данные из последовательного порта Arduino, получаемые им от последовательного порта Bluetooth модуля, и выполнять соответствующие инструкции.
Затем мы запрограммируем функции для различных направлений движения машины. Всего будет использоваться пять условий для задания направления движения машины, представленных в следующей таблице:
Далее представлен полный текст программы.
if(str[i-1]==’1′)
{
Serial.println(“Forward”);
forward();
i=0;
}
else if(str[i-1]==’2′)
{
Serial.println(“Left”);
right();
i=0;
}
else if(str[i-1]==’3′)
{
Serial.println(“Right”);
left();
i=0;
}
else if(str[i-1]==’4′)
{
Serial.println(“Backward”);
backward();
i=0;
}
else if(str[i-1]==’5′)
{
Serial.println(“Stop”);
Stop();
i=0;
}
delay(100);
}
}
#define m11 11 // задний двигатель #define m12 12 #define m21 10 // передний двигатель #define m22 9 charstr[2],i; voidforward() { digitalWrite(m11,LOW); digitalWrite(m12,LOW); digitalWrite(m21,HIGH); digitalWrite(m22,LOW); } voidbackward() { digitalWrite(m11,LOW); digitalWrite(m12,LOW); digitalWrite(m21,LOW); digitalWrite(m22,HIGH); } voidleft() { digitalWrite(m11,HIGH); digitalWrite(m12,LOW); delay(100); digitalWrite(m21,HIGH); digitalWrite(m22,LOW); } voidright() { digitalWrite(m11,LOW); digitalWrite(m12,HIGH); delay(100); digitalWrite(m21,HIGH); digitalWrite(m22,LOW); } voidStop() { digitalWrite(m11,LOW); digitalWrite(m12,LOW); digitalWrite(m21,LOW); digitalWrite(m22,LOW); } voidsetup() { Serial.begin(9600); pinMode(m11,OUTPUT); pinMode(m12,OUTPUT); pinMode(m21,OUTPUT); pinMode(m22,OUTPUT); } voidloop() { while(Serial.available()) { charch=Serial.read(); str[i ]=ch; if(str[i–1]==‘1’) { Serial.println(“Forward”); forward(); i=0; } elseif(str[i–1]==‘2’) { Serial.println(“Left”); right(); i=0; } elseif(str[i–1]==‘3’) { Serial.println(“Right”); left(); i=0; } elseif(str[i–1]==‘4’) { Serial.println(“Backward”); backward(); i=0; } elseif(str[i–1]==‘5’) { Serial.println(“Stop”); Stop(); i=0; } delay(100); } } |
Код программы для «малыша»:
#include <SoftwareSerial.h> // Подключаем библиотеку SoftwareSerial для общения с модулем по программной шине UART #include <iarduino_Bluetooth_HC05.h> // Подключаем библиотеку iarduino_Bluetooth_HC05 для работы с Trema Bluetooth модулем HC-05 SoftwareSerial softSerial(9, 10); // Создаём объект softSerial указывая выводы RX, TX (можно указывать любые выводы Arduino UNO). Вывод 2 Arduino подключается к выводу TX модуля, вывод 3 Arduino подключается к выводу RX модуля iarduino_Bluetooth_HC05 hc05(13); // Создаём объект hc05 указывая любой вывод Arduino, который подключается к выводу K модуля // uint8_t pinShield_H2 = 4; // Вывод, подключенный к драйверу, для задания направления вращения левым мотором uint8_t pinShield_E2 = 5; // Вывод ШИМ, подключенный к драйверу, для задания скорости левого мотора uint8_t pinShield_E1 = 6; // Вывод ШИМ, подключенный к драйверу, для задания скорости правого мотора uint8_t pinShield_H1 = 7; // Вывод, подключенный к драйверу, для задания направления вращения правым мотором uint8_t pinLED_RED = 12; // Вывод с красным светодиодом uint8_t pinLED_BLUE = 11; // Вывод с синим светодиодом uint16_t time_period = 200; // Частота мигания светодиодов (в миллисекундах) uint8_t valSpeed = 255; // Максимальная скорость ШИМ (число от 0 до 255) bool arrRoute[2] = {1, 1}; // Направление движения для каждого мотора ([0]- правый мотор, [1] - левый мотор) uint16_t arrSpeed[2]; // Скорость для каждого мотора ([0]- правый мотор, [1] - левый мотор) uint32_t tmrLED; // Время последнего включения светодиодов uint32_t flgTime; // Флаг для задания времени принятия пакетов от Bluetooth телефона uint8_t flg; // Флаг кнопок uint32_t tmrWait; // Время до начала сопряжения с новыми устройствами bool flg_LED; // Флаг включения светодиодов // </iarduino_bluetooth_hc05.h></softwareserial.h> void setup() { // // BLUETOOTH МОДУЛЬ // Serial.begin (9600); // Инициируем передачу данных по аппаратной шине UART для вывода результата в монитор последовательного порта Serial.print ("begin: "); // Выводим текст "begin: " в монитор последовательного порта if (hc05.begin(softSerial)) {Serial.println("Ok");} // Инициируем работу с Trema модулем hc05, указывая объект softSerial через который осуществляется связь по шине UART else {Serial.println("Error");} // Если работа с модулем не инициирована, то выводим сообщение об ошибке tmrWait = millis(); // Устанавливаем таймер ожидания сопряжения while (!hc05.checkConnect() && millis()<tmrWait 60000) {;} // Ждём в течении 60 секунд сопряжения с последним устройством из памяти if (millis()<tmrWait 60000) {Serial.println("Connect with last ADR");} // Если сопряжение произошло, то выдаём в монитор порта сообщение об этом else { // Если сопряжение не произошло, то if (hc05.createSlave("BT_CAR", "1234")) // Создаем ведомую роль модулю, указывая его имя и pin-код (в примере имя = "BT_CAR", pin-код = "1234") {Serial.println("Slave create");} // Если ведомая роль была создана, выводим сообщение об успехе в монитор порта, else {Serial.println("Slave not create");} // а если не была создана - выводим сообщение об ошибке в монитор порта. } // // МОТОРЫ // pinMode(pinShield_H2, OUTPUT); // Конфигурируем вывод pinShield_H2 как выход (направление вращения левого мотора) pinMode(pinShield_E2, OUTPUT); // Конфигурируем вывод pinShield_E2 как выход (скорость вращения левого мотора, ШИМ) pinMode(pinShield_E1, OUTPUT); // Конфигурируем вывод pinShield_E1 как выход (скорость вращения правого мотора, ШИМ) pinMode(pinShield_H1, OUTPUT); // Конфигурируем вывод pinShield_H1 как выход (направление вращения правого мотора) // СВЕТОДИОДЫ // pinMode(pinLED_RED,OUTPUT); // Конфигурируем вывод pinLED_RED как выход pinMode(pinLED_BLUE,OUTPUT); // Конфигурируем вывод pinLED_BLUE как выход tmrLED = millis(); // Устанавливаем таймер светодиодов равным millis() flg_LED = 0; // Сбрасываем флаг светодиодов } // void loop() { // if (softSerial.available()) { // Если есть принятые данные, то ... String str; // Создаём строку str while (softSerial.available()) { // Выполняем цикл пока есть что читать ... str = char(softSerial.read()); // Читаем очередной принятый символ из UART в строку str delay(5); // Задержка на 5 мс на случай медленного приёма } // Цикл завершён, значит читать больше нечего // КНОПКИ ДВИЖЕНИЯ // // Флаг времени Флаг кнопки // if (str == "II") { flgTime = millis(); flg = 1; } // Кнопка "стрелка вверх-влево" if (str == "FF") { flgTime = millis(); flg = 2; } // Кнопка "стрелка вверх" if (str == "GG") { flgTime = millis(); flg = 3; } // Кнопка "стрелка вверх-вправо" if (str == "RR") { flgTime = millis(); flg = 4; } // Кнопка "стрелка влево" if (str == "SS") { flgTime = millis(); flg = 5; } // СТОП if (str == "LL") { flgTime = millis(); flg = 6; } // Кнопка "стрелка вправо" if (str == "JJ") { flgTime = millis(); flg = 7; } // Кнопка "стрелка вниз-влево" if (str == "BB") { flgTime = millis(); flg = 8; } // Кнопка "стрелка вниз" if (str == "HH") { flgTime = millis(); flg = 9; } // Кнопка "стрелка вниз-вправо" // КНОПКИ ДОПОЛНИТЕЛЬНЫХ ФУНКЦИЙ // // Если кнопка нажата меняем флаг // if (str == "SWS" || str == "SwS") {flg_LED = !flg_LED;} // Кнопка включения светодиодов if (str == "S0S") {flg = 10; } // Ползунок скорости в положении 0 if (str == "S1S") {flg = 11; } // Ползунок скорости в положении 1 if (str == "S2S") {flg = 12; } // Ползунок скорости в положении 2 if (str == "S3S") {flg = 13; } // Ползунок скорости в положении 3 if (str == "S4S") {flg = 14; } // Ползунок скорости в положении 4 if (str == "S5S") {flg = 15; } // Ползунок скорости в положении 5 if (str == "S6S") {flg = 16; } // Ползунок скорости в положении 6 if (str == "S7S") {flg = 17; } // Ползунок скорости в положении 7 if (str == "S8S") {flg = 18; } // Ползунок скорости в положении 8 if (str == "S9S") {flg = 19; } // Ползунок скорости в положении 9 if (str == "SqS") {flg = 20; } // Ползунок скорости в положении 10 // ====================================================================================================================================================== switch (flg) {//Направление левого мотора Направление правого мотора Скорость левого мотора Скорость правого мотора case 1: arrRoute[1] = 1; arrRoute[0] = 1; arrSpeed[1] = (valSpeed / 2); arrSpeed[0] = valSpeed; break; // С-З case 2: arrRoute[1] = 1; arrRoute[0] = 1; arrSpeed[1] = valSpeed; arrSpeed[0] = valSpeed; break; // С case 3: arrRoute[1] = 1; arrRoute[0] = 1; arrSpeed[1] = valSpeed; arrSpeed[0] = (valSpeed / 2); break; // С-В case 4: arrRoute[1] = 1; arrRoute[0] = 1; arrSpeed[1] = 0; arrSpeed[0] = valSpeed; break; // З case 5: arrRoute[1] = 1; arrRoute[0] = 1; arrSpeed[1] = 0; arrSpeed[0] = 0; break; // Стоп case 6: arrRoute[1] = 1; arrRoute[0] = 1; arrSpeed[1] = valSpeed; arrSpeed[0] = 0; break; // В case 7: arrRoute[1] = 0; arrRoute[0] = 0; arrSpeed[1] = (valSpeed / 2); arrSpeed[0] = valSpeed; break; // Ю-З case 8: arrRoute[1] = 0; arrRoute[0] = 0; arrSpeed[1] = valSpeed; arrSpeed[0] = valSpeed; break; // Ю case 9: arrRoute[1] = 0; arrRoute[0] = 0; arrSpeed[1] = valSpeed; arrSpeed[0] = (valSpeed / 2); break; // Ю-В } // } // ======================================================================================================================================================= if (flg == 10){valSpeed = 5;} // 0 режим скорости else if(flg == 11){valSpeed = 30;} // 1 режим скорости else if(flg == 12){valSpeed = 55;} // 2 режим скорости else if(flg == 13){valSpeed = 80;} // 3 режим скорости else if(flg == 14){valSpeed = 105;} // 4 режим скорости else if(flg == 15){valSpeed = 130;} // 5 режим скорости else if(flg == 16){valSpeed = 155;} // 6 режим скорости else if(flg == 17){valSpeed = 180;} // 7 режим скорости else if(flg == 18){valSpeed = 205;} // 8 режим скорости else if(flg == 19){valSpeed = 230;} // 9 режим скорости else if(flg == 20){valSpeed = 255;} // 10 режим скорости // if (flg_LED) { // Если флаг установлен (была нажата кнопка включения фары) if (millis() - tmrLED > time_period) { // мигаем светодиодами с заданной частотой tmrLED = millis(); // сохраняем время digitalWrite(pinLED_RED, digitalRead(pinLED_BLUE)); // управляем питанием красного светодиода digitalWrite(pinLED_BLUE, !digitalRead(pinLED_BLUE)); // управляем питанием синего светодиода } // } else { // если флаг сброшен, то digitalWrite(pinLED_RED, LOW); // гасим светодиоды digitalWrite(pinLED_BLUE, LOW); // } // if (flgTime > millis()) { // Если millis() переполнен, то flgTime = 0; // сбрасываем флаг в ноль } // // ПОДАЧА ЗНАЧЕНИЙ СКОРОСТИ И НАПРАВЛЕНИЯ ВРАЩЕНИЯ НА ВЫВОДЫ // if (flgTime > (millis() - 500)) { // Если сигналы с телефона приходят (в течении 50 мс) digitalWrite(pinShield_H2, arrRoute[1]); // тогда задаем направление вращения правого мотора digitalWrite(pinShield_H1, arrRoute[0]); // и левого мотора analogWrite(pinShield_E2, arrSpeed[1]); // Задаём скорость вращения для правого мотора analogWrite(pinShield_E1, arrSpeed[0]); // и для левого мотора } else { // Если пакеты не приходят analogWrite(pinShield_E2, 0); // Останавливаем работу моторов analogWrite(pinShield_E1, 0); // } // } //
Ссылка для скачивания скетча.
В данном коде управление роботом осуществляется в три основных этапа: получение данных с телефона; изменение значений переменных arrSpeed, arrRoute; подача питания на моторы и задание направления их вращения. Так же в коде присутствуют дополнительные блоки: включение/выключение светодиодов; изменение скорости вращения колёс; вход в режим сопряжения.
- Получение данных с пульта:
- Данный блок начинается с оператора
if
, в условии которого написаноsoftSerial.available()
. Это условие будет верно, если в последовательный порт будут приходить данные с телефона, в противном случае условие будет ложно; - Далее следует еще один оператор
while
, условием которого опять являетсяsoftSerial.available()
. Если условие верно, то значение, поступившее в последовательный порт, будет записано в переменнуюstr
; задержка в 5 миллисекунд сделана для того, чтобы при низкой скорости передачи Arduino успел полностью прочитать значение из последовательного порта в переменнуюstr
;
- Данный блок начинается с оператора
- Изменение значений переменных arrSpeed, arrRoute:
- Данный блок начинается с оператора
if
, в условии которого написаноstr == XX
. В зависимости от значенияXX
, которое принимает переменнаяstr
(одно из 9 для основных функций), сбрасываетсяflgTime
– таймер начала выполнения функции, а так же устанавливается значение флагаflg
(от 1 до 9); - Далее следует конструкция
switch...case
, в которой операторswitch
сравнивает значение флагаflg
с операторомcase
и, в зависимости от значения флагаflg
, выполняет код, где задаётся, на какой мотор будет подано питание (переменнаяarrSpeed
) и с каким направлением вращения ( переменнаяarrRoute
);
- Данный блок начинается с оператора
- Подача питания на моторы и задание направления их вращения:
- Данный блок начинается с оператора
if
, в условии которого написаноflgTime > (millis() - 50)
. Это условие будет верно в течении 50 миллисекунд после начала приёма сигнала от телефона и установит на выводах Arduino значения переменныхarrSpeed
иarrRoute
. Если же сигнала в течении 50 миллисекунд не поступит, то операторelse
сбросит значение скорости в 0 и робот остановится;
- Данный блок начинается с оператора
- Включение/выключение светодиодов:
- Данный блок включает в себя 2 части: получение сигнала с телефона и изменение флага
flg_LED
; включение/выключение светодиодов; - Первая часть начинается с оператора
if
, в условии которого написано( str == "SWS" || str == "SwS")
. Условие будет верно, если значение переменнойstr
будет равноSWS
ИЛИSwS
, что приведёт к установке флагаflg_LED
в противоположное от нынешнего значение; - Вторая часть начинается с оператора
if
, в условии которого написано(flg_LED)
. Условие будет верно, если значение флагаflg_LED
будетtrue
, что приведёт к включению светодиодов. Если же значение флагаflg_LED
будетfalse
, то светодиоды погаснут.
- Данный блок включает в себя 2 части: получение сигнала с телефона и изменение флага
- Изменение скорости вращения колёс:
- Данный бок включает в себя 2 части: получение сигнала с телефона и изменение флага
flg
; изменение значения переменнойvalSpeed
; - Первая часть начинается с оператора
if
, в условии которого написаноstr == XX
. В зависимости от значенияXX
, которое принимает переменнаяstr
(одно из 11 для дополнительных функций), устанавливается значение флагаflg
(от 10 до 20); - Вторая часть начинается с оператора
if
, в условии которого написаноflg == XX
. В зависимости от значенияXX
, которое принимает переменнаяflg
(одно из 11 для дополнительных функций), устанавливается значение переменнойvalSpeed
(от 5 до 255);
- Данный бок включает в себя 2 части: получение сигнала с телефона и изменение флага
- Вход в режим сопряжения (выполняется при подаче питания на робота):
- Данный блок находится в коде
void setup()
и начинается с оператораif
, в условии которого написаноhc05.begin(softSerial)
. Это условие будет верно, если произошла успешная инициализация с Bluetooth модулем по шине UART, о чём будет выведено сообщение в монитор последовательного порта; - Далее происходит сброс таймера
tmrWait
и идёт проверка условия!hc05.checkConnect() && millis()<tmrWait 60000
в операторе циклаwhile
. До тех пор, пока не произойдёт сопряжения Bluetooth модуля робота и телефона И не истечёт минута(60 сек), модуль будет выполнять пустой цикл. - После цика
while
следует операторif
, в условии которого написаноmillis()<tmrWait 60000
. Условие будет верно, если одно из условие!hc05.checkConnect()
цикла while изменится на противоположное и произойдёт это раньше, чем через 60 секунд от подачи питания на робота. Тогда в монитор последовательного порта будет выведено сообщение о том, что сопряжение произошло с ранее созданной парой из памяти устройства. - Если по истечении минуты не произошло сопряжение ранее созданной пары, то далее следует оператор
else
, который выполняет вызов функцииcreateSlave("BT_CAR", "1234")
объектаhc05
, которая назначает Bluetooth модулю робота роль ведомого с именем “BT_CAR” и PIN-кодом “1234”, разрывает ранее установленную связь с мастером (если она была) и стирает список ранее созданных пар. После этого модуль начинает ожидать подключения мастера, который правильно укажет имя и PIN-код модуля. Об успешном или, наоборот, неудачном выполнении функции будет выведено сообщение в монитор последовательного порта.
- Данный блок находится в коде
Получение данных и работа с Trema-модулем Bluetooth HC-05 осуществляется через функции и методы объекта hc05 библиотеки iarduino_Bluetooth_HC05, с подробным описанием которых можно ознакомиться на странице Wiki – Trema-модуль bluetooth HC-05.
Управляем arduino через bluetooth hc-06, с компьютера или смартфона
Для беспроводного обмена информации, между различными устройствами на небольших дистанциях, можно использовать Bluetooth-технологию. Для этих целей китайской промышленностью выпускаются различные Bluetooth-модули, среди которых широкую популярность получили модели HC-05 и HC-06. В своё время на Алиэкспресс я приобрёл HC-06, на котором и буду проводить дальнейшие эксперименты, а так же подключать к своему китайскому аналогу Arduino.
Непосредственно сам Bluetooth-модуль. В таком виде он может использоваться в различных устройствах, где впаивается непосредственно в плату. Модуль имеет 34 вывода, среди которых: выводы для соединения с компьютером по UART, передачи звука по методу PCM (импульсно кодовая модуляция), аналоговый вход и выход, контакты для подключения к USB разъёму, SPI интерфейс, а также порты общего назначения. На самом деле не все эти выводы доступны к использованию, заблокирован доступ к выводам передачи звука (5-8), аналоговым входу и выходу (9, 10), а так же к группе контактов для подключения к USB (15, 20).
HC-06 построен на чипе BC417 (BlueCore4-External device), спецификация Bluetooth V2.0. На борту так же имеется кварц на 26 МГц и флеш-память на 8 Мб. Питание осуществляется от 3,3В.
Для своих конструкций удобнее всего использовать модуль с макетной платой, на которой выведены необходимые контакты для подключений, а так же имеется стабилизатор напряжения, который позволяет питаться от 5 вольт.
При покупки подобных модулей, можете столкнуться с различными их маркировками. По сути это одно и то же устройство, отличающееся прошивкой, которая определяет режим модуля (master / slave).
Отличие HC-05 от HC-06 состоит в том, что HC-05 можно использовать в качестве ведомого (master) или ведущего (slave). Данные режимы задаются с помощью АТ-команд. Кнопка на плате модуля переключает его в режим ввода АТ-команд. Режим master даёт возможность модулю самому обнаруживать подобное устройство и организовывать связь с ним. Модуль HC-06 может работать только в одном фиксированном режиме slave.
Так же существуют модели HC-03 и HC-04, но они выпускаются для промышленных целей.
Обозначение контактов на плате HC-06.
STATE – проверка состояние модуля. На этом контакте дублируется сигнал, который отображает встроенный на плате светодиод. Если он очень быстро мигает, значит модуль находится в активном состоянии. В режиме установления связи ток составляет 30-40 мА. Когда модуль устанавливает связь с другим устройством, светодиод просто горит. В режиме передачи данных ток составляет 8 мА.
RX – получение данных.
TX – передача данных.
GND – подключается к земле.
5V – питание 5 Вольт
EN – включение / выключение модуля. Если на этот контакт подать логическую 1 (5 вольт), модуль выключится, если подать логический 0 или не подключаться к этому контакту, модуль будет работать.
По-умолчанию HC-06 имеет имя для обнаружения другими устройствами «HC-06», с пин-кодом «1234».
Для изменения этих данных нужно модуль подключить к компьютеру и с помощью программы-терминала ввести АТ-команды. Это можно сделать с помощью переходника USB to COM с TTL уровнями. Для этих целей подойдёт адаптер на PL2303HX, CH340G, либо другой подобный. На компьютере к этому моменту уже должен быть установлен драйвер для USB адаптера.
Контакты соединяем следующим образом:
При подключении этой сборки к компьютеру, красный светодиод на плате Bluetooth-модуля начнёт быстро мигать. Для ввода АТ-команд можно воспользоваться любой терминальной программой, я использую для этой цели Arduino IDE.
В настройках выбираем номер виртуального COM-порта, на котором подключен USB адаптер, в моём случае это COM44. Откроем окно «Монитора последовательного порта».
Введём заглавными буквами команду «AT», если устройство удачно подключилось, в ответ должно возвратится «ОК». По-умолчанию скорость обмена данными 9600 бод.
Для проверки версии прошивки, введём команду «AT VERSION», в моём случае ответ возвратился «OKlinvorV1.8».
Командой «AT NAMEyyy», где ууу — произвольный набор символов на латинице, можем сменить имя, по которому будут находить наш модуль bluetooth-устройства (по-умолчанию HC-06). В своём примере я ввёл «AT NAMEfox», ответ возвращается OKsetname.
Командой «AT PINxxxx», где xxxx – произвольный набор цифр, можно сменить пин-код (по-умолчанию 1234). В ответ возвращается «OKsetPIN».
Командой «AT BAUDx», где x – значение от 1 до 9, можно изменить скорость в бодах (по-умолчанию 9600).
1 – 1200
2 – 2400
3 – 4800
4 – 9600
5 – 19200
6 – 38400
7 – 57600
8 – 115200
9 – 230400
Допустим, если ведём команду «AT BAUD8», где 8 — скорость 115200 бод, в ответ возвратится «OK115200».
Подключение HC-06 к Arduino.
Пример 1. Зальём в Arduino скетч, с помощью которого будем включать и выключать светодиод, распаянный на 13 пине Arduino, через Bluetooth-модуль.
Если у вас нет на плате данного светодиода, подключите его к 13 пину по схеме, номиналы резисторов можно взять от 220 Ом до 1кОм.
Обесточим Arduino и подключим HC-06. Контакт TX модуля подключаем к контакту RX Ардуино (пин 0 на плате UNO), а контакт RX, к контакту TX (пин 1). Контакты 5V и GND, подключаются к соответствующим пинам Ардуино.
Конструкция в сборе. Подав питание на Ардуино, светодиод на HC-06 должен быстро мигать.
Управление Arduino через HC-06, с помощью компьютера.
Пример буду показывать на Windows XP. К компьютеру должен быть подключен любой USB Bluetooth-адаптер и установленны на него драйвера.
В моём случае использовался вот такой адаптер.
При его подключении к ПК, в трее (возле часов) появляется соответствующая иконка.
Нажимаем правой кнопкой мыши на данной иконке и в контекстном меню выбираем «Добавить устройство Bluetooth».
Ставим переключатель «Устройство установлено и готово к обнаружению» и нажимаем «Далее».
В списке обнаруженных устройств отобразится наш Bluetooth-модуль, с новым именем, которое я поменял ранее. Выбираем его и нажимаем «Далее».
В следующем окне вводим пин-код для подключения к модулю, выбрав пункт «Использовать ключ доступа из документации:». По-умолчанию это «1234», но я его сменил на «9999». Нажимаем «Далее».
Bluetooth-модуль успешно связался с компьютером, о чём можно узнать с соответствующего окна. Следует обратить внимание, при образовании связи между двумя Bluetooth-устройствами, на компьютере создастся два новых виртуальных COM-порта (будут отображаться в диспетчере устройств), один для исходящих данных, другой для входящих. Нам понадобится порт для исходящих данных, в моём случае это COM45.
Вновь открываем какую-нибудь программу-терминал, я воспользуюсь Arduino IDE. В настройках выбираем исходящий порт (у меня COM45), открываем «Монитор последовательного порта», вводим переменно команды «1» и «0». При команде «1» светодиод загорается, при «0» гаснет.
Управление Arduino через HC-06 с помощью смартфона.
Наверное уже все современные смартфоны имеют в своём составе встроенный Bluetooth. Остаётся только установить программу терминал. В моём случае использовалась Lumia 640 DS, с установленной Windows mobile 10. В качестве программы терминала использую «BT Terminal». На Android-смартфонах всё аналогично, в качестве программы можно использовать «Bluetooth Terminal».
Для обладателей смартфонов компании Apple не получится работать с Bluetooth-модулями HC-05 и HC-06 (Bluetooth V2.0), для них придётся использовать адаптеры с технологией BLE (Bluetooth low energy), спецификация Bluetooth 4.0. Ярким представителем является модуль HM-10.
Сопрягаем HC-06 с блютузом смартфона.
1. В «Параметрах» смартфона выбираем пункт «Устройства».
2. Далее «Bluetooth и другие устройства».
3. Включаем ползунком блютуз смартфона и нажимаем на «плюс в квадрате» для поиска и добавления нового Bluetooth-устройства, в нашем случае HC-06.
4. В разделе «Добавить устройство» выбираем «Bluetooth».
5. Смартфон произведёт поиск Bluetooth-устройств находящихся в округе и отобразит их имена. В моём примере найден модуль HC-06, который я переименовал в «fox».
6. Вводим пин-код устройства, к которому подключаемся, нажимаем кнопку «Подключиться».
Устанавливаем и запускаем терминальную программу «BT Terminal». Подключенный к смартфону модуль HC-06, отображается в списке, выбираем его.
Появится поле для ввода команд и кнопка для отправки. Вводим попеременно «1» и «0» и наблюдаем за светодиодом на 13 пине, который будет зажигаться или гаснуть.
Пример 2. Подключим к Arduino три светодиода и попробуем управлять ими через Bluetooth-модуль HC-06.
Светодиоды подключил к 9, 11 и 13 пину, если будите использовать другие пины, их нужно указать в скетче.
int data; int LED1 = 9; int LED2 = 11; int LED3 = 13; void setup() { Serial.begin(9600); pinMode(LED1, OUTPUT); pinMode(LED2, OUTPUT); pinMode(LED3, OUTPUT); digitalWrite(LED1, HIGH); digitalWrite(LED2, HIGH); digitalWrite(LED3, HIGH); } void loop() { if (Serial.available()) { data = Serial.read(); if (data == ‘1’) { digitalWrite(LED1, HIGH); } if ( data == ‘2’) { digitalWrite(LED1, LOW); } if (data == ‘3’) { digitalWrite(LED2, HIGH); } if ( data == ‘4’) { digitalWrite(LED2, LOW); } if (data == ‘5’) { digitalWrite(LED3, HIGH); } if ( data == ‘6’) { digitalWrite(LED3, LOW); } } } |
При заливке скетча модуль HC-06 нужно отсоединить от Ардуино, потому что и компьютер, и блютуз работают по UART. Ардуина не может на одном UART работать с несколькими устройствами.
Запускаем программу-терминал и пробуем скетч в действии. Смысл управления светодиодами следующий, имеется три светодиода, каждый из которых может быть либо включенный, либо выключенный. Получается 6 команд. Команды представляют из себя цифры от 1 до 6 ( 1, 3, 5 – зажечь 1, 2 и 3 светодиоды. 2, 4, 6 – погасить). Цифры можно вводить по одной, либо в виде комбинаций. Например: 145 – зажечь первый, погасить 2-й, зажечь 3-й.
Пример 3. Подключим к Arduino реле-модуль из статьи «Подключаем мощную нагрузку к Arduino, через реле модуль» и попробуем управлять мощной нагрузкой через Bluetooth. По сути, у нас получится «умная розетка». К реле-модулям можно подключать различные нагрузки (лампочки, насосы, вентиляторы) и управлять ими на расстоянии.
Скетч по этому примеру появится в ближайшее время.