Arduino RobotCar vezetéknélküli irányítással (Android okostelefonnal, Joystickkal)




 19. Projekt -- Arduino Robot autó vezetéknélküli irányítással -- V1.0

 by Roboworld Hobbielektronika


Rövid leírás:

Ebben a rövid projektben bemutatjuk neked hogyan tudod az előző projektben elkészített vezetékes irányítású robotautót úgy módosítani, hogy azt vezeték nélkül lehessen vezérelni. A vezetéknélküli kommunikációt egy HC-05 típusú bluetooth modul fogja szolgáltatni számunkra. Természetesen a vezetéknélküli kommunikációra más modulok is megtennék mint pl.: NRF24L01 vagy a HC-12 adóvevő modul. A vezetéknélküli vezérlésre két különböző lehetőséget fogok mutatni. Az egyik az amikor saját „távirányítót” készítünk. A másik pedig amikor egy Androidos okostelefonre készítjük el saját alkalmazásunkat és azon keresztül irányítjuk az autót.

Hardware:
1db Arduino UNO mikrovezérlő
1db Arduino Nano mikrovezérlő
1 db L298N motorvezérlő 2 db DC motor
1db Joystick
2 db HC-05 Bluetooth modul vagy 2db HC-06 Bluetooth modul modul
1db lemez/falap az autó vázához.
1db Androidos okostelefon

1.eset: Irányítás Joystickkal, távirányító készítés
Kapcsolási rajz


Amire szükségünk van az két DC motor egy Arduino mikrovezérlő, egy L298N motorvezérlő valamint egy Joystick, amivel irányíthatjuk az autónkat. Valamint szükségünk van még két darab Bluetooth modulra, amely a kommunikációért felel.

Elsőként a bluetooth kommunikációval kezdjük, mivel ki kell alakítani a Master- Slave kapcsolatot. Ezt könnyedén megtudjuk tenni. A Joystick lesz a Master (mester) eszközünk mivel az fogja közvetíteni a robot felé, hogy merre akarjuk irányítani. Az Arduino robotautó pedig fogja betölteni a Slave (szolga) opciót.

Mintakód:
Az előző projektben létrehozott programkódot használjuk, ahol közvetlenül vezetéken keresztül tudtuk vezérelni az autót. A vezetéknélküli kommunikációhoz csak néhány módosítást kell elvégezni.

HC-05 Master mintakód:
int xAxis, yAxis; 
void setup() { 
Serial.begin(38400); // alapértelmezett kommunikációs csatorna a Bluetooth modulhoz 
} 
void loop() { 
xAxis = analogRead(A0); //Olvassa a Joystick X tengely értékét 
yAxis = analogRead(A1); //Olvassa a Joystick Y tengely értékét 

//Küldi az értékeket a Slave HC-05 Bluetooth eszköznek. 

Serial.write(xAxis/4); // Osztja az értéket (0-1023 tartomány) 4-el ezzel elérve a konvertálást 0-255 tartományra. 
Serial.write(yAxis/4); 
delay(20); 
} 

A mintakód a Master eszközön egészen egyszerű. Csak le kell olvastatnunk az X és az Y tengely értékeit a Joystickról, amellyel ténylegesen szabályozzuk a motor sebességét és ezeket az értékeket küldjük el a Slave bluetooth eszköznek. Itt megkell hogy említsem, hogy a Joystick analóg értékeit (0-1023) átkell konvertálnunk 0-255 tartományra. Ez azért tesszük mert a 0-255 tartomány az 1 byte és az gyorsabban elküldhető mint 4 byte (0-1023) a Bluetooth eszközzel. 1byte-ot pedig sokkal könnyebb fogadni is a Slave oldalon.

Tehát ha a master oldalon a két értéket (X,Y tengelyértékek) vagyis 2 byte-ot elküldtük a bluetooth eszközön keresztül akkor a slave oldalon ezeket az elküldött értékeket kell olvasni a Serial.read() paranccsal. Először az X majd az Y tengelyértékeket olvassuk le.

HC-05 Slave mintakód változása
// Olvassuk a bejövő adatokat a Joystickról amelyet a Master Bluetooth eszköz közvetít. 
while (Serial.available() >= 2) { 
x = Serial.read(); 
delay(10); 
y = Serial.read(); 
} 

Most pedig az értékeket vissza kell konvertálni 0-255 tartományról 0-1023 tartományra, amely sokkal testreszabottabb a motorvezérlő kódnak, amelyet lejjebb láthatsz.
//Vissza konvertálja az értékeket 0-255 tartományról 0-1023 
xAxis = x*4; 
yAxis = y*4; 

 
TELJES HC-05 Slave mintakód
#define enA 9 
#define in1 4 
#define in2 5 
#define enB 10 
#define in3 6 
#define in4 7 
int xAxis, yAxis; 
unsigned int x = 0; 
unsigned int y = 0; 
int motorSpeedA = 0; 
int motorSpeedB = 0; 

void setup() { 
pinMode(enA, OUTPUT); 
pinMode(enB, OUTPUT); 
pinMode(in1, OUTPUT); 
pinMode(in2, OUTPUT); 
pinMode(in3, OUTPUT); 
pinMode(in4, OUTPUT); 
Serial.begin(38400); // alapértelmezett kommunikációs csatorna a bluetooth modulhoz 
} 

void loop() { 
// Alapértelmezett érték- Nincs mozgás, ha középen van a Joystick. 
x = 510 / 4; 
y = 510 / 4; 
// Olvassa a bejövő adatokat a Josytickról amelyet a Master Bluetooth eszköz közvetít 
while (Serial.available() >= 2) { 
x = Serial.read(); 
delay(10); 
y = Serial.read(); 
} 
delay(10); 
// Vissza konvertálja az értékeket 0-255 tartományról 0-1023 
xAxis = x*4; 
yAxis = y*4; 
// Y-tengely az előremenet és hátramenet használatára 
if (yAxis < 470) { 
// Motor A hátramenet 
digitalWrite(in1, HIGH); 
digitalWrite(in2, LOW); 
// Motor B hátramenet 
digitalWrite(in3, HIGH); 
digitalWrite(in4, LOW); 
//Az Y tengely a hátramenet miatt 470-0 à 0-255 tartományra konvertáljuk. Ahogy növekszik ebben a tartományban az érték //(PWM) úgy nő a motor sebessége. 
motorSpeedA = map(yAxis, 470, 0, 0, 255); 
motorSpeedB = map(yAxis, 470, 0, 0, 255); 
} 
else if (yAxis > 550) { 
// Motor A előremenet 
digitalWrite(in1, LOW); 
digitalWrite(in2, HIGH); 
// Set Motor B előremenet 
digitalWrite(in3, LOW); 
digitalWrite(in4, HIGH); 
//Az Y tengely a előremenet miatt 550-1023 à 0-255 tartományra konvertáljuk. Ahogy növekszik ebben a tartományban az //érték(PWM) úgy nő a motor sebessége. 
motorSpeedA = map(yAxis, 550, 1023, 0, 255); 
motorSpeedB = map(yAxis, 550, 1023, 0, 255); 
} 
//Ha a Joystick középen van akkor nincs motor mozgás 
else { 
motorSpeedA = 0; 
motorSpeedB = 0; 
} 
// X-tengely a jobb és bal irányra használjuk 
if (xAxis < 470) { 
//Konvertáljuk az X tengely 470-0 tartományát 0-255 tartományra. 
int xMapped = map(xAxis, 470, 0, 0, 255); 
// Balra irányít -  Csökkenti a bal motor sebességét, míg a jobb oldalit növeli 
motorSpeedA = motorSpeedA - xMapped; 
motorSpeedB = motorSpeedB + xMapped; 
// A tartomány meghatározása 0 és 255 között. 
if (motorSpeedA < 0) { 
motorSpeedA = 0; 
} 
if (motorSpeedB > 255) { 
motorSpeedB = 255; 
} 
} 
if (xAxis > 550) { 
//Konvertáljuk az X tengely 550-1023 tartományát 0-255 tartományra. 
int xMapped = map(xAxis, 550, 1023, 0, 255); 
// Jobbra irányít -  Csökkenti a jobb motor sebességét, míg a bal oldalit növeli 
motorSpeedA = motorSpeedA + xMapped; 
motorSpeedB = motorSpeedB - xMapped; 
// A tartomány meghatározása 0 és 255 között. 
if (motorSpeedA > 255) { 
motorSpeedA = 255; 
} 
if (motorSpeedB < 0) { 
motorSpeedB = 0; 
} 
} 
// Alacsony fordulatszámon történő zümmögés megakadályozása. Motortól függően a motorok nem mozognak, ha PWM érték //70-nél kisebb 
if (motorSpeedA < 70) { 
motorSpeedA = 0; 
} 
if (motorSpeedB < 70) { 
motorSpeedB = 0; 
} 
analogWrite(enA, motorSpeedA); // Elküldeni PWM jelet a MOTOR A-nak 
analogWrite(enB, motorSpeedB); // Elküldeni PWM jelet a MOTOR B-nak 
} 

2.eset: Irányítás okostelefonnal, APP készítés

Most pedig nézzük, hogyan kell az Arduino robotautónkat egy okostelefonnal irányítani. A kapcsolási rajz nem változott, mivel csak a irányításra használt eszközt változtattuk meg. Tehát tulajdonképpen az Joystick szerepét az okostelefon veszi át. Az Android applikációt a már korábban (LINK ) használt MIT App Inventor segítségével készítjük el.

A serial.read függvényt használjuk ezen esetben is.
// Olvassuk a bejövő adatokat az Android applikációból 
while (Serial.available() >= 2) { 
x = Serial.read(); 
delay(10); 
y = Serial.read(); 
} 
Amire szükségünk van az az, hogy az okostelefonból beérkező X,Y értékeket átkonvertáljuk 0-1023 tartományra, amely a motorvezérlés miatt szükséges. A konvertálási érték függ az applikáció „Canvas” méretétől. Az X és az Y értékek, amelyeket az applikációból nyertem ki az 60 -220 tartomány. A map() függvényt használva pedig könnyedén tudjuk konvertálni a megfelelő értékre.
if (x > 60 & x < 220) { 
xAxis = map(x, 220, 60, 1023, 0); // Konvertáljuk az értékeket 0-1023 tartományra. 
} 
if (y > 60 & y < 220) { 
yAxis = map(y, 220, 60, 0, 1023); 
} 
Az applikációban ugyancsak láthatjuk, hogy amikor a virtuális Joystickot megérintjük és előre irányt választunk akkor előre megy az autónk. Elengedve azt pedig visszatér középállapotba amely az autó megállását eredményezi.

Az applikációt letöltheted az alábbi linkről, valamint csatolom az aia kiterjesztésű fájlt, amelyet beillesztve a MIT App Inventorba magad is testre szabhatod azt. (A MIT App Inventorba a következő menüpont alatt találod a beillesztést: Project/ Import project (aia) from your computer). Mindenképp ajánlom, hogy nézd meg az aia kiterjesztésű fájl, hogy még jobban láthasd, hogy mi van az applikáció belsőjében.


Applikáció funkcióblokkjai




TELJES MINTAKÓD (Okostelefon használata esetén)
#define enA 9 
#define in1 4 
#define in2 5 
#define enB 10 
#define in3 6 
#define in4 7 
int xAxis, yAxis; 
int x = 0; 
int y = 0; 
int motorSpeedA = 0; 
int motorSpeedB = 0; 

void setup() { 
pinMode(enA, OUTPUT); 
pinMode(enB, OUTPUT); 
pinMode(in1, OUTPUT); 
pinMode(in2, OUTPUT); 
pinMode(in3, OUTPUT); 
pinMode(in4, OUTPUT); 
Serial.begin(38400); // Alapértelmezett kommunikációs csatorna beállítása a Bluetooth modulnak 
} 

void loop() { 
// Alapértelmezett érték- nincs mozgás, ha a Joystick középállásban van 
xAxis = 510; 
yAxis = 510; 
// Olvassa a bejövő értékeket az okostelefon appjáról. 
while (Serial.available() >= 2) { 
x = Serial.read(); 
delay(10); 
y = Serial.read(); 
} 
delay(10); 
if (x > 60 & x < 220) { 
xAxis = map(x, 220, 60, 1023, 0); // Konvertálja az okostelefon X , Y koordinátáját 0-1023 tartományra 
} 
if (y > 60 & y < 220) { 
yAxis = map(y, 220, 60, 0, 1023); 
} 
// Y-tengely az előremenet és hátramenet használatára 
if (yAxis < 470) { 
// Motor A hátramenet 
digitalWrite(in1, HIGH); 
digitalWrite(in2, LOW); 
// Motor B hátramenet 
digitalWrite(in3, HIGH); 
digitalWrite(in4, LOW); 
//Az Y tengely a hátramenet miatt 470-0 à 0-255 tartományra konvertáljuk. Ahogy növekszik ebben a tartományban az érték //(PWM) úgy nő a motor sebessége. 
motorSpeedA = map(yAxis, 470, 0, 0, 255); 
motorSpeedB = map(yAxis, 470, 0, 0, 255); 
} 
else if (yAxis > 550) { 
// Motor A előremenet 
digitalWrite(in1, LOW); 
digitalWrite(in2, HIGH); 
// Motor B előremenet 
digitalWrite(in3, LOW); 
digitalWrite(in4, HIGH); 
//Az Y tengely a előremenet miatt 550-1023 à 0-255 tartományra konvertáljuk. Ahogy növekszik ebben a tartományban az //érték(PWM) úgy nő a motor sebessége. 
motorSpeedA = map(yAxis, 550, 1023, 0, 255); 
motorSpeedB = map(yAxis, 550, 1023, 0, 255); 
} 
//Ha a Joystick középen van akkor nincs motor mozgás 
else { 
motorSpeedA = 0; 
motorSpeedB = 0; 
} 
// X-tengely a jobb és bal irányra használjuk 
if (xAxis < 470) { 
//Konvertáljuk az X tengely 470-0 tartományát 0-255 tartományra. 
int xMapped = map(xAxis, 470, 0, 0, 255); 
// Balra irányít -  Csökkenti a bal motor sebességét, míg a jobb oldalit növeli 
motorSpeedA = motorSpeedA - xMapped; 
motorSpeedB = motorSpeedB + xMapped; 
// A tartomány meghatározása 0 és 255 között. 
if (motorSpeedA < 0) { 
motorSpeedA = 0; 
} 
if (motorSpeedB > 255) { 
motorSpeedB = 255; 
} 
} 
if (xAxis > 550) { 
//Konvertáljuk az X tengely 550-1023 tartományát 0-255 tartományra. 
int xMapped = map(xAxis, 550, 1023, 0, 255); 
// Jobbra irányít -  Csökkenti a jobb motor sebességét, míg a bal oldalit növeli 
motorSpeedA = motorSpeedA + xMapped; 
motorSpeedB = motorSpeedB - xMapped; 
// A tartomány meghatározása 0 és 255 között. 
if (motorSpeedA > 255) { 
motorSpeedA = 255; 
} 
if (motorSpeedB < 0) { 
motorSpeedB = 0; 
} 
} 
// Alacsony fordulatszámon történő zümmögés megakadályozása. Motortól függően a motorok nem mozognak, ha PWM érték //70-nél kisebb 
if (motorSpeedA < 70) { 
motorSpeedA = 0; 
} 
if (motorSpeedB < 70) { 
motorSpeedB = 0; 
} 
analogWrite(enA, motorSpeedA); // // Elküldeni PWM jelet a MOTOR A-nak 
analogWrite(enB, motorSpeedB); // Elküldeni PWM jelet a MOTOR B-nek 
} 
Letöltés
 A leírás PDF-ben: itt található


Megjegyzések