Buongiorno sono nuovo del forum e anche del mondo di arduino. Spero di essere nella sezione giusta, e che qualcuno riesca a darmi una mano per un problema che mi stà dando molti grattacapi.Premettendo che o già provato a cercare qualcosa in rete, non riesco a risolvere il mio problema che forse a molti di voi può sembrare banale, ma che viste le mie poche conoscenze del mondo arduino e elettronica in generale mi stanno creando più confusione in testa che chiarezza vista la quantità di informazioni da imparare. Ed e per questo che approdo nel forum di arduino per cercare qualcuno che mi dia l'Illuminazione. Ma bando alle ciance vengo ad esporvi il mio problema...Praticamente ho la necessita di controllare 4 elettrovalvole da 12 volt ovviamente con relativi relay, e 4 pulsanti per attivare le elettrovalvole separatamente e fare in modo di avere 4 pulsanti che attivano la relativa elettrovalvola...
Fin qui tutto chiaro ogni pulsante attiva la relativa elettrovalvola e ripremendo la disattiva, ma il mio problema è che vorrei temporizzare il tutto e rendere la chiusura della valvola automatica senza dover ripremere il pulsante dopo un certo tot tempo e fare in modo che si possano attivare piu elettrovalvole contemporaneamente. la funzione delay mi salta subito all'occhio che va scartata...e quindi mi sono avventurato nella relativa funzione millis, ma esendo un novizio non riesco a risolvere il mio problema.
Mi affido alle vostre conoscenze, attendo con ansia una vostra delucidazione in merito ringraziandovi in anticipo.
Cordiali saluti
Enrico
P:S ( uso arduino uno)
Ciao,
ti rimando ad un articoli che dovrebbe chiarirti come utilizzare millis, se leggi tutto l'articolo troverai anche la gestione di due compiti indipendenti, da li a farne diventare quattro non dovrebbe essere difficile...
http://www.leonardomiliani.com/2013/programmiamo-i-compiti-con-millis/
Sul sito di Leonardo troverai anche molti altri articoli utili nonchè il leOS2 che potresti pensare di utilizzare per ciò che devi fare (anche se sarebbe uno spreco di risorse innutile in quanto con la millis ottieni ciò che desideri)
mayette89:
Buongiorno sono nuovo del forum e
Ti invitiamo a presentarti (dicci quali conoscenze hai di elettronica e di programmazione) qui: Presentazioni
e a leggere il regolamento: Regolamento
- qui una serie di schede by xxxPighi per i collegamenti elettronici vari: ABC - Arduino Basic Connections
- qui le pinout delle varie schede by xxxPighi: Pinout
- qui una serie di link generali utili: Link Utili
Se cerchi qualche pagina indietro ho scritto un post dove trovi un sistema ancora più raffinato ed elegante che utilizza uno Scheduler elementare.
E' sufficiente sfruttare le caratteristiche del Timer1 dell'Atmega328 e ricavare un "Tic" di sistema con il quale aggiornare delle variabili, legate ciascuna ad un qualsiasi Task.
fabpolli:
Ciao,
ti rimando ad un articoli che dovrebbe chiarirti come utilizzare millis, se leggi tutto l'articolo troverai anche la gestione di due compiti indipendenti, da li a farne diventare quattro non dovrebbe essere difficile...
http://www.leonardomiliani.com/2013/programmiamo-i-compiti-con-millis/
Sul sito di Leonardo troverai anche molti altri articoli utili nonchè il leOS2 che potresti pensare di utilizzare per ciò che devi fare (anche se sarebbe uno spreco di risorse innutile in quanto con la millis ottieni ciò che desideri)
Intanto vi ringrazio subito tutti per la disponibilità e la rapida risposta. In quanto all'articolo gli avevo già dato un'occhiata, ma non riesco a fare in modo che solo quando il pulsante viene premuto il led si accende per 3 secondi e poi si spegne da solo e il tutto riparte...per le Os2 e gli scheduler gli avevo già dato una veloce occhiata ma non volevo entrare per adesso nel merito perchè vorrei imparare a usare al meglio prima la funzione millis() ancora grazie in anticipo.
saluti
Enrico
ciao
mayette89:
... ma non riesco a fare in modo che solo quando il pulsante viene premuto il led si accende per 3 secondi e poi si spegne da solo e il tutto riparte...
Devi utilizzare una variabile di stato.
Quando premi il pulsante accendi il led , ti memorizzi il valore di millis e metti la variabile a TRUE
Il controllo del tempo lo fai solo se la variabile é TRUE; se è passato il tempo che ti serve spegni il led e metti la variabile a FALSE.
Se non vuoi che premendo ancora il pulsante prima che passino i 3 secondi il tempo ricominci (ovvero ad esempio se premi ogni 2 secondi il pulsante il led non si spegne mai) la lettura del pulsante devi farla solo se la variabile è FALSE.
Sperando di non aver aumentato la confusione... ![]()
ciao
pippo72
Ok piu o meno inizio a capire...il mio problema e che a parole il mio apprendimento va un pó a rilento
:)...comunque più tardi se riesco provo a postare uno sketch di quello che intendo fare così se ne hai voglia mi puoi dire dove sbaglio o eventuali migliorie..
Grazie ancora pippo 72.
Saluti
Enrico
Eccomi di nuovo qui, in questi giorni sono stato un pò impegnato e ho avuto anche dei problemi con la linea internet quindi non ho potuto fare poco...come avevo detto vi posto lo sketch perchè ho provato in tutti i modi ma alla fine ho capito che non ho capito niente.....
![]()
1 int ledPin = 12;
2 int button = 11;
3 int ledState = LOW;
4 unsigned long previousMillis = 0;
5 unsigned long interval = 3000;
6
7 void setup()
8 {
9 pinMode(ledPin, OUTPUT);
10 pinMode(button, INPUT);
11 }
12
13 void loop()
14 {
15 unsigned long currentMillis = millis();
16 button = digitalRead(11);
17
18 if (button == HIGH)
19 {
20 if (currentMillis - previousMillis >= interval)
21 previousMillis = currentMillis;
22
23 if (ledState == LOW)
24 ledState = HIGH;
25 else
26 ledState = LOW;
27 digitalWrite(ledPin, ledState);
28 }
30 }
ho preso spunto dall'esempio di arduino "blink withou delay" ma non riesco proprio a fare in modo di fare in modo che solo quando premi il pulsante parte il conteggio dei secondi per poi farglielo spegnere e tornare in attesa di un' altra pressione del pulsante per fare ripartire il loop...
saluti Enrico
dopo aver passato tutta la notte a fare delle prove e visitare siti web in cerca di una soluzione alla fine sempre sul sito consigliatomi da fabpolli c'era un'altro articolo interessante http://www.leonardomiliani.com/2014/arduino-operazioni-con-timeout/ che spiega come fare alcune operazioni con i timeout con l'uso di un pulsante (collegato con una resistenza di pull up di un canale analogico di arduino precedentemente impostato nel setup) , ed un led. Il programma fà si che premuto un pulsante, il led si accenda. A questo punto ci sono due possibilità, se il pulsante viene ripremuto il led emette alcuni lampeggi per poi spegnersi e uscire dal ciclo in cui si trova, invece nel caso il pulsante non venga ripremuto arduino grazie alla funzione millis e al ciclo do.. for praticamente calcola "x" tempo, se in quel lasso di tempo non viene ripremuto il pulsante il led si spegne.
Detto questo ho modificato leggermente lo sketch in modo che:
1)premo il pulsante
2)accendo il led
3)se mentre il led e acceso ripremo il pulsante non deve accadere nulla
4)quasi allo scadere del tempo il led inizia a lampeggiare per qualche istatnte
5)il led si spegne
lo skecth:
const byte led_1 = 12;
const byte pulsante_1 = 11;
const unsigned long timeout = 10000; //timeout in millisecondi
void setup() {
pinMode(led_1, OUTPUT); //led pin di uscita
pinMode(pulsante_1, INPUT_PULLUP); //pulsante pin di entrata settato pull up
}
void loop() {
//l'utente ha premuto il pulsante?
if (!digitalRead(pulsante_1)) {
//aspetto per evitare rimbalzi
delay(30);
//il bottone e stato premuto, non era un rimbalzo
if (!digitalRead(pulsante_1)) {
funzionePulsante1();
}
}
}
void funzionePulsante1() {
unsigned long startingTime; //usata per memorizzare il momento iniziale
boolean pressed = false; //usata per sapere se l'utente ha premuto il tasto
// attendere per il rilascio del tasto
while(!digitalRead(pulsante_1));
digitalWrite(led_1, HIGH); //LED acceso
//loop
startingTime = millis();
do {
//l'utente ha premuto il tasto?
if (!digitalRead(pulsante_1)) {
//rimbalzo
delay(30);
if (!digitalRead(pulsante_1)) {
//l'utente ha premuto il pulsante
pressed = true;
}
}
} while ((!pressed) && ((millis() - startingTime) < timeout));
//questo ciclo avrà fine solo quando l'utente preme il pulsante o va in timeout
if (timeout) {
//lampeggio fine del tempo
for (byte i = 0; i < 4; i++) {
digitalWrite(led_1, HIGH);
delay(300);
digitalWrite(led_1, LOW);
delay(300);
}
}
}
e fin qui tutto a posto lo provato e funziona alla perfezione....ma adesso vorrei aggiungere un'altro pulsante e fare in modo che faccia le stesse cose del pulsante uno, e quindi ci ho rimesso le mani nel codice per non limitarmi a un solo pulsante e un solo led.
Quello che è venuto fuori e questo:
const byte led_1 = 12;
const byte led_2 = 9;
const byte pulsante_1 = 11;
const byte pulsante_2 = 10;
const unsigned long timeout = 10000; //timeout in millisecondi
void setup() {
pinMode(led_1, OUTPUT); //led pin di uscita
pinMode(led_2, OUTPUT);
pinMode(pulsante_1, INPUT_PULLUP); //pulsante pin di entrata
pinMode(pulsante_2, INPUT_PULLUP);
}
void loop() {
//l'utente ha premuto il pulsante?
if (!digitalRead(pulsante_1)) {
//aspetto per evitare rimbalzi
delay(30);
//il bottone e stato premuto, non era un rimbalzo
if (!digitalRead(pulsante_1)) {
funzionePulsante1();
}
}
else if (!digitalRead(pulsante_2)) {
delay(30);
if (!digitalRead(pulsante_2)) {
funzionePulsante2();
}
}
}
void funzionePulsante1() {
unsigned long startingTime; //usata per memorizzare il momento iniziale
boolean pressed = false; //usata per sapere se l'utente ha premuto il tasto
// attendere per il rilascio del tasto
while(!digitalRead(pulsante_1));
digitalWrite(led_1, HIGH); //LED acceso
//loop
startingTime = millis();
do {
//l'utente ha premuto il tasto?
if (!digitalRead(pulsante_1)) {
//rimbalzo
delay(30);
if (!digitalRead(pulsante_1)) {
//l'utente ha premuto il pulsante
pressed = true;
}
}
} while ((!pressed) && ((millis() - startingTime) < timeout));
//questo ciclo avrà fine solo quando l'utente preme il pulsante o va in timeout
if (timeout) {
//lampeggio fine del tempo
for (byte i = 0; i < 4; i++) {
digitalWrite(led_1, HIGH);
delay(300);
digitalWrite(led_1, LOW);
delay(300);
}
}
}
void funzionePulsante2() {
unsigned long startingTime1;
boolean pressed1 = false;
while(!digitalRead(pulsante_2));
digitalWrite(led_2, HIGH);
startingTime1 = millis();
do {
if (!digitalRead(pulsante_2)) {
delay(30);
if (!digitalRead(pulsante_2)) {
pressed1 = true;
}
}
}
while ((!pressed1) && ((millis() - startingTime1) < timeout));
if (timeout) {
for (byte i = 0; i < 4; i++) {
digitalWrite(led_2, HIGH);
delay(300);
digitalWrite(led_2, LOW);
delay(300);
}
}
}
ma praticamente e come la vecchia formula con il delay()...non riesco a fare lavorare i due pulsanti e relativi led contemporaneamente
solo voi potete aiutarmi....non ci dormo più la notte!
Scusate per la lunghezza del post ma ci tenevo a essere il più preciso possibile.
Continuerò a provare e riprovare in attesa di una vostra risposta.
Saluti
Enrico
voglio fare un po' la voce fuori dal coro
![]()
fare polling (ossia controllare continuamente) quanto vale millis è un'azione che richiede tempo ad arduino e noi stiamo costringendo il nostro povero micro a farla tante volte a ciclo ossia migliaia di volte al secondo!
Forse una soluzione più eficiente è far partire un timer che ogni secondo genera un interrupt e incrementa una variabile cosi quando saranno passati tre secondi questa variabile sarà incrementata tre volte e a te basta controllare quanto vale questa variabile per sapere da quanto tempo hai premuto il bottone!
in questo modo una volta impostato il timer non devi più preoccuparti di millis o di chissà quale confronto (che poi millis va in overflow e lo devi gestire) e basta controllare un semplice int che incrementa.
Spero di aver dato qualche idea utile,
un saluto
Davide
Forse una soluzione più eficiente è far partire un timer che ogni secondo genera un interrupt e incrementa una variabile
si ho visto qualcosa in rete sugli interrupt, e se non ho capito male io, usando arduino uno, ho la possibilità di farlo grazie hai pin 2 e 3, la mia domanda è avendo solo due canali disponibili per gli interrupt riesco poi alla fine a gestire 4 pulsanti con 2 interrupt???
scusate se faccio delle domande magari stupide ma sono un principiante, ha cui e stato affibbiato questo progetto con la promessa di un sostegno che poi non è arrivato, e più o meno un mese di tempo per poterlo portare a termine, quindi sono un pò sotto pressione e ho davvero poco tempo (viste le mie conoscenze limitate di elettronica e arduino)per capire e approfondire certi concetti.....
cosi quando saranno passati tre secondi questa variabile sarà incrementata tre volte e a te basta controllare quanto vale questa variabile per sapere da quanto tempo hai premuto il bottone!
in questo modo una volta impostato il timer non devi più preoccuparti di millis o di chissà quale confronto
per questo ti chiedo se riesci a farmi un'esempio pratico, con del codice. Solo così posso capire al meglio il concetto senza dover "studiare" un gran mole di roba che poi mi crea confusione in testa invece che chiarezza.
Grazie ancora.
Enrico
allora niente, se hai problemi con la programmazione e sei alle prime esperienze per di più con un tempo prefissato è meglio lasciar stare tutte le cose "sofisticate" e darsi alle soluzioni poco efficienti ma semplici da scrivere. Butto giù un biocolo di codice (non l'ho nemmeno compilato quini ci saranno degli errori):
void setup(){
pinMode(pulsante1, INPUT); //imposti il bottone come input con pullup
digitalWrite(pulsante1,HIGH);
}
long time1; //variabile globale (è una brutta cosa, lo so, ma meglio di niente) in cui "ricordo" quando è stato premuto il bottone
void loop(){
if(!digitalRead(pulsante1)){
//se il pulsante uno è premuto non serve debounce tanto farà questa azione comunque per tre secondi che se rimbalza
time1=millis(); //segno "che ore sono" quando ho premuto il pulsante
accendi_funzione1(); //lanci la funzione che fa l'azione corrisondente al pusalte uno (accendere un led o non so cosa)
}
if(millis()- time1>3000){
spegni_funzione1(); //se sono tracorsi tre secondi tra il tempo attuale e quelo che mi ero "segnato" nela variabile allora lanci la funzione che spegne il led o quel che sia
}
}
Se qualcosa non è chiaro dici pure. Credo sia il modo più facile e veloce (per te, non per il micro) per fare questa operazione di accensione a pulsante e spegnimento dopo 3 secondi. ovviamente da fare copia e incolla per tutti gli altri pulsanti ma il senso è quello.
Spero di esserti stato utile.
un saluto,
Davide
Grazie davide mi sei stato utilissimo, e mi hai semplificato di gran lunga il codice. Il ragionamento che ci sta dietro mi e chiaro, ma non capisco perchè se nel void loop() aggiungo un else if, per verificare se il pulsante_2 e stato premuto, non esegue la funzione di attivazione\disattivazione_2() il secondo led non si accende e non accade nulla mentre se premo il primo pulsante il led_1 si accende correttamente per poi spegnersi dopo 3 secondi.....
int ledPin_1 = 7;
int ledPin_2 = 9;
int pulsante_1 = 10;
int pulsante_2 = 11;
void setup() {
pinMode(ledPin_1, OUTPUT);
pinMode(ledPin_2, OUTPUT);
pinMode(pulsante_1, INPUT);
pinMode(pulsante_2, INPUT);
digitalWrite(pulsante_1, HIGH);
digitalWrite(pulsante_2, HIGH);
}
unsigned long timer_1;
long timer_2;
void loop() {
if (!digitalRead(pulsante_1)) {
timer_1 = millis();
attivaFunzione_1();
}
else if (!digitalRead(pulsante_2)) {
timer_2 = millis();
attivaFunzione_2();
}
if (millis() - timer_1 > 3000) {
disattivaFunzione_1();
}
else if (millis() - timer_2 > 5000) {
disattivaFunzione_2();
}
}
void attivaFunzione_1() {
digitalWrite(ledPin_1, HIGH);
}
void attivaFunzione_2() {
digitalWrite(ledPin_2, HIGH);
}
void disattivaFunzione_1() {
digitalWrite(ledPin_1, LOW);
}
void disattivaFunzione_2() {
digitalWrite(ledPin_2, LOW);
}
questo e quello che sono riuscito a fare non riesco a capire dove potrebbe essere l'errore...
ti ringrazio ancora per la tua disponibilità.
Enrico
è vero non ci avevo pensato te l'ho detto, ho scritto il codice senza compilarlo e senza provarlo.
"else" non viene valutato perchè il primo "if" in effetti è vero. ogni ciclo di loop lui lancia la funzione di spegnimento anche se sono già spenti i led perchè la condizione è vera.
missis()-timer_1 >3000
è vera sempre finchè non ripremi il pulsante e solo allora diventa falsa, poi passati i tre secondi torna ad essere vera finchè non ripremi di nuovo.
essendo vero il primo if, l' else non viene proprio valutato.
Togli quell'else e lascia solo if e il problema è risolto
EDIT: faccio una piccola aggiunta. Se vuoi risparmiare soldi e programmazione usa tre NE555 come monostabli, sul web trovi mille guide per calcolare il tempo. In tutto costano meno di 5€ e bastano una manciata di resistenze e 3 condensatori
con quei punti esclamativi quando rilascia il pulsante non raggiunge più il tempo desiderato
Solo un paio di suggerimenti ...
Primo, i debounce falli via hardware, cosi te li levi dal software, che si incasina di meno, e non bloccano lo sketch nemmeno per quelle poche decine di millisecondi (in fondo basta un condensatore da 100n ed una resistenza da 100 ohm, o valori simili, per pulsante)
Secondo, se devi sia contare il tempo che ignorare le pressioni successive del pulsante finche' non e' passato, sia far lampeggiare il led alla fine del tempo, direi che una sola variabile di stato non basta, e che non serve a nulla fare incrementare un contatore, ma bisogna poter controllare il tutto a ripetizione, poter impostare i tempi come vuoi, e poter discriminare lo stato ed il momento, quindi, anche se la soluzione non sara' "elegante" (vedo gia i puristi della programmazione storcere il naso e pensare a come si poteva fare in modo diverso, maledicendomi nel frattempo ... scherzo
:D), direi che dei cicli di controllo consecutivi usando degli if/else siano la cosa piu semplice, se non proprio magari la piu efficente ...
Cosi ad occhio, se devi usare 4 pulsanti, ti serviranno 4 variabili di tempo, 4 variabili di stato del pulsante, 4 variabili di stato precedente, e 4 variabili di controllo (ovviamente ogni pulsante dovra' avere le proprie, altrimenti si incasina tutto), e se vuoi pure i lampeggi altre 4 variabili per lo stato dei lampeggi ... ma iniziamo con uno solo, tanto per fare un'esempio ... poniamo che:
millis1 e' la variabile che usi per controllare il tempo di attivazione del pulsante,
tempo1 e' quella che contiene il tempo per cui il led deve rimanere acceso (in modo da poterlo cambiare senza dover riscrivere ogni volta l'intero sketch, in caso servisse),
stato1 e statoprec1 sono quelle che usi per controllare se il pulsante e' stato premuto oppure e' ancora premuto da prima (in modo che il ciclo non si ripeta da solo se qualcuno tiene il pulsante premuto piu a lungo dell'intervallo che hai impostato),
flash1 serve solo se vuoi che faccia i lampeggi a fine ciclo,
e controllo1 e' quella che usi per sapere se il tempo in cui il led e' acceso (e quindi il periodo in cui una nuova pressione del tasto deve essere ignorata) e' passato o meno, ed anche per definire quali cicli di controllo eseguire e quali saltare del tutto, per alleggerire un po l'esecuzione ...
la logica di controllo e' pensata per ingressi con pullup ed attivati chiudendoli
a massa, ovviamente se usi ingressi che si chiudono al positivo, devi invertirla
{
if (controllo1 == LOW) //leggi il pulsante 1 solo se il led1 e' spento per evitare di ripetere inutilmente cicli di controllo
{
stato1 = digitalRead(pin) //leggi ingresso pulsante
if ((stato1 != statoprec1) && (statoprec1 == 1)) // pulsante appena premuto
{
statoprec1 = stato1; //setta flag per pulsante premuto
millis1 = millis(); imposta variabile per controllo tempo
digitalWrite(led1, HIGH); //accende led 1
controllo1 = HIGH; //setta flag stato led
}
if ((stato1 != statoprec1) && (statoprec1 == 0)) //pulsante rilasciato
{
statoprec1 = stato1; //resetta flag per pulsante rilasciato
}
}
if (controllo1 == HIGH) //esegui controlli solo se il tempo non e' ancora terminato per evitare di ripetere inutilmente cicli di controllo
{
if ((millis() - millis1 > tempo1) //se il tempo totale del led1 non e' ancora passato
{
//inizio blocco lampeggi
if ((millis() - millis1) > (tempo1 - 600)) || ((millis() - millis1) > (tempo1 - 400)) || ((millis() - millis1) > (tempo1 - 200)) && (flash1 == LOW)
{
digitalWrite (led1, LOW);
flash1 = HIGH;
}
if ((millis() - millis1) > (tempo1 - 500)) || ((millis() - millis1) > (tempo1 - 300)) || ((millis() - millis1) > (tempo1 - 100)) && (flash1 == HIGH)
{
digitalWrite (led1, HIGH);
flash1 = LOW;
}
//fine blocco lampeggi
//nota: tutto questo blocco serve solo per far lampeggiare il led1 3 volte ad intervalli di 100mS prima che il tempo scada
//e si spenga del tutto, lo stesso per la variabile flash1, quindi se i lampeggi non servono non lo si inserisce del tutto
if ((millis() - millis1) > tempo1)) //termine del tempo impostato per il led1
{
digitalWrite (led1, LOW); //spegni led
controllo1 = LOW; //resetta flag di controllo
}
}
}
}
NOTA BENE: l'ho buttato giu al volo con il notepad, e non posso ne provarlo ne compilarlo, quindi usalo come riferimento, ma non si garantisce che funzioni (cioe', cosi a logica dovrebbe poter funzionare, ma non si sa mai ... fornito gratis, errori compresi ;))
ho provato a modificare nuovamente il codice....
int ledPin_1 = 7;
int ledPin_2 = 9;
int pulsante_1 = 5;
int pulsante_2 = 10;
void setup() {
pinMode(ledPin_1, OUTPUT);
pinMode(ledPin_2, OUTPUT);
pinMode(pulsante_1, INPUT);
pinMode(pulsante_2, INPUT);
digitalWrite(pulsante_1, HIGH);
digitalWrite(pulsante_2, HIGH);
}
long time1;
long time2;
void loop() {
if (!digitalRead(pulsante_1)) {
time1 = millis();
attivaFunzione1();
}
if (!digitalRead(pulsante_2)) {
time2 = millis();
attivaFunzione2();
}
if (millis() - time1 > 3000) {
disattivaFunzione1();
}
if (millis() - time2 > 5000) {
disattivaFunzione2();
}
}
void attivaFunzione1() {
digitalWrite(ledPin_1, HIGH);
digitalWrite(ledPin_2, HIGH);
}
void disattivaFunzione1() {
digitalWrite(ledPin_1, LOW);
digitalWrite(ledPin_2, LOW);
}
void attivaFunzione2() {
digitalWrite(ledPin_1, HIGH);
digitalWrite(ledPin_2, HIGH);
}
void disattivaFunzione2() {
digitalWrite(ledPin_1, LOW);
digitalWrite(ledPin_2, LOW);
}
ma come risultato ottengo solo che se premo per prima solo uno dei due pulsanti i due led si accendono fino a che non viene rilasciato. Solo dopo aver premuto il primo pulsante e poi vado a premere il secondo pulsante (o viceversa) i due led si accendono per 5 secondi, questo mi fa capire almeno credo che la variabile long time1; non viene presa in considerazione....fatemi degli esempi con del codice se no non ci salto pìù fuori....
con quei punti esclamativi quando rilascia il pulsante non raggiunge più il tempo desiderato
potresti spiegarti meglio?, io pensavo che il punto esclamativo davanti !digitaRead(pulsante_1) servisse per controllare se lo stato del pulsante connesso a quel pin di arduino è cambiato oppure no..ho preso un granchio??
Forse spiegando meglio il mio progetto potrete capire meglio quello che ho intenzione di realizzare così magari qualcuno può dare nuove idee su come sviluppare il tutto.
Praticamente devo costruire una gettoniera per il controllo temporizzato dell'acqua calda di 4 doccie, (lasciando a parte per adesso il discorso di come collegare la gettoniera ad arduino e fargli riconoscere gli impulsi in uscita dalla gettoniera) quando viene inserito il gettone si ha la possibilità di scegliere tramite 4 pulsanti con led incorporato, quale doccia attivare.
Quando un pulsante viene premuto (dopo aver inserito il gettone), il led del pulsante premuto dovrà accendersi, per segnalare che quella doccia e occupata, si dovrà attivare un relè, che poi attiverà a sua volta una elettrovalvola, poi arduino dovrà calcolare mettiamo 1 minuto di tempo da quando e avvenuta la selezione dellla doccia da attivare, per poi passato quel tempo chiudere l'elettrovalvola, spegnere il led dalla pulsantiera per segnalare che la doccia è libera. Tutto questo lo devo fare per quattro doccie...questo vuol dire che avrò 4 elettrovalvole attaccate a 4 relè che dovrò temporizzare singolarmente appunto con arduino. il problema maggiore è:
Premo il pulsante1 si accende il led1 quindi si attiva il relè connesso al pulsante1, che fa passare 12v e alimenta la bobina dell'elettrovalvola, e lasciare tutto invariato per mettiamo 1 minuto passato il quale tutto torna allo stato iniziale.
Se un utente preme il Pulsante1 quello non sarà più disponibile prima di un minuto, se durante quel minuto arriva un'atro utente e preme il pulsante2 dovrà partire da quel momento il conteggio del tempo
per dargli la possibilità di lavarsi in un minuto
senza che però per le altre elettrovalvole cambi il conteggio del tempo...
Praticamente penso di dover temporizzare in modo separato 4 pulsanti, led, relè ed elettrovalvole....
Qualcuno di voi mi può dire se è una cosa fattibile praticamente usando quello che già ho visto che i fondi per il progetto sono già stati spesi in parte per la realizzazione fisica di una cassetta di metallo che fungerà da cassa per acquistare i relè le elettrovalvole e la gettoniera....(praticamente sono al verde
)
e se la cosa potrebbe essere fattibile secondo voi facile o no che sia quale sarebbe il miglior modo per realizzare questo progetto? contando sempre i materiali che ho a disposizione?
in attesa delle vostre opinioni continuo ad impazzire appresso e sti led che non riesco a temporizzare singolarmente se una certa condizione si verifica..
Grazie ancora per la panziena concessami...
Enrico
Etemenanki:
Solo un paio di suggerimenti ...Primo, i debounce falli via hardware, cosi te li levi dal software, che si incasina di meno, e non bloccano lo sketch nemmeno per quelle poche decine di millisecondi (in fondo basta un condensatore da 100n ed una resistenza da 100 ohm, o valori simili, per pulsante)
Secondo, se devi sia contare il tempo che ignorare le pressioni successive del pulsante finche' non e' passato, sia far lampeggiare il led alla fine del tempo, direi che una sola variabile di stato non basta, e che non serve a nulla fare incrementare un contatore, ma bisogna poter controllare il tutto a ripetizione, poter impostare i tempi come vuoi, e poter discriminare lo stato ed il momento, quindi, anche se la soluzione non sara' "elegante" (vedo gia i puristi della programmazione storcere il naso e pensare a come si poteva fare in modo diverso, maledicendomi nel frattempo ... scherzo
:D), direi che dei cicli di controllo consecutivi usando degli if/else siano la cosa piu semplice, se non proprio magari la piu efficente ...
Cosi ad occhio, se devi usare 4 pulsanti, ti serviranno 4 variabili di tempo, 4 variabili di stato del pulsante, 4 variabili di stato precedente, e 4 variabili di controllo (ovviamente ogni pulsante dovra' avere le proprie, altrimenti si incasina tutto), e se vuoi pure i lampeggi altre 4 variabili per lo stato dei lampeggi ... ma iniziamo con uno solo, tanto per fare un'esempio ... poniamo che:
millis1 e' la variabile che usi per controllare il tempo di attivazione del pulsante,
tempo1 e' quella che contiene il tempo per cui il led deve rimanere acceso (in modo da poterlo cambiare senza dover riscrivere ogni volta l'intero sketch, in caso servisse),
stato1 e statoprec1 sono quelle che usi per controllare se il pulsante e' stato premuto oppure e' ancora premuto da prima (in modo che il ciclo non si ripeta da solo se qualcuno tiene il pulsante premuto piu a lungo dell'intervallo che hai impostato),
flash1 serve solo se vuoi che faccia i lampeggi a fine ciclo,
e controllo1 e' quella che usi per sapere se il tempo in cui il led e' acceso (e quindi il periodo in cui una nuova pressione del tasto deve essere ignorata) e' passato o meno, ed anche per definire quali cicli di controllo eseguire e quali saltare del tutto, per alleggerire un po l'esecuzione ...
la logica di controllo e' pensata per ingressi con pullup ed attivati chiudendoli
a massa, ovviamente se usi ingressi che si chiudono al positivo, devi invertirla
{
if (controllo1 == LOW) //leggi il pulsante 1 solo se il led1 e' spento per evitare di ripetere inutilmente cicli di controllo
{
stato1 = digitalRead(pin) //leggi ingresso pulsante
if ((stato1 != statoprec1) && (statoprec1 == 1)) // pulsante appena premuto
{
statoprec1 = stato1; //setta flag per pulsante premuto
millis1 = millis(); imposta variabile per controllo tempo
digitalWrite(led1, HIGH); //accende led 1
controllo1 = HIGH; //setta flag stato led
}
if ((stato1 != statoprec1) && (statoprec1 == 0)) //pulsante rilasciato
{
statoprec1 = stato1; //resetta flag per pulsante rilasciato
}
}
if (controllo1 == HIGH) //esegui controlli solo se il tempo non e' ancora terminato per evitare di ripetere inutilmente cicli di controllo
{
if ((millis() - millis1 > tempo1) //se il tempo totale del led1 non e' ancora passato
{
//inizio blocco lampeggi
if ((millis() - millis1) > (tempo1 - 600)) || ((millis() - millis1) > (tempo1 - 400)) || ((millis() - millis1) > (tempo1 - 200)) && (flash1 == LOW)
{
digitalWrite (led1, LOW);
flash1 = HIGH;
}
if ((millis() - millis1) > (tempo1 - 500)) || ((millis() - millis1) > (tempo1 - 300)) || ((millis() - millis1) > (tempo1 - 100)) && (flash1 == HIGH)
{
digitalWrite (led1, HIGH);
flash1 = LOW;
}
//fine blocco lampeggi
//nota: tutto questo blocco serve solo per far lampeggiare il led1 3 volte ad intervalli di 100mS prima che il tempo scada
//e si spenga del tutto, lo stesso per la variabile flash1, quindi se i lampeggi non servono non lo si inserisce del tutto
if ((millis() - millis1) > tempo1)) //termine del tempo impostato per il led1
{
digitalWrite (led1, LOW); //spegni led
controllo1 = LOW; //resetta flag di controllo
}
}
}
}
NOTA BENE: l'ho buttato giu al volo con il notepad, e non posso ne provarlo ne compilarlo, quindi usalo come riferimento, ma non si garantisce che funzioni (cioe', cosi a logica dovrebbe poter funzionare, ma non si sa mai ... fornito gratis, errori compresi ;))
stavo scrivendo il post precedente prima di leggere il tuo messaggio.....
e mi sembri tu il mio salvatore...hahahaaha scherzi a parte finalmente ho ricevuto una risposta hai mie livelli terra terra di conoscenza con delle spiegazioni dettagliate...ti sono infinitamente grato grazie grazie.
questa sera con calma mi studio il codice e poi ti faccio saper comè andata.
Ancora grazie
Saluti enrico
spero che quella soluzione sia per te la più efficace, in fondo è l'unica cosa che conta anche se sinceramente non capisco proprio perchè il mio non funziona... hai collegato bene i pulsanti?
io pensavo che il punto esclamativo davanti !digitaRead(pulsante_1) servisse per controllare se lo stato del pulsante connesso a quel pin di arduino è cambiato oppure no
no,il ! cambia lo stato logico di un valore booleano. Mi spiego meglio: digitalWrite controlla se su quel pin c'è voltaggio o meno. se C'è allora torna 1 se non c'è torna 0. Dato che noi usiamo il pull-up quando il pulsante non è premuto abbiamo 5V quando invece lo premi abbiamo 0V quindi a pulsante premuto lui torna zero (ossia falso) e col punto esclamativo diventa 1 ossia vero perchè infatti il pulsante è premuto.
il pulsante come l'hai collegato? da una parte al pin digitale e l'altra? dovrebbe andare a massa e credo che il mio codice funzioni
dadduni:
spero che quella soluzione sia per te la più efficace, in fondo è l'unica cosa che conta anche se sinceramente non capisco proprio perchè il mio non funziona... hai collegato bene i pulsanti?
no,il ! cambia lo stato logico di un valore booleano. Mi spiego meglio: digitalWrite controlla se su quel pin c'è voltaggio o meno. se C'è allora torna 1 se non c'è torna 0. Dato che noi usiamo il pull-up quando il pulsante non è premuto abbiamo 5V quando invece lo premi abbiamo 0V quindi a pulsante premuto lui torna zero (ossia falso) e col punto esclamativo diventa 1 ossia vero perchè infatti il pulsante è premuto.
il pulsante come l'hai collegato? da una parte al pin digitale e l'altra? dovrebbe andare a massa e credo che il mio codice funzioni
dadduni ho appena finito di cenare adesso provo e vedo cosa combino....
ringrazio anche a te che adesso mi hai chiarito il "!". il pulsante lo avevo collegato proprio come hai detto tu da una parte al pin digitale e l'altra a massa senza nessuna resistenza di mezzo.
Ma molto probabilmente se forse rileggi il codice, ci potrebbe essere un qualche errore fatto da me...
Ho bisogno dei vostri consigli, suggerimenti, e soprattutto delle vostre critiche per capire dove sbaglio e come posso migliorare per apprendere concetti che non sono mai stati del tutto facili per me!!!
Detto questo ragazzi criticatemi criticatemi e criticatemi e fatemi notare dove sbaglio..
Ps. daddone comunque il codice che mi hai dato non lo abbandono, mi ha fatto uscire pazzo per un pomeriggio e voglio capire come fare funzionere anche quello.