L'IF con l'utilizzo di mills() in quel modo è errato ... studia QUI come usare millis() per le temporizzazioni
Guglielmo
L'IF con l'utilizzo di mills() in quel modo è errato ... studia QUI come usare millis() per le temporizzazioni
Guglielmo
Tra l'altro usare millis solo per attendere quattro secondi senza fare niente altro ha poco senso, allora tantovale usare delay(4000).
Due domande:
Si, ho barato quando ho detto che le domande erano solo due
maubarzi:
Due domande:
- Quando scatta il giallo si spegne il verde?
- Perchè tratti i 4 semafori in modo indipendente e non li accoppi a due a due? Gli opposti dovrebbero essere uguali
- Questa è la versione ottimizzata che non funziona, quella funzionante com'era?
- Hai dimestichezza con un po' di elettronica digitale? Sistemato questo codice, vuoi uno spunto per semplificare al massimo il software delegando un pelo all'hardware? Solo dopo aver sistemato questo però
Si, ho barato quando ho detto che le domande erano solo due
Nella versione originale i semafori li ho accoppiati due a due (immagina un quadrivio con due coppie di semafori alternati). Ti posto qui il codice usato (semplicemente accendendo e spegnendo i led con delay)
void setup()
{
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(13, OUTPUT);
pinMode(12, OUTPUT);
pinMode(11, OUTPUT);
}
void loop()
{
// Inizio Blocco1
// Accendo Rosso semafori 1 e 3 - Verde semaforo 2
// e 4
digitalWrite(2, HIGH);
// Accendi Rosso1
digitalWrite(3, LOW);
// Spegni Giallo1
digitalWrite(4, LOW);
// Spegni Verde1
digitalWrite(5, HIGH);
// Accendi Verde2
digitalWrite(6, LOW);
// Spegni Giallo2
digitalWrite(7, LOW);
// Spegni Rosso2
digitalWrite(8, HIGH);
// Accendi Rosso3
digitalWrite(9, LOW);
// Spegni Giallo3
digitalWrite(10, LOW);
// Spegni Verde3
digitalWrite(13, HIGH);
// Accendi Verde4
digitalWrite(12, LOW);
// Spegni Giallo4
digitalWrite(11, LOW);
// Spegni Rosso4
// Fine Blocco1
delay(5000); // Wait for 5000 millisecond(s)
// Inizio Blocco2
// Spengo Verde 2 e 4 - accendo Giallo 2 e 4
digitalWrite(5, LOW);
// Spegni Verde2
digitalWrite(13, LOW);
// Spegni Verde4
digitalWrite(6, HIGH);
// Accendi Giallo2
digitalWrite(12, HIGH);
// Accendi Giallo4
// Fine Blocco2
delay(5000); // Wait for 5000 millisecond(s)
// Inizio Blocco3
// Spengo Giallo 2 e 4 - Accendo Rosso 2 e 4
digitalWrite(6, LOW);
// Spegni Giallo2
digitalWrite(12, LOW);
// Spegni Giallo4
digitalWrite(7, HIGH);
// Accendi Rosso2
digitalWrite(11, HIGH);
// Accendi Rosso4
// Fine Blocco3
delay(5000); // Wait for 5000 millisecond(s)
// Inizio Blocco4
// Accendo Verde 1 e 3 -
digitalWrite(4, HIGH);
// Accendi Verde1
digitalWrite(10, HIGH);
// Accendi Verde3
digitalWrite(2, LOW);
// Spegni Rosso1
digitalWrite(8, LOW);
// Spegni Rosso3
// Fine Blocco4
delay(5000); // Wait for 5000 millisecond(s)
// Inizio Blocco5
// Spengo Verde 1 e 3 - Accendo Giallo 1 e 3
digitalWrite(4, LOW);
// Spegni Verde1
digitalWrite(10, LOW);
// Spegni Verde3
digitalWrite(3, HIGH);
// Accendi Giallo1
digitalWrite(9, HIGH);
// Accendi Giallo3
// Fine Blocco5
delay(5000); // Wait for 5000 millisecond(s)
// Inizio Blocco6
// Spengo Giallo 1 e 3 - Accendo Rosso 1 e 3
digitalWrite(3, LOW);
// Spengo Giallo1
digitalWrite(9, LOW);
// Spengo Giallo3
digitalWrite(2, HIGH);
// Accendo Rosso1
digitalWrite(8, HIGH);
// Accendo Rosso3
delay(5000); // Wait for 5000 millisecond(s)
// Fine Blocco6
}
Ok, quindi alla 1 capisco che la risposta è SI, quando si accende il giallo voglio che si spenga il verde.
Per la 2 intendevo che con un singolo comando, cioè 3 pin, pilotavi due semafori, quindi ogni pin 2 led dello stesso colore per i semafori opposti.
Comunque, non cambia molto, era solo una mia curiosità.
Ora entriamo nel merito con altre domande:
Perchè dici che non funziona? che problema riscontri?
Hai capito cosa ti è stato scritto ai post 2 e 3? cioè come usare millis() ?
Hai capito a cosa serve impostare il pinMode nel setup?
Perchè fai 4 for identici e non uno solo?
Perchè non hai fatto semplicemente un for da 2 a 13?
astroboy81:
...ho creato con thinkercad un progetto di un incrocio semaforico a 4 postazioni ...Il progetto è completo e funzionante
Scusa, 2 curiosità.
nid69ita:
Scusa, 2 curiosità.
- In thinkercad hai creato un progetto elettrico e in qualche modo lui ha generato il codice Arduino ?
- lui lo simula ? E poi lo hai provato nella realtà e funziona ?
Ma se non sai cosa sia TinkerCad, perché non gli dai un'occhiata? A volte è anche comodo provare e sperimentare senza dover necessariamente costruire il prototipo (per cose abbastanza "basic", ma va benino entro certi limiti).
docdoc:
(per cose abbastanza "basic", ma va benino entro certi limiti)
I limiti alla fine sono nella mancanza dell'hardware, non si vedono bene le variazioni li luminosità dei led pwm per esempio. E in qualche caso bisogna aggiungere un delay(10) nel loop per far avanzare il tempo simulazione correttamente (altrimenti va lentissimo).
Una domanda, ma come si chiama il singolo semaforo? Incrocio sono tutti assieme e semaforo il singolo?
Comunque, e qui dico la mia, un incrocio siffatto è un caso particolare di una macchina a stati finiti, particolare perché gli stati si seguono sempre, senza mai salti o deviazioni
Insomma vanno passo a passo a spasso (per chi ha voglia di cercare)
docdoc:
Ma se non sai cosa sia TinkerCad, perché non gli dai un'occhiata? A volte è anche comodo provare e sperimentare senza dover necessariamente costruire il prototipo (per cose abbastanza "basic", ma va benino entro certi limiti).
Grazie.
Lo conosco solo per il disegno 3D, la parte circuito non l'ho provato. Sarei curioso di vedere il progetto di @astroboy81,
@astroboy81, è pubblico? che nome ha ? "Quadruplo semaforo per incrocio" ?
Perchè dici che non funziona? che problema riscontri?
Hai capito cosa ti è stato scritto ai post 2 e 3? cioè come usare millis() ?
Ho capito che è una funzione che restituisce un valore a un tot di tempo dall'accensione della scheda
Hai capito a cosa serve impostare il pinMode nel setup?
Il pinMode dovrebbe servire ad impostare i pin della scheda come input o output
Perchè fai 4 for identici e non uno solo?
Perchè non hai fatto semplicemente un for da 2 a 13?
il for non l'ho capito tanto bene,dovrei rileggermi un po qualche guida
Scusa, 2 curiosità.
- In thinkercad hai creato un progetto elettrico e in qualche modo lui ha generato il codice Arduino ?
- lui lo simula ? E poi lo hai provato nella realtà e funziona ?
Ho creato il progetto in thinkercad posizionando i componenti e i collegamenti.
Per quanto riguarda il codice lo devi creare tu,ma hai 2 possibilità:
1.Posizionando dei blocchi con le funzioni (utile ai principianti che vogliono capire come funziona)
2.Scrivendo direttamente il codice.
Nel primo caso (selezionando nella schermata "blocchi+testo" o solo "blocchi") thinkercad ti scrive il codice in base a come posizioni i blocchi. Nel secondo caso invece il codice lo devi scrivere tu.
In tutti e due i casi,comunque non puoi tornare all'altra visualizzazione,cioè,se crei il codice con blocchi o blocchi+testo,selezionando solo testo,il codice si azzera...stessa cosa se passi da solo testo a blocchi o blocchi+testo.
Ultimato circuito elettronico e codice puoi fare la simulazione,e in caso di errori nel codice te lo segnala cosi da poter apportare le modifiche necessarie.
Una domanda, ma come si chiama il singolo semaforo? Incrocio sono tutti assieme e semaforo il singolo?
Banalmente li ho chiamati Semaforo1,semaforo2,semaforo3 e semaforo4... si trovano di fronte 1 con 3 e 2 con 4
Sarei curioso di vedere il progetto di @astroboy81,
@astroboy81, è pubblico? che nome ha ?
Qesta è la versione originale funzionante (con il codice lungo).
nid69ita:
Lo conosco solo per il disegno 3D, la parte circuito non l'ho provato.
La parte simulazione è fatta abbastanza bene (nulla di eccezionale, sei limitato ad esempio ai componenti "virtuali" a disposizione ed alle sole librerie che ti mettono a disposizione), ha anche ovviamente il serial monitor, anche grafico.
Io ogni tanto lo uso per "sketchare" al volo qualcosa che voglio verificare magari una funzione specifica, ma la cosa molto comoda è la possibilità di andare anche in debug, con breakpoint e visualizzazione del valore delle variabili.
Tu piazzi Arduino, una breadboard, ed inizi ad aggiungere componenti, quindi vai in "Codice" ed inserisci il tuo codice, quindi con "Avvia simulazione" lo "accendi".
Sarei curioso di vedere il progetto di @astroboy81
Bah vabbè avrà messo 12 LED (Tinkercad ti avvisa pure se non metti la resistenzina... ) e al massimo un pulsante di start/stop, che altro ci sarà mai su quel circuito?
astroboy81:
Perchè dici che non funziona? che problema riscontri?
Ho creato il progetto in thinkercad posizionando i componenti e i collegamenti.
Ma l'errore (almeno questo mostrato) è chiaro...
Definisci un array a 4 valori e ne inizializzi 6?
Poi ci sono altri problemi ma, scusami, se non indenti decentemente mi rifiuto di proseguire, perché ti basta fare un Ctrl-T nell'IDE e postare il codice indentato "bene".
E già allora puoi forse anche tu vedere qualcuno degli altri errori...
Ma l'errore (almeno questo mostrato) è chiaro...
Definisci un array a 4 valori e ne inizializzi 6?
in effetti volevo capire bene come utilizzare questa funzione....
Poi ci sono altri problemi ma, scusami, se non indenti decentemente mi rifiuto di proseguire, perché ti basta fare un Ctrl-T nell'IDE e postare il codice indentato "bene".
E già allora puoi forse anche tu vedere qualcuno degli altri errori...
tieni conto sempre che non sono esperto,e magari qualcosa non la so....
Si, tranquillo, si era notato un cicinin.
Scusa se faccio sempre domande, ma perchè, conoscendo poco niente del linguaggio di programmazione, ti stavi ponendo il problema di ottimizzare il codice?
Cioè, se hai solo una vaga idea di cosa sia un ciclo for, che tipo di ottimizzazioni pensavi di fare?
Visto che hai una base di partenza funzionante, studiati bene quella e poi cerca di modificare un singolo pezzo per volta.
Ad es. da
void setup()
{
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(13, OUTPUT);
pinMode(12, OUTPUT);
pinMode(11, OUTPUT);
}
a
void setup()
{
for (byte i = 2; i <= 13; i++) {
pinMode(i, OUTPUT);
}
}
cercando di imparare, applicandoli, i fondamentali.
Che puoi trovare un po' ovunque cercando guide o documenti sul linguaggio C o C++.
Grazie per le info
stanotte, invece di dormire ho pensato
e invece di pensare ad "aiutatemi ad aiutarvi" ho pensato al semaforo (vergogna vergogna.....)
e ho tirato fuori questo:
// di Nelson "StandardOil"
// Idea da sviluppare:
// Semaforo alternativo
enum statisemaforo {SEM_SPENTO, SEM_VERDE, SEM_GIALLO, SEM_ROSSO, SEM_LAMPEGGIO, SEM_INIT};
// stati possibili di un semaforo, dove SEM_INIT è monostabile su SEM_SPENTO
typedef struct Semaforo_struct
{
byte verde; // pin luce verde
byte rosso; // pin loce rossa
byte giallo; // pin luce gialla
statisemaforo statoattuale; // lo stato attuale del semforo
statisemaforo inizializza(void)
{
// inizializza il semaforo
// provando anche le sue lampade
pinMode(verde, OUTPUT);
digitalWrite(verde, HIGH);
delay(100);
digitalWrite(verde, LOW);
pinMode(rosso, OUTPUT);
digitalWrite(rosso, HIGH);
delay(100);
digitalWrite(rosso, LOW);
pinMode(giallo, OUTPUT);
digitalWrite(giallo, HIGH);
delay(100);
digitalWrite(giallo, LOW);
statoattuale = SEM_SPENTO;
return statoattuale;
}
statisemaforo stato(void)
{
return statoattuale;
}
statisemaforo azione(statisemaforo comando)
{
statoattuale = comando;
switch (comando)
{
case SEM_SPENTO:
digitalWrite(verde, LOW);
digitalWrite(rosso, LOW);
digitalWrite(giallo, LOW);
break;
case SEM_VERDE:
digitalWrite(verde, HIGH);
digitalWrite(rosso, LOW);
digitalWrite(giallo, LOW);
break;
case SEM_GIALLO:
digitalWrite(verde, HIGH);
digitalWrite(rosso, HIGH);
digitalWrite(giallo, LOW);
break;
case SEM_ROSSO:
digitalWrite(verde, LOW);
digitalWrite(rosso, LOW);
digitalWrite(giallo, HIGH);
break;
case SEM_LAMPEGGIO:
// lampeggio sarà il problema
digitalWrite(verde, LOW);
digitalWrite(rosso, LOW);
digitalWrite(giallo, LOW);
break;
case SEM_INIT:
// ntd, ci pensa una funzione apposta
statoattuale = inizializza();
break;
default:
break;
}
return statoattuale;
}
} Semaforo;
Semaforo semafori[] = {{2, 3, 4}, {5, 6, 7,}, {8, 9, 10}, {11, 12, 13}};
// dichiaro un array di semafori, ognuno con 3 pin di uscita (rosso, giallo, verde) e lo stato iniziale a zero
byte Nsemafori = sizeof(semafori) / sizeof(semafori[0]);
void setup(void)
{
// inizializzo i semafori
for (byte i = 0; i < Nsemafori; i++)
{
semafori[i].azione(SEM_INIT);
// invoco il metodo azione con argomento lo stato di inizializzazione del sameforo
// in alterativa potevo invocare direttamente il metodo inizializza() senza argomento
}
}
void loop(void)
{
static byte passo = 0;
passo = passo % numerostati;
}
poi però è arrivato il sonno e non ho finito, ma manca poco, sono al 90perccenttooo del lavoro, ancoa
vi piace?
Accoppiando i semafori, hai solo 4 condizioni:
rosso verde DURV
rosso giallo DURG
verde rosso DURV
giallo rosso DURG
0ppure 6 condizioni, se vuoi fare come nella realtà, con uno o due secondi di rosso per tutti:
rosso verde
rosso giallo
rosso rosso
verde rosso
giallo rosso
rosso rosso
Puoi fare 4 o 6 #define e poi richiamarle in sequenza:
#define stato1 spegniTutto();digitalWrite(rosso1,HIGH);digitalWrite(verde2,HIGH)
#define stato2 spegniTutto();digitalWrite(rosso1,HIGH);digitalWrite(giallo2,HIGH)
// #define stato2 spegniTutto();digitalWrite(rosso1,HIGH);digitalWrite(verde2,HIGH);digitalWrite(giallo2,HIGH)
#define stato3 spegniTutto();digitalWrite(verde1,HIGH);digitalWrite(rosso2,HIGH)
#define stato4 spegniTutto();digitalWrite(giallo1,HIGH);digitalWrite(rosso2,HIGH)
// #define stato4 spegniTutto();digitalWrite(verde1,HIGH);digitalWrite(giallo1,HIGH);digitalWrite(rosso2,HIGH)
void spegniTutto()
{
digitalWrite(rosso1,LOW);
digitalWrite(giallo1,LOW);
...
}
Se utilizzi solo la porta D da D0 a D5 (I/O da 0 a 5) per comandare le luci, puoi scrivere più semplicemente:
void spegniTutto() {PORTD&=0b11000000;}
// Durata dei verdi:
#define DURV 10
// Durata dei gialli:
#define DURG 3
unsigned long t;
void setup()
{
t=millis()/1000;
}
void loop()
{
if (millis()/1000-t>=DURV+DURG+DURV+DURG) t=millis/1000;
if (millis()/1000-t>=DURV+DURG+DURV) stato4;
else if (millis()/1000-t>=DURV+DURG) stato3;
else if (millis()/1000-t>=DURV) stato2;
else stato1;
/*In maniera forse più comprensibile, si può anche scrivere:
if (millis()/1000-t<DURV) stato1;
else if (millis()/1000-t<DURV+DURG) stato2;
else if (millis()/1000-t<DURV+DURG+DURV) stato3;
else stato4;
*/
}
P.S.: non ho verificato bene le condizioni. Potrebbe esserci qualche errore...
P.P.S.: il punto e virgola alla fine dei #define stato1, ... può essere omesso, in quanto vengono aggiunti negli "if"
Dalle mie parti il giallo si accende senza spegnere il verde, visto che hai aggiunto i 2 secondi di rosso per tutti...