Salve, da qualche giorno ho ripreso in mano un mio vecchio progetto che ho iniziato tempo fa ma che non ho mai portato a termine per vari impegni, una centralina antifurto a solo scopo didattico. Questa centrale si attiva e disattiva attraverso 2 sensori RFID (uno remoto, ovvero invia il suo stato attraverso un modulo nrf11 e uno locale, collegato direttamente alla centrale). In oltre è presente un modulo 433mhz che riceve lo stato di alcuni sensori pir e un relè che attiva e disattiva una sirena. Lo so che per quanto posso fare un lavoro bene la seguente centrale è sempre vulnerabile, questa centrale non sarà installata veramente in un appartamento, ma è solamente una mia soddisfazione personale di portare un progetto al termine.
Ho scritto la seguente funzione che richiama altre funzioni che attivano/disattivano la centrale in base allo stato ricevuto da uno dei due sensori RFID:
unsigned long previousMillis = 0;
const long interval = 20000;
bool statoCentalina ()
{
/* Controllo lo stato dell'RFID locale */
if(getUID()){
if(stato==false){
stato=true;
}
else
stato=false;
}
/* */
/* Controllo lo stato dell'RFID remoto */
delay(5);
radio.startListening();
if ( radio.available()) {
radio.read(&stato, sizeof(stato));
Serial.println(stato);
}
/* */
/* in base allo stato ricevuto da uno dei due RFID attivo o disattivo l'antifurto */
if (stato==true && count==0) //se lo stato ricevuto è true..
{
flag=true;
inizializzazione ();
Serial.print("L'antifurto sara' attivato fra\t");
Serial.print (interval/1000);
Serial.print("\tsecondi.\n");
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
//qua voglio che la funzione inserito() venga eseguita dopo 20 secondi, valore impostato attraverso la variabile "interval"
inserito (); //vado ad inserire l'allarme e comunico il nuovo stato della centrale al sensore RFID
count=1;
flag=false;
}
}
if (stato==false && count==1)
{
count=0;
//previousMillis=0;
disinserito ();
inizializzazione ();
}
if (stato==false && flag==true)
{
flag=false;
count=0;
previousMillis=0;
annullaInserimento ();
inizializzazione ();
}
/* */
return stato;
}
se lo stato ricevuto è "true" richiamo la funzione predefinita "millis()" poiche voglio che l'antifurto venga inserito dopo 20 secondi (valore stabilito dalla variabile interval), infatti come facile intuire, se l'utente attiva la centralina dall'RFID locale, appena passa davanti a un sensore la centrale manda in allarme la sirena, bisogna quindi dare all'utente il tempo di uscire dalla zona dei sensori.
Ebbene, questo tempo che deve trascorrere prima che venga inserito l'antifurto non è sempre 20 secondi, a volte meno, altre volte invece viene inserito all'istante. Sapreste dirmi cosa posso correggere?
Grazie in anticipo.
...inoltre la variabile 'previousMillis' deve essere impostata al valore attuale di millis() solo nel momento esatto da cui si vuole iniziare a contare il tempo, e non in altri momenti, e men che meno va messa a zero.
non deve più essere const ma variare secondo la logica che ti serve e che non ho visto descritta per cui l'aiuto si limita a questo per ora.
non capisco perchè questa variabile non può essere costante se l'intervallo voglio che sia sempre di venti secondi. Più in la voglio implementare un altra funzione che mi permette di variare tale valore e di andarlo a memorizzare nella EEPROM, ma al momento non va bene se la rimango come costante?
Comunque la logica del loop è questa:
si parte dallo stato uguale a false, se passo una tessera vicino all'RFID diventa a true, a questo punto voglio che dopo 20 secondi venga attivato l'antifurto. In questa chiamiamola pausa di 20 secondi posso ripassare la tessera vicino all'RFID e annullare l'inserimento dell'antifurto (quindi stato ritorna a false), da notare che le due funzioni "disinserito ()" e "annullaInserimento ()" svolgono quasi le stesse funzioni, cambia solo che stampano cose diverse nella seriale.
Se ripasso di nuovo la tessera vicino all'RFID perchè voglio attivare l'antifurto, l'intervallo prima che questo venga attivato, non deve riprendere da dove si era fermato prima, ma deve essere sempre di 20 secondi. Passati questi 20 secondi, l'antifurto passa allo stato di attivo, quando voglio posso disattivarlo e non deve trascorrere nessuna pausa prima che venga disattivato.
Datman:
Ogni volta che passi la tessera devi riprendere il tempo di millis().
Non ho ben capito, cioè devo impostare la variabile currentmillis in questi punti che ho segnato?
/* Controllo lo stato dell'RFID locale */
if(getUID()){
if(stato==false){
stato=true;
//in questo punto
}
else
stato=false;
//in questo punto
}
/* */
/* Controllo lo stato dell'RFID remoto */
delay(5);
radio.startListening();
if ( radio.available()) {
radio.read(&stato, sizeof(stato));
//in questo punto
Serial.println(stato);
}
/* */
bool statoCentalina ()
{
/* Controllo lo stato dell'RFID locale */
if(getUID()){
if(stato==false){
stato=true;
}
else
stato=false;
}
/* */
/* Controllo lo stato dell'RFID remoto */
delay(5);
radio.startListening();
if ( radio.available()) {
radio.read(&stato, sizeof(stato));
Serial.println(stato);
}
/* */
/* in base allo stato ricevuto da uno dei due RFID attivo o disattivo l'antifurto */
if (stato==true && count==0) //se lo stato ricevuto è true..
{
flag=true;
inizializzazione ();
Serial.print("L'antifurto sara' attivato fra\t");
Serial.print (interval/1000);
Serial.print("\tsecondi.\n");
//unsigned long currentMillis = millis();
if (millis() - previousMillis >= interval) {
//previousMillis = currentMillis;
previousMillis = millis();
inserito (); //vado ad inserire l'allarme e comunico il nuovo stato della centrale al sensore RFID
count=1;
flag=false;
}
}
if (stato==false && count==1)
{
count=0;
//previousMillis=0;
previousMillis = millis();
disinserito ();
inizializzazione ();
}
if (stato==false && flag==true)
{
flag=false;
count=0;
//previousMillis=0;
previousMillis = millis();
annullaInserimento ();
inizializzazione ();
}
/* */
return stato;
}
Correggetemi se ce ancora qualcosa che non va.
Ciò che mi turba adesso è dato che si suppone che la centrale resta accesa 24 ore su 24 cosa succede quando la Variabile "previousMillis" va in overflow?
cosmo96:
Ciò che mi turba adesso è dato che si suppone che la centrale resta accesa 24 ore su 24 cosa succede quando la Variabile "previousMillis" va in overflow?
Direi che di questo "falso problema" se ne è parlato centinaia di volte sul forum, per cui ... studiaQUI.
Brevemente, se l'IF è fatto come si deve ... l'evento non ha alcun effetto.
Guglielmo
P.S.: ... e NON è "previousMillis" ad andare i overflow, ma il contatore che la funzione millis() restituisce