Pilotare un motore passo-passo con un server web
Introduzione
Grazie ad Internet e alla disponibilità di microcontrollori a basso costo, realizzare sistemi di controllo da remoto, definiti anche IOT (Internet of Things), sono alla portata di tutti.
In questo post realizzeremo insieme un sistema per pilotare, tramite un server, la rotazione di un motore da remoto.
Questo progetto può avere diverse applicazioni pratiche, per esempio la rotazione di una telecamera, l’apertura di una porta, un distributore d’alimenti per animali ecc.
Suggeritemi nei commenti altre possibili soluzioni d’uso di questo progetto, potrebbe essere argomento di un altro post.
Anche in questo progetto, utilizzeremo il sistema ESP32.
Da italiano dovrei promuovere l’utilizzo di Arduino, ottimo progetto e con numerosissime soluzioni molto valide, ma quello che mi spinge ad usare l’ESP32 è il costo d’acquisto molto basso insieme alle ottime caratteristiche.
Prima di iniziare la lettura del post vi consiglio di leggere prima l’articolo sul mio sito in cui descrivo le caratteristiche e il processo di funzionamento del motore passo passo link
Comunque ho in “cantiere” diversi progetti in cui utilizzerò dei sistemi con Arduino.
Come ruotare un motore a distanza con l’ESP32
Implementeremo un server connesso ad un motore passo passo.
Il server mostrerà una pagina HTML, con un form per l’inserimento dei comandi da far eseguire al motore, che sono la direzione di rotazione e il numero di passi e quindi l’angolo di rotazione.
Sul microcontrollore ESP32 verrà installato un server connesso alla rete Internet , tramite un wi-fi domestico oppure tramite una SIM di un operatore mobile.
Utilizzeremo il motore passo passo 28BYJ-48 , con il relativo driver ULN2003, che solitamente è venduto abbinato con il motore.
Come collegare un motore 28BYJ-48 al driver ULN2003
Il motore 28BYJ-48 ha due bobine e ciascuna di esse ha una presa centrale.
Le due prese centrali sono collegate internamente e pertanto in uscita ci sono 5 fili, l’alimentazione è il filo rosso.
Nella figura di seguito è riportata l’immagine del motore con i collegamenti interni degli induttori e la sua pin function.
Il motore esegue uno step completo di 11,25°, ma al suo interno c’è un riduttore di 64, pertanto, un singolo passo può eseguire una rotazione di:
Il numero di passi per effettuare una rotazione completa è dato dalla seguente relazione:
Per effettuare un giro completo il motore deve eseguire 2048 passi.
La corrente massima d’uscita dell’ESP32 non può pilotare direttamente gli induttori del motore, per questo motivo è necessario introdurre un driver tra i due dispositivi.
Il motore è solitamente venduto in abbinamento al driver ULN2003, prodotto dalla Texas Instruments.
Il circuito integrato ULN200A è formato da sette di transistor Darlington e la corrente massima d’uscita è 500 mA, idoneo per pilotare il nostro motore.
Schema elettrico
Lo schema elettrico è molto semplice:
Possiamo osservare che in questo progetto l’alimentazione è fornita tramite un alimentatore esterno, ma è anche possibile, sui modelli che hanno anche la tensione 5v disponibile, prelevarla direttamente dalla scheda.
Codice
#include <Arduino.h> #include <WiFi.h> #include <AsyncTCP.h> #include <ESPAsyncWebServer.h> #include <Stepper.h> // Impstazioni del motore passo passo const int NumeroMaxGiro = 2048; // Il numero di step del motore, per un angolo giro #define IN1 17 #define IN2 16 #define IN3 4 #define IN4 0 Stepper myStepper(NumeroMaxGiro, IN1, IN3, IN2, IN4); // le credenziali della tua rete wifi const char* ssid = "--------"; const char* password = "-------"; // Creamo un ogegtto server sulla porta 80 AsyncWebServer server(80); // I parametri di impostazione della rotazione const char* Parametro_direzione = "direzione"; const char* Parametro_numero_passi = "psssi"; // Le variabili per salvare i valori impostati nel form HTML String direzione; String psssi; // Variabile per il controllo di una nuova richiesta bool NuovaRichiesta = false; // Pagina HTML del server const char index_html[] PROGMEM = R"rawliteral( <!DOCTYPE html> <html> <head> <title>Motore Passo Passo </title> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <h1> Controllo del Motore Passo Passo</h1> <form action="/" method="POST"> <input type="radio" name="direzione" value="CW" checked> <label for="CW"> Direzione orario </label> <input type="radio" name="direzione" value="CCW"> <label for="CW">Direzione antiorario</label><br><br><br> <label for="psssi">Numero di psssi:</label> <input type="number" name="psssi"> <input type="submit" value="Vai!"> </form> </body> </html> )rawliteral"; // connessione alla tua rete wifi void initWiFi() { WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); Serial.print("mi sto connetendo al WiFi .."); while (WiFi.status() != WL_CONNECTED) { Serial.print('.'); delay(1000); } Serial.println(WiFi.localIP()); } void setup() { Serial.begin(115200); initWiFi(); myStepper.setSpeed(5); // Root URL del web server server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ request->send(200, "text/html", index_html); }); // gestire le richieste dal form server.on("/", HTTP_POST, [](AsyncWebServerRequest *request) { int params = request->params(); for(int i=0;i<params;i++){ AsyncWebParameter* p = request->getParam(i); Serial.println(HTTP_POST); if(p->isPost()){ // HTTP POST (direzione) if (p->name() == Parametro_direzione) { direzione = p->value().c_str(); Serial.print("direzione set to: "); Serial.println(direzione); } // HTTP POST (passi) if (p->name() == Parametro_numero_passi) { psssi = p->value().c_str(); Serial.print("Numero di passi: "); Serial.println(psssi); } } } request->send(200, "text/html", index_html); NuovaRichiesta = true; }); server.begin(); } void loop() { // verifica di una nuova richiesta if (NuovaRichiesta){ if (direzione == "CW"){ // rotazione del motore in senso orario myStepper.step(psssi.toInt()); } else{ // rotazione del motore in senso anti orario myStepper.step(-psssi.toInt()); } NuovaRichiesta = false; } }
Descrizione
#include <Arduino.h> #include <WiFi.h> #include <AsyncTCP.h> #include <ESPAsyncWebServer.h> #include <Stepper.h>
Come quasi tutte le applicazioni si inserisco le librerie.
La libreria WiFI, per la connessione alla rete domestica, mentre le librerie AsyncTCP e ESPAsyncWebServer per il server e in ultimo la libreria Stepper per il motore passo passo.
const int NumeroMaxGiro = 2048;
Questo il numero massimo di passi che può effettuare il motore, nel nostro caso corrisponde a 2048, come spiegato nel paragrafo precedente.
#define IN1 17 #define IN2 16 #define IN3 4 #define IN4 0
Assegnazione dei pins per il collegamento al motore tramite il driver ULN2003.
Stepper myStepper(NumeroMaxGiro, IN1, IN3, IN2, IN4);
Inizializziamo la libreria myStepper indicando il numero massimo di passi e i pins usati sull’ESP32.
// le credenziali della tua rete wifi const char* ssid = "--------"; const char* password = "-------"; // Creamo un ogegtto server sulla porta 80 AsyncWebServer server(80);
Credenziali connessione wifi.
// I parametri di impostazione della rotazione const char* Parametro_direzione = "direzione"; const char* Parametro_numero_passi = "psssi"; // Le variabili per salvare i valori impostati nel form HTML String direzione; String psssi;
Inizializziamo le variabili che devono essere visualizzate sul nostro server.
In questa applicazione selezioneremo il senso di rotazione e numero di passi che deve eseguire il motore.
// Variabile per il controllo di una nuova richiesta bool NuovaRichiesta = false;
Questa variabile sarà usata per memorizzare una nuova richiesta sul server.
// Pagina HTML del server const char index_html[] PROGMEM = R"rawliteral( <!DOCTYPE html> <html> <head> <title>Motore Passo Passo </title> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <h1> Controllo del Motore Passo Passo</h1> <form action="/" method="POST"> <input type="radio" name="direzione" value="CW" checked> <label for="CW"> Direzione orario </label> <input type="radio" name="direzione" value="CCW"> <label for="CW">Direzione antiorario</label><br><br><br> <label for="psssi">Numero di psssi:</label> <input type="number" name="psssi"> <input type="submit" value="Vai!"> </form> </body> </html> )rawliteral";
Questa è la sezione HTML del form per la visualizzazione della pagina WEB.
L’elemento action, è l’azione che deve eseguire il nostro sistema.
Quando l’utente preme il pulsante invio, i dati sono forniti al server (ESP32).
In questo caso il metodo d’invio è il POST.
Il metodo POST invia i dati al server nel corpo del messaggio, a differenza del metodo GET li invia nell’indirizzo web che ritorna al server.
Con il comando “radio” inviamo al server ESP32 le indicazioni sulla direzione di rotazione del motore.
// Root URL del web server server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ request->send(200, "text/html", index_html); });
Avviamo il server e invia la risposta al client dopo la connessione, come da protocollo.
// gestire le richieste dal form server.on("/", HTTP_POST, [](AsyncWebServerRequest *request) { int params = request->params(); for(int i=0;i<params;i++){ AsyncWebParameter* p = request->getParam(i); Serial.println(HTTP_POST); if(p->isPost()){ // HTTP POST (direzione) if (p->name() == Parametro_direzione) { direzione = p->value().c_str(); Serial.print("direzione set to: "); Serial.println(direzione); } // HTTP POST (passi) if (p->name() == Parametro_numero_passi) { psssi = p->value().c_str(); Serial.print("Numero di passi: "); Serial.println(psssi); } } } request->send(200, "text/html", index_html); NuovaRichiesta = true; });
Gestiamo le richieste e individuiamo le variabili per il comando che deve eseguire il motore (direzione e numero di passi).
void loop() { // verifica di una nuova richiesta if (NuovaRichiesta){ if (direzione == "CW"){ // rotazione del motore in senso orario myStepper.step(psssi.toInt()); } else{ // rotazione del motore in senso anti orario myStepper.step(-psssi.toInt()); } NuovaRichiesta = false; } }
Questa parte di codice esegue il comando richiesto dal client sul server ad ogni nuova richiesta.
Conclusioni
Con questo progetto si possono realizzare innumerevoli progetti, se avete dei suggerimenti e/o dei quesiti non esitate a scrivere nel form di seguito.
BUON LAVORO!