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
ARCELI A4988 Stepper StepStick con motore compatibile con dissipatore di calore per 3D Printer Controller Ramps 1.4 (confezione da 5 pezzi) - rosso
8,59 €AZDelivery 3 x Modulo Driver Motore Passo-Passo A4988 Scheda Breakout con dissipatore di calore compatibile con Arduino incluso un E-Book!
9,99 €DollaTek Stampante 3D 42 Scheda di espansione del Driver del Motore Passo-Passo 8825 / A4988
5,99 €ARCELI A4988 Stepper StepStick con Motore Compatibile con dissipatore di Calore per 3D Printer Controller Ramps 1.4 (Confezione da 5 Pezzi) - Verde
8,99 €WJMY A4988 Stepper Motor Driver Module 5 pz Con Mini Dissipatore Di Calore Compatibile Con Stampante 3D RepRap
11,59 €3-axis Laser Engraver Control Board DIY CNC Module GRBL Stepper Motor Drive Support xyz limit Switch
46,30 €YLQUXEUV Inching Switch LXW5-11G2 Trip Switch Limit Switch Open And Close Self Reset
24,19 € (a partire da 18 Gennaio 2025 11:33 GMT +01:00 - Altre informazioniProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on [relevant Amazon Site(s), as applicable] at the time of purchase will apply to the purchase of this product.)HUJWLBWF Inching Switch LXW5-11G2 Trip Switch Limit Switch Open And Close Self Reset
24,38 € (a partire da 18 Gennaio 2025 11:33 GMT +01:00 - Altre informazioniProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on [relevant Amazon Site(s), as applicable] at the time of purchase will apply to the purchase of this product.)EGPBUABIO 1PCS Travel Switch Limit Switch Microswitch Z-15GW21-B
23,33 € (a partire da 18 Gennaio 2025 11:33 GMT +01:00 - Altre informazioniProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on [relevant Amazon Site(s), as applicable] at the time of purchase will apply to the purchase of this product.)EGPBUABIO 1PCS LXW5-11N2 Limit Switch Travel Switch Switch LXW5 Series
23,19 € (a partire da 18 Gennaio 2025 11:33 GMT +01:00 - Altre informazioniProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on [relevant Amazon Site(s), as applicable] at the time of purchase will apply to the purchase of this product.)STEPPERONLINE Motore passo-passo Nema 17 bipolare 42Ncm 1.5A 42x42x39mm 4 fili con cavo da 1 m e connettore per stampante 3D/fresatrice CNC, nero
11,85 €Aihasd 3 pezzi DC 5 V Motore passo-passo stepper motor 28BYJ-48 ULN2003 + 3 pezzi ULN2003 Scheda conducente per Arduino
9,99 €ELEGOO 5 Set 28BYJ-48 ULN2003 5V Motore Passo-Passo Stepper + ULN2003 Scheda Controllo Motore
19,99 €STEPPERONLINE Nema - Motore passo-passo per pancake, 1 A, 17 Ncm, bipolare, 1,8 gradi, 4 conduttori, lunghezza corpo 23 mm, per estrusore CNC stampante 3D
11,61 €Scheda controller driver motore passo-passo COVVY TB6600 4A DC 9-42V controller CNC 32 segmenti 2/4 fasi ibrida motore passo-passo
12,99 €Arduino UNO Rev3 [A000066]
Arduino UNO R4 WiFi [ABX00087] - Renesas RA4M1 / ESP32-S3 - Wi-Fi, Bluetooth, USB-C, CAN, DAC, OP AMP, connettore Qwiic, matrice LED 12x8
30,80 €ELEGOO UNO R3 Board Scheda con Cavo USB Compatibile con i progetti IDE di Arduino Conforme alla direttiva RoHS
22,99 €AZDelivery Scheda Microcontrollore con Cavo USB e con eBook
13,99 €Diymore 1PCS Scheda di Sviluppo,AT328P-R3 Microcontrollore CH340 16MHz 5V
8,99 €ARCELI 300pcs 15Value Condensatore elettrolitico Portata da 0,1uF a 470uF Assortimento Kit di condensatori
9,99 €AUKENIEN 23 Valori 288pz Condensatori Elettrolitici Kit Assortimento di Condensatore Elettrolitico Range da 10uF a 2200uF 10V 16V 25V 35V 50V Capacitor Elettrico in Alluminio
17,99 €BOJACK 24 valori 630 pezzi alluminio condensatori elettrolitici assortimento scatola kit gamma 0.1uF-1000uF
18,99 €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 €Vegena 24 Valore 500 Pezzi Condensatore Elettrolitico, Condensatori Elettrolitici, Kit Assortimento Da 0,1uf A 1000uf 10v 16v 25v 50v Capacitor Elettrico In Alluminio Con Scatola Portaoggetti
14,88 € (0,03 € / unità)Il video
Circuito per slitta motorizzata con Arduino
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 😉
Commentati Recentemente