Il tutorial passaggio a livello con tinkecard si unisce ai precedenti video tutorial che hai già letto in questo blog.
Se non hai ancora letto i tutorial precedenti ti consiglio di visitare la pagina dedicata ai tutorial tinkercad a cui regolarmente aggiungo gli articoli dedicati al tema.
Video tutorial passaggio a livello con tinkecard
in linea con i precedenti tutorial dedicati a tinkercad ho realizzato il video in cui puoi seguire sia i passaggi per la realizzazione del circuito sia la scrittura del codice fino alla simulazione:
In questo video tutorial passaggio a livello con tinkecard il tema ti sarà stato chiaro dal titolo, ho simulato un passaggio a livello per modellismo ferroviario usando due servo, 4 led per la parte semaforica ed un pulsante.
Quest’ultimo serve per attivare il passaggio a livello, premuto una colta apre le sbarre e premuto la seconda volta le richiude.
Puoi ovviamente collegare più pulsanti in parallelo se vuoi, ad esempio, che ad attivare il passaggio a livello sia il passaggio del treno in un determinato punto in entrambe le direzioni.
Puoi trovare il progetto condiviso pubblicamente qui.
Il circuito del passaggio a livello
Il circuito che puoi utilizzare per il tutorial passaggio a livello con tinkecard è il seguente:
in cui non ci son passaggi complessi, devi solo considerare alcune particolarità:
- i servo motori devono essere connessi a due pin PWm di Arduino, nel mio esempio 5 e 6;
- i led sono connessi in modo incrociato: il primo led a sinistra è connesso al pin 8 ed all’ultimo led a destra; il secondo led da sinistra è collegato al pin 7 ed al trezo led da sinistra.
- il pulsante connesso in modalità pull down rimanda il valore 0 ad arduino quando non è premuto e 1 al momento in cui avviene la pressione.
Il circuito è semplice ed il video, nel paragrafo precedente, evidenzia come in pochi minuti possa essere costruito.
Lo sketch di simulazione del passaggio a livello per ferromodellismo
Lo sketch che hai visto nel video te lo ripropongo di seguito per descriverne le parti principali e commentare le linee più importanti:
#include <Servo.h> const byte pinLedA = 7; const byte pinLedB = 8; const byte pinServoA = 6; const byte pinServoB = 5; const byte pinButton = 2; bool ledState = false; bool butState = false; bool ledOnOff = false; const int timeDelay = 250; unsigned long oldTimeDelay = 0; const byte angleStart = 0; const byte angleEnd = 90; byte angleA = angleStart; byte angleB = angleEnd; Servo servoA; Servo servoB; void setup() { Serial.begin(9600); pinMode(pinLedA, OUTPUT); pinMode(pinLedB, OUTPUT); pinMode(pinButton, INPUT); servoA.attach(pinServoA); servoB.attach(pinServoB); servoA.write(angleStart); servoB.write(angleEnd); } void loop() { if (digitalRead(pinButton) == 1) { butState = !butState; delay(300); ledOnOff = true; } if ( butState ) { if (angleStart <= angleA && angleA < angleEnd) angleA++; if (angleStart < angleB && angleB <= angleEnd) angleB--; } else { if (angleStart < angleA && angleA <= angleEnd) angleA--; if (angleStart <= angleB && angleB < angleEnd) angleB++; } Serial.print(angleA); Serial.print(" - "); Serial.println(angleB); if (((millis() - oldTimeDelay) >= timeDelay) && ledOnOff) { oldTimeDelay = millis(); ledState = !ledState; digitalWrite(pinLedA, ledState); digitalWrite(pinLedB, !ledState); servoA.write(angleA); servoB.write(angleB); } if (angleA == angleStart || angleA == angleEnd || angleB == angleStart || angleB == angleEnd) { delay(15); digitalWrite(pinLedA, 0); digitalWrite(pinLedB, 0); ledOnOff = false; } }
Descrizione del tutorial passaggio a livello con tinkecard
Dopo aver incluso la libreria Servo.h necessaria al controllo dei servo, parti con le linee 03-07 in cui definisci i pin a cui sono connessi sia i servo, sia i led ed il bottone;
linee 09-20: definisci tutte le variabili di stato per il controllo dei led e dei movimenti dei servo, definendo sia il grado da cui far partire il servo sia quello a cui deve arrivare per controllare la sbarra del passaggio a livello;
linee 22-23: definisci le due istanze servo ( A e B ) con cui controllerai i due servomotori;
linea 26: imposta il monitor seriale a 9600 baud per avere a disposizione una sorta di Debug;
linee 28-30: imposta i due pin a cui sono connessi i led in modalità OUTPUT e quello a cui è collegato il bottone in modalità INPUT;
linee 32-36: usa il metodo attach per assegnare a ciascuna istanza il pin a cui è collegato il rispettivo servo motore; ed utilizza il metodo write per assegnare ad entrambi i servo un angolo da cui partire.
Considera che nel mio esempio ho deciso di far lavorare i due servo in modo speculare partendo dal principio che i due servo si trovino nel plastico uno rivolto al contrario dell’altro.
linea 41: normalmente il pulsante, non premuto, restituisce il valore 0 e solo quando lo premi restituisce 1, verificando quindi la condizione di “1” puoi determinare che il pulsante sia stato premuto;
linea 42: imposta il cambio di stato della variabile butState come l’inverso del suo precedente valore, questa variabile funziona in modalità toggle il cui stato varia ad ogni pressione del pulsante;
linee 43-44: imposta un delay di 300 millisecondi come debounce ( antirimbalzo ) e il valore della variabile ledOnOff a true, questo valore indicherà allo sketch che i led devono iniziare a lampeggiare;
linea 47: valuta lo stato della butState in modo che determini la direzione in cui muovere i servo;
linee 49-50: incrementa il valore di A e decrementa il valore B in funzione del valore corrente degli angoli A e B all’interno dell’intervallo di start ed end;
linee 54-55: sono identiche alle precedenti con la sola differenza che l’angolo A viene decrementato e l’angolo B incrementato;
Notice
Il millis() conteggia il tempo trascorso dall’avvio dello sketch il tempo trascorso in millisecondi, senza interrompere il funzionamento dello sketch stesso, è utile in tutte quelle situazioni in cui non vuoi che un delay ti inibisca il funzionamento;
linea 63: per determinare il lampeggio alternato dei led senza interrompere la sequenza di movimento dei servo devi utilizzare il millis() in mod che sottraendo il tempo precedentemente misurato da quello attuale, riportato dal millis(), tu possa determinare se hai superato o meno il tempo timeDelay impostato.
La condizione di if si completa con la valutazione dello stato della variabile ledOnOff che hai impostato nelle linee superiori dello sketch;
Linea 64: reimposta il nuovo valore della oldTimeDelay come il valore corrente di millis();
linea 66: usando il medesimo metodo utilizzato per la butState alla linea 42, usa la ledState per definire se accendere o spegnere i led;
linee 67-68: imposta il valore del primo led uguale allo stato attuale ed il valore del secondo led come l’inverso di se stesso, in questo modo, ad esempio, il primo led si accede ed il secondo si spegne e viceversa;
linee guida 70-71: imposta il grado a cui far arrivare il servo seguendo le direttive di angolo per A e B impostate alle linee 49-50 o 54-55;
linea 74: è una linea unica con la 75 che rappresenta le condizioni di estremo per i valori, in gradi, dei servo; in pratica ogni volta che uno dei servo raggiunge uno degli estremi impostati esegui le linee successive;
linea 77: imposta un tempo di 15 millisecondi prima di procedere con le linee successive;
linee 78-79: spegni entrambi i led;
linea 80: imposta a false il valore di ledOnOff per indicare al loop successivo di non accendere i led e spostare i servo,
Trasferisci lo sketch ad arduino e potrai vedere:
i servo motori muoversi ed i led accendersi in modo alternato alla pressione del pulsante:
Se fai delle modifiche allo sketch o aggiungi qualche componente al tuo plastico ferroviario, usa i commenti per condividere le tue idee con altri appassionati.
4 commenti
Vai al modulo dei commenti
Ciao! bellissimo progetto. Vorrei sapere se per caso sei in grado di convertire il codice nel linguaggio di Octave??
Autore
Ciao Asia,
purtroppo non conosco Ottave, lascio il tuo commento on-line qualora qualche altro maker conosca entrambi i linguaggi e possa aiutarti.
Salve riguardo al passaggio a livello di arduino posso collegare un reed invece di Interruttore e comandare 2 servo per un certo tempo contemporaneamente? Grazie.
Autore
Ciao Dario,
certo è una bella evoluzione del progetto.