Go Down

Topic: Semaforo Complesso OK-Flip Flop Semplice ( e non ci salto fuori). (Read 6223 times) previous topic - next topic

Puso

Salve
premesso che sono alle prime armi,
sto tentando di realizzare il mio primo programma concreto,IL SEMAFORO.
Ora avendo gia scritto un programma per prendere confidenza,ho ipotizzato un incrocio ed i semafori che lavorano nella loro sequenza,poi pero mi sono posto un problema;

e se arriva un Vecchio che preme il pulsante Pedonale,che succede?

Nulla,perchè se ho capito bene o lo preme in un preciso istante del LOOP,oppure resta li e continua ad invecchiare.

Mi è venuto in mente una soluzione elettrotecnica(in cui sono più ferrato) in cui il pulsante si comporta ON quando viene premuto e ritorna OFF dopo un certo periodoe E QUI in ELETTRONICA ed PROGRAMMAZIONE per ignoranza mi sono arenato.

DOMANDA:

1 esiste una programmaziione che legge un input digitale DURANTE ed INDIPENDENTE dal LOOP?
2  se non esiste,come posso replicare la mia soluzione elettrotecnica,il più semplicemente possibile, magari con un transistor (che sono la mia dannazione e non mi entrano in testa)?


Grazie se mi rispondete

ORSO2001

Ciao Puso,

presentati nell'apposita sezione QUI.

poi per fare quello vuoi ti ci sono diversi modi...anche solo software.

Puso

ho cliccato
 ma non ho capito  dove devo scrivere.

scusate ma non sono pratico dei forum

ORSO2001

ciao...ti sei già presentato...non so perchè ma prima non vedevo il tuo post di presentazione...detto questo se fai una ricerca nei miei post ...un po' di tempo fa...ho postato quello che ti serve.

Puso

ciao orso
grazie per avermi risposto

io non sono piu un ragazzino e faccio fatica atrovare i tuoi post e non leggo inglese( è come i transitor,non mi entrano in testa).

puoi darmi qualche riferimento?

Puso

in pratica mi son messo dalla parte del vecchietto che preme un pulsante per attraversare un passaggio pedonale mentre è in esecuzione un CICLO.

e mi trovo al punto che o mi studio tutto il ciclo e premo il pulsante al momento opportuno, oppure;
-resto li fino a diventare una mummia.
-ci provo e passo durante il cilo LOOP, rischiando di farmi investire.
-oppure mi arrangio con un semolice Relè ed un Timer (ELETTROTECNICA).
-oppure qualkuno mi aiuta e mi da un alternativa.

ORSO2001

ciao...

bhe...al momento ho scritto solo nella sezione in italiano...per cercare nei post di qualcuno basta che clicchi sulla suo icona/avater...ho il dubbio che il tuo sketch faccia tanto uso della funzione delay()...no buono!

se non vuoi fare un po' di ricerca nei vari post devo dirti di dare un occhio QUI e QUI

docsavage

alternative:

monostabile che memorizza il fatto di aver premuto un tasto almeno per un tempo superiore ad un ciclo di loop
santo 555 aiutami tu

ma un metodo del genere è concettualmente arcaico

usare un interrupt, connesso al pulsante
funziona certamente, ma è come sparare con un 88/70 contro una zanzara
uno spreco di risorse

pensiero laterale
far gestire la cosa alla setup invece che alla loop
il pulsante invece che normalmente aperto è normalmente chiuso, e taglia l'alimentazione di arduino
una pressata, l'arduino resetta e riparte la setup
si potrebbe anche usare direttamente il pin reset

ma questi son metodi da macellaio, non da veri programmatori

secondo me la soluzione vera è tenere la loop veloce,velocissima ed eseguire le azioni di accensione/spegnimento delle luci non in funzione di una delay, ma di un test sulla millis

io farei così

per cominciare una funzione di "comando luci" che riceve in ingresso un array di char
ad ogni elemento dell'array associo una terna di luci, e una lettera che indica lo stato
del tipo RGRG indica rosso sulla palina 1 giallo( col verde) sulla palina 2
e via così

così comandare il semaforo diventa semplice
comanda_luci("RGRG");

se questo va passerei a scrivere nella loop una cosa del tipo

if tempo>millis()....{
comanda_luci(quello che serve)
tempo=millis()+nuova attesa
}

appena fatto questo , che richiede il tempo minimo tecnico
posso controllare il pulsante
e naturalmente iniziare la nuova sequenza che serve

si potrebbe pensare ad una array di strutture
-configurazione luci
-tempo che deve durare

la loop si limita a ciclare l'array principale
E' stato bello... ma appunto: è stato
Ocio, che adesso c'è qualcuno che dice le stesse cose per le quali mi martellavate... Il tempo è galantuomo

Puso

Si lo ammetto
 tanto uso della funzione delay per rendere i semafori abbastanza realistici(in tutto il loop dura circa 20 secondi)

credo che anche utilizzando

if tempo>millis()....{
comanda_luci(quello che serve)
tempo=millis()+nuova attesa
}

tutto il ciclo completo dei semafori durerebbe sempre 20 secondi.

Potrei aggiungere ulteriori delay velocissimi in modo da far lampeggiare i led velocissimamente (cosi l'occhio umano li percepirebbe accesi) ed in mezzo ad ogni stringa infilarci la lettura del pulsante,ma per farlo dovrei scrivere uno sketch lungo come la bibbia e i vangeli assieme.

Ammetto anche  che utilizzare il Reset oppure NE555........sono state le prime 2 soluzioni che mi sono venute in mente e per il momento vedo poche alternative.

In realtà  mi servirebbe una funzione che stia ell'esterno del LOOP e che agisca comunque.


astrobeed

ma questi son metodi da macellaio, non da veri programmatori
Mi sono appena reso conto che nessuno in questo forum, ma anche su i vari libri per Arduino, ha mai spiegato come si deve scrivere un programma, a partire dal fatto che usare una variabile di tipo int per definire i pin è uno spreco assurdo della ram, risorsa preziosa e limitata sulle piccole mcu, per finire col fatto che il ciclo main(), loop() su Arduino, deve essere ripetuto il maggior numero possibile di volte al secondo e che nessuna funzione deve essere bloccante e/o impegnare la cpu per più di pochi ms.
Se oggi trovo un'oretta libera da dedicare alla cosa vedo di preparare un pdf che spiega, almeno il minimo sindacale, come si deve scrivere un programma.
Scientia potentia est

Puso

 :smiley-confuse:
nel frattempo mi dici se al mio problema esiste un metodo alternativo a quelli da macellaio.

Claudio_FF

Quote from: Puso
Potrei aggiungere ulteriori delay velocissimi in modo da far lampeggiare i led velocissimamente (cosi l'occhio umano li percepirebbe accesi) ed in mezzo ad ogni stringa infilarci la lettura del pulsante,ma per farlo dovrei scrivere uno sketch lungo come la bibbia e i vangeli assieme
Ci sei quasi, l'idea del "velocissimo spezzettato" per fare più cose assieme è corretta, ma probabilmente non l'implementazione a cui pensi. In realtà è più semplice (macchine a stati finiti), attendiamo il post di Astro per avere qualcosa di pratico su cui discutere.

Tra l'altro, se riesci a fare uno schema a relè/temporizzatori/pulsanti "classici", tradurlo in funzioni logiche equivalenti è un altro modo ancora per affrontare il problema.

In entrambi i casi il loop dovrebbe procedere a diverse migliaia di cicli completi al secondo.
Una domanda ben posta è già mezza risposta.

PaoloP

Io creerei una struttura del genere
Code: [Select]
void loop(){
controllopulsanti();
controllotempo();
comandasemafori();
}

il codice deve girare sempre senza delay usando la funzione millis() per determinare lo stato di accensione delle varie luci.
Userei poi una struttura per definire i semafori e passare i parametri da una funzione all'altra.

Puso

Fare uno schema a relè/temporizzatori/pulsanti "classici", tradurlo in funzioni logiche equivalenti potrei anche riusirci,resta il fatto che il LOOP,legge le righe in fila ed una volta che è partito non posso aggiungere o toglier niente.

Anche utilizzando la struttura che consigli,resta sempre il fatto che il ciclo completo dei semafori durerebbe 20 secondi e dovrei premere il pulsante al momento giusto per fargli leggere lo stato differente.

mi sa che devo preparmi davvero ad uno sketch lungo come la divina commedia.

PaoloP

Non stai pensando quadrimensionalmente! (cit.)

Anche se una lampadina deve rimanere accesa 20 secondi, il loop() non deve durare 20 secondi.
Il ciclo loop() deve durare una frazione di secondo e deve essere sufficientemente breve da intercettare la pressione del pulsante.

Esempio:
Code: [Select]
void loop() {
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= 20000) {
    previousMillis = currentMillis;
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }
    digitalWrite(ledPin, ledState);
  }

}

Il led si accende e si spegne ad intervalli di 20 secondi. il ciclo dura meno di un millisecondo.

Go Up