Circuito per slitta motorizzata con Arduino
Realizzazione di un circuito per una slitta motorizzata con Arduino.
Finalmente un pò di libertà per smanettare ancora una volta con Arduino.
E’ passato moltissimo tempo dall’ultimo articolo, tempo durante il quale purtroppo, sono stato assente dal sito e dal canale YouTube. Ciò nonostante, devo dire, siete stati in tanti a scrivere e a commentare (anche privatamente) per dei consigli o anche solo per dei ringraziamenti. Quindi prima di cominciare questo nuovo post, ringrazio tutti voi per aver continuato a leggere i miei seppur vecchi articoli, e per avermi dimostrato che se non altro sono serviti a qualcuno.
Grazie davvero!
Iniziamo
Tra gli articoli più gettonati, ho notato che a suscitare molto interesse, sono stati quelli relativi al controllo di motori passo passo, come ad esempio:
Pilotare un motore passo passo con Arduino e il driver A4988
Controllo di due motori passo passo con Arduino e un Joystick
Prendendo spunto dagli ultimi commenti, ho pensato di realizzare qualcosa che possa, se non soddisfare, quanto meno avvicinarsi, all’esigenza di Walter.
L’idea generale è quella di una slitta che si muove autonomamente avanti e in dietro su un binario. Il tutto immaginario perchè mi sono limitato soltanto alla realizzazione del circuito e del codice. Senza slitta e senza binario per intenderci 😀
All’accensione del sistema, la slitta deve essere in grado di resettare il suo stato e posizionarsi all’inizio del binario.
Questa fase l’ho chiamata “Homing”.
Al termine della fase di homing, la slitta rimane in attesa della pressione di un pulsante, il bottone “Work”, per iniziare il suo movimento.
Per determinare i fine corsa del binario, ho utilizzato due “Limit Switch” o interruttori di fine corsa (come preferisci).
Durante la fase di lavoro sarà possibile scegliere il livello di “risoluzione” del motore. Per risoluzione intendo lo scostamento in termini di step del rotore che grazie al pulsante “Risoluzione” tramite il driver A4988, potrà essere definito in: uno step, 1/2, 1/4, 1/8 e 1/16 di step.
Se durante l’esecuzione dovessero esserci problemi, ho previsto un pulsante di “Reset” che interrompe l’esecuzione del movimento e ripristina lo stato della slitta, che quindi si riposiziona in modalità iniziale.
Scenario
In uno scenario di utilizzo tipo, le cose andrebbero in questo modo:
– accendo il dispositivo;
– aspetto che termini la fase di Homing;
– avvio il movimento con il pulsante Work;
– tramite il pulsante Risoluzione scelgo quella che fa al caso mio (di default è 1 STEP);
– individuata la risoluzione ideale premo il pulsante Reset per riposizionare la slitta;
– a questo punto sono pronto per ripremere il pulsante Work ed eseguire il movimento alla risoluzione scelta.
Lo schema
Come avrai potuto notare dallo schema dei collegamenti, in questa occasione ho deciso di utilizzare un’unica fonte di alimentazione. Uso un alimentatore a 12 volt che alimenta sia Arduino, sia la VMOT del driver A4988 e di conseguenza il motore. Per l’alimentazione logica del driver, uso i 5 volt forniti da Arduino.
La capacità del condensatore elettrolitico posto in parallelo all’alimentazione motore è di 100uF, e come riportato dal sito del produttore deve essere almeno di 47uF.
Warning: This carrier board uses low-ESR ceramic capacitors, which makes it susceptible to destructive LC voltage spikes, especially when using power leads longer than a few inches. Under the right conditions, these spikes can exceed the 35 V maximum voltage rating for the A4988 and permanently damage the board, even when the motor supply voltage is as low as 12 V. One way to protect the driver from such spikes is to put a large (at least 47 µF) electrolytic capacitor across motor power (VMOT) and ground somewhere close to the board.
Sui limit switch e sui pulsanti di comando, ho collegato delle resistenze da 12 Ohm anche se sarebbe meglio qualcosa di più sostanzioso, tipo 10K, in modo da limitare il passaggio di corrente quando premuti e quindi posti a massa. Serve per salvaguardare i pin di Arduino. Purtroppo a casa avevo solo queste.
Il led di stato è collegato sul pin 13 di Arduino. Questo pin presenta già un led on board sulla scheda quindi puoi anche evitare di montarne uno esterno.
Eventualmente, anche in questo caso occorre mettere una resistenza.
Per l’eventuale led esterno, una resistenza da 220 Ohm andrà bene.
In merito al Driver A4988
Ricorda che è possibile regolare la corrente di uscita del driver A4988 tramite il trimmer onboard.
Guarda qui sotto il video del produttore per capire come fare.
Durante i miei test non ho fatto nessuna regolazione, sarà fortuna o sarà un caso, ma né il modulo né il motore sembrano risentirne.
Il codice
Come potrai notare, la velocità del motore durante le fasi di homing e di lavoro sono cablate nel codice. Se non soddisfano le tue esigenze, puoi modificarle da “SPEED_WORKING” e “SPEED_HOMING”.
Tra il movimento di andata ed il movimento di ritorno della fase di lavoro e della fase di homing, ci sono delle pause. Di default sono 4 secondi per la fase di lavoro e 2 secondi per la fase di homing. Anche queste possono essere modificate agendo sui valori delle costanti DELAY_WORK e DELAY_HOMING.
Come sempre, il codice è ampiamente commentato ma per qualsiasi dubbio o chiarimento, puoi fare riferimento alla sezione commenti a fondo pagina.
Ricordati di includere le due librerie: AccelStepper e Bounce2.
Se non le hai già, basta andare in gestione librerie dall’IDE di Arduino ed installarle.
//Inclusione delle librerie
#include <AccelStepper.h>
#include <Bounce2.h>
//Definizione costanti relative ai PIN
const int PIN_SW_LIMIT_END = 2;
const int PIN_SW_WORK = 3;
const int PIN_SW_RESET = 4;
const int PIN_SW_RISOLUZIONE = 5;
const int PIN_DR_DIR = 6;
const int PIN_DR_STEP = 7;
const int PIN_MS_3 = 8;
const int PIN_MS_2 = 9;
const int PIN_MS_1 = 10;
const int PIN_DR_ENABLE = 11;
const int PIN_SW_LIMIT_START = 12;
const int PIN_LED_STATO = 13;
/*
Tabella di riferimento relativa alla risoluzione del motore prelevata dal sito del produttore
https://www.pololu.com/product/1182
+---+------+------+------+----------------------+
| # | MS1 | MS2 | MS3 | Microstep resolution |
+---+------+------+------+----------------------+
| 0 | Low | Low | Low | Full step |
| 1 | High | Low | Low | Half step |
| 2 | Low | High | Low | Quarter step |
| 3 | High | High | Low | Eighth step |
| 4 | High | High | High | Sixteenth step |
+---+------+------+------+----------------------+
*/
//Creiamo un array bidimensionale per contenere i valori della tabella della risoluzione.
const int RISOLUZIONE[5][3] = {
{0, 0, 0},
{1, 0, 0},
{0, 1, 0},
{1, 1, 0},
{1, 1, 1}
};
const unsigned long DELAY_WORK = 4000;
const unsigned long DELAY_HOMING = 2000;
//Imposta velocità del motore durante la fase di lavoro
const double SPEED_WORKING = 20.0;
//Imposta velocità del motore durante la fase di reset della posizione
const double SPEED_HOMING = 40.0;
//il delay in ms di debounce applicato agli switch
const unsigned long DEBOUNCE_DELAY = 10;
boolean homing, working;
//risoluzione iniziale del motore
int selRisoluzione = 0;
//istanzia il motore
AccelStepper motore(AccelStepper::DRIVER, PIN_DR_STEP, PIN_DR_DIR);
//istanzia i bottoni
Bounce btnSwResolution = Bounce(); //Scelta risoluzione step
Bounce btnSwReset = Bounce(); //Reset operazioni
Bounce btnSwWork = Bounce(); //Avvia esecuzione
Bounce btnSwLimitHome = Bounce(); //Limite iniziale
Bounce btnSwLimitEnd = Bounce(); //Limite fine corsa
void setup() {
//definizione delle modalità dei pin
pinMode(PIN_LED_STATO, OUTPUT);
pinMode(PIN_DR_ENABLE, OUTPUT);
pinMode(PIN_MS_1, OUTPUT);
pinMode(PIN_MS_2, OUTPUT);
pinMode(PIN_MS_3, OUTPUT);
pinMode(PIN_SW_RISOLUZIONE, INPUT_PULLUP);
pinMode(PIN_SW_RESET, INPUT_PULLUP);
pinMode(PIN_SW_WORK, INPUT_PULLUP);
pinMode(PIN_SW_LIMIT_START, INPUT_PULLUP);
pinMode(PIN_SW_LIMIT_END, INPUT_PULLUP);
//associamo i pin degli switch alle istanze dei bottoni (Boune)
btnSwResolution.attach(PIN_SW_RISOLUZIONE);
btnSwResolution.interval(DEBOUNCE_DELAY);
btnSwReset.attach(PIN_SW_RESET);
btnSwReset.interval(DEBOUNCE_DELAY);
btnSwWork.attach(PIN_SW_WORK);
btnSwWork.interval(DEBOUNCE_DELAY);
btnSwLimitHome.attach(PIN_SW_LIMIT_START);
btnSwLimitHome.interval(DEBOUNCE_DELAY);
btnSwLimitEnd.attach(PIN_SW_LIMIT_END);
btnSwLimitEnd.interval(DEBOUNCE_DELAY);
delay(2000);
//Esegui reset posizione del motore.
resetHomePosition();
}
void loop() {
//se non siamo in fase di reset della posizione
if (!homing ) {
//Tieni d'occhio gli switch "Work", "Reset" e "Risoluzione"
handleSwResetAndResolution();
handleSwWork();
//Se siamo in fase di lavoro (working)
if (working) {
//Vai avanti fin quando non viene premuto lo switch di fine corsa
while (digitalRead(PIN_SW_LIMIT_END) && working) {
handleSwResetAndResolution(); //Durante il while, controlla sempre se vengono premuti i tasti "Reset" o "Risoluzione"
motore.move(100);
motore.run();
}
motore.setCurrentPosition(0);
//Raggiunta la posizione finale aspetta DELAY_WORK secondi
delay(DELAY_WORK);
//Torna in dietro fin quando non viene premuto lo switch di inizio corsa
while (digitalRead(PIN_SW_LIMIT_START) && working) {
handleSwResetAndResolution(); //Durante il while, controlla sempre se vengono premuti i tasti "Reset" o "Risoluzione"
motore.move(-100);
motore.run();
}
motore.setCurrentPosition(0);
//Al termine del lavoro, disabilita il driver e rimettiti in attesa
working = false;
setPinEnable(working);
}
}
}
//Funzione di comodo per accorpare la chiamata delle due funzioni contenute in essa
void handleSwResetAndResolution() {
handleSwReset();
handleSwResolution();
}
//Esegui reset della posizione del motore
void resetHomePosition() {
homing = true;
working = false;
//abilitiamo il pin del driver e accendiamo il led di stato
setPinEnable(true);
//impostiamo velocita e accelerazione di reset
motore.setMaxSpeed(SPEED_HOMING);
motore.setSpeed(SPEED_HOMING);
motore.setAcceleration(SPEED_HOMING * 3);
//Durante la fase di reset facciamo girare il motore in full step
setPinResolution(0, 0, 0);
while (digitalRead(PIN_SW_LIMIT_END)) {
motore.move(100);
motore.run();
}
motore.setCurrentPosition(0);
delay(DELAY_HOMING);
while (digitalRead(PIN_SW_LIMIT_START)) {
motore.move(-100);
motore.run();
}
motore.setCurrentPosition(0);
//Terminata la fase di reset, reimpostiamo la risoluzione del motore in base al valore di "selRisoluzione"
setPinResolution(
RISOLUZIONE[selRisoluzione][0],
RISOLUZIONE[selRisoluzione][2],
RISOLUZIONE[selRisoluzione][3]
);
//reimpostiamo velocita e accelerazione di lavoro
motore.setMaxSpeed(SPEED_WORKING);
motore.setSpeed(SPEED_WORKING);
motore.setAcceleration(SPEED_WORKING * 3);
//definisci stato delle variabili
homing = false;
working = false;
//Disabilita il driver e spegni il led
setPinEnable(false);
}
//Tieni d'occhio il bottone "Risoluzione"
void handleSwResolution() {
btnSwResolution.update();
/*
Ad ogni pressione del tasto risoluzione, incrementa di uno il valore di "selRisoluzione" fin quando non raggiunge la lunghezza
dell'array "RISOLUZIONE".
In questo modo possiamo cambiare risoluzione in termini di step del motore.
*/
if (btnSwResolution.fell()) {
if (selRisoluzione < ((sizeof(RISOLUZIONE) / sizeof(RISOLUZIONE[0])) - 1)) {
selRisoluzione++;
} else {
selRisoluzione = 0;
}
//Setta i valori contenuti nell'array "RISOLUZIONE" determinati dal numero presente in "selRisoluzione" sui pin MS1, MS2, MS3
setPinResolution(
RISOLUZIONE[selRisoluzione][0],
RISOLUZIONE[selRisoluzione][2],
RISOLUZIONE[selRisoluzione][3]
);
}
}
//Tieni d'occhio il bottone di "Reset"
void handleSwReset() {
btnSwReset.update();
if (btnSwReset.fell()) {
delay(DELAY_HOMING);
resetHomePosition(); //Richiama resetHomePosition() per resettare la posizione del motore.
}
}
//Tieni d'occhio il bottone "Work"
void handleSwWork() {
btnSwWork.update();
if (btnSwWork.fell()) {
working = !working;
setPinEnable(working);
}
}
//Imposta lo stato dei pin "PIN_DR_ENABLE" e "PIN_LED_STATO" in base al parametro "working";
void setPinEnable(boolean working) {
digitalWrite(PIN_DR_ENABLE, !working);
digitalWrite(PIN_LED_STATO, working);
}
//Imposta lo stato dei pin "PIN_MS_1", "PIN_MS_2" e "PIN_MS_3" in base ai parametri "MS1", "MS2" e "MS3"
void setPinResolution(int MS1, int MS2, int MS3) {
digitalWrite(PIN_MS_1, MS1);
digitalWrite(PIN_MS_2, MS2);
digitalWrite(PIN_MS_3, MS3);
}
A fine pagina trovi il link per scaricare il pacchetto con codici e schemi di collegamento. Come sempre ti ricordo che acquistando prodotti Amazon passando attraverso i link del mio sito, io percepisco una piccola commissione (parliamo di centesimi) in buoni regalo. Questi buoni sommati alle eventuali donazioni PayPal, servono a mantenere attivo il sito web e ad acquistare nuovi componenti.
Prodotti Amazon
Auto Amazon Links: Nessun prodotto trovato.
Auto Amazon Links: Nessun prodotto trovato.
Auto Amazon Links: Nessun prodotto trovato.
Arduino UNO R4 WiFi [ABX00087] - Scheda di sviluppo con microcontrollore ARM Cortex-M4 e WiFi integrato, ideale per progetti IoT, automazione e applicazioni connesse con Arduino IDE.
AZDelivery Scheda Microcontrollore con Cavo USB e con eBook
13,99 €ELEGOO UNO R3 Advanced Starter Kit per progetti per Principianti con Kit di apprendimento Italiano Compatibile con i progetti IDE di Arduino
ELEGOO UNO R3 Project Basic Starter Kit per Principianti, Incluso Kit di Apprendimento Tutorial in Italiano, Compatibile con Arduino IDE
29,99 €Arduino UNO R4 Minima [ABX00080] - Scheda di sviluppo con microcontrollore ARM Cortex-M4, ideale per progetti IoT, automazione e applicazioni con IDE Arduino.
Condensatori Elettrolitici Kit 24 Valori 700pz Assortimento di Condensatore Elettrolitico Range da 0,1uF a 1000uF 10V 16V 25V 50V Capacitor Elettrico in Alluminio
18,99 €ARCELI 300pcs 15Value Condensatore elettrolitico Portata da 0,1uF a 470uF Assortimento Kit di condensatori
9,99 €Aerzetix - 30 x Condensatore elettrolitico , chimico , 47µF ± 20% 25V THT 105°C 2000h Ø5 x11 mm radiale .
7,57 €Condensatori elettrolitici THT 1000 μF, 25 V, Ø10 x 20 mm, confezione da 5
5,59 €BOJACK 24 valori 630 pezzi alluminio condensatori elettrolitici assortimento scatola kit gamma 0.1uF-1000uF
18,99 €Il video
Come sempre
- Importa le librerie necessarie;
- Assicurati che tutti i collegamenti siano corretti;
- Ricordati di impostare la porta COM del tuo Arduino;
- Utilizza le tensioni corrette;
- Ricorda che io non mi assumo nessuna responsabilità per eventuali danni o disastri che causi 😀
Spero che questo post ti sia stato utile! Per qualsiasi domanda o chiarimento, fai riferimento alla sezione commenti.
Sono ben accetti, birre, caffè e donazioni 😉


![Arduino UNO R4 WiFi [ABX00087] - Scheda di sviluppo con microcontrollore ARM Cortex-M4 e WiFi integrato, ideale per progetti IoT, automazione e applicazioni connesse con Arduino IDE. #1](https://m.media-amazon.com/images/I/51z3unD0rSL._SL120_.jpg)
![Arduino UNO R4 WiFi [ABX00087] - Scheda di sviluppo con microcontrollore ARM Cortex-M4 e WiFi integrato, ideale per progetti IoT, automazione e applicazioni connesse con Arduino IDE. #2](https://m.media-amazon.com/images/I/51qwMwhIEpL._SL120_.jpg)
![Arduino UNO R4 WiFi [ABX00087] - Scheda di sviluppo con microcontrollore ARM Cortex-M4 e WiFi integrato, ideale per progetti IoT, automazione e applicazioni connesse con Arduino IDE. #3](https://m.media-amazon.com/images/I/41xRusra-PL._SL120_.jpg)
![Arduino UNO R4 WiFi [ABX00087] - Scheda di sviluppo con microcontrollore ARM Cortex-M4 e WiFi integrato, ideale per progetti IoT, automazione e applicazioni connesse con Arduino IDE. #4](https://m.media-amazon.com/images/I/51Pj4AYoI2L._SL120_.jpg)
![Arduino UNO R4 WiFi [ABX00087] - Scheda di sviluppo con microcontrollore ARM Cortex-M4 e WiFi integrato, ideale per progetti IoT, automazione e applicazioni connesse con Arduino IDE. #5](https://m.media-amazon.com/images/I/51aGD+zFqLL._SL120_.jpg)
![Arduino UNO R4 WiFi [ABX00087] - Scheda di sviluppo con microcontrollore ARM Cortex-M4 e WiFi integrato, ideale per progetti IoT, automazione e applicazioni connesse con Arduino IDE. #6](https://m.media-amazon.com/images/I/51qB0r6PqYL._SL120_.jpg)
![Arduino UNO R4 WiFi [ABX00087] - Scheda di sviluppo con microcontrollore ARM Cortex-M4 e WiFi integrato, ideale per progetti IoT, automazione e applicazioni connesse con Arduino IDE. #7](https://m.media-amazon.com/images/I/518XcmBXXAL._SL120_.jpg)
![Arduino UNO R4 WiFi [ABX00087] - Scheda di sviluppo con microcontrollore ARM Cortex-M4 e WiFi integrato, ideale per progetti IoT, automazione e applicazioni connesse con Arduino IDE. #8](https://m.media-amazon.com/images/I/41mGAFfpn9L._SL120_.jpg)

















![Arduino UNO R4 Minima [ABX00080] - Scheda di sviluppo con microcontrollore ARM Cortex-M4, ideale per progetti IoT, automazione e applicazioni con IDE Arduino. #1](https://m.media-amazon.com/images/I/51L0AYnxlBL._SL120_.jpg)
![Arduino UNO R4 Minima [ABX00080] - Scheda di sviluppo con microcontrollore ARM Cortex-M4, ideale per progetti IoT, automazione e applicazioni con IDE Arduino. #2](https://m.media-amazon.com/images/I/5111WEC6vgL._SL120_.jpg)
![Arduino UNO R4 Minima [ABX00080] - Scheda di sviluppo con microcontrollore ARM Cortex-M4, ideale per progetti IoT, automazione e applicazioni con IDE Arduino. #3](https://m.media-amazon.com/images/I/41752hu+9BL._SL120_.jpg)
![Arduino UNO R4 Minima [ABX00080] - Scheda di sviluppo con microcontrollore ARM Cortex-M4, ideale per progetti IoT, automazione e applicazioni con IDE Arduino. #4](https://m.media-amazon.com/images/I/51gDXfwE4qL._SL120_.jpg)
![Arduino UNO R4 Minima [ABX00080] - Scheda di sviluppo con microcontrollore ARM Cortex-M4, ideale per progetti IoT, automazione e applicazioni con IDE Arduino. #5](https://m.media-amazon.com/images/I/519n0CHiF5L._SL120_.jpg)
![Arduino UNO R4 Minima [ABX00080] - Scheda di sviluppo con microcontrollore ARM Cortex-M4, ideale per progetti IoT, automazione e applicazioni con IDE Arduino. #6](https://m.media-amazon.com/images/I/515PpgJcSfL._SL120_.jpg)
![Arduino UNO R4 Minima [ABX00080] - Scheda di sviluppo con microcontrollore ARM Cortex-M4, ideale per progetti IoT, automazione e applicazioni con IDE Arduino. #7](https://m.media-amazon.com/images/I/519E0KPfiHL._SL120_.jpg)

















RSS - Articoli
Commentati Recentemente