Содержание:

 

  1. Введение
  2. Видеопрезентация работы
  3. Шаг 1. Устройство с системой Android
  4. Шаг 2. Самодельное автомобильное шасси
  5. Шаг 3. Контроллер (блок микропрограммного управления)
  6. Шаг 4. Модуль Bluetooth
  7. Шаг 5. Контроллер двигателя
  8. Шаг 6. Остальные детали
  9. Шаг 7. Теоретическая часть
  10. Шаг 8. Приложение Android
  11. Шаг 9. Соединения проводками машинки и Arduino контроллера
  12. Шаг 10. Исходный код

 


Введение:

Это простой проект робо-автомобиля, который управляется через Bluetooth. Здесь используется контроллер Arduino.

Для управления автомобилем используется Androidный гаджет со встроенным акселерометром. Наклон акселерометра вперед продвигает машину ехать вперед, наклон влево - машина поворачивает налево, наклон назад - машина едет назад. Всё предельно просто. Скорость движения или вращения зависит от того, насколько круто вы наклоните устройство. Чувствительность и значение наклона устанавливается в настройках приложения Android. Также предоставляется обычный способ управления – кнопки на экране. В дополнение ко всему можно реализовать сенсорное управление.



Видеопрезентация работы:



Шаг 1. Устройство с системой Android:

Самая важная часть проекта - Androidный гаджет с акселерометром и поддержкой Bluetooth. Это может быть планшет, смартфон и др. В качестве примера используется дешевый китайский планшет "Ainol Aurora" с внешним USB-Bluetooth модулем, потому что здесь нет собственного, подключенным через USB-хост.

Шаг 2. Самодельное автомобильное шасси:

Нам понадобится любое шасси с 2 или 4 двигателями постоянного тока. Вы можете использовать старую игрушечную машинку на пульте управления. В качестве платформы используется небольшая дистанционно управляемая база для самодельных устройств, которую можно приобрести на eBay за $ 25. Для лучшей работы устройства рекомендуется использовать колесное шасси.



1 – светодиодный Bluetooth маркер
2 – контроллер движок L289N
3 – двигатель переменного тока
4 – модуль Bluetooth
5 – литиево-полимерный аккумулятор
6 – контроллер Arduino
7 – выключатель для контроллера
8 – выключатель для двигателя.

Шаг 3. Контроллер (блок микропрограммного управления):

Для этого проекта нужен Arduino-совместимый контроллер. Контроллер должен поддерживать 2 PWM и UART.



Шаг 4. Модуль Bluetooth:

В качестве модуля Bluetooth используется дешевый китайский модуль HC-06 (6-8 $ на eBay). Инструкцию по подключению модуля Bluetooth для Arduino можно посмотреть здесь.
Вы можете использовать HC-05, HC-07 и другие серийные модули Bluetooth.



Шаг 5. Контроллер двигателя:

В данном примере используется L298N Dual Bridge, контроллер для двигателя постоянного тока. На eBay эта штука стоит всего 4-5 долларов.



Шаг 6. Остальные детали:



1 – термоусадочные трубки
2 – переключатель
3 – проводки
4 – держатель для батарей

Шаг 7. Теоретическая часть:

Все расчеты производятся в Android-приложении, и сразу же вычисляют значения 2‹2‹ PWM (широтно-импульсная модуляция) для левого и правого двигателя. Приложение имеет гибкие настройки, такие как диапазон PWM, чувствительность наклона, минимальный порог для PWM и другие.
Примеры команд, передаваемых через Bluetooth, следующие:
L-255\rR-120\r
L - команда для левого двигателя
R - для правого
Прочерк означает вращения двигателя
255 - PWM значение (для Arduino это максимальная скорость вращения)
\ r - конец команды.
Заданная команда будет двигать автомобиль вперед и слегка наклонять вправо, а правый двигатель будет медленно поворачиваться влево.

L255\rR-255\r
С этой командой левый двигатель будет вращаться вперед и назад вправо, заставляя машинку вращаться вокруг своей оси против часовой стрелки.

H1\r
Эта команда требует дополнительный канал, к которому можно подключить, например, свет, звук и т.д.
Символы команды L, R и H можно определить в настройках Android-приложения.

В программе управления микроблок обеспечивает таймер, который выключает двигатель, если последняя команда продлилась больше нескольких секунд. Данные хранятся в памяти контроллера EEPROM и могут быть изменены с устройством Android. Диапазон этого параметра составляет от 0,1 секунд до 99,9 секунд. Эта установка может быть отключена. Для работы с EEPROM предоставляются команды: Fr - чтение значений 2‹2‹ и Fw - рекордные значения.

На картинке представлена блок-схема устройства:



Шаг 8. Приложение Android:

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

Приложение для Android было написано в Eclipse IDE. Все источники и сам проект Eclipse вы можете скачать ниже. Android версия на устройстве должна быть продвинутей, чем 3.0.
Приложение содержит несколько особенностей. Основной особенностью является начальный экран с кнопками запуска различных режимов работы и параметров.
Есть 3 режима управления Bluetooth-машинкой: от акселерометра, экранных кнопок и сенсорного управления.

Настройки приложения Android:
Настройки приложения CxemCar Android версии 1.0 изображены на рисунке.
МАС-адрес
Чтобы установить соединение с Bluetooth-модулем автомобиля, вы должны установить MAC-адрес в настройках приложения. Но для этого, во-первых, необходимо настроить пару устройств на Androidном гаджете: откройте Настройки -> Bluetooth и нажмите "Search for devices (поиск устройств)". Когда гаджет находит ваш Bluetooth-модуль, нажмите на него и введите пароль для подключения (как правило, "1234").
Узнать MAC-адрес модуля Bluetooth можно из любого приложения, такого как Bluetooth Terminal. Для этого нажмите "Подключить устройство - Безопасность" и в появившемся окне нажмите кнопку "Поиск устройств". Программное обеспечение будет сканировать Bluetooth устройства и выводить их MAC-адреса.





Шаг 9. Соединения проводками машинки и Arduino контроллера:

В схеме используются перемычки (на рисунке Jmp1), потому что с подключенным модулем Bluetooth невозможно загрузить схему Arduino.

Припаяйте Bluetooth-модуль к контроллеру Arduino и проведите индикатор состояния. Модуль HC-06 должен быть помещен в термоусадочную трубку 10 мм. Светодиодный маркер Bluetooth с ограничительным резистором также нужно поместить в термоусадочную трубку.

В макетной платформе просверлите отверстия и поместите L298N двигатель. Arduino плата крепится с помощью двухсторонней липкой ленты.

Между платформой автомобиля и макетом поместите 3 Li-Po батарейки по 3,7 В емкостью 1100 мАч. Подключите контроллер и двигатели по отдельности: Arduino питается от одной батареи 3,7 В, а двигатели и контролеры двигателей L298N – от двух батарей 3,7 В, соединенных последовательно. Есть две позиции переключателя питания – первая позиция обеспечивает питание от батарей для потребителей, а другая – заряжает  терминалы.

Между контактами BT RX (2) и Arduino TX может потребоваться сдвиг уровней. Для этого вы можете использовать делитель напряжения: расчет 5V до 3,3.







1 – светодиод и резистор
2 - Arduino Nano v3
3 – модуль Bluetooth НС-06





Шаг 10. Исходный код:

Для Arduino IDE 1.01 была написанная следующая программа, включая EEPROM:

#include "EEPROM.h"

#define D1 2          // direction of motor rotation 1
#define M1 3          // PWM left motor
#define D2 4          // direction of motor rotation 2
#define M2 5          // PWM right motor
#define HORN 13       // additional channel 1
//#define autoOFF 2500  // milliseconds after which the robot stops when the connection

#define cmdL 'L'      // UART-command for left motor
#define cmdR 'R'      // UART-command for right motor
#define cmdH 'H'      // UART-command for additional channel (for example Horn)
#define cmdF 'F'      // UART-command for EEPROM operation
#define cmdr 'r'      // UART-command for EEPROM operation (read)
#define cmdw 'w'      // UART-command for EEPROM operation (write)

char incomingByte;    // incoming data

char L_Data[4];       // array data for left motor
byte L_index = 0;     // index of array L
char R_Data[4];       // array data for right motor
byte R_index = 0;     // index of array R
char H_Data[1];       // array data for additional channel
byte H_index = 0;     // index of array H
char F_Data[8];       // array data for  EEPROM
byte F_index = 0;     // index of array F
char command;         // command

unsigned long currentTime, lastTimeCommand, autoOFF;

void setup() {
  Serial.begin(9600);       // initialization UART
  pinMode(HORN, OUTPUT);    // additional channel
  pinMode(D1, OUTPUT);      // output for motor rotation
  pinMode(D2, OUTPUT);      // output for motor rotation
  /*EEPROM.write(0,255);
  EEPROM.write(1,255);
  EEPROM.write(2,255);
  EEPROM.write(3,255);*/
  timer_init();             // initialization software timer
}

void timer_init() {
  uint8_t sw_autoOFF = EEPROM.read(0);   // read EEPROM "is activated or not stopping the car when losing connection"
  if(sw_autoOFF == '1'){                 // if activated
    char var_Data[3];
    var_Data[0] = EEPROM.read(1);
    var_Data[1] = EEPROM.read(2);
    var_Data[2] = EEPROM.read(3);
    autoOFF = atoi(var_Data)*100;        // variable autoOFF ms
  }
  else if(sw_autoOFF == '0'){        
    autoOFF = 999999;
  }
  else if(sw_autoOFF == 255){
    autoOFF = 2500;                      // if the EEPROM is blank, dafault value is 2.5 sec
  }
  currentTime = millis();                // read the time elapsed since application start
}

void loop() {
  if (Serial.available() > 0) {          // if received UART data
    incomingByte = Serial.read();        // raed byte
    if(incomingByte == cmdL) {           // if received data for left motor L
      command = cmdL;                    // current command
      memset(L_Data,0,sizeof(L_Data));   // clear array
      L_index = 0;                       // resetting array index
    }
    else if(incomingByte == cmdR) {      // if received data for left motor R
      command = cmdR;
      memset(R_Data,0,sizeof(R_Data));
      R_index = 0;
    }
    else if(incomingByte == cmdH) {      // if received data for additional channel
      command = cmdH;
      memset(H_Data,0,sizeof(H_Data));
      H_index = 0;
    }   
    else if(incomingByte == cmdF) {      // if received data for EEPROM op
      command = cmdF;
      memset(F_Data,0,sizeof(F_Data));
      F_index = 0;
    }
    else if(incomingByte == '\r') command = 'e';   // end of line
    else if(incomingByte == '\t') command = 't';   // end of line for EEPROM op

    if(command == cmdL && incomingByte != cmdL){
      L_Data[L_index] = incomingByte;              // store each byte in the array
      L_index++;                                   // increment array index
    }
    else if(command == cmdR && incomingByte != cmdR){
      R_Data[R_index] = incomingByte;
      R_index++;
    }
    else if(command == cmdH && incomingByte != cmdH){
      H_Data[H_index] = incomingByte;
      H_index++;
    }   
    else if(command == cmdF && incomingByte != cmdF){
      F_Data[F_index] = incomingByte;
      F_index++;
    }   
    else if(command == 'e'){                       // if we take the line end
      Control4WD(atoi(L_Data),atoi(R_Data),atoi(H_Data));
      delay(10);
    }
    else if(command == 't'){                       // if we take the EEPROM line end
      Flash_Op(F_Data[0],F_Data[1],F_Data[2],F_Data[3],F_Data[4]);
    }
    lastTimeCommand = millis();                    // read the time elapsed since application start
  }
  if(millis() >= (lastTimeCommand + autoOFF)){     // compare the current timer with variable lastTimeCommand + autoOFF
    Control4WD(0,0,0);                             // stop the car
  }
}

void Control4WD(int mLeft, int mRight, uint8_t Horn){

  bool directionL, directionR;      // direction of motor rotation L298N
  byte valueL, valueR;              // PWM M1, M2 (0-255)

  if(mLeft > 0){
    valueL = mLeft;
    directionL = 0;
  }
  else if(mLeft < 0){
    valueL = 255 - abs(mLeft);
    directionL = 1;
  }
  else {
    directionL = 0;
    valueL = 0;
  }

  if(mRight > 0){
    valueR = mRight;
    directionR = 0;
  }
  else if(mRight < 0){
    valueR = 255 - abs(mRight);
    directionR = 1;
  }
  else {
    directionR = 0;
    valueR = 0;
  }

  analogWrite(M1, valueL);            // set speed for left motor
  analogWrite(M2, valueR);            // set speed for right motor
  digitalWrite(D1, directionL);       // set direction of left motor rotation
  digitalWrite(D2, directionR);       // set direction of right motor rotation

  digitalWrite(HORN, Horn);           // additional channel
}

void Flash_Op(char FCMD, uint8_t z1, uint8_t z2, uint8_t z3, uint8_t z4){

  if(FCMD == cmdr){           // if EEPROM data read command
    Serial.print("FData:");       // send EEPROM data
    Serial.write(EEPROM.read(0));     // read value from the memory with 0 address and print it to UART
    Serial.write(EEPROM.read(1));
    Serial.write(EEPROM.read(2));
    Serial.write(EEPROM.read(3));
    Serial.print("\r\n");         // mark the end of the transmission of data EEPROM
  }
  else if(FCMD == cmdw){          // if EEPROM data write command
    EEPROM.write(0,z1);               // z1 record to a memory with 0 address
    EEPROM.write(1,z2);
    EEPROM.write(2,z3);
    EEPROM.write(3,z4);
    timer_init();             // reinitialize the timer
    Serial.print("FWOK\r\n");         // send a message that the data is successfully written to EEPROM
  }
            

Данная программа использует библиотеку для работы с EEPROM AVR-памятью. Arduino плата USART с Bluetooth модулем получает готовые данные для левого и правого двигателя. Все основные расчеты производятся в приложении Android.

Структуру проекта Eclipse вы можете увидеть на снимке.