Sono alle mie primissime esperienze con arduino e sto cercando di crearmi un piccolo programma per gestire un motore passo passo del quale vorrei gestirne il numero di rotazioni con dislay lcd ed avviarne la rotazione chuidendo un contatto. Ho sistemato su una bredboard un display lcd 16 x 2, un led che lampeggiando simula le rotazioni del motore, e tre pulsanti di cui due per aumentare o diminuire il numero di cicli da visualizzare sul display ed uno per azionare il ciclo di lampeggi. Scopiazzando e provando un poco mi è riuscito di far funzionare il sistema, ma mi sono arenato di fronte ad un problema apparentemente banale, ma che non sono riuscito a risolvere. Ogni volta che aziono uno dei pulsanti per impostare il numero di lampeggi il programma esegue l'intero ciclo, azionando il led, mentre io avrei bisogno di far ruotare il programma solamente attorno alla gestione del display fino a quando chiudendo il contatto del terzo pulsante possa partire il ciclo di lampeggi. Qualcuno mi potrebbe dare qualche dritta? Grazie.
![]()
Ti segnalo che, nella sezione in lingua Inglese, si può scrivere SOLO in Inglese ... quindi, per favore, la prossima volta presta più attenzione in quale sezione metti i tuoi post; questa volta esso è stato spostato, da un moderatore della sezione di lingua Inglese, nella sezione di lingua Italiana ... la prossima volta potrebbe venire direttamente eliminato. Grazie.
A quanto detto da UKHeliBob aggiungo ...
... cortesemente, come prima cosa, leggi attentamente il REGOLAMENTO della sezione Italiana del forum, (... e, per evitare future possibili discussioni/incomprensioni, prestando sempre molta attenzione al punto 15), dopo di che, come da suddetto regolamento, fai la tua presentazione NELL'APPOSITA DISCUSSIONE spiegando bene quali esperienze hai in elettronica e programmazione, affinché noi possiamo conoscere la tua esperienza ed esprimerci con termini adeguati.
Grazie,
Guglielmo
P.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione nell’apposita discussione, nel rispetto del succitato regolamento nessuno ti risponderà (eventuali risposte o tuoi ulteriori post, verrebbero temporaneamente nascosti), quindi ti consiglio di farla al più presto. ![]()
ciao ziorobi
posta il codice che hai scritto e vediamo.
Il problema è già stato ampiamente affrontato sul forum, per cui non sei il primo che si trova con questa necessità.
Sono cosciente che con il tuo livello di competenze questi link non risolvono il problema. Quindi documentati, fatti una tua idea, scrivi il codice e postalo.
Ciao.
Basta riscrivere la descrizione in una forma più logica/schematica, traducibile nelle istruzioni comprensibili dalla macchina.
Ad esempio:
SE premuto pulsante1 E NON sequenza attiva:
incrementa valore
visualizzalo su display
SE premuto pulsante2 E NON sequenza attiva:
decrementa valore
visualizzalo su display
SE premuto pulsante avvio:
imposta sequenza attiva
SE sequenza attiva:
...fai cose...
SE finita sequenza:
imposta sequenza disattiva
Basta usare una variabile flag (bandierina segnalatrice) per abilitare/disabilitare le condizioni, ed eseguire solo ciò che in quello specifico momento ha senso eseguire.
Grazie mille per la vostra disponibilità, ora cerco di studiarci sopra e mettere a frutto i vostri consigli, come ha chiesto andrea provo ad allegare il mio schetch malfunzionante.
A dire la verità usando il pulsantino carica mi compare solo il titolo, non so se sia corretto così oppure si deva fare il copia incolla direttamente dal testo.
ULTIMO_SALVATAGGIO_LCD_REGOLAZIONE_MOTORE_PULSANTE.ino (3,1 KB)
Iniziamo da qui:
Spiega questi commenti due commenti:
//const int rossoa = 8;//led lampeggiante digitale continuo
//const int verde = 9;//led lampeggiante analogico continuo
Cosa vuole dire analogico continuo e digitale continuo?
Lampeggiante ok, ma quando devono lampeggiare sempre, si accendono e si spengono assieme o alternativamente, comunque questa parte la considero accessoria.
Il loop è disattivato perché non vedo nulla di buono da prendere ma non si sa mai.
Ciao.
Se invece di allegare si vuole scrivere il codice nel testo c'è l'apposito simboletto </>
Il testo sorgente da mostrare ad altri va indentato (incolonnato/spaziato) correttamente, l'IDE di Arduino lo fa automaticamente con CTRL+T (strumenti → formattazione automatica).
Questo permette anche di vedere meglio gli errori commessi, come il fatto che hai condizionato con la variabile 'stato' l'esecuzione di tutto quello che c'è dopo, e non solo l'aggiornamento del display (come secondo me invece dovrebbe avvenire). Scegliendo 'aggiorna' come nome per quella variabile, il suo scopo sarebbe più chiaro.
E l'esecuzione della sequenza dovrebbe invece essere condizionata con un'altra variabile, ad esempio chiamata 'sequenza', da impostare a 1 (o true che è la stessa cosa) quando si preme il pulsante di avvio.
Grazie per il supporto, le descrizioni lampeggiante analogico continuo e digitale continuo sono chiaramente forvianti e sono frutto di insana dimenticanza. Inizialmente il mio progetto dovevav essere costituito da un display in cui venivano visualizzate tre variabili: lunghezza di tiraggio, velocità motore e ritardo alla partenza. In uscita invece avevo lampeggiante analogico per alimentare un led che simulasse gli impulsi al motore e un led con segnale fisso digitale che durante la rotazione del motore avrebbe dovuto simulare l'attivazione di una elettrovalvola pneumatica. Le prove fatte utilizzando separatamente le varie funzioni erano state soddisfacenti, ma è mettendo assieme il tutto che casca l'asino. Beati i vecchi relè. in questa fase mi sono reso conto dei miei limiti ed ho iniziato a togliere pezzi (dimenticando qualche descrizione che riprodotta con copia incolla non aiuta certo a capire). Ora il progetto è ridimensionato al solo controllo della lunghezza di avanzamento visualizzata sul display e regolabile con i due pulsantini e la sola uscita analogica lampeggiante, ma mi sono reso conto che ancora non ci siamo, penso sia utile per il momento riporre il tutto, dedicarmi un pò allo studio della grammatica di Arduino e poi riprendere con un minimo di padronanza del linguaggio a cimentarmi con la programmazione. Per il momento vi ringrazio nella speranza di poter quanto prima consultarvi in maniera più competente.
Ok, ora si comprende meglio anche il post iniziale.
Il simulatore online wokwi ha un componente driver per motore passo passo e un motore passo passo, per cui si può simulare il progetto in questione.
Se apri nuovamente il link al progetto che ho postato dovresti trovare differenze. Prima che io modifichi il progetto conviene farsi una proprio copia dal menu accanto a "Save". In questo modo posso ripulire il sorgente dai commenti che per te sono utili.
Io ho affrontato il problema scomponendolo. Il programma visualizza sul display il valore della variabile posizioneMotore. Il pulsante BLUE è il + per incrementare e quello grigio per decrementare.
Uso la libreria JC_Button per i pulsanti che gestisce il debounce.
Se tieni premuto uno dei due pulsanti dopo 350ms si innesca l'auto incremento o decremento. Non è perfetto come vorrei ma è un inizio.
Ciao.
Grazie Mauro, più cerco di capire arduino più rimango sgomento dalla sua complessità e dalle sue potenzialità. Purtroppo mi trovo a combattere faticosamente con i miei limiti mentali a cui si aggiunge l'ignoranza della lingua inglese ed il poco tempo disponibile, ma non ho intenzione di demordere subito. Tornando a noi, ho riaperto il tuo progetto su wokwi, effettivamente tutto è molto più complesso di quanto io non immaginassi inizialmente. Veramente fantastico il simulatore. Ho provato a riportare il programma su arduino, ma il funzionamento è diverso da quanto si vede sul simulatore, i due led rimangono accesi fissi ed il display sfarfalla. Se questa sera mi riesce di trovare il tempo provo a vedere se ho commesso qualche errore nel trasferire il programma o nei collegamenti. Grazie ancora e Buona Giornata.
I due led non li ho usati per simulare il motore, li ho solo collegati e testato il collegamento tramite la funzione:
void testPulsantiLed() {
// test dei pulsanti e dei led
digitalWrite(PIN_REDLED, !digitalRead(PIN_START_SWITCH));
digitalWrite(PIN_GREENLED, !digitalRead(PIN_AVANTI_SWITCH));
digitalWrite(PIN_GREENLED, !digitalRead(PIN_INDIETRO_SWITCH));
}
Funzione che chiamo nel loop().
I led devono accendersi quando premi i pulsanti.
Il pulsanti AVANTI e INDIETRO sono collegati con il led GREENLED (led verde).
Il pulsante START e collegato con il led REDLED (led rosso).
Io ho affrontato il problema scomponendolo. Questo significa che il problema motore al momento non ci interessa. L'obbiettivo principale pare essere quello di mostrare sul display un valore di una variabile che modifichiamo tramite i pulsanti verde (+) e grigio (-).
Nota che il programma è adesso diverso dal precedente. Se ti sei fatto una copia bene diversamente lo abbiamo perso.
Ciao.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
//inizializzazione della libreria in cui è descritta la modalità di
LiquidCrystal_I2C lcd(0x27, 16, 2); //impostazione dell'indirizzo de
#define Pulsante 2 //porta del pulsante di start
#define aumenta 4 //porta del pulsante + di regolazione della lunghezza di avanzamento visualizzabile sul display
#define diminuisci 3 //porta del pulsante - di regolazione della lunghezza di avanzamento visualizzabile sul display
#define aumentaVelocita 5 //porta del pulsante + di regolazione della velocità di avanzamento visualizzabile sul display
#define giallo 10 // porta del led giallo
#define verde 9 // porta del led verde
#define rosso 8 //porta del led rosso
int AVANZAMENTO = 0;//stato iniziale della variabile AVANZAMENTO espressa sul display
int statoAvanzamento = 0;
int buttonState = 0; //stato iniziale del pulsante
int VELOCITA = 0;
int statoVelocita = 0;
void setup()
{
lcd.init();//inizializzazione dell'LCD
lcd.backlight(); //attivazione della retroilluminazione
Serial.begin(9600);
pinMode(Pulsante, INPUT);
pinMode(aumenta, INPUT);
pinMode(diminuisci, INPUT);
pinMode(aumentaVelocita, INPUT);
pinMode(giallo, OUTPUT); //tipo di porta del led giallo
pinMode(verde, OUTPUT); //tipo di porta del led verde
pinMode(rosso, OUTPUT); //tipo di porta del led rosso
}
void loop() {
if (digitalRead(aumenta) == HIGH)
AVANZAMENTO++;
delay(20);// Attendo che sollevi il dito dal pulsante
statoAvanzamento = 1;
if (digitalRead(diminuisci) == HIGH)
AVANZAMENTO--;
delay(20);// Attendo che sollevi il dito dal pulsante
statoAvanzamento = 1;
//Limitazione valori
if (AVANZAMENTO > 100) AVANZAMENTO = 1; //premendo avanti, superando valore 100 torna a 1
if (AVANZAMENTO < 1) AVANZAMENTO = 100; // premendo indietro, arrivato a valore 1, torna a 100
if (statoAvanzamento)
if (digitalRead(aumentaVelocita) == HIGH)
VELOCITA++;
delay(30);// Attendo che sollevi il dito dal pulsante
statoVelocita = 1;
if (VELOCITA > 5) VELOCITA = 1; //premendo avanti, superando valore 5 torna a 1
if (VELOCITA < 1) VELOCITA = 5; // premendo indietro, arrivato a valore 1, torna a 5
if (statoVelocita)
{
// StampaLcd AVANZAMENTO;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print ("AVANZAMENTO");
lcd.setCursor(0, 1);
lcd.print ("VELOCITA");
lcd.setCursor(12, 0);
lcd.print(AVANZAMENTO);
lcd.setCursor(12, 1);
lcd.print(VELOCITA);
statoAvanzamento = 0;
statoVelocita = 0;
}
buttonState = digitalRead (Pulsante);
if (buttonState == HIGH)
for (int i = 0; i < AVANZAMENTO / 1 ; i++ ) // abbina il valore scritto sul display al numero lampeggi(solo numeri decimali)
for (int v = 0; v <= 255; v += 80)
{
digitalWrite(verde, v); //assegna la funzione analogica, ed il tempo dello spegnimento
delay(9 * VELOCITA);
}
for (int v = 255; v >= 0; v -= 20)
{ }
}
Finalmente! Non è certamente molto, ma è il primo passo che mi ero prefissato, ora mi riesce di selezionare sul display con i pulsantini più e meno, il numero lampeggi e la velocità, il prossimo passo che proverò a raggiungere sarà tramutare i lampeggi in azionamento di motore passo passo. Sono molto lento, ma con calma ce la posso fare. Grazie ancora per il prezioso aiuto.
Lo vuoi un consiglio?
No e io te lo do lo stesso.
Usa sempre le parentesi graffe, anche per una sola istruzione, cioè così:
if (condizione) { // se la scrivi a seguire non la dimentichi mai
// qui l'istruzione da eseguire anche una sola.
}
Sembra quasi tu conosca il linguaggio python, ma questo è C++.
if (digitalRead(aumentaVelocita) == HIGH)
VELOCITA++;
delay(30);// Attendo che sollevi il dito dal pulsante
Qui sopra il delay viene eseguito a prescindere dalla condizione digitalRead(aumentaVelocita) == HIGH
Ora magari era questo che volevi ottenere ma chi legge il tuo codice non lo sa, mentre esplicitando il blocco di codice tramite le parentesi graffe non si lascia il dubbio. Ci sono altri buoni motivi che non elenco.
Le variabili tutte maiuscole evitale, il maiuscolo è riservato alle macro del preprocessore C++. Cioè quelle che in alcuni sketch iniziano con il #, esempio #define, #if, #endif ecc.
Ciao.
Che 0 sia lo stato iniziale di quella variabile (che, in realtà, essendo scritta in maiuscolo sembra essere una costante!) è ovvio. Io ero andato a cercare il significato di quella variabile che non si capisce che cosa significhi... Quanto è andato avanti che cosa?...
Anche questo è lapalissiano...
Ok. Grazie mille per i vostri consigli che accetto volentieri e di cui farò tesoro. Quindi variabili in minuscolo e parentesi graffe sempre per dividere in maniera chiara i blocchi. Inizialmente le parentesi c'erano, ma credevo erroneamente di rendere più pulito il programma riducendole all'osso.
La funzione più e meno della variabile espressa sul display l'avevo copiata da un tutorial, probabilmente non è la scelta migliore, ma funziona. Nelle mie intenzioni il mio progetto dovrebbe mirare ad azionare un motore passo passo che alla chiusura di un contatto dovrebbe fare un ciclo di avanzamento (in questo caso simulato dall'intermittenza del led) in cui si possono determinare i giri che deve fare il motore selezionando con + e - la variabile lunghezza e determinarne la velocità su 5 valori per i quali è sufficiente il pulsante + dal momento che arrivati a 5 si ritorna ad 1.
Mi sono preso la soddisfazione di vedere che fin qui funziona, ma sono assolutamente convinto che per imparare a fare sul serio servirà ancora molta strada. Grazie ancora e Buon Natale a tutti i partecipanti del forum.
Grazie. Auguri di un sereno S. Natale anche a te e a tutti.
Finalmente con tanta pazienza e grazie ai suggerimenti trovati sul forum il mio modesto progetto di tiraggio della pellicola tramite motore passo passo, con disinserimento del freno e regolazione di velocità e lunghezza di tiraggio per mezzo di 4 pulsantini, il tutto visualizzabile su display lcd ha finalmente preso forma e, malgrado le imperfezioni, sembra fare molto bene il suo lavoro. Ora però mi si pone un altro problema, utilizzando la stessa strumentazione: "arduino 1, display lcd a 2 righe e driver 6560 da 3 A." Ho deciso di fare un contacopie che a mezzo di una fotocellula mi conta delle cover che, in uscita da una macchina da stampa vanno ad adagiarsi su di un nastro trasportatore. Il contacopie al raggiungimento del numero di copie impostate, (generalmente fra le 20 e le 30) azionando un motore passo passo da 2,8 A. identico a quello usato precedentemente, mette in movimento il nastro facendo uscire il pacco di cover dalla macchina. Fin qui tutto bene, il mio problema è il fatto che ho bisogno quest'ultimo motore possa girare ad una velocità molto più elevata di quanto non mi sia ruiscito fino ad ora. Ho impostato il segnale in entrata al driver con; " digitalWrite (verde, HIGH); delay (1);
digitalWrite (verde, LOW); delay (1);" ma il motore gira a quasi un decimo di quanto sia necessario, ho provato a cercare delle frazioni aggiungendo all'uno un divisore, ma il motore procede in maniera irregolare perdendo passi e talvolta non si muove nemmeno. L'unica cosa di cui sono certo è che il problema non è attribuibile al motore, dal momento che collegato ad altri azionamenti gira più di quanto sia necessario nel mio caso. In conclusione dovrei riuscire a capire se ciò dipende da un limite delle performance del driver, oppure il limite è determinato solo dalla mia incapacità. Qualcuno mi potrebbe dare qualche dritta per risolvere questo mio enigma?