Buonasera,
dopo un po' di tempo trascorso ad apprendere i fondamenti del linguaggio di programmazione di Arduino, prendendo spunto da un codice fornito da un collega universitario, ho voluto creare un semplice allarme, utilizzabile tanto in casa quanto in una rimessa per le auto.
L'hardware consiste in un sistema di alimentazione a 12V pilotabile ad esempio da un radiocomando, una sirena a 12V, un relè, un buzzer ed un misuratore ad ultrasuoni orientato su un riscontro posizionato sulla porta di accesso.
Il funzionamento, riassunto per passi, è il seguente:
- alimento Arduino
- il buzzer suona 3 volte per confermare l'accensione
- attendo un certo tempo necessario a chiudere la porta
- dopo 5 secondi il buzzer suona una volta per segnalare l'inizio delle misurazioni della distanza
- allarme operativo
- apro la porta
- il buzzer suona il countdown
- se entro la fine del countdown tolgo l'alimentazione al microcontrollore non accade nulla
- se ancora alimentato, attivo il relè che suona la sirena
Allego il codice:
const int tempo_chiusura = 5000; // tempo impegato per chiudere la porta
const int tempo_spegnimento = 8000; // tempo impiegato per spegnere l'allarme
const int tempo_assestamento = 1000;
const int triggerPort = 9;
const int echoPort = 8;
const int rele = 11;
const int buzzer = 10;
long distanza;
int accensione = 0;
void setup() {
pinMode(rele, OUTPUT);
digitalWrite(rele, HIGH);
pinMode(triggerPort, OUTPUT);
pinMode(echoPort, INPUT);
pinMode(buzzer, OUTPUT);
Serial.begin(9600);
}
void loop() {
digitalWrite(rele, HIGH); // se quando finisco il loop la sirena suona, adesso si spegne
if (accensione == 0) {
for (int x = 0; x < 3; x++) {
tone(buzzer, 1500, 100); // suona una nota per 3 volte sul pin buzzer alla frequenza di 1500 Hz per 100 ms (#2) | tone(buzzer,1500);
delay(200); // fa una pausa di 200 ms che inizia contare appena esegue la precedente istruzione, che dura 100 ms | delay(200);
} // (quindi in realta per 100 ms suona e per 100 ms no) | noTone(buzzer)
delay(tempo_chiusura);
tone(buzzer, 800, 1500); // suona una nota sul pin buzzer alla frequenza di 800 Hz per 1500 ms (#4)
delay(5000);
digitalWrite(triggerPort, LOW); // porta bassa l'uscita del trigger
digitalWrite(triggerPort, HIGH); // invia un impulso di 10microsec su trigger
delayMicroseconds(10);
digitalWrite(triggerPort, LOW);
long durata = pulseIn(echoPort, HIGH);
long distanza = 0.034 * durata / 2;
Serial.println(distanza);
accensione = 1;
}
digitalWrite(triggerPort, LOW); // porta bassa l'uscita del trigger
digitalWrite(triggerPort, HIGH); // invia un impulso di 10microsec su trigger
delayMicroseconds(10);
digitalWrite(triggerPort, LOW);
long durata_attuale = pulseIn(echoPort, HIGH);
long distanza_attuale = 0.034 * durata_attuale / 2;
Serial.println(distanza_attuale);
if (distanza_attuale > distanza) {
delay(tempo_assestamento);
if (distanza_attuale > distanza) {
for (int x = 0; x < 10; x++) { // esgui il countdown per 10s in attesa dello spegnimeto
tone(buzzer, 1000, 250); // suona una nota sul pin buzzer alla frequenza di 1000 Hz per 250 ms | tone(buzzer,1000);
delay(1250); // | delay(250);
} // | noTone(buzzer);
while (accensione > 0) { // se non è spento, ripete all'infinito (condizione sempre verificata)
digitalWrite(rele, LOW); // (LOW = relè acceso)
delay(5000); // suona per 5s
digitalWrite(rele, HIGH); // (HIGH = relè spento)
delay(1000); // non suonare per 1s
}
}
}
}
All'atto pratico si verificano una serie di problemi:
- le distanze visualizzate nel monitor seriale sono degli interi (forse è solo legato alla visualizzazione?) e comunque, nonostante le prove siano state effettuate senza muovere il sensore (HC-SR04) non sono uguali!
- nonostante la
distanza_attuale
risulti dal monitor seriale minore delladistanza
letta inizialmente, il cowntdown inizia comunque (a dire il vero, senza il delay dopo il suono di inizio misurazione, il cowntdown si sovrappone a quest'ultimo). In pratica la misurazione delladistanza_attuale
viene effettuata una sola volta, in quanto il codice entra subito nel cicloif
.
Dal punto di vista logico il codice mi sembra corretto e compila senza errori. Non riesco a comprendere questo comportamento anomalo...
Ringrazio chi mi vorrà aiutare.