Logica del codice
Abstract: Descrizione:
Apertura completa
Apertura parziale
Allarmi
Durata movimenti
Apertura completa
-----------------------------------------------------------------------------o-----------------------------------------------------------------------
- Premo apri la tenda inizia ad aprirsi:
- statoTenda = APERTURA
- durataMovimentoMax = 45 sec
- timerMovimento= now registro la partenza
- tick controlla se sono trascorsi i 45 sec e chiude
- statoTenda = APERTA;
- da impulso di chiusura per fermare Cosmi
--------------------------------------------------------------------------o-----------------------------------------------------------------------
Apertura parziale
-----------------------------------------------------------------------------o-----------------------------------------------------------------------
- Ripartiamo dal set di parteza. Premo apri la tenda inizia ad aprirsi:
- Tutto uguale fino al num 4. Lo statoTenda è APERTURA
- A 10 sec pigio chiudi (controcomando) essendo statoTenda = APERTURA non esco e proseguo verso
- Nuova Chiusura ma qui non etrerò perché lo stato è APERTURA, la condizione non è soddisfatta (entri solo se è APERTA o INTERMEDIA) quindi slta a
- “Controcomando da apertura” Ferma la tenda qui entro perché la condizione è vera: statoTenda == APERTURA
- Memorizzo il tempo trascorso: tempoTrascorso = now - timerMovimento;
- Imposto statoPrecedenteMovimento = APERTURA;
- Avvio l’impulso di chiusura la tenda si blocca statoTenda = INTERMEDIA la tenda è ferma;
Ripartenza in apertura
- Situazione: statoTenda = INTERMEDIA, statoPrecedenteMovimento = APERTURA, timerMovimento = 0, tempoTrascorso = 10 sec,
- Pigio Apri, non esco perché ho INTERMEDIA
- Vado in Nuova Apertura ed entro perché : statoTenda = INTERMEDIA (ferma)
- Ora la possibilità è questa:
- statoPrecedenteMovimento == APERTURA e il tempoTrascorso >0 sec (è infatti 10 sec)
- durataMovimentoResidua = durataMovimentoMax - tempoTrascorso cioè 45 – 10 =35 ci vorranno 35 sec per aprire completamente la tenda
- esco da if e do l’impulso di chiusura che se non ci sono altri controcomandi porterà la tenda ad aprirsi completamente dopo 35 sec
- tick controllerà se sono trascorsi 35 sec chiude e imposta statoTenda = APERTA
Ripartenza in chiusura
- Situazione: statoTenda = INTERMEDIA, statoPrecedenteMovimento = APERTURA, timerMovimento = 0, tempoTrascorso = 10 sec,
- Pigio Chiudi, non esco perché ho INTERMEDIA
- Entro in Nuova Chiusura ed entro perché : statoTenda = INTERMEDIA (ferma)
- Ora la possibilità è questa:
- statoPrecedenteMovimento == APERTURA && tempoTrascorso > 0
- durataMovimentoResidua = tempoTrascorso + tempoExtra cioè 10 + 5 = 15 sec per chiudere completamente la tenda
- esco da if e do l’impulso di chiusura che se non ci sono altri controcomandi porterà la tenda ad chiudersi completamente dopo 15 sec
- tick controllerà se sono trascorsi 15 sec chiude e imposta statoTenda = CHIUSA
--------------------------------------------------------------------------o-----------------------------------------------------------------------
Allarmi
-----------------------------------------------------------------------------o-----------------------------------------------------------------------
Quando si verifica un’allarme vento o pioggia si accendono sempre i relativi led, si blocca il monitoraggio e gli allarmi RTC.
Poi si possono avere queste situazioni:
- Se la tenda è chiusa non accade nulla, la tenda rimane chiusa
- Se la tenda è in chiusura non si interviene e si lascia termiare la chiusura
- Se la tenda è aperta, la tenda si chiude ma senza attivare la pausa tecnica
- Se la tenda è in stato intermedio cioè ferma in una posizione intermadia la tenda si chiude ma lo fa con il tempo residuo. Se si è in stato intermedio sicuramente avremo sia la variabile tempoTrascorso che statoPrecedenteMovimento impostate e quindi premiChiusura calcolerà l’esatto tempo di chiusura. Non vi è necessita della pausa tecnica
- Se la tenda è in apertura è l’unico caso in cui serve impostare la pausa tecnica. In questo caso ho creato una variabile bool alarm; che è inizialmente impostata a false, quando scatta l’allarme su tick in:
// Se è scatato un'allarme
if (sensori && sensori->getAlarm() != NESSUNO) {
alarm =true;
premiChiusura;
}
-
--------------------------------------------------------------------------o-----------------------------------------------------------------------
Durata del movimento
-----------------------------------------------------------------------------o-----------------------------------------------------------------------
Dopo che un’azione premiApertura o premiChiusura si è verificata questi metodi impostano la variabile timerMovimento = now cioè al momento esatto in cui questa azione si verifica es:
Quando avvio lo sketch millis inizia a contare i milliscondi che scorrono.
Quando poi nel loop entro in tick questo reimposta la variabile del tempo istantaneo:
unsigned long now = millis();
Poi entra in: // Aggiornamento movimenti, dove va a verificare se durataMovimentoResidua è terminata.
if (timerMovimento > 0 && (now - timerMovimento >= durataMovimentoResidua)) {
es:
timerIniziale = 1000 ms
timerMovimento = 10000 ms (il tempo al momento dell'azione)
now = 20000 ms (quello istantaneo)
durataMovimentoResidua = 45000 ms (per un'azione di apertura o chiusura completa ci vogliono 45 sec)
tempoExstra = 5000 ms
ultimoStop=0 ms
percui: 20000 - 10000 = 10000 (tempo trascorso dall'azione)
In questo caso 10000 non è maggiore di 45000, non si entra nel blocco e tick continua a girare, il tempo istantaneo va via via aumentando, ad un certo punto superi 45001 ciò significa che è il momento di interrompere l'azione. Si entra nel blocco dove manderemo l'impulso di controcomando fermando la tenda
Gli stati in cui si può trovare la tenda sono: APERTA, CHIUSA, APERTURA, CHIUSURA, INTERMEDIA le durate del movimento saranno diverse a seconda dello stato in cui la tenda è al momento della chiamata
Situazioene dell'es precedente.
Stop ripetuti
Partiamo da una situazione iniziale
- Variabili:
tempoMax=45 sec.
tempoTrascorso=0
ultimoStop=0
statoTenda= CHIUSA
statoPrecedenteMovimento = CHIUSA
direzione=1 (1 avanti 0 indietro)
- Tenda CHIUSA ultimoStop=0 direzione=1
- Azione: premiApertura la tenda si va aprendo
- Azione: premiChiusura (Controcomando), primo stop, la tenda si ferma, stato INTERMEDIA
- Viene calcolato il tempo trascorso dall'ultima posizione ad es sono trascorsi 10 sec
- viene memorizzato in ultimoStop facendo 0+10=10 nel codice così: ultimoStop += tempoTrascorso ultimoStop=10
- Azione: premiApertura, la tenda prosegue la sua apertuta
- Calcoliamo la direzione:
if (statoPrecedenteMovimento == CHIUSA || statoPrecedenteMovimento == CHIUSURA )
direzione = 0;
else if (statoPrecedenteMovimento == APERTA || statoPrecedenteMovimento == CHIUSURA)
direzione = 1;
- Se si lasciasse terminare la completa apertura il tempo residuo sara: tempoMax - ultimoSttopdi cioè 45 - 10 = 35 sec
- Se si invertisse la direzione allora sarebbe ultimoStop + tempoExstra
- Azione: premiChiusura (Controcomando), la tenda si ferma, secondo stop, stato INTERMEDIA
- Viene calcolato il tempo trascorso dall'ultima posizione ad es sono trascorsi 15 sec
- Azione: premiApertura, la tenda prosegue la sua apertura
- Calcoliamo la direzione:
if (statoPrecedenteMovimento == APERTURA)
direzione = 0;
else if (statoPrecedenteMovimento == CHIUSURA)
direzione = 1;
- Se si lasciasse terminare nella direzione di apertura il tempo residuo sarebbe tempoMax - ultimoStop cioè 45 - 25 = 20
- Azione: premiChiusura (Controcomando), primo stop contrario, la tenda si ferma, stato INTERMEDIA
- Viene calcolato il tempoTrascorso es 20 sec.
- questa volta dalla posizione 25 a tornare indietro, viene memorizzato in ultimoStop ma adesso facendo 25 - 20 = 5 nel codice così: ultimoStop -= tempoTrascorso ultimoStop=5
- Azione: premiChiusura, la tenda si va chiudendo partendo dall'ultima posizione raggiunta ultimoStop = 25, la tenda inizia a richiudersi
- Viene calcolata la direzione:
- ma ora dalla posizione a 10 sec, siamo avanzati per altri 15 sec, in ultimoStop ora dobbiamo memorizzare il valore precedente + il nuovo e avremo 10+15=25 sec sempre con lo statment: ultimoStop += tempoTrascorso, ultimoStop=25
Variabili:
tempoMax = 45
tempoTrascorso = 0
stopPrecedente = 0
stopUltimo =
statoTenda = CHIUSA
statoPrecedenteMovimento = CHIUSA
direzione=APERTURA
| Precedente |
Azione e Verso |
StpPre |
Tempo |
StpUlt |
Tempo Residuo |
| CHIUSA |
premiApertura |
0 |
10 |
0 + 10 |
10 |
Max-StpUlt 45-10 |
35 |
| APERTURA |
pemiApertura |
10 |
15 |
10 +15 |
25 |
Max-StpUlt 45-25 |
20 |
| APERTURA |
premiChiusura |
25 |
5 |
25 - 5 |
20 |
StpUlt+tEx 20+5 |
25 |
| CHIUSURA |
premiApertura |
20 |
10 |
20+10 |
30 |
Max-StpUlt 45-30 |
15 |
| APERTURA |
premiChiusura |
30 |
15 |
30-15 |
15 |
StpUlt+tEx 15+5 |
20 |
| CHIUSURA |
premiChiusura |
15 |
5 |
15-5 |
10 |
StpUlt+tEx 10+5 |
15 |
Calcolo del tempo trascorso (la posizione) variabile stopUltimo:
- if ( premiApertura) stopPrecedente + stopUltimo;
- if ( premiChiusura) stopPrecedente - stopUltimo;
nota:
stopUltimo += stopPrecedente è come scrivere: stopUltimo = stopUltimo + stopPrecedente;
stopUltimo += stopPrecedente è come scrivere: stopUltimo = stopUltimo - stopPrecedente;
Calcolo del tempo residuo:
- La formula tempoMax - stopUltimo quando:
- La formula stopUltimo + tempoExtra quando:
Quindi si può condensare così:
Se premiApertura:
stopUltimo = stopPrecedente + stopUltimo;
durataMovimentoResidua = durataMovimentoMax - stopUltimo;
Se premiChiusura:
stopUltimo = stopPrecedente + stopUltimo;
durataMovimentoResidua = durataMovimentoMax - stopUltimo;
Dove inserire il codice:
- Nel controcomando:
- Il calcolo del tempo trascorso
- Nell'azione successiva allo stop: premiApertura o premiChiusura:
- il calcolo del tempo residuo
Debug con print e messaggi ricorrenti:
per evitare che se metto dei Serial.print per monitorare i punti interessanti nel codice ed i valori delle variabili, in vari punti all'interno di tick che è il metodo che normalmente si inserisce nel loop e che quindi viene eseguito migliaia di volte al secondo accade che qui print vengono ripettutamente visualizzati sul monitor seriale e questo rende impossibile leggerne i valori. Allora ho escogitato un sistema a flag flagTk inizialmente impostato = true. Il tick è strutturato in questo modo:
void Pulsan::tick() {
qui mettiamo tutto ciò che deve essere eseguito sempre es il controllo dei pulsanti
es
if (btnApertura.click()) {
premiApertura();
}
if (flagTk){
esegui i controlli di termine timer/impulsi per fermare le varie azioni
flagTk = false;
}
}
Mentre premiApertura è continuamente controllato quello chè è all'interno del blocco if (flagTk){
invece viene eseguito solo una volta. Vediamo la sequenza:
Premo premiApertura si passa in questo metodo che avvia il timerReleApertura, riporta flagTk = true
in modo che tornando a tick possa essere eseguito la fine dell'impulso
e cosi avviene la tenda si apre. tick riporta il flagTk = false in modo che i successivi loop di tick rimanda vigile solo il monitoraggio dei pulsanti. Ora premo premiChiusura per eseguire un controcomando che mi farà fermare la tenda. lamano passa a premiChiusura che attiva l'impulso di chiusura impostando
timerReleChiusura = now, imposta flagTk = true e rimanda a tick questo esegue il controllo se
timerReleChiusura è >= impulsoBreve
e se lo è termina e la tenda si ferma, tick imposta flagTk=false. Ora eseguo di nuovo premiChiusura per richiudere la tenda che si era fermata (statoTenda = INTERMEDIA) tick chiama premiChiusura il quale
Ricominciamo il raagionamento:
| Precedente |
Azione e Verso |
StpPre |
Tempo |
StpUlt |
Tempo Residuo |
| CHIUSA |
premiApertura |
0 |
10 |
0 + 10 |
10 |
Max-StpUlt 45-10 |
35 |
| APERTURA |
pemiApertura |
10 |
15 |
10 +15 |
25 |
Max-StpUlt 45-25 |
20 |
| APERTURA |
premiChiusura |
25 |
5 |
25 - 5 |
20 |
StpUlt+tEx 20+5 |
25 |
| CHIUSURA |
premiApertura |
20 |
10 |
20+10 |
30 |
Max-StpUlt 45-30 |
15 |
| APERTURA |
premiChiusura |
30 |
15 |
30-15 |
15 |
StpUlt+tEx 15+5 |
20 |
| CHIUSURA |
premiChiusura |
15 |
5 |
15-5 |
10 |
StpUlt+tEx 10+5 |
15 |
Il problema è che le due variabili stopPrecdente e stopUltimo quando si arriva a completa Apertura o Completa chiusura bisogna azzerarle entrambe. Questo cambia il comportamento.
Procediamo partendo da e facciamo:
Partenza Chiusa: Apertura -> Stop Controcomando -> Apertura fino a Completamente Aperta.
Azzeriamo le variabili e proseguiamo all'indietro:
Partenza Aperta: -> Chiusura -> Stop Controcomando -> Chiusura fino a Cpmpletamente Chiusa
Azzeriamo le variabili e così via
Partenza tenda CHIUSA
| Azione |
Tempo |
StpPre |
StpUlt |
Tempo Residuo alla fine |
Arresto |
stpPre |
stpUlt |
| premiApertura |
10 |
0 |
0 + 10 |
10 |
Max-StpUlt 45-10 |
35 |
Intermedio |
0 (10) |
10 |
| pemiApertura |
15 |
10 |
10 +15 |
25 |
Max-StpUlt 45-25 |
20 |
Aperto |
10 (45) |
25(45) |
| premiChiusura |
5 |
45 |
45 - 5 |
40 |
StpUlt 40 |
40 |
Intermedio |
45 (40) |
40 |
| premiChiusura |
20 |
40 |
40 - 20 |
20 |
StpUlt 20 |
20 |
Chiuso |
40 (0) |
20 (0) |
Questo è il comportamento andando sempre in un verso, anche con fermate intermedie, fino alla fine per poi tornare indietro, anche con fermate intermedie, fino all'inizio. Alla fine stoPre e stpUlt vengono portate a 45 mentre all'inizio a 0.
Ora prendiamo in considerazione questa sequenza:
Partenza Chiusa: Apertura -> Stop Controcomando -> Chiusura -> Stop Controcomando Chiusura fino a completamento Chiusura.
| Azione |
Tempo |
StpPre |
StpUlt |
Tempo Residuo alla fine |
Arresto |
stpPre |
stpUlt |
| premiApertura |
30 |
0 |
0 + 30 |
30 |
Max-StpUlt 45-30 |
15 |
Intermedio |
0 (30) |
30 |
| premiChiusura |
15 |
30 |
30 - 15 |
20 |
Max-StpUlt 45-5 |
40 |
Intermedio |
45 (40) |
40 |
| premiChiusura |
20 |
40 |
40 - 20 |
20 |
StpUlt + extra 20 + 5 |
25 |
Chiuso |
40 (0) |
20 (0) |
--------------------------------------------------------------------------o-----------------------------------------------------------------------
Corpo
|