.. note:: Ciao, benvenuto nella SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasts Community su Facebook! Approfondisci Raspberry Pi, Arduino ed ESP32 insieme ad altri appassionati. **Perché unirti?** - **Supporto esperto**: Risolvi i problemi post-vendita e le sfide tecniche con l'aiuto della nostra community e del nostro team. - **Impara e condividi**: Scambia suggerimenti e tutorial per migliorare le tue competenze. - **Anteprime esclusive**: Ottieni accesso anticipato agli annunci di nuovi prodotti e alle anteprime. - **Sconti speciali**: Goditi sconti esclusivi sui nostri prodotti più recenti. - **Promozioni festive e omaggi**: Partecipa a concorsi e promozioni festive. 👉 Pronto a esplorare e creare con noi? Clicca su [|link_sf_facebook|] e unisciti oggi! .. _3.1.9_c_pi5: 3.1.9 Campanello d'allarme ============================= Introduzione ----------------- In questo progetto, realizzeremo un dispositivo di allarme manuale. Puoi sostituire l'interruttore a levetta con un termistore o un sensore fotosensibile per creare un allarme di temperatura o di luce. Componenti necessari ------------------------------- In questo progetto, abbiamo bisogno dei seguenti componenti. .. image:: ../img/list_Alarm_Bell.png :align: center È sicuramente conveniente acquistare un kit completo, ecco il link: .. list-table:: :widths: 20 20 20 :header-rows: 1 * - Nome - ELEMENTI IN QUESTO KIT - LINK * - Kit Raphael - 337 - |link_Raphael_kit| Puoi anche acquistarli separatamente dai link sottostanti. .. list-table:: :widths: 30 20 :header-rows: 1 * - INTRODUZIONE COMPONENTE - LINK PER L'ACQUISTO * - :ref:`cpn_gpio_extension_board` - |link_gpio_board_buy| * - :ref:`cpn_breadboard` - |link_breadboard_buy| * - :ref:`cpn_wires` - |link_wires_buy| * - :ref:`cpn_resistor` - |link_resistor_buy| * - :ref:`cpn_led` - |link_led_buy| * - :ref:`cpn_buzzer` - |link_passive_buzzer_buy| * - :ref:`cpn_slide_switch` - |link_slide_switch_buy| * - :ref:`cpn_transistor` - |link_transistor_buy| * - :ref:`cpn_capacitor` - |link_capacitor_buy| Schema elettrico ---------------------- ============ ======== ======== === T-Board Name physical wiringPi BCM GPIO17 Pin 11 0 17 GPIO18 Pin 12 1 18 GPIO27 Pin 13 2 27 GPIO22 Pin 15 3 22 ============ ======== ======== === .. image:: ../img/Schematic_three_one10.png :align: center Procedure sperimentali ----------------------------- **Passo 1**: Costruisci il circuito. .. image:: ../img/image266.png **Passo 2**: Vai alla cartella del codice. .. raw:: html .. code-block:: cd ~/raphael-kit/c/3.1.9/ **Passo 3**: Compila. .. raw:: html .. code-block:: gcc 3.1.9_AlarmBell.c -lwiringPi -lpthread **Passo 4**: Esegui. .. raw:: html .. code-block:: sudo ./a.out Dopo l'avvio del programma, sposta l'interruttore a levetta verso destra e il cicalino emetterà suoni di allarme. Allo stesso tempo, i LED rosso e verde lampeggeranno a una certa frequenza. .. note:: Se il programma non funziona dopo l'esecuzione o compare il messaggio di errore: "wiringPi.h: No such file or directory", consulta :ref:`install_wiringpi_pi5`. Spiegazione del codice ------------------------- .. code-block:: c #include  In questo codice, utilizzerai una nuova libreria, ``pthread.h``, che è un insieme di librerie di thread comuni e può realizzare il multithreading. Aggiungiamo il parametro ``-lpthread`` al momento della compilazione per consentire il funzionamento indipendente del LED e del cicalino. .. code-block:: c void *ledWork(void *arg){            while(1)         {            if(flag==0){             pthread_exit(NULL);         }         digitalWrite(ALedPin,HIGH);         delay(500);         digitalWrite(ALedPin,LOW);         digitalWrite(BLedPin,HIGH);         delay(500);         digitalWrite(BLedPin,LOW);     } } La funzione ``ledWork()`` aiuta a impostare lo stato di funzionamento di questi 2 LED: mantiene il LED verde acceso per 0,5 secondi, quindi lo spegne; allo stesso modo, mantiene il LED rosso acceso per 0,5 secondi, quindi lo spegne. .. code-block:: c void *buzzWork(void *arg){     while(1)     {         if(flag==0){             pthread_exit(NULL);         }         if((note>=800)||(note<=130)){             pitch = -pitch;         }         note=note+pitch;         softToneWrite(BeepPin,note);         delay(10);     } } La funzione ``buzzWork()`` viene utilizzata per impostare lo stato di funzionamento del cicalino. Qui impostiamo la frequenza tra 130 e 800, per accumulare o decrescere a intervalli di 20. .. code-block:: c void on(){     flag = 1;     if(softToneCreate(BeepPin) == -1){         printf("setup softTone failed !");         return;      }         pthread_t tLed;          pthread_create(&tLed,NULL,ledWork,NULL);         pthread_t tBuzz;       pthread_create(&tBuzz,NULL,buzzWork,NULL);       } Nella funzione on(): 1) Definisci il flag ``flag=1``, che indica la terminazione del thread di controllo. 2) Crea un pin per il tono controllato dal software ``BeepPin``. 3) Crea due thread separati in modo che il LED e il cicalino possano funzionare contemporaneamente. * ``pthread_t tLed``: Dichiara un thread ``tLed``. * ``pthread_create(&tLed,NULL,ledWork,NULL)``: Crea il thread e il suo prototipo è il seguente: .. code-block:: int pthread_create(pthread_t *restrict tidp,const pthread_attr_t*restrict_attr,void*(*start_rtn)(void*),void *restrict arg); Se ha successo, restituisce 0; altrimenti restituisce il numero di errore -1. * Il primo parametro è un puntatore all'identificatore del thread. * Il secondo parametro serve per impostare l'attributo del thread. * Il terzo parametro è l'indirizzo di partenza della funzione di esecuzione del thread. * L'ultimo parametro è quello che esegue la funzione. .. code-block:: c void off(){     flag = 0;     softToneStop(BeepPin);     digitalWrite(ALedPin,LOW);     digitalWrite(BLedPin,LOW); } La funzione ``off()`` definisce ``flag=0`` per uscire dai thread **ledWork** e **buzzWork** e poi spegnere il cicalino e i LED. .. code-block:: c int main(){            setup();      int lastState = 0;     while(1){         int currentState = digitalRead(switchPin);         if ((currentState == 1)&&(lastState==0)){             on();         }         else if((currentState == 0)&&(lastState==1)){             off();         }         lastState=currentState;     }     return 0; } Main() contiene l'intero processo del programma: innanzitutto legge il valore dell'interruttore a levetta; se l'interruttore viene spostato verso destra (lettura 1), viene chiamata la funzione ``on()``, il cicalino viene attivato per emettere suoni e i LED rosso e verde lampeggiano. In caso contrario, il cicalino e i LED non funzionano. Immagine del fenomeno -------------------------- .. image:: ../img/image267.jpeg :align: center