Riprendiamo lo sketch dlla parte pulsanti e uscite rel Ã?.

Ciao a tutti, finalmente, dopo tanti lavoretti di riparazione fra casa mia e vicini di casa posso riprendere lo studio del programma anemomentro.

due pulsanti (apertura e chiusura tenda) lavorano come volevo e

Quindi, se premo il tasto per meno di un secondo, il motore rimane attivo fino al raggiungimento del fine corsa (questa parte ancora non

il motore si ferma quando lo rilascio.

se la tenda si sta aprendo e premo il tasto di chiusura, deve fermarsi tutto e vice versa, poi se voglio fare un azione devo ripremere un tasto.

Come posso fare? :-)

int tasto_AP = 4; //pin tasto apertura int tasto_CH = 5; //pin tasto chiusura int rele_AP = 6; //pin rele apertura int rele_CH = 7; //pin rele chiusura

int stato_AP; //memorizza stato tasto apertura int conteggio_AP; //memorizza stato conteggio apertura int stato_CH; //memorizza stato tasto chiusura int conteggio_CH; //memorizza stato conteggio chiusura

long t0_AP; // memorizzano i tempi per il long t_AP; // calcolo del tempo premuto long t0_CH; long t_CH;

void setup() { pinMode(tasto_AP, INPUT); pinMode(rele_AP, OUTPUT); pinMode(tasto_CH, INPUT); pinMode(rele_CH, OUTPUT);

stato_AP = 0; //imposta lo stato iniziale del pulsante di apertura conteggio_AP = LOW; //imposta lo stato iniziale del conteggio tempo

stato_CH = 0; //imposta lo stato iniziale del pulsante di chiusura conteggio_CH = LOW; //imposta lo stato iniziale del conteggio tempo }

void loop(){ stato_AP = digitalRead(tasto_AP); stato_CH = digitalRead(tasto_CH);

if ((conteggio_AP == LOW) && (stato_AP == HIGH)) { conteggio_AP = HIGH; t0_AP = millis(); digitalWrite(rele_AP, HIGH); //Serial.println("Premuto tasto APERTURA");

}

if ((conteggio_AP == HIGH) && (stato_AP == LOW)) { conteggio_AP = LOW; t_AP = millis() - t0_AP;

if (t_AP 1000) digitalWrite(rele_AP, LOW); }

}

if ((conteggio_CH == LOW) && (stato_CH == HIGH)) { conteggio_CH = HIGH; t0_CH = millis(); digitalWrite(rele_CH, HIGH);

}

if ((conteggio_CH == HIGH) && (stato_CH == LOW)) { conteggio_CH = LOW; t_CH = millis() - t0_CH;

if (t_CH 1000) digitalWrite(rele_CH, LOW); }

} }
Reply to
Drizzt do'Urden
Loading thread data ...

Drizzt do'Urden ha spiegato il 12/10/2019 :

int StoppaTutto

void loop(){

stato_AP = digitalRead(tasto_AP); stato_CH = digitalRead(tasto_CH);

//disattivo "StoppaTutto" solo a pulsanti rilasciati if ((stato_AP == LOW) && (stato_CH == LOW)) { StoppaTutto = false; }

//attiva StoppaTutto se sta aprendo e premo chiudi if ((stato_AP == HIGH) && (rele_CH==HIGH)) { StoppaTutto = true; }

//attiva StoppaTutto se sta chiudendo e premo apri if ((stato_CH == HIGH) && (rele_AP==HIGH)) { StoppaTutto = true; }

if (StoppaTutto == true) { stato_AP = LOW; stato_CH = LOW; rele_CH = LOW; rele_AP = LOW; digitalWrite(rele_AP, LOW); digitalWrite(rele_CH, LOW); conteggio_AP == LOW conteggio_CH == LOW }

Ma piuttosto: ricorda che ogni 50 giorni mills si resetta e torna a zero e che quindi rischi di avere una variabile che contiene mills +

" This number will overflow (go back to zero), after approximately 50 days."

Reply to
Franz_aRTiglio

Il 13/10/2019 09:31, LAB ha scritto:

Ne salta fuori sempre una :-( Ora provo ad aggiustare pure questo e provo anche la soluzione di Franz_aRTiglio.

Reply to
Drizzt do'Urden

Il 13/10/19 09:31, LAB ha scritto:

Correzione:

- Cosi` funziona sempre, anche in caso di overflow (ritorno a zero del contatore), cioe` risolve il problema di misurare tempi a cavallo dell'overflow.

- Ma in ogni caso usando solo il contatore a 32 bit di millis non si possono gestire o misurare tempi superiori a 2 alla 32esima millisecondi.

- Che poi a causa dell'imprecisione dell'oscillatore (fatto con un risuonatore invece che con un quarzo) i tempi riportati da millis hanno un errore di qualche secondo all'ora.

Reply to
Claudio_F

Il 13/10/2019 02:31, Franz_aRTiglio ha scritto:

Ora mi concentro su questo aspetto di millis(), faccio fatica a ragionare quadrimensionalmente :-) Ipotizziamo che premo il tasto e memorizzo il primo valore di millis() poco prima dell'overflow, diciamo 19990 poi mollo il pulsante dopo che

19990 quindi inferiore a 1000 (come richiesto dal if nel programma). Alla fine funzionerebbe ugualmente o sbaglio ragionamento?

if (t_AP 1000) digitalWrite(rele_AP, LOW);

Reply to
Drizzt do'Urden

Il 13/10/19 12:58, Drizzt do'Urden ha scritto:

La sottrazione intera senza segno darebbe come risultato 4294987146

Reply to
Claudio_F

Il 13/10/19 13:08, Claudio_F ha scritto:

Chiarisco meglio visivamente...

Hai un orologio con una lancetta a 2**32 posizioni (dalle 0 alle 4294987145)

La lancetta e` sulle 10.

La tiri indietro di 19990 posizioni.

Alla fine si trova alle 4294987146.

Reply to
Claudio_F

Il 13/10/19 13:11, Claudio_F ha scritto:

cancella... ho sbagliato qualche calcolo...

Reply to
Claudio_F

Il 13/10/19 12:58, Drizzt do'Urden ha scritto:

Ricominciamo da qui.

Il ragionamento che hai scritto e` corretto, anche se il risultato non e` negativo perche' si usano variabili senza segno.

Ipotizziamo l'orologio da 0 a 19999 secondi (20000 posizioni).

Prima lettura 19990, seconda lettura 10.

Sono trascorsi 10 - 19990 = 20 secondi (perche' tornando indietro dalla posizione 10 per 19990 posizioni su una ruota da 20000 posizioni si arriva alla posizione 20).

Infatti queste condizioni funzionano correttamente:

trascorso = millis - inizio;

se (trascorso < intervallo) ...

se (trascorso >= intervallo) ...

Poi nella realta` cambia solo che millis va da 0 a 4294967295 (un orologio da 2 alla 32 posizioni). Dieci secondi prima dell'overflow siamo alla posizione 4294957296, dopo 10 secondi siamo alla posizione

10000, il tempo trascorso e` 10000 - 4294957296 = 20000

-------------------------------------------------------

Invece quello che diceva Franz e' che se si usa questa forma errata:

fine = inizio + intervallo;

if (millis > arrivo)

allora si incorre nel problema dell'overflow, perche' inizio (19990) + intervallo (20) risulta 10, e millis risulta maggiore di 10 gia` da subito.

Reply to
Claudio_F

Il 13/10/2019 14:06, Claudio_F ha scritto:

modo? :-)

Posso concentrarmi sull'interblocco fra le due uscite.

--
Saluti da Drizzt. 


www.agidone.altervista.org 
http://www.tappezzeriagraziella.com/ 
MAI PIU' OPEL IN VITA MIA!!!!
Reply to
Drizzt do'Urden

Il 13/10/19 14:16, Drizzt do'Urden ha scritto:

Si, perche' calcoli i tempi trascorsi con millis()-inizio che e` corretto.

Reply to
Claudio_F

Il 13/10/2019 02:31, Franz_aRTiglio ha scritto:

Grande Franz_aRtiglio, funziona :-) ho solo dovuto modificare qualche comando, immagino per le differenze fra il linguaggio che usi e quello di Arduino:

void loop() { stato_AP = digitalRead(tasto_AP); stato_CH = digitalRead(tasto_CH);

if ((stato_AP == LOW) && (stato_CH == LOW)) { stoppatutto = LOW; }

if ((stato_AP == HIGH) && (digitalRead(rele_CH) == HIGH)) { stoppatutto = HIGH; }

if ((stato_CH == HIGH) && (digitalRead(rele_AP) == HIGH)) { stoppatutto = HIGH; }

if (stoppatutto == HIGH) { stato_AP = LOW; stato_CH = LOW; digitalWrite (rele_AP, LOW); digitalWrite (rele_CH, LOW); conteggio_AP = LOW; conteggio_CH = LOW; }

Reply to
Drizzt do'Urden

Dopo dura riflessione, Drizzt do'Urden ha scritto :

Bravo tu che sei riscito ad adattare codice scritto "a braccio" ;)

Reply to
Franz_aRTiglio

Il 14/10/2019 20:34, Franz_aRTiglio ha scritto:

ehhhh, piano piano ci arrivo ma non ho ancora la mente "logica" :-)

Comunque domani parto per una mini vacanza, quando torno aggiungiamo un altro pezzo :-)

--
Saluti da Drizzt. 


www.agidone.altervista.org 
http://www.tappezzeriagraziella.com/ 
MAI PIU' OPEL IN VITA MIA!!!!
Reply to
Drizzt do'Urden

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.