Controllo di due motori DC con Arduino e un Joystick

Sulla scia del precedente articolo e la richiesta di un Pinco Pallino (http://disq.us/p/1jdnfxe) ecco come realizzare un sistema di controllo di due motori DC con Arduino e un Joystick.
Come sempre per il controllo di semplici motori DC mi avvalgo del comodissimo modulo L298N che con le sue due uscite è l’ideale per pilotare entrambi i motori del nostro progetto.
In occasione di questo progetto mi sono cimentato nella scrittura della mia prima Libreria Arduino. Si chiama L298N e la puoi trovare qui: https://github.com/AndreaLombardo/L298N
Il codice come al solito è ampiamente commentato, ma se qualcosa non ti torna puoi tranquillamente usare la sezione commenti.

Il codice

/*
   Controllo di due motori DC con Arduino e un Joystick

   Autore  : Andrea Lombardo
   Web     : http://www.lombardoandrea.com
   Post    : http://wp.me/p27dYH-Lh
*/

//Inclusione delle librerie
#include <L298N.h>
#include <Bounce2.h>

const int ledEnable = 13; //il led on board ci mostrerà lo stato di attivazione dei motori
const int pinSwEnable = 2;  //il bottone presente nel modulo joystick che abilita o disabilita il controllo

unsigned long debounceDelay = 10; //millisecondi per il debonuce del bottone

const int jX = A0;  //pin analogico che legge i valori per le X
const int EN_X = 3;
const int IN1_X = 4;
const int IN2_X = 5;
long speedX, valX, mapX;  //variabili di gestione movimenti motore X
unsigned int direzioneX;

const int jY = A1;  //pin analogico che legge i valori per le Y
const int EN_Y = 6;
const int IN1_Y = 7;
const int IN2_Y = 8;
long speedY, valY, mapY;  //variabili di gestione movimenti motore Y
unsigned int direzioneY;

const int maxSpeed = 255; //massima velocità settabile per il motore
const int minSpeed = 0; //minima velocità settabile per il motore

const int treshold = 30;  //la lettura dei potenziometri non è mai affidabile al 100%, questo valore aiuta a determinare il punto da considerare come "Stai fermo" nei movimenti
long tresholdUp, tresholdDown;  //variabili di servizio per espletare il compito descritto sopra

boolean abilitato, muoviX, muoviY, enable;  //variabili di gestione dei movimenti

const uint8_t AVANTI = L298N::FORWARD;
const uint8_t DIETRO = L298N::BACKWARD;

Bounce btnEnable = Bounce();  //istanzia un bottone dalla libreria Bounce

//istanzia i motori
L298N motoreX(EN_X, IN1_X, IN2_X);
L298N motoreY(EN_Y, IN1_Y, IN2_Y);

void setup() {
  //inizializza valori
  speedX = speedY = 0;
  enable = false;

  //definizione delle modalità dei pin
  pinMode(ledEnable, OUTPUT);

  pinMode(pinSwEnable, INPUT_PULLUP); //l'input dello switch ha bisogno di essere settato come INPUT_PULLUP

  digitalWrite(ledEnable, enable);

  //configura il bottone del joystick utilizzando la libreria Bounce
  btnEnable.attach(pinSwEnable);
  btnEnable.interval(debounceDelay);

  //calcola range valori entro i quali considerare la posizione del joystick come "Stai fermo"
  tresholdDown = (maxSpeed / 2) - treshold;
  tresholdUp = (maxSpeed / 2) + treshold;

  //configura parametri dei motori
  motoreX.setSpeed(minSpeed);
  motoreY.setSpeed(minSpeed);
}

void loop() {
  //esegui funzione di controllo e lettura del bottone che determina lo stato di abilitazione
  checkEnable();

  digitalWrite(ledEnable, enable);  //mostra stato di abilitazione tramite il led su pin 13

  //esegui lettura analogica dei valori provenienti dai potenziometri del joystick
  valX = analogRead(jX);
  valY = analogRead(jY);

  //mappa i valori letti in funzione della velocità minima e massima
  mapX = map(valX, 0, 1023, minSpeed, maxSpeed);
  mapY = map(valY, 0, 1023, minSpeed, maxSpeed);

  //esegui funzione di comando dei motori
  pilotaMotori(mapX, mapY);
}

void pilotaMotori(long mapX, long mapY) {

  if (mapX <= tresholdDown) {
    //x va indietro
    speedX = map(mapX, tresholdDown, minSpeed,   minSpeed, maxSpeed);
    muoviX = true;
    direzioneX = DIETRO;
  } else if (mapX >= tresholdUp) {
    //x va avanti
    speedX = map(mapX,  maxSpeed, tresholdUp,  maxSpeed, minSpeed);
    muoviX = true;
    direzioneX = AVANTI;
  } else {
    //x sta fermo
    speedX = 0;
    muoviX = false;
  }

  if (mapY <= tresholdDown) {
    //y va giù
    speedY = map(mapY, tresholdDown, minSpeed,   minSpeed, maxSpeed);
    muoviY = true;
    direzioneY = DIETRO;
  } else if (mapY >= tresholdUp) {
    //y va su
    speedY = map(mapY,  maxSpeed, tresholdUp,  maxSpeed, minSpeed);
    muoviY = true;
    direzioneY = AVANTI;
  } else {
    //y sta fermo
    speedY = 0;
    muoviY = false;
  }

  if (enable) {
    if (muoviX) {
      motoreX.setSpeed(speedX);
      motoreX.run(direzioneX);
    } else {
      motoreX.stop();
    }

    if (muoviY) {
      motoreY.setSpeed(speedY);
      motoreY.run(direzioneY);
    } else {
      motoreY.stop();
    }
  } else {
    motoreX.stop();
    motoreY.stop();
  }
}

void checkEnable() {

  btnEnable.update();

  if (btnEnable.fell()) {
    enable = !enable;
  }

}

Come avrai notato, ho utilizzato un’altra libreria nel codice. Si chiama Bounce2 ed è utilissima nella gestione dei bottoni. Per maggiori informazioni ti rimando alla sua pagina GitHub.

Lo schema dei collegamenti

Prodotti Amazon




Potrebbero interessarti anche...

Available for Amazon Prime