Mașinile teleghidate au o magie a lor, pe care ne-o dorim să o simțim de când suntem copii. Cred că fiecare dintre noi și-a dorit la un moment dat să realizeze una. Ținând cont de faptul că plăcile de bază IoT, senzorii și motorașele electrice au devenit relativ accesibile, vă propun să valorificăm această oportunitate și să ne realizăm jucăriile mult visate. În acest articol, vom porni un astfel de proiect, prin construirea unei mașinuțe teleghidate care va avea și un senzor ultrasonic pentru a nu se ciocni de obiecte.
Cel mai simplu mod este să vă luați un kit arduino de mașină. Veți primi toate componentele necesare, dar foarte probabil fără niciun fel de documentație. Bineînțeles că vă puteți comanda și separat toate componentele. Pentru proiectul de față am folosit:
patru sau două motoare electrice;
Driver motor L298M;
Placă de dezvoltare Arduino Uno;
Modul senzor de recepție infraroșu cu telecomandă;
Suport de baterii 6x1.5 V;
Modul senzor ultrasonic HC-SR04;
Veți mai avea nevoie de un pistol de lipit și de un cablu USB de tip A/B pentru conectarea plăcii Arduino la calculator.
În funcție de modul în care ați configurat sistemul, putem folosi patru sau două motoare. Comenzile vor fi realizate pentru două și vor fi duplicate, dacă este nevoie. În cazul de față vom merge pe configurația cu patru motoare.
Primul pas este conectarea cu ajutorul unui pistol de lipit, a două fire de cele două borne ale fiecărui motor. Folosiți culori diferite pentru a le putea diferenția. Lipiți firele roșii în partea de sus, iar cele negre în partea de jos.
În continuare, pentru a putea controla motoarele, vom avea nevoie de o placă specială, driver/shield. Deoarece, puterea necesară controlului motoarelor este mai mare decât ceea ce ne oferă placa Arduino, vom folosi driverul L298M conectat la o sursă de curent mai mare. Va fi folosit suportul de baterii care ne va da o ieșire de 8V de la cele șase baterii.
Vom conecta în continuare fiecare motor la bornele verzi de pe shield. Acesta ne va da posibilitatea de a controla independent două motoare electrice de curent continuu. Vom conecta câte două fire de la fiecare motor la borne astfel:
MotorA - firele de la motoarele din partea stângă sau dreaptă;
MotorB - firele de la motoarele pe cealaltă parte.
Aveți grijă să conectați firele de același fel împreună, negre și roșii, la aceeași bornă. În continuare, conectăm bornele albastre:
VMS - va fi conectat cablul roșu de la suportul de baterii;
GND - cablul negru de la suportul de baterii și un fir de la placa Arduino Uno de la un slot GND;
Controlul motoarelor se va realiza prin conectarea pinilor: ENA, IN 1 și IN2 pentru primul motor și ENB, IN3 și IN4 pentru cel de-al doilea. ENA și ENB se vor conecta la pinii PWM (Pulse Width Modulation) de pe placa Arduino. Aceștia sunt 3,5,6,19 și 11 și vom folosi ieșirea digitală a acestora pentru a transmite viteza de rotație motoarelor în intervalul 0-255. Real va fi de la 120 la 255, o valoare mai mică va cauza doar un sunet al motoarelor, fără ca acestea să se învârtă. Dacă totul este conectat corect, se vor aprinde leduri atât pe shield cât și pe placa Arduino Uno. Mai multe specificații tehnice puteți găsi aici: https://www.bananarobotics.com/shop/How-to-use-the-L298N-Dual-H-Bridge-Motor-Driver
Pentru a merge înainte, un exemplu simplu este următorul, având grijă să se respecte pini folosiți în mod particular pentru fiecare conexiune:
int dir1PinA=2;
int dir2PinA=3;
int speedPinA=9;
int dir1PinB=4;
int dir2PinB=5;
int speedPinB=10;
void setup(){
pinMode(dir1PinA, OUTPUT);
pinMode(dir2PinA, OUTPUT);
pinMode(speedPinA, OUTPUT);
pinMode(dir1PinB, OUTPUT);
pinMode(dir2PinB, OUTPUT);
pinMode(speedPinB, OUTPUT);
}
void loop(){
analogWrite(speedPinA,200);
digitalWrite(dir1PinA, LOW);
digitalWrite(dir2PinA, HIGH);
analogWrite(speedPinB,200);
digitalWrite(dir1PinB, HIGH);
digitalWrite(dir2PinB, LOW);
}
Așa cum se poate vedea, există destul de mult cod redundant. Dar în Arduino, singurul mod de a realiza o clasă este prin scrierea unei librării. Vom realiza acest lucru într-un stil de lucru C, în care este nevoie să scriem un header h. și definițiile metodelor în .cpp. Se vor defini metode pentru deplasarea în toate cele patru direcții:
#ifndef Motorscontrol_h
#define Motorscontrol_h
#include "Arduino.h"
class Motorscontrol
{
public:
Motorscontrol(int motorPin, int in1,
int in2, int directSpeed, int turnSpeed);
void up();
void down();
void left();
void right();
void stoping();
private:
int _motorPin;
int _in1;
int _in2;
int _directSpeed;
int _turnSpeed;
};
#endif
#include "Motorscontrol.h"
#include "Arduino.h"
Motorscontrol::Motorscontrol(int motorPin, int in1,
int in2, int directSpeed, int turnSpeed)
{
_motorPin=motorPin;
_in1=in1;
_in2=in2;
_directSpeed=directSpeed;
_turnSpeed=turnSpeed;
pinMode(_motorPin, OUTPUT);
pinMode(_in1, OUTPUT);
pinMode(_in2, OUTPUT);
}
void Motorscontrol::stoping(){
analogWrite(_motorPin,0);
digitalWrite(_in1, LOW);
digitalWrite(_in2, LOW);
}
void Motorscontrol::up()
{
analogWrite(_motorPin,_directSpeed);
digitalWrite(_in1, LOW);
digitalWrite(_in2, HIGH);
}
void Motorscontrol::down()
{
analogWrite(_motorPin,_directSpeed);
digitalWrite(_in1, HIGH);
digitalWrite(_in2, LOW);
}
void Motorscontrol::left()
{
analogWrite(_motorPin,_turnSpeed);
digitalWrite(_in1, HIGH);
digitalWrite(_in2, LOW);
}
void Motorscontrol::right()
{
analogWrite(_motorPin,_turnSpeed);
digitalWrite(_in1, LOW);
digitalWrite(_in2, HIGH);
}
Codul este disponibil pe GitHub: https://github.com/ovidiumatan/arduino . Înainte de a folosi librăria, haideți să conectăm la mașinuță telecomanda și senzorul cu ultrasunete, astfel încât să avem o interfață pentru transmiterea comenzilor și să evităm ciocnirile frontale.
Este compus dintr-un receptor, care primește diferite coduri în infraroșu de la o telecomandă. Puteți folosi orice fel de telecomandă sau cea care a venit cu senzorul.
În continuare, vom integra librăria în codul principal. Pentru a avea sens, trebuie să adăugăm suportul pentru telecomandă. Vom folosi codul de mai jos pentru a determina codul butoanelor ce ne interesează. Puteți folosi orice telecomandă disponibilă. Vom conecta pini senzorului astfel:
Y - la unul dintre porturile digitale de pe placa Arduino Uno;
R - la alimentarea de 5V de pe shieldul L298N;
Vom scrie acum o mică aplicație de test pentru determinarea id-urilor asociate butoanelor de pe telecomandă ce vor fi folosite pentru deplasarea mașinuței: sus, jos, stânga, dreapta și stop.
#include <IRremote.h>
const int RECV_PIN = 6;
IRrecv irrecv(RECV_PIN);
decode_results results;
void setup()
{
Serial.begin(9600);
irrecv.enableIRIn();
irrecv.blink13(true);
}
void loop() {
if (irrecv.decode(&results)) {
Serial.println(results.value, HEX);
irrecv.resume();
}
}
Lansăm aplicația și deschidem Serial Monitor, pentru a vedea valorile tipărite. Serial monitorul este un tool util pentru tipărirea diferitelor loguri în consolă atât timp cât suntem conectați la calculator.
Odată descoperite și notate tastele de pe telecomandă cu ajutorul cărora dorim să controlăm roboțelul, putem trece la pasul următor.
Funcționează pe principiul unui sonar și ne ajută să descoperim distanța până la următorul obstacol. Vom conecta firele astfel:
Vcc - alimentarea de 5V de pe shieldul L298N;
Trig - portul analogic A0 de pe Arduino Uno;
Echo - portul analogic A1;
Încercați să puneți senzorul de ultrasunete în fața mașinuței. Partea de construire hardware s-a terminat, trecem acum la aplicația principală Arduino.
#include <Motorscontrol.h>
#include <IRremote.h>
#include <Ultrasonic.h>
const int RECV_PIN = 7;
IRrecv irrecv(RECV_PIN);
decode_results results;
Motorscontrol motorA(9,2,3,200,120);
Motorscontrol motorB(10,4,5,200,120);
Ultrasonic ultrasonic(A0,A1);
int distance;
void setup(){
Serial.begin(9600);
irrecv.enableIRIn();
irrecv.blink13(true);
}
void loop(){
distance = ultrasonic.read();
if (distance<15){
motorA.stoping();
motorB.stoping();
}
Serial.println(distance);
if (irrecv.decode(&results)){
switch (results.value){
case 0xFF18E7: //Up
Serial.println("up");
if (distance>10){
motorA.up();
motorB.down();
} else {
Serial.println("too close");
}
break;
case 0xFF4AB5: //down
Serial.println("down");
motorA.down();
motorB.up();
break;
case 0xFF5AA5: //right
Serial.println("right");
motorA.right();
motorB.right();
break;
case 0xFF10EF: //left
Serial.println("left");
motorA.left();
motorB.left();
break;
case 0xFF38C7: //Ok
motorA.stoping();
motorB.stoping();
break;
default:
motorA.stoping();
motorB.stoping();
}
delay(100);
irrecv.resume();
}
}
Dacă aplicați un singur impuls, un click, mașinuța va realiza comanda în continuu. Dacă în schimb, țineți apăsat pe o direcție, se va realiza o scurtă mișcare, după care mașinuța se va opri.
Sper ca acest articol să vă inspire să realizați mai multe automatizări și roboței în casă.