Aiuto, problemi programmazione.

Buonasera a tutti.
Sto realizzando un programma nel quale ho due led e due pulsanti. Premendo il primo pulsante il led1 rimane acceso, se tengo premuto il pulsante2 il led1 si spegne, ma il led2 deve stare acceso per 5 secondi, dopodiché deve spegnersi anche se il pulsante è ancora premuto e far accendere il LED1. Ho provato con il comando Millis() ma non riesco a trovare una soluzione.
Sapreste indicarmi quali costrutti, funzioni o comandi dovrei usare?
Grazie

vincenzO88:
Sapreste indicarmi quali costrutti, funzioni o comandi dovrei usare?Grazie

Più che comandi.... direi sequenza logica... questa va bene? Realizza la sequenza voluta?

finché P1 non premuto:
    nulla
accendi led1
ripeti:
    finché p2 non premuto:
        nulla
    spegni led1
    accendi led2
    pausa 5 sec
    accendi led1
    spegni led2
    finché P2 premuto:
        nulla

della serie Claudio_FF "poi possiamo iniziare a parlare di millis :smiley:

miky_police:
poi possiamo...

Mi sa di no. Il problema è posto in modo troppo ambiguo, infatti non ho la minima idea se lo pseudocodice che ho postato faccia quello che l'OP realmente vuole...

Scusate se mi intrometto, non ho resistito,

vincenzO88
a volte basta una piccola ricerca in rete, ed io non sono molto bravo a farla,
però potresti vedere qui

ma c'è ne sono molte altre

È che non è chiaro cosa vuole, se solo ottenere quella sequenza, se deve ottenerla in modo non bloccante, se vuole solo provare a usare millis ecc.

Lo pseudocodice non bloccante con uso di millis potrebbe essere questo:

se fase 1  e  premuto p1:
   accendi L1
   fase = 2

se fase 2  e  premuto p2:
   carica tempo da millis
   spegni L1
   accendi L2
   fase = 3

se fase 3  e  trascorsi 5 sec:
   spegni L2
   accendi L1
   se P2 premuto:
       fase = 4
   altrimenti:
       fase = 2

se fase 4  e  P2 non premuto:
    fase = 2

...e stiamo sempre assumendo che i pulsanti vengano letti correttamente, che non ci siano dimenticanze di resistenze di pull, e che ci sia l'adeguato debounce hardware...

fase 1 2 3 4 a cosa corrispondono?

Sono le situazioni in cui il programma si viene a trovare: Attesa P1, Attesa P2, temporizzazione, attesa rilascio P2... esattamente le stesse del codice del post #1.

Lo risolverei senza macchine a stati finiti, ma solo con tre flag, una per controllare il led1, una per controllare l'intervallo di tempo, e una per disabilitare il pulsante 2.

Mi sembra che il problema da valutare sia il comportamento del pulsante2 ! Mi sembra che il problema si possa risolvere abbastanza facilmente facendo in modo che il pulsante2 "agisca" una sola volta quando è premuto, da cui ho pensato a un flag per il pulsante2, premo e agisco, il flag annulla l'azione del pulsante2.

1)Premo il pulsante1 flagLed1=1 accendo il led
2)Premo pulsante2 flagLed1=0 e spengo il led1, flagPulsante2=0 e disabilito il pulsante, flagTempoLed2=1 accendo il led2 al trascorre del tempo.

3)Passati 5 secondi, flagLed1=1 accendo il led1, flagPulsante2=1 riabilito il pulsante2, flagTempoLed2=0;

torn24:
Lo risolverei senza macchine a stati finiti, ma solo con tre flag, una per controllare il led1, una per controllare l'intervallo di tempo, e una per disabilitare il pulsante 2 ...

Credo che imparare ad usare una "macchina a stati finiti" sia molto più educativo; non solo, appena la cosa si complica un po', con un sistema a stati finiti implementi facilmente, mentre, come dici tu, ti complichi immediatamente la vita.

Guglielmo

Credo che imparare ad usare una "macchina a stati finiti" sia molto più educativo;

Sicuramente :slight_smile: Imparare un "sistema-meccanismo" che può essere applicato in innumerevoli situazioni, ha un utilità indiscutibile.

Ma ho descritto la soluzione che mi veniva naturale immediata per questo problema, forse perché non mi viene spontaneo usare una macchina a stati finiti, se la uso probabile che sia l'unica soluzione possibile :slight_smile:

torn24:
... forse perché non mi viene spontaneo usare una macchina a stati finiti, se la uso probabile che sia l'unica soluzione possibile :slight_smile:

... infatti l'invito è anche a te ... se ti abitui ad utilizzae una logica come quella, riesci a scomporre programmi complessi in "stati finiti", a descriverli graficamente in modo più chiaro (... è solo un esempio grafico slegato dal caso in esame) ...


... e ti ci muovi molto più agevolmente :slight_smile:

Guglielmo

Guardate che anche se considerate la combinazione di più variabili e non di una sola dedicata ad identificare gli stati, si parla comunque di automa a stati finiti.
Lo stato di un automa a stati finiti può tranquillamente essere un insieme di condizioni, anche complesse.
Poi si può rendere più comprensibile facendo convergere tutto su una singola variabile, ma questo non cambia la sostanza, sempre di automa a stati finiti si tratta.
Quindi, @torn24, anche la tua proposta del post 8 è un automa a stati finiti :stuck_out_tongue: anche se magari meno "ordinato e identificabili" a colpo d'occhio :wink:
Quello che esprime Guglielmo qui sopra, è un approccio per impostare le cose in modo più lineare e comprensibile che aiuta a tenere sotto controllo anche complessità molto maggiori.
Anche tu identifichi stati (combinazioni valide di valori dei 3 flag che vuoi usare) e transizioni (taca staca led & company)...

Sto documentandomi meglio in rete su "macchine o automa a stati finiti", non è un argomento basilare.
Capire il concetto è abbastanza semplice, abbiamo degli stati e possiamo passare da uno all'altro in base ad degli eventi.
Come applicarla in diversi problemi "sembra poi che tutte le automazioni si possano fare con una macchina a stati", non mi viene affatto facile :slight_smile: :slight_smile: :slight_smile:

La macchina a stati finiti non è una tecnica di programmazione ma un modo per descrivere un certo sistema, poi c'è l'implementazione che può essere fatta in N modi differenti, anche incasinati, dipende da quanto schizzato è chi programma :wink: .

Il trucco è di identificare le condizioni che ti servono e dargli un nome, anche astratto, giusto per identificarle anche solo nella tua testa e poi ragioni sul come dove e quando ti serve identificarle nel tuo software e cosa va fatto una volta identificate.

Se riesci bene ad isolare queste condizioni e le azioni da fare, risulta tutto più semplice.
Tu hai fatto lo stesso ragionamento, senza però, schematizzare in modo ben separato le varie condizioni per cui ti pare che sia un approccio differente, ma semplicemente hai limitato la tua azione ai pochi stati che ti interessavano e li hai gestiti direttamente.
Per cose semplici, il tuo metodo, funziona bene perchè è più diretto e immediato, per cose più articolate perdi facilmente il controllo, per cui schematizzare bene le cose ti aiuta a identificare eventuali problemi.
Ad es. sul disegno postato da Guglielmo, se dentro i cerchietti degli stati ci metti l'elenco delle condizioni da verificare, ti salta subito all'occhio se ci sono duplicati e quindi il ragionamento non fila.
O se non ci sono azioni per passare da uno stato ad un'altro che invece ti serve ci siano.

Poi, se riesci ad entrare nel meccanismo, puoi mappare processi anche molto complessi, sulla carta senza scrivere una sola riga di codice, verificando se le cose quadrano.
Fatto questo la scrittura del codice è un esercizio banale, devi solo tradurre nella sintassi del linguaggio ma la struttura è già bella e pronta.
Per fare pratica segui alcuni post di @Claudio_FF che in questi giorni si sta sbizzarrendo, non serve usare diagrammi tipo quello di Guglielmo, ma anche elenchi ordinati, per i casi semplici dei post di cui parlavo qui sopra. In uno ha espresso un automa semplicemente con un elenco indentato.

Puoi anche partire da una sorta di tavola della verità (quelle che si usano in algebra booleana per descrivere le porte logiche, per capirci, dove indichi gli ingressi e tutte le combinazioni possibili indicando l'output atteso) e analizzare gli stati possibili eliminando quelli impossibili (non tutte le combinazioni degli ingressi sono sempre possibili, ad es. potresti avere ingressi mutualmente esclusivi se uno è attivo l'altro è spento e viceversa, quindi escludi quelli dove sono uguali indicandoli come impossibili), poi raggruppando per stati che devono portare allo stesso risultato e da li, avendo appena identificato gli stati fondamentali, ragionare sulle azioni da fare per cambiare stato.

torn24:
Sto documentandomi meglio in rete su "macchine o automa a stati finiti", non è un argomento basilare ...

Prova a dare una letta QUI, ed anche QUI ... sono un buon punto di parteza ... :wink:

Guglielmo

Avete già detto tutto... la sintesi è che ogni volta che un codice reagisce non solo in base agli ingressi ma tiene conto anche di qualche informazione precedente (anche un semplice flag) allora è sicuramente una macchina a stati. Poi appunto ci sono diverse implementazioni più o meno chiare / efficienti / compatte / comode. Il codice procedurale bloccante (con while di attesa e delay) è il caso limite più involuto cui gli stati non è che non ci sono, ma sono realizzati implicitamente passo passo nella sequenza delle istruzioni.

chiaro, conciso e inequivocabile, come sempre.
concorquoto... ah no, scusare, quello lo fa il mio socio, io quotocordo :wink:

poi c'è l'implementazione che può essere fatta in N modi differenti, anche incasinati, dipende da quanto schizzato è chi programma :wink: .

:smiley:

A proposito di schizzati, mi sono chiesto come fare l'AND tra due stati, OR non è un problema mentre con AND servono due core che eseguono in parallelo. AND dove la sequenza ha importanza, cessa di essere un AND, perché si che vengono eseguiti entrambe, ma prima uno e poi l'altro.

Puoi anche partire da una sorta di tavola della verità (quelle che si usano in algebra booleana per descrivere le porte logiche, per capirci, dove indichi gli ingressi e tutte le combinazioni possibili indicando l'output atteso) e analizzare gli stati possibili eliminando quelli impossibili (non tutte le combinazioni degli ingressi sono sempre possibili, ad es. potresti avere ingressi mutualmente esclusivi se uno è attivo l'altro è spento e viceversa, quindi escludi quelli dove sono uguali indicandoli come impossibili), poi raggruppando per stati che devono portare allo stesso risultato e da li, avendo appena identificato gli stati fondamentali, ragionare sulle azioni da fare per cambiare stato.

Dalla teoria all'implementazione si commettono errori, ed sufficiente lasciare che la macchina assuma un stato non previsto per avere alla fine una macchina a stati non finiti. L'implementazione deve aiutare anche in questo senso, per cose semplici ma che devono essere affidabili si usa un array dove ogni elemento contiene lo stato e la giusta sequenza che ti permette anche di andare indietro nel tempo, cioè nel senso che da array[10] anziché passare ad array[0] passi ad array[9].

Ciao.

Una macchina a stati finiti non necessariamente ha stati sequenziali. :wink: e non necessariamente gli stati sono mappati con un univo valore di una singola variabile :wink: per tutto il resto c'è mastercard :stuck_out_tongue:

Riguardo il quesito schizzato sull'AND ti rimanderei temporaneamente a questo thread :stuck_out_tongue: (sto scherzando ovviamente, ma dire che ci ho capito poco è poco a sua volta :wink: ). Apri discussione apposita e ne parliamo :wink: