arduinoBTcontrol — управление Arduino через Bluetooth

Управление Arduino через Bluetooth с помощью HC-06 и Android-приложения, созданного в App Inventor 2.

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/bluetooth-serial-app-2.jpg

Android-приложение

Приложение создано в MIT App Inventor 2. Файл .aia можно скачать внизу страницы. Приложение имеет:

  • Кнопки для включения/выключения светодиодов

  • Ползунки для управления RGB-светодиодом

  • Навигационную клавиатуру

  • Кнопки команд

  • Демо-режим для тестирования без Bluetooth-подключения

Настройка Arduino

Макет

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/bluetooth-serial-app-22.jpg

В руководстве используется RGB-светодиод с общим анодом и резисторами 220–330 Ом.

Подключение Bluetooth-модуля

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/bluetooth-serial-app-21.jpg

Ключевые подключения:

— Arduino D2 (программный serial RX) к BT TX
— Arduino D3 (программный serial TX) к BT RX через делитель напряжения
— GND к GND
— BT VCC к Arduino 5V

«Arduino считает 3.3 В от BT TX пина как HIGH, поэтому его можно подключить напрямую», а TX Arduino требует делителя напряжения.

Настройки BT по умолчанию: скорость 9600 бод, имя HC06.

Сопряжение

  1. Включите HC-06 (светодиод быстро мигает)

  2. Откройте Настройки Android => Bluetooth

  3. Найдите устройства

  4. Выберите HC-06 и введите PIN по умолчанию «1234»

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/bluetooth-serial-app-1.jpg

Подключение к Arduino

  • Запустите Arduino

  • Откройте приложение, перейдите в настройки

  • Нажмите кнопку Bluetooth

  • Выберите HC-06

  • Кнопка BT изменится на «Connected»

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/bluetooth-serial-app-11.jpg

Управление Arduino

Кнопки LED

Переключение вкл/выкл при каждом нажатии.

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/bluetooth-serial-app-12.jpg

Ползунки RGB

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/bluetooth-serial-app-13.jpg https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/bluetooth-serial-app-20.jpg

Скетч Arduino

/*
 * arduinoBTcontrolUpdated
 * Bluetooth-управление с Android-приложения
 * Скачайте Android-приложение на www.martyncurrey.com
 *
 * Пины
 * 2 Software serial - RX
 * 3 Software serial - TX
 * 4-8, 12, 14-18 выходы LED
 * 9-11 пины RGB LED (R, G, B)
 */

// ОТЛАДКА
boolean debug = true;

#include <SoftwareSerial.h>
SoftwareSerial BTserial(2,3); // RX | TX

const byte numChars = 21;
char receivedChars[numChars];
boolean newData = false;

unsigned int red = 255;
unsigned int green = 255;
unsigned int blue = 255;

byte UPpin = 16;
byte DOWNpin = 15;
byte LEFTpin = 14;
byte RIGHTpin = 17;
byte OKpin = 18;

void setup()
{
     pinMode(12, OUTPUT);
     pinMode(8, OUTPUT);
     pinMode(7, OUTPUT);
     pinMode(6, OUTPUT);
     pinMode(5, OUTPUT);
     pinMode(4, OUTPUT);
     pinMode(11, OUTPUT);
     pinMode(10, OUTPUT);
     pinMode(9, OUTPUT);

     // RGB LED с общим анодом, 255 = выключен
     analogWrite(9, red);
     analogWrite(10, green);
     analogWrite(11, blue);

     pinMode(14, OUTPUT);
     pinMode(15, OUTPUT);
     pinMode(16, OUTPUT);
     pinMode(17, OUTPUT);
     pinMode(18, OUTPUT);

     Serial.begin(9600);
     if (debug) { Serial.println("arduinoBTcontrol Ver 2.0"); }
     if (debug) { Serial.println("For use with the arduinoBTcontrol Android app"); }

     BTserial.begin(9600);
}

void loop()
{
     if (BTserial.available() > 0) { recvWithStartEndMarkers(); }
     if (newData) { parseData(); }
}

void parseData()
{
        newData = false;
        if (debug) { Serial.println( receivedChars ); }

        // КНОПКА - формат B001ON / B001OF
        if (receivedChars[0] == 'B')
        {
             int tmp = convertToNumber( 1 );
             if ( receivedChars[4] == 'O' && receivedChars[5] == 'N' ) { digitalWrite(tmp,HIGH); }
             if ( receivedChars[4] == 'O' && receivedChars[5] == 'F' ) { digitalWrite(tmp,LOW);  }
        }

        // RGB ПОЛЗУНОК - формат Trrrgggbbb
        if ( receivedChars[0] == 'T' )
        {
            red = 255 - convertToNumber( 1 );
            green = 255 - convertToNumber( 4 );
            blue = 255 - convertToNumber( 7 );
            analogWrite(9, red);
            analogWrite(10, green);
            analogWrite(11, blue);
        }

        // НАВИГАЦИЯ - формат NUON / NUOF
        if ( receivedChars[0] == 'N' )
        {
              if ( receivedChars[1] == 'U' ) // ВВЕРХ
              {
                  if ( receivedChars[2] == 'O' && receivedChars[3] == 'N' ) { digitalWrite(UPpin,HIGH); }
                  if ( receivedChars[2] == 'O' && receivedChars[3] == 'F' ) { digitalWrite(UPpin,LOW); }
              }

              if ( receivedChars[1] == 'D' ) // ВНИЗ
              {
                  if ( receivedChars[2] == 'O' && receivedChars[3] == 'N' ) { digitalWrite(DOWNpin,HIGH); }
                  if ( receivedChars[2] == 'O' && receivedChars[3] == 'F' ) { digitalWrite(DOWNpin,LOW); }
              }

              if ( receivedChars[1] == 'L' ) // ВЛЕВО
              {
                  if ( receivedChars[2] == 'O' && receivedChars[3] == 'N' ) { digitalWrite(LEFTpin,HIGH); }
                  if ( receivedChars[2] == 'O' && receivedChars[3] == 'F' ) { digitalWrite(LEFTpin,LOW); }
              }

              if ( receivedChars[1] == 'R' ) // ВПРАВО
              {
                  if ( receivedChars[2] == 'O' && receivedChars[3] == 'N' ) { digitalWrite(RIGHTpin,HIGH); }
                  if ( receivedChars[2] == 'O' && receivedChars[3] == 'F' ) { digitalWrite(RIGHTpin,LOW); }
              }

              if ( receivedChars[1] == 'K' ) // OK
              {
                   if ( receivedChars[2] == 'O' && receivedChars[3] == 'K' )
                   {   digitalWrite(OKpin,HIGH);
                       delay(75);
                       digitalWrite(OKpin,LOW);
                   }
              }
        }

        // Кнопки КОМАНД
        if (strcmp ("CCMD1",receivedChars) == 0)
        {
                for ( byte Count = 1; Count <= 15; Count++)
                {
                    digitalWrite(4,HIGH); delay(100); digitalWrite(4,LOW);
                    digitalWrite(12,HIGH); delay(100); digitalWrite(12,LOW);
                }
                 sendOK(1);
        }

        if (strcmp ("CCMD2",receivedChars) == 0)
        {
              for ( byte Count = 1; Count <= 5; Count++)
              {
                  digitalWrite(4,HIGH);  delay(100); digitalWrite(4,LOW);
                  digitalWrite(5,HIGH);  delay(100); digitalWrite(5,LOW);
                  digitalWrite(6,HIGH);  delay(100); digitalWrite(6,LOW);
                  digitalWrite(7,HIGH);  delay(100); digitalWrite(7,LOW);
                  digitalWrite(8,HIGH);  delay(100); digitalWrite(8,LOW);
                  digitalWrite(12,HIGH); delay(100); digitalWrite(12,LOW);
              }
              sendOK(2);
        }

        if (strcmp ("CCMD3",receivedChars) == 0)
        {
            red = 255; green = 255; blue = 255;
            for(int red = 255; red > 0; red--) { analogWrite(9, red); delay(5); }
            for(int red = 0; red < 256; red++) { analogWrite(9, red); delay(5); }
            for(int green = 255; green > 0; green--) { analogWrite(10, green); delay(5); }
            for(int green = 0; green < 256; green++) { analogWrite(10, green); delay(5); }
            for(int blue = 255; blue > 0; blue--) { analogWrite(11, blue); delay(5); }
            for(int blue = 0; blue < 256; blue++) { analogWrite(11, blue); delay(5); }
            sendOK(3);
        }
}

void recvWithStartEndMarkers()
{
     static boolean recvInProgress = false;
     static byte ndx = 0;
     char startMarker = '[';
     char endMarker = ']';
     char rc;

     if (BTserial.available() > 0)
     {
          rc = BTserial.read();
          if (recvInProgress == true)
          {
               if (rc != endMarker)
               {
                    receivedChars[ndx] = rc;
                    ndx++;
                    if (ndx >= numChars) { ndx = numChars - 1; }
               }
               else
               {
                     receivedChars[ndx] = '\0';
                     recvInProgress = false;
                     ndx = 0;
                     newData = true;
               }
          }
          else if (rc == startMarker) { recvInProgress = true; }
     }
}

int convertToNumber(byte startPos)
{
    unsigned int tmp = 0;
    tmp = (receivedChars[startPos]-48) * 100;
    tmp = tmp + (receivedChars[startPos+1]-48) * 10;
    tmp = tmp + receivedChars[startPos+2]-48;
    return tmp;
}

void sendOK(int val)
{
    BTserial.print("OK");BTserial.print(val);BTserial.print("#");
    if (debug) { Serial.print("OK");Serial.print(val);Serial.println("#"); }
}

Объяснение скетча

Основные функции:

  • recvWithStartEndMarkers() — читает данные из serial между маркерами „[“ и „]“

  • parseData() — проверяет полученные команды и выполняет действия

Android-приложение (MIT App Inventor 2)

Управление экранами

Приложение использует вкладки (кнопки) для показа/скрытия контейнеров вместо нескольких экранов, чтобы сохранить Bluetooth-соединение при переключении между видами.

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/bluetooth-serial-app-3.jpg https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/bluetooth-serial-app-4.jpg

Bluetooth-подключение

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/bluetooth-serial-app-5.jpg https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/bluetooth-serial-app-6.jpg

Приём данных

Таймер установлен на 200 мс (5 раз в секунду) для проверки входящих данных. «Буфер проверяется на наличие определённых маркеров» (символ # как конечный маркер).

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/bluetooth-serial-app-7.jpg https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/bluetooth-serial-app-8.jpg

Демо-режим

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/bluetooth-serial-app-9.jpg

Позволяет тестировать без Bluetooth-подключения.

Кнопки пинов (экран MAIN)

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/bluetooth-serial-app-10.jpg https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/bluetooth-serial-app-15.jpg

Кнопки переключают LED вкл/выкл и отправляют команды через функцию buttonPressed.

Кнопки навигации

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/bluetooth-serial-app-16.jpg
  • Кнопки направления отправляют при нажатии и отпускании

  • Кнопка OK отправляет только при нажатии

Кнопки команд

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/bluetooth-serial-app-17.jpg

Становятся красными при активации, ожидают подтверждения Arduino, возвращаются к зелёному при завершении.

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/bluetooth-serial-app-18.jpg

Ползунки RGB

https://alashed-media.s3.eu-north-1.amazonaws.com/wiki/martyncurrey/bluetooth-serial-app-19.jpg

Отправляют значения в формате Trrrgggbbb (ASCII, по 3 символа на каждый цвет).

Скачать

Скачать arduinoBTcontrolUpdated — содержит скетч Arduino и файл App Inventor .aia (273.45 KB)