Arduino – lezione 05: controllo presenza

Questa lezione nasce da un commento di Aldo Biscotti (seguite il link), che ha la necessità di realizzare l’illuminazione temporizzata delle scale di casa. Si sta cimentando in questo progetto e la sua richiesta di aiuto mi da parecchi spunti per la realizzazione di una lezione ad hoc per i miei allievi.
Per la realizzazione del suo progetto avrà la necessità di usare dei sensori di presenza, che in questa lezione saranno sostituiti da semplici pulsanti.

Dal commento che mi è stato lasciato desumo che la necessità descritta da Aldo è quella di comandare due lampade di due ambienti diversi mediante due distinti rilevatori di presenza.
Nel realizzare un primo prototipo di studio Aldo giustamente, visto che sta imparando a programmare Arduino, utilizza i pulsanti in sostituzione dei rilevatori e i diodi led in sostituzione delle lampade.

Questa la sua necessità:

Pulsante 1:
(salita) start,
accensione del led 1,
dopo 2 secondi accensione led 2,
dopo 2 secondi spegnimento led 1,
dopo 2 secondi spegnimento led 2,
end.

Pulsante 2:
(discesa) start,
accensione del led 2,
dopo 2 secondi accensione led 1,
dopo 2 secondi spegnimento led 2,
dopo 2 secondi spegnimento led 1,
end.

Grazie Aldo.

Risponderò ad Aldo prendendo in analisi il suo primo sketch e da questo ne svilupperò una serie di programmi in cui introdurrò nuovi concetti.

Innanzitutto realizziamo il primo circuito di test, costituito da due diodi led, una resistenza ed un pulsante, in questa lezione vedrete che utilizzerò sia una scheda Arduino UNO, che Arduino 2009, assolutamente simili dal punto di vista della programmazione:

Questo invece il disegno realizzato con Fritzing

l5-02b-arduino

Analizziamo il primo sketch.

// Esempio 1: accensione led

int led_1 = 8;
int led_2 = 9;
int btn_pin = 2; 

void setup() {
     pinMode(led_1, OUTPUT);
     pinMode(led_2, OUTPUT);
     pinMode(btn_pin, INPUT);
} 

void loop()
{
     int in = digitalRead(btn_pin);
     if (in == LOW)
     {
         digitalWrite(led_1, LOW);
         delay (2000);
         digitalWrite(led_2, LOW);
         delay (2000);
     }
      else
     {
         digitalWrite(led_1, HIGH);
         delay (2000);
         digitalWrite(led_2, HIGH);
         delay (2000);
     }
}

Non funziona molto bene, come si desume dal filmato vi sono alcune correzioni da fare:

Nell’if viene controllato se il pulsante non è stato premuto “in == LOW”, se vero vengono spenti in modo sequenziale i due LED, domanda:

Se una luce è già spenta perché aggiungere un ritardo?

Ciò implica che se il programma è in esecuzione nella prima parte dell’if non verrà rilevata la presenza di una persona al massimo per 4 secondi ed è come dire che appena entro nella stanza sarò al buio per 4 secondi prima che le luci vengano accese e quindi una persona potrà:

  • fermarsi ed attendere 4 secondi
  • oppure camminare per 4 secondi al buio compiendo circa 5 metri di spazio camminando, presumibilmente supererà la prima stanza al buio.

Questa la mia prima variazione:

// Esempio 2: accensione temporizzata di un led in una sola direzione

#define led_1 8    // il pin 8 è usato per il LED
#define led_2 9    // il pin 9 è usato per il LED
#define btn_pin 2  // il pin 2 è usato per il PULSANTE 1

// Variabili
int in = 0;

void setup() {
     pinMode(led_1, OUTPUT);    // impostiamo il pin led_1 come output
     pinMode(led_2, OUTPUT);    // impostiamo il pin led_2 come output
     pinMode(btn_pin, INPUT);   // impostiamo il pin btn_pin come input
} 

void loop()
{
     in = digitalRead(btn_pin); // assegna lo stato del pulsante
     if (in == HIGH)            // controlla se il pulsante è stato premuto
     {
         digitalWrite(led_1, HIGH);  // accendiamo il LED 1
         delay (2000);               // attesa di 2 sec
         digitalWrite(led_2, HIGH);  // accendiamo il LED 2
         delay (2000);               // attesa di 2 sec
         digitalWrite(led_1, LOW);   // spegniamo il LED 1
         delay (2000);               // attesa di 2 sec
         digitalWrite(led_2, LOW);   // spegniamo il LED 2
     }
}

Controllo se il pulsante e premuto, se vero inizia la sequenza di accensione, altrimenti se il pulsante non è premuto l’if non viene eseguito, le luci continuano a rimanere spente e ricomincia nuovamente il loop().
Ovviamente se durante la sequenza di accensione e spegnimento di 6 secondi viene premuto nuovamente il pulsante non accade nulla, vedremo più avanti che questa soluzione potrebbe causare qualche problema.

Vediamo adesso come utilizzare due pulsanti (o rilevatori di presenza) per governare l’accensione in senso opposto, il circuito realizzato è il seguente:

Questo lo sketch

// Esempio 3: accensione temporizzata di due led
// in due direzioni con uso dell'if 

#define led_1 8    // il pin 8 è usato per il LED
#define led_2 9    // il pin 9 è usato per il LED
#define btn_pin1 2  // il pin 2 è usato per il PULSANTE 1
#define btn_pin2 3  // il pin 3 è usato per il PULSANTE 2

// Variabili
int in1 = 0;        // variabile per memorizzare lo stato del PULSANTE 1
int in2 = 0;        // variabile per memorizzare lo stato del PULSANTE 2

void setup() {
     pinMode(led_1, OUTPUT);
     pinMode(led_2, OUTPUT);
     pinMode(btn_pin1, INPUT);
     pinMode(btn_pin2, INPUT);
} 

void loop()
{
     in1 = digitalRead(btn_pin1);
     in2 = digitalRead(btn_pin2);

     if (in1 == HIGH && in2 == LOW)  // se PULSANTE 1 premuto e PULSANTE 2 no sequenza 1
       {
           digitalWrite(led_1, HIGH);
           delay (2000);
           digitalWrite(led_2, HIGH);
           delay (2000);
           digitalWrite(led_1, LOW);
           delay (2000);
           digitalWrite(led_2, LOW);
       }
     if (in1 == LOW && in2 == HIGH)  // se PULSANTE 1 premuto e PULSANTE 2 no sequenza 2
       {
           digitalWrite(led_2, HIGH);
           delay (2000);
           digitalWrite(led_1, HIGH);
           delay (2000);
           digitalWrite(led_2, LOW);
           delay (2000);
           digitalWrite(led_1, LOW);
       }
}

Come potete notare ho usato l’operatore logico AND (&&) che effettua un controllo su quale dei pulsanti è acceso in questo modo controllo la direzione di accensione.

Per chiarire meglio ho realizzato uno schema che visualizza meglio cosa accade:

Si ricordi che la progettazione viene fatta usando pulsanti, ma voi estrapolate e pensate a dei rilevatori di presenza.

Supponiamo che la direzione sia da destra a sinistra, la persona 1 viene rilevata dal sensore R1, si accende la luce L1 per 2 secondi, entra nella stanza 2 e supponendo che non sia più veloce di due secondi, rischiando di entrare in una stanza buia, viene rilevato dal sensore R2, si accende la luce L2 e dopo 4 secondi si spegne la luce L1.

Ma cosa accade se nei primi 2 secondi entra un’altra persona nella prima stanza a destra?
La seconda persona resta al buio.
Stesso inconveniente accade nella direzione opposta da sinistra verso destra.

Quindi per superare questo incoveniente è necessario che l’accensione delle luci non duri solamente per un tempo prefissato, ma per tutto il tempo in cui la persona è presente nel locale, dopo di che la luce può spegnersi.

La soluzione più semplice di tutte è quella descritta dallo sketch che segue, si ricordi che premere il pulsante corrisponde a: “persona rilevata”

// Esempio 4: accensione di due led comandati da due pulsanti

#define led_1 8    // il pin 8 è usato per il LED
#define led_2 9    // il pin 9 è usato per il LED
#define btn_pin1 2  // il pin 2 è usato per il PULSANTE 1
#define btn_pin2 3  // il pin 3 è usato per il PULSANTE 2

// Variabili
int in1 = 0;
int in2 = 0;

void setup() {
  pinMode(led_1, OUTPUT);
  pinMode(led_2, OUTPUT);
  pinMode(btn_pin1, INPUT);
  pinMode(btn_pin2, INPUT);
} 

void loop()
{
  in1 = digitalRead(btn_pin1);
  in2 = digitalRead(btn_pin2);

  if (in1 == HIGH)                  // PULSANTE 1 premuto
  {
    digitalWrite(led_1, HIGH);      // accensione LED 1
  }
  else
  {
    digitalWrite(led_1, LOW);      // seil PULSANTE 1 non premuto LED 1 spento
  }

  if (in2 == HIGH)                  // PULSANTE 2 premuto
  {
    digitalWrite(led_2, HIGH);      // accensione LED 2
  }
  else
  {
    digitalWrite(led_2, LOW);      // seil PULSANTE 2 non premuto LED 2 spento
  }

}

Per evitare che ci sia uno spegnimento brusco dell’illuminazione appena si esce dalla stanza, ritardo lo spegnimento dell’illuminazione della stanza che ho appena abbandonato:

// Esempio 5: accensione di due led comandati da due pulsanti
// con ritardo di spegnimento di due secondi

#define led_1 8    // il pin 8 è usato per il LED
#define led_2 9    // il pin 9 è usato per il LED
#define btn_pin1 2  // il pin 2 è usato per il PULSANTE 1
#define btn_pin2 3  // il pin 3 è usato per il PULSANTE 2

// Variabili
int in1 = 0;
int in2 = 0;

void setup() {
  pinMode(led_1, OUTPUT);
  pinMode(led_2, OUTPUT);
  pinMode(btn_pin1, INPUT);
  pinMode(btn_pin2, INPUT);
} 

void loop()
{
  in1 = digitalRead(btn_pin1);
  in2 = digitalRead(btn_pin2);

  if (in1 == HIGH){                 // PULSANTE 1 premuto
    digitalWrite(led_1, HIGH);      // accensione LED 1
    delay (2000);                   // ritardo di 2 sec
  }
  else
  {
    digitalWrite(led_1, LOW);       // se il PULSANTE 1 non premuto LED 1 spento
  }

  if (in2 == HIGH){                 // PULSANTE 2 premuto
    digitalWrite(led_2, HIGH);      // accensione LED 2
    delay (2000);                   // ritardo di 2 sec
  }
  else
  {
    digitalWrite(led_2, LOW);        // seil PULSANTE 2 non premuto LED 2 spento
  }
}

Nella prossima lezione al fine di rendere più utile e gradevole il controllo sull’illuminazione della stanza vedremo come aumentare e diminuire gradualmente l’illuminazione usando una tecnica che sfrutta la modulazione di larghezza di impulso (PWM).


Vai alle altre lezioni:

Lezione01: Incominciamo con Arduino Arduino – lezione 02: facciamo lampeggiare un led Arduino – lezione 03: controlliamo un led con un pulsante
Lezione Arduino Lezione Arduino Lezione Arduino
Arduino – lezione 04: realizzare un programma che identifica le variazioni di stato Arduino – lezione 05: controllo presenza
Lezione Arduino Lezione Arduino
Questa voce è stata pubblicata in arduino e contrassegnata con , , , , , . Contrassegna il permalink.

23 risposte a Arduino – lezione 05: controllo presenza

  1. Aldo Biscotti scrive:

    Salve, chiedo scusa per in ritardo, ma il lavoro non mi ha lasciato molto tempo libero.
    Ho visto, provato ed ammirato gli skecth che hai pubblicato, non ho parole.. funzionano
    perfettamente (ovviamente) ma contengono tanti dati e soluzioni che ancora non avevo visto. Adesso mettendo a confronto i miei test alle tue soluzioni, capisco quanto ho ancora da imparare, cosa dire…. grazie infinite per l’ aiuto e aspetto con
    ansia l’ uscita della sesta lezione, per vedere e studiare l’ ulteriore evoluzione di questo progetto.
    Grazie Michele, grazie professore.

  2. massimo scrive:

    Chiedo scusa, sono un neofita principiante nell’utilizzo di Arduino.

    Ho appena concluso il primo tutorial con l’accensione/spegnimento LED.

    Ho una domanda banale: come si fa a cancellare il programma sulla scheda per inserirne uno nuovo?

    grazie

    • admin scrive:

      Ciao Massimo.

      Ogni volta che effettui l’upload di un nuovo sketch sulla scheda, questo sovrascrive il precedente.

      Ciao.

      • daniele scrive:

        salve… sto reallizando un cancello a ante in miniatura.. con fotocellule, tasto per l’apertura/chiusura . non riesco a scrivere la parte di programma che controlla se il tasto è premuto e che controlla se le fotocellule sono a 1 (presenza ostacolo)… potreste darmi un mano nel codice?

  3. Nicola scrive:

    Salve,
    davo uno sguardo ai tutorial, molto interessanti e con una spiegazione passo passo veramente notevole da far capire, a chi è alle prime armi con arduino, cosa ci si può fare con tutto ciò.
    Mi sono dato ad arduino da poco, sto ancora studiando la parte teorica prima di cimentarmi sul pratico, anche se con arduino non server essere un ingegnere elettronico, voglio ripetere e approfondire alcuni aspetti che oramai mi so scordato.
    Mi occupo di tutt’altro precisamente networking e web design, ma considerando che attualemente ho un bel pò di tempo libero, voglio approfondire arduino, per integrarlo in qualche progetto su Asterisk, visto che lo uso e ci gioco da quasi 3 anni.
    Complimenti ancora…oh che ti seguo eh 🙂
    Saluti

    • admin scrive:

      Ciao Nicola.

      Grazie per l’interesse alle mie lezioni, spero potranno esserti di aiuto per il tuo lavoro, se poi fai qualche esperienza con Asterisk e Arduino, se possibile fammi sapere, magari mi dai qualche spunto interessante da sperimentare con i miei allievi.
      Come hai notato non ci vogliono grandi competenze elettroniche per incominciare con Arduino, in realtà all’inizio è più importante avere competenze di programmazione.
      Noterai poi successivamente che la metodologia di sperimentazione con Arduino in realtà ti porta gradualmente anche ad acquisire le conoscenze dei principi di base dell’elettronica ed è questa la caratteristica più intressante dal punto di vista didattico in quanto gli allievi riescono a provare soddisfazione nello studio dell’elettronica proprio perché, finalmente, realizzano oggetti che interagiscono con il mondo fisico e quindi la didattica assume concretezza nelle loro menti.

      In ogni caso se hai necessità di risorse gratuite on-line per l’apprendimento dell’elettronica ti consiglio di aggiungere ai tuoi bookmarks questi due link:

      Grazie ancora.
      Saluti.

  4. francesca scrive:

    Salve a tutti,
    sono una studentessa universitaria e sto svolgendo un lavoro di tesi e vorrei utilizzare Arduino 2009.Il sistema che devo realizzare è il seguente:
    tramite due sensori devo rilevare il passaggio di palline molto piccole che scorrono in un tubo,arduino mi dovrebbe calcolare la velocità di queste palline e dare un impulso di trigger ad una fotocamera per fotografarle.Il mio problema è sui sensori perchè danno un uscita di 30V con corrente max 100mA(sono digitali, uscita pnp a collettore aperto) mentre dal sito leggo che gli ingressi digitali possono supportare solo 5V!inoltre la loro alimentazione e 12-24Vc.c.I valori sono cosi alti perchè sono sensori industriali muniti già di amplificatore in fibra ottica!Mi sembra chiaro che sono incompatibili con arduino..non posso neanche alimentarli dalla scheda.Avete qualcosa da propormi?

  5. fabio scrive:

    ho appena comprato arduino 2009… volevo comandare dei servomotori, potresti darmi una dritta su come generare degli impulsi? il servo è questo: http://www.futurashop.it/allegato/7300-SERVO209.asp?L2=AZIONAMENTI&L1=ROBOTICA&L3=SERVOMOTORI&cd=7300-SERVO209&nVt=&d=8,70

    • admin scrive:

      Ciao Fabio, scusami tanto per la risposta tardiva, giorni di fuoco a scuola.
      Probabilmente avrai già trovato una soluzione.
      In ogni caso per l’uso dei servo come punto di partenza fai riferimento al sito Arduino.cc

      Sweep
      Knob

      Al fondo delle pagine segnalate guarda anche le istruzioni nella sezione “See also”

      Per spiegazione dettagliata sui servo ti consiglio l’ottimo sito di elettronica: settorezero.com vai alla lezione: Come funziona un servocomando.

      Saluti.

  6. Fabiolino scrive:

    Salve….
    Mi chiamo Fabio e sono circa due settimane che sto iniziando a giocare con Arduino.
    Tutto e’ iniziato da quando ho finito il mio corso di PLC.

    Ho notato che il PLC e questa scheda hano tantissime cose in comune.

    Ho pero’ una domanda da fare: affidereste mai ad Arduino un controllo di un particolare processo a livello industriale o quanto meno a livello domestico? Quanto e’ affidabile questa scheda?

    Fino a che punto vi affidereste ad Arduino?

    Grazie mille……specialmente per le lezioni.
    Grazie ancora professore.

    • admin scrive:

      Ciao Fabio.
      La domanda che mi fai è certamente interessante e tra le più ricorrenti che mi vengono rivolte via mail dagli utenti.
      Considera che Arduino è una scheda di prototipazione, questo vuol dire che la potrai utilizzare per sviluppare un progetto, se vuoi vederla in altro modo pensa ad Arduino come una basetta millefori o ad una breadboard che ti servono per progettare il circuito finale.
      Quindi la scheda Arduino è ottima per prototipare e per applicazioni hobbistiche, la ritengo ottima per la didattica, però se devi sviluppare un oggetto da commercializzare probabilmente dovrai tener conto di una serie di fattori:

      • in un ambiente “industriale” i livelli di stress potrebbero essere elevati (temperatura, umidità, campi elettromagnetici…) quindi bisogna vedere cosa vuoi realizzare;
      • il costo unitario di Arduino è di circa 25 Euro che è relativamente basso per l’utente che ha necessità di sperimentare, ma secondo me alto ai fini industriali, certamente sui grandi numeri la cifra si abbassa ma per un progetto commerciale non saranno necessarie tutte le funzionalità hardware e software, quindi il prodotto finale potrebbe avere costi notevolmente più bassi.
        Per esperienza, in preparazione delle prossime lezioni, ho realizzato io delle schede compatibili Arduino basate sull’ATmega328 con quantità di componenti, spazi e costi notevolmente inferiore.
      • il prodotto dovrà essere conforme alle direttive europee.

      Per quanto riguarda l’affidabilità, non ho esperienze dirette in campo industriale con Arduino, per ora, ma considera che ATmega328 viene impiegato moltissimo in azienda per la realizzazione di sistemi embedded quindi sicuramente il microcontrollore è affidabile. Io con Arduino ho sviluppato diversi prototipi per la demotica: antifurto, controllo inquinamento atmosferico, allarmi per fughe di gas, controlli remoti per attivare e disattivare elettrodomestici ed altri e tutti quanti non mi hanno dato nessun problema hardware e stanno funzionando senza nessun problema.

      Quindi ti direi, si io mi affiderei ad Arduino per prototipare e poi forse per applicazioni industriali progetterei una scheda compatibile Arduino, ma prendila come risposta non definitiva, la scelta dipende moltissimo dal campo di impiego e dal budget disponibile.

      Saluti.

  7. Michele scrive:

    Salve, intanto complimenti per il sito e per le lezioni, sono molto utili.
    Non mi è chiara una cosa però, il comando delay mette in pausa lo sketch, ma se ho la necessità che il mio sketch vada avanti mentre un led lampeggia(quindi usa dei delay)?
    Non so se mi sono spiegato, per esempio in questo codice leggo delay(2000) per ritardare lo spegnimento della luce comandata dal primo sensore, ma in quei 2 secondi tutto è bloccato, se il secondo sensore rivela la presenza la seconda lampada non si accende. Questo per me è un problema, nel senso che nel mio sketch ho bisogno di ritardi di parecchi secondi e non posso permettermi di bloccare tutto. (Ho cominciato da poco con la programmazione)

    Grazie e ancora complimenti, attenderò i seguiti delle sue lezioni con ansia.

    • Andrea scrive:

      Buonasera professore,

      Ho lo stesso problema di Michele, ci dà qualche consiglio per risolvere? Quello che servirebbe è un counter che viaggia in parallelo ad codice… sicuramente ci sono svariati modi, ma quale è il migliore secondo lei??

  8. Alessandro scrive:

    Salve, volevo ringraziarla per il lavoro che sta svolgendo. Le sue guide sono ottime per i principianti come me. Volevo chiederle un aiuto per quanto riguarda un progettino che sto provando a fare con arduino.
    Ho comprato la versione Arduino Ethernet, un sensore di umidità che si collega e alimenta direttamente con arduino e una ventola da 12 v. Il mio scopo era quello di far accendere la ventola al superamento di una determinata soglia di umidità e spegnerla quando l’umidità scende al di sotto di un certo livello. Trovo delle difficoltà a collegare la ventola ad arduino il quale fornisce solo 5v e la ventola ne consuma 12.
    Se potrebbe darmi dei consigli ne sarei molto felice.

    La ringrazio ancora moltissimo per il lavoro che svolge.

    Alessandro

  9. myself scrive:

    Salve,
    ho letto con piacere le guide presenti su questo sito, ma mi è rimasto l’amaro in bocca quando mi sono reso conto che dopo la lezione 05 non ce ne sono più.
    Come mai?

  10. Nicola scrive:

    Ancora complimenti per il sito . Mi ricollego al pilotaggio di carichi importanti . Volevo chiederle se e’ possibile con Arduino misurare la potenza utilizzata dall’impianto elettrico ; il fine sarebbe quello di avere un controllo razionale della gestione dei carichi dell’impianto staccandoli x esempio in sequenza a partire da quelli meno importanti evitando cosi di superare la soglia imposta dal gestore . Grazie
    Nicola

  11. Cristian scrive:

    Salve, sto seguendo le sue guide e le trovo molto interessanti e utili per un neofita. Mi interessa questo progetto dell’accessione/spegnimento delle luci tramite rilevatori. Aspetto la lezione 5.
    Grazie e buon lavoro.

    • admin scrive:

      Grazie a te Cristian, cercherò di concludere il discorso sull’accessione/spegnimento delle luci tramite rilevatori. Nel mentre puoi visionare anche le lezioni 6 e 7 che non sono ditrettamente collegate alla lezione 5, ma utili per le successive lezioni.

      Saluti.

  12. Matteo scrive:

    Salve professore, mi chiamo Matteo, ho 11 anni e ho cominciato a seguire le sue lezioni su come programmare Arduino. Nella lezione 05 ho notato che nel 1° schemino fatto con Fritzing riguardante l’accensione di due led con un pulsante, c’è un errore. Il cavetto che si collega al pulsante, è inserito nella linea – GND invece che nella linea +5 come si vede nella foto soprastante lo schema. Congratulazioni comunque x le lezioni, sono molto utili,speriamo che ne escano altre.

    BUON LAVORO

    Matteo

    • admin scrive:

      Grazie molte Matteo.
      Ho eseguito la correzione che mi segnalavi sul primo schema fatto in Fritzing.
      Mi fa enormemente piacere che stai seguendo le mie lezioni.

      Un caro saluto.

  13. vincenzo scrive:

    Buongiorno, una cortesia premetto che sono un neofita e autodidatta, volevo chiederle una cortesia in questo progetto si accendono dei led e al posto dei sensori ci sono due pulsanti, ma se io volessi far funzionare al posto dei led le luci di casa come posso fare devo integrarci dei transistor? e al posto dei due pulsanti posso mettere due sensori pir? Grazie

  14. Vi scrive:

    salve e complimenti, preciso sono ignorante in materia ma amo queste cose ho fatto questo circuito e funziona volevo chiederle se fosse possibile sennò non fa niente come sositituire i due pulsanti con due veri sensori pir, cosa si deve fare? perchè non so molto programmare.Grazie

Rispondi a Fabiolino Annulla risposta

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.