Ведение
Всем доброго времени суток, сегодня я бы хотел вам показать простого робота на Arduino, управляемого с телефона. С помощью приложения вы сможете не только управлять его движением но и регулировать скорость.
Детали
Первое что нужна сделать это купить не достающие вам детали вот их списочек.
1) 4шт колеса с моторчиками
2) 1шт плата Arduino uno или arduino Leonardo ( 2е было использовано мной)
3) 1шт Bluetooh модуль HC-06 с адаптером
4) 1шт Двойной мост L298 контролер двигателей
5) 3шт акомуляторные батарейки с разъемом
6) 1шт резистор на 1КОМ
Сборка
Вот схема нашего робота при дальнейшей сборке придерживайтесь ее.
1) Прикрепите моторчики с колесами на платформу
2) Присоединить двойной мост L298 к нашей платформе с моторчиками. также нам надо подключить моторчики к мосту, и добавить 2 провода для питания.
3) С помощью куска плоского провода мы будем подключать его к плате Arduino, для этого нам понадобится всего 6 проводов, но я оставлю несколько дополнительных на потом.
4) Поместим держатель для батареи в передней части нашего робота.
5) добавим 2 часть нашей платформы с помощью отверстий.
6) Подключим к нашей плате Bluetooh модуль, и закрепим на платформе. Важно rxd не пин к нему припаиваем наш резистор
Программа
Далее загрузим на нашу плату нашу программу
#include <SoftwareSerial.h>
SoftwareSerial BtSerial(10, 11); // RX on Arduino to TX of the module, TX on Arduino to RX of the module - init the software serial lib
const char CR = 13; //ascii(13)= /r
const char LF = 10; //ascii(10)= /n
//Motors
const byte BACK=0;
const byte FORW=1;
const byte LEFT=2;
const byte RIGHT=3;
const byte STOP=4;
const byte BRAKE=5;
//Keys
const byte KEYS_OFF=0;
const byte KEY1_ON=1;
const byte KEY2_ON=2;
const byte KEY3_ON=3;
String ATmode = "AT";
String Device = "ArduinoRover"; //board name
boolean Echo = false; //enable-disable echo mode of usb data
String RcvUsb; //received string from USB
byte BtBuffer[10]; //Bt receive buffer
//pins
int pinIN1=2; //Low = DX motor back, output
int pinIN2=3; //Low = DX motor Forw, output
int pinENA=5; //PWM speed, DX motor, output PWM
int pinIN3=4; //Low = SX motor back, output
int pinIN4=7; //Low = SX motor Forw, output
int pinENB=6; //PWM speed, SX motor, output PWM
int pinLed=13; //Onboard led, output
byte SxSpeed=0;
byte SxAccel=0;
byte DxSpeed=0;
byte DxAccel=0;
byte Trigger=10; //minimum value from remote control required to operate, do not set to 0
unsigned long SafeTime=1500; //fail safe timer, if no data arrives the rover will stop after SafeTime, just in case the connection drops
unsigned long LastTime=0;
void setup()
{
//setup pins
pinMode(pinLed,OUTPUT);
digitalWrite(pinLed,LOW);
pinMode(pinIN1,OUTPUT);
pinMode(pinIN2,OUTPUT);
pinMode(pinIN3,OUTPUT);
pinMode(pinIN4,OUTPUT);
pinMode(pinENA,OUTPUT);
pinMode(pinENA,OUTPUT);
digitalWrite(pinIN1,HIGH); //stop motors
digitalWrite(pinIN2,HIGH);
digitalWrite(pinIN3,HIGH);
digitalWrite(pinIN4,HIGH);
analogWrite(pinENA,0); //no PWM to motors
analogWrite(pinENB,0);
//Open USB communication
Serial.begin(57600); // usb data rate
//Open Bluetooth communication, the data rate MUST match your module setting (usually 9600bps on a new module)
//If you get trouble try change this setting, also try to send AT from the serial monitor to see if the BT module answer
BtSerial.begin(9600); // SoftwareSerial data rate
while (!Serial && !BtSerial.available()) {
//wait for serial port to connect. Needed for Leonardo only
//exit loop if serial bluetooth data arrives
}
if (Serial) {
//just send a message over Serial monitor
Serial.println("Connected to: " + Device);
}
}
void loop() // run over and over
{
if (BtSerial.available()>6) { //almost 7 bytes received
if (getReceivedBytes()==true) {
//Received data is OK!
LastTime=millis(); //Reload failSafe timer
//received data is ok,bytes:
//0:Function keys values ,1:horizontal slider value,
//2: horizontal acceleration NOT used in this sketch, 3: vertical slider value,
//4: vertical acceleration value NOT used in this sketch,
//5: always 0xFF (transmission terminator), 6: received CRC8
if (BtBuffer[1]==100 && BtBuffer[3]==100) {
//stop
setMotors(LEFT,STOP);
setMotors(RIGHT,STOP);
analogWrite(pinENA,0);
analogWrite(pinENB,0);
digitalWrite(pinLed,LOW);
//Serial.println("Stop!");
}
if (BtBuffer[3]>100+Trigger) {
//back mode
setMotors(LEFT,BACK);
setMotors(RIGHT,BACK);
SxSpeed=map(BtBuffer[3],0,100, 0, 255); //map from 0 to 100
DxSpeed=SxSpeed;
analogWrite(pinENA,DxSpeed);
analogWrite(pinENB,SxSpeed);
digitalWrite(pinLed,HIGH);
//Serial.print("Back: ");
//Serial.println(SxSpeed,DEC);
}
if (BtBuffer[3]<100-Trigger) {
//forw mode
setMotors(LEFT,FORW);
setMotors(RIGHT,FORW);
SxSpeed=map(BtBuffer[3],100,0, 0, 255); //map from 100 to 0
DxSpeed=SxSpeed;
analogWrite(pinENA,DxSpeed);
analogWrite(pinENB,SxSpeed);
digitalWrite(pinLed,HIGH);
//Serial.print("Forw: ");
//Serial.println(SxSpeed,DEC);
}
if (BtBuffer[1]>100+Trigger) {
//Steer right
setMotors(LEFT,FORW);
setMotors(RIGHT,BACK);
SxSpeed=map(BtBuffer[1],0,100, 0, 255); //map from 0 to 100
DxSpeed=SxSpeed;
analogWrite(pinENA,DxSpeed);
analogWrite(pinENB,SxSpeed);
digitalWrite(pinLed,HIGH);
//Serial.print("Right: ");
//Serial.println(SxSpeed,DEC);
}
if (BtBuffer[1]<100-Trigger) {
//Steer left
setMotors(LEFT,BACK);
setMotors(RIGHT,FORW);
SxSpeed=map(BtBuffer[1],100,0, 0, 255); //map from 100 to 0
DxSpeed=SxSpeed;
analogWrite(pinENA,DxSpeed);
analogWrite(pinENB,SxSpeed);
digitalWrite(pinLed,HIGH);
//Serial.print("Left: ");
//Serial.println(SxSpeed,DEC);
}
switch (BtBuffer[0]) {
//check for function keys pressed
case KEYS_OFF:
//do what you want when the functions keys are released
//Serial.println("Keys released");
break;
case KEY1_ON:
//do what you want when the function key1 is pressed
//Serial.println("Key1 on");
break;
case KEY2_ON:
//do what you want when the function key2 is pressed
//Serial.println("Key2 on");
break;
case KEY3_ON:
//do what you want when the function key3 is pressed
//Serial.println("Key3 on");
break;
default:
//not used
break;
}
}
}
//check for safe timer
if(millis() - LastTime >= SafeTime) {
//receive timeout, stop the rover
setMotors(LEFT,STOP);
setMotors(RIGHT,STOP);
analogWrite(pinENA,0);
analogWrite(pinENB,0);
digitalWrite(pinLed,LOW);
//Serial.println("Stop for timeout");
}
//check for data over USB
if (Serial.available())
{
RcvUsb = ReadUsbBuffer(Echo);
//do usb commands
if (RcvUsb.startsWith("Echo")) {
//Echo on Echo off mode
UsbEchoMode(RcvUsb);
}
if (RcvUsb == ("Device")) {
//Send the description of the connected device
Serial.println(Device);
}
if (RcvUsb.startsWith(ATmode)) {
//Echo on Echo off mode
UsbSendAtMode(RcvUsb);
}
}
}
//Set the motors on or off and direction
void setMotors(byte Side, byte Direction) {
if (Side==LEFT) {
//left side motors
switch (Direction) {
case FORW:
digitalWrite(pinIN3,HIGH);
digitalWrite(pinIN4,LOW);
break;
case BACK:
digitalWrite(pinIN3,LOW);
digitalWrite(pinIN4,HIGH);
break;
case STOP:
//free wheel
digitalWrite(pinIN3,HIGH);
digitalWrite(pinIN4,HIGH);
break;
default:
//not used
break;
}
}
if (Side==RIGHT) {
//right side motors
switch (Direction) {
case FORW:
digitalWrite(pinIN1,HIGH);
digitalWrite(pinIN2,LOW);
break;
case BACK:
digitalWrite(pinIN1,LOW);
digitalWrite(pinIN2,HIGH);
break;
case STOP:
//free wheel
digitalWrite(pinIN1,HIGH);
digitalWrite(pinIN2,HIGH);
break;
default:
//not used
break;
}
}
}
//get data from serial bluetooth
//data must End with 0xFF
//data Is: Function, servo1 pos, speed1, servo2 pos, speed2, 0xFF, CRC8
//BtData=Array As Byte(Function,Hv,2.5*HoServoAcc,Vv,2.5*VrServoAcc,255,CRC8)
boolean getReceivedBytes() {
//clear bluetooth buffer
for (int i = 0; i < 7; i++)
{
BtBuffer[i]=0;
}
//read 7 bytes from serial
BtSerial.readBytes(BtBuffer,7);
if (Echo==true) { //print received bytes to usb if Echo is set
for (int i = 0; i < 6; i++) //data byte 6 is CRC8
{
Serial.print(BtBuffer[i],DEC);
Serial.print("\t");
}
Serial.print(BtBuffer[6],HEX); //print the received CRC8 in Hex format
Serial.print("\t");
}
//check data integrity: 0xFF end of frame and CRC8
if (BtBuffer[5]==0xFF && BtBuffer[6]==CRC8(BtBuffer,6)) {
//good reception
if (Echo==true) {
Serial.println("CRC is OK");
}
return true;
} else {
//no good, discard data
if (Echo==true) {
Serial.println("CRC bad");
}
BtSerial.flush();
return false;
}
}
//Receive data from usb, must end with LF !
// if echo mode is true then print data back to usb
String ReadUsbBuffer(boolean Echo) {
String Received;
Received = Serial.readStringUntil(LF);
if (Echo == true) {
Serial.print("You sent: ");
Serial.println(Received);
}
return Received;
}
//set the usb echo mode
void UsbEchoMode( String Received) {
if (Received.endsWith("off")) {
Echo = false;
Serial.println("Echo is off");
}
else {
Echo = true;
Serial.println("Echo is on");
}
}
//Send AT commands to the module, wait for response and print back to USB
//This function is timed-out, the BT module can take more than 500msec to answer
void UsbSendAtMode( String Received) {
BtSerial.print(Received);
Received = BtSerial.readString(); //read until timeout
Serial.println(Received);
}
//CRC-8 - based on the CRC8 formulas by Dallas/Maxim
//code released under the therms of the GNU GPL 3.0 license
//credits to : http://www.leonardomiliani.com/en/2013/un-semplice-crc8-per-arduino/
byte CRC8(const byte *data, byte len) {
byte crc = 0x00;
while (len--) {
byte extract = *data++;
for (byte tempI = 8; tempI; tempI--) {
byte sum = (crc ^ extract) & 0x01;
crc >>= 1;
if (sum) {
crc ^= 0x8C;
}
extract >>= 1;
}
}
return crc;
}
Запустим нашу программу и включим серийный монитор, в строке должна появиться надпись "связанны: ArduinoRover". В серийном мониторе установим скорость обмена данными до 115200.От серийного монитора напишите "Echo" и нажмите отправить. После этого вы увидите отголоски от следующей команды. От серийного монитора напишите "Device" и нажмите кнопку отправить. Вы увидите " Connected to: ArduinoRover". Сейчас вы должны послать "AT". Вы увидите кнопку"OK" примерно через секунду это значит что ваш модуль Bluetooh правильно подключен. Теперь попробуйте найти модуль с телефона и вставить код, как правило это 1234.
Приложение
Теперь ваш робот готов к запуску! Осталось только установить приложение для телефона оно называется IRacer & Arduino BT controller.
Ссылка: https://play.google.com/store/apps/details?id=com.rfo.IRaceradvanced
Приложение позволит вам управлять марсоходом с четырех позиционный джойстик в портретном режиме или с 2 джойстика (мультитач) в ландшафтном режиме.
Откройте меню (значок шестеренки), выберите "Настройки" и выберите устройство Arduino Ровер.
Из меню, выбрать подключение и выберите уже в паре имя Bluetooth модуль из списка для подключения.
В настройках меню есть много вариантов (фон, ограничение скорости ...), чтобы играть с, наслаждайтесь :)
|