ABONAMENTE VIDEO REDACȚIA
RO
EN
×
▼ LISTĂ EDIȚII ▼
Numărul 78
Abonament PDF

Proiect IOT: mașina teleghidată

Ovidiu Mățan
Fondator @ Today Software Magazine
PROGRAMARE


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.

Pregătirea

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:

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.

Conectarea motoarelor

Î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:

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

Clasa Motorscontrol:

#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.

Senzorul infraroșu

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:

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.

Senzorul ultrasonic

Funcționează pe principiul unui sonar și ne ajută să descoperim distanța până la următorul obstacol. Vom conecta firele astfel:

Î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(); 

  }

}

Folosim librăria definită de noi, Motorscontrol și de asemenea, IRemote și Ultrasonic pentru controlul senzorilor. Codul este destul de simplu: se citește distanța până la cel mai apropiat obiect. Dacă este mai mică de 15 cm, mașinuța se oprește. În continuare, se citește valoarea primită de la telecomandă și în funcție de aceasta, se comandă motoarele. În funcție de modul cum au fost conectate motoarele, veți putea inversa unele comenzi de direcție, astfel încât să se potrivească cu sistemul vostru. De asemenea, datorită modului în care sunt conectate pe șasiu motoarele, pentru a merge înainte comanda de la un motor, trebuie să fie inversată la celălalt pentru a putea înainta. În caz contrar, obținem o mișcare de rotație.

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ă.

LANSAREA NUMĂRULUI 87

Prezentări articole și
Panel: Project management

Marți, 24 Septembrie, ora 18:00
Impact Hub, București

Înregistrează-te

Facebook Meetup

Conferință

Sponsori

  • ntt data
  • 3PillarGlobal
  • Betfair
  • Telenav
  • Accenture
  • Siemens
  • Bosch
  • FlowTraders
  • MHP
  • Connatix
  • UIPatj
  • MetroSystems
  • Globant
  • Colors in projects