Motori passo passo per Assi X Y Z con Arduino e Joystick

Eccoci qua, purtroppo come sapete non riesco a stare dietro al sito per mantenerlo aggiornato e nutrirlo di contenuti. Tempo fa avevo scritto un articolo (Controllo di due motori passo passo con Arduino e un Joystick) nel quale spiegavo come controllare due stepper motor attraverso un joystick.

In diversi mi avete chiesto come poter aggiungere un terzo motore con lo scopo quindi di controllare tre assi X Y Z con Arduino e due Joystick, da qui il titolo.

Come mostrato in altre occasioni, una delle migliori soluzioni per pilotare un motore passo passo tramite Arduino è quella di utilizzare dei driver appositi. Ultimamente sto usando dei moduli Pololu A4988 semplici, completi ed affidabili.
Sono progettati per poter comandare i motori in modalità full-, half-, quarter-, eighth-, e sixteenth-step. Ovvero è possibile far ruotare l’asse del motore di uno step completo oppure di 1/2, 1/4, 1/8 e 1/16. Questa funzionalità fa si che i movimenti del motore siano più o meno fluidi e precisi a seconda delle nostre esigenze.


La semplicità di utilizzo sta nel fatto che al nostro driver, in una configurazione base, basteranno solo due PIN (non considerando l’alimentazione logica) ai quali far arrivare due segnali per determinarne la velocità ed il senso di marcia del motore.
La velocità, tramite il pin STEP richiede un alternanza (pulse) di stati logici alto/basso per poter far muovere il motore, mentre tramite il pin DIR, decideremo il senso di marcia.
Maggiori dettagli e caratteristiche sul driver le trovi qui.


Per quanto riguarda invece la parte software deputata alla gestione dei motori passo passo, AccelStepper è la libreria che fa al caso nostro.


Tornando allo scopo del post ti mostro subito il codice che come al solito è ampiamente commentato quindi non necessita di spiegazioni, ma se qualcosa non ti torna puoi tranquillamente usare la sezione commenti.

Il Codice

/*
   Motori passo passo per Assi X Y Z con Arduino e Joystick

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

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

//definizione delle costanti dei pin di Arduino
const int pinSwEnable = 7;  //il bottone presente nel modulo joystick che abilita o disabilita il controllo dei motori X - Y
const int pinSwEnableZ = 11;  //il bottone presente nel modulo joystick che abilita o disabilita il controllo del motore Z
const int pinEnable = 8;  //gestisce lo stato ENABLE dei driver A4988 per i motori X -Y che sono collegati assieme (linea verde dello schema)
const int pinEnableZ = 12;  //gestisce lo stato ENABLE del driver A4988 per il motore Z (linea blu dello schema)

unsigned long debounceDelay = 10; //millisecondi per il debonuce dei bottoni

const int jX = A0;  //pin analogico che legge i valori per le X
const int stepX = 3;  //pin digitale che invia i segnali di STEP al driver delle X
const int dirX = 4; //pin digitale che invia il segnale DIREZIONE al driver delle X
long speedX, valX, mapX;  //variabili di gestione movimenti motore X

const int jY = A1;  //pin analogico che legge i valori per le Y
const int stepY = 5;  //pin digitale che invia i segnali di STEP al driver delle Y
const int dirY = 6; //pin digitale che invia il segnale DIREZIONE al driver delle Y
long speedY, valY, mapY;  //variabili di gestione movimenti motore Y

const int jZ = A2;  //pin analogico che legge i valori per le Z
const int stepZ = 9;  //pin digitale che invia i segnali di STEP al driver delle Z
const int dirZ = 10; //pin digitale che invia il segnale DIREZIONE al driver delle Z
long speedZ, valZ, mapZ;  //variabili di gestione movimenti motore Z

//variabili utilizzate dalla libreria AccelStepper
const int maxSpeed = 1000;  //stando alla documentazione della libreria questo valore può essere impostato fino a 4000 per un Arduino UNO
const int minSpeed = 0; //velocità minima del motore
const float accelerazione = 50.0; //numero di step al secondo in accelerazione

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 muoviX, muoviY, muoviZ, enable, enableZ;  //variabili di gestione dei movimenti

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

//istanzia i motori
AccelStepper motoreX(AccelStepper::DRIVER, stepX, dirX);
AccelStepper motoreY(AccelStepper::DRIVER, stepY, dirY);
AccelStepper motoreZ(AccelStepper::DRIVER, stepZ, dirZ);

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

  enable = false;
  enableZ = false;

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

  //l'input degli switch dei Joystick hanno bisogno di essere settati come INPUT_PULLUP
  pinMode(pinSwEnable, INPUT_PULLUP);
  pinMode(pinSwEnableZ, INPUT_PULLUP);

  //I driver A4988 disabilitano i comandi al motore se sul pin ENABLE ricevono un segnale HIGH
  digitalWrite(pinEnable, !enable);
  digitalWrite(pinEnableZ, !enableZ);

  //configura i botton dei joystick utilizzando la libreria Bounce
  btnEnable.attach(pinSwEnable);
  btnEnableZ.attach(pinSwEnableZ);
  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.setMaxSpeed(maxSpeed);
  motoreX.setSpeed(minSpeed);
  motoreX.setAcceleration(accelerazione);

  motoreY.setMaxSpeed(maxSpeed);
  motoreY.setSpeed(minSpeed);
  motoreY.setAcceleration(accelerazione);

  motoreZ.setMaxSpeed(maxSpeed);
  motoreZ.setSpeed(minSpeed);
  motoreZ.setAcceleration(accelerazione);
}

void loop() {

  //esegui funzione di controllo e lettura dei bottoni che determinano lo stato di abilitazione/disabilitazione dei motori
  checkEnable();

  digitalWrite(pinEnable, !enable);
  digitalWrite(pinEnableZ, !enableZ);

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

  //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);
  mapZ = map(valZ, 0, 1023, minSpeed, maxSpeed);

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

}

void pilotaMotori(long mapX, long mapY, long mapZ) {

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

  if (mapY <= tresholdDown) {
    //y va dietro
    speedY = -map(mapY, tresholdDown, minSpeed,   minSpeed, maxSpeed);
    muoviY = true;
  } else if (mapY >= tresholdUp) {
    //y va avanti
    speedY = map(mapY,  maxSpeed, tresholdUp,  maxSpeed, minSpeed);
    muoviY = true;
  } else {
    //y sta fermo
    speedY = 0;
    muoviY = false;
  }


  if (mapZ <= tresholdDown) {
    //z va giù
    speedZ = -map(mapZ, tresholdDown, minSpeed,   minSpeed, maxSpeed);
    muoviZ = true;
  } else if (mapZ >= tresholdUp) {
    //z va su
    speedZ = map(mapZ,  maxSpeed, tresholdUp,  maxSpeed, minSpeed);
    muoviZ = true;
  } else {
    //z sta fermo
    speedZ = 0;
    muoviZ = false;
  }

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

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

  if (muoviZ) {
    motoreZ.setSpeed(speedZ);
    motoreZ.run();
  } else {
    motoreZ.stop();
  }

}


void checkEnable() {

  btnEnable.update();
  btnEnableZ.update();

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

  if (btnEnableZ.fell()) {
    enableZ = !enableZ;
  }

}

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

Schema collegamenti  Motori passo passo per Assi X Y Z con Arduino e Joystick
Schema dei collegamenti

Per i Joystick
Ricorda che Vcc e GND (joystick) vanno collegati rispettivamente a +5 e GND (Arduino) mentre i pin analogici per i valori di X, Y e Z per il secondo joystick, vanno sui pin A0, A1 e A2. I Pin digitali degli switch vanno sui pin D7 e D12.

Come sempre

  • Assicurati che tutti i collegamenti siano corretti;
  • Ricordati di impostare la porta COM del tuo Arduino;
  • Utilizza le tensioni corrette;
  • E ricorda che io non mi assumo nessuna responsabilità per eventuali danni o disastri che causi 😀

Prodotti Amazon





Potrebbero interessarti anche...