Sensore PIR con Arduino e ESP terza parte
Nell’articolo precedente ci siamo soffermati sulla comunicazione tra Arduino e ESP.
In questo articolo tratteremo brevemente l’utilizzo degli interrupt di Arduino nel progetto illustrato nei due articoli precedenti qui e qui.
Per una completa trattazione sugli interrupt si rimanda al reference ufficiale.
Questa chiamata attiva l’interrupt sul pin wakePin. I vari arduino hanno vari pin che possono accettare degli interrupt. Nel nostro caso abbiamo selezionato il numero2. attachInterrupt(digitalPinToInterrupt(wakePin), wakeUp, RISING) Il secondo parametro è la funzione che dovrà essere eseguita quando arriva l’interrupt. Nel nostro caso si tratta della funzione wakeUp. Il terzo parametro è il modo che può assumere 4 valori (LOW, RISING, CHANGE; FALLING).
Nel nostro codice abbiamo utilizzato RISING poichè il sensore PIR fa passare il pin 2 da basso che è ad alto innescando in questo modo l’interrupt.
La funzione detachInterrupt viene utilizzata nel codice per scollegare temporaneamente l’interrupt in modo da evitare gli avvii ripetuti non intenzionali mentre Arduino sveglia ESP e gli invia i comandi.
Dopo aver inviato i comandi a ESP il codice ritorna all’inizio della funzione loop e viene riattivato l’interrupt e poi viene messo arduino in deep sleep.
Le funzioni per gestire il deep sleep di arduino si trovano nella libreria avr/sleep.h L’utilizzo di set_sleep_mode permette di settare il tipo di deep sleep. Nel nostro caso si è scelto lo stato power down mode per minimizzare l’utilizzo di energia. É bene ricordare che da tale stato arduino può essere svegliato solo con un interrupt sul PIN 2. Da altri tipi di stati può essere svegliato in modo periodico senza aiutoo di interrupt esterni.
Qui possono essere reperiti maggiori dettagli su questa libreria.
Di seguito l’intero codice utilizzato nel progetto
#include <EchoCommands.h> #include<SoftwareSerial.h> #include <Wire.h> #include <avr/sleep.h> SoftwareSerial Serial1(8, 9); // RX, TX uint32_t baud = 9600; EchoCommands echoc(Serial, Serial1, 9600); //LOG initialize const byte wakePin = 2; //Porta per il segnale di risveglio - const byte wakePinESP = 4; //ESP wake up port arduino-to ESP RST PORT String ssid="yourssid"; String pwd="yourssidpwd"; #define DEST_IP "DomoticzIP" //Domoticz IP // *************wake routine **************************** void wakeUp() { sleep_disable(); // disabilita la modalita' sleep (sveglia il sistema) // wake up again //Serial.println("Woke up this morning..."); } // ****************************** sleep routine ****************************************** void sleepNow() { //Serial.println("dormo - sleep.... "); sleep_enable(); // abilita l'addormentamento del sistema delay(100); set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Select "power down mode" to maximize energy saving cli(); // disable interrupts sleep_bod_disable(); // disabilita il controllo interno di alimentazione (brown out detection) sei(); // riabilita l'interrupt - enable interrupts sleep_cpu(); // "addormenta" la cpu - sleep mode on cpu } // ******** SETUP ******** void setup() { //uint32_t baud = 9600; //Serial.begin(baud); // Communication with PC monitor via USB pinMode(wakePin, INPUT); //porta che riceve l'interrupt dal sensore PIR pinMode(wakePinESP, OUTPUT); //porta che genera output per il reset del sensore PIR } // ******** LOOP ******** void loop() { //Serial.print("going tosleep.... "); attachInterrupt(digitalPinToInterrupt(wakePin), wakeUp, RISING);//RIATTIVA INTERRUPT delay (1000); sleepNow(); // call sleep routine // ********** Arduino return in loop section here, after woke detachInterrupt(digitalPinToInterrupt(wakePin)); //DISATTIVA TEMPORANEAMENTE INTERRUPT delay(100); echoc.wakeUpESP(wakePinESP); delay(100); echoc.wifi_init(ssid,pwd); if (!echoc.echoCommand("AT+CIPMUX=1", "OK", CONTINUE)) { echoc.sleepDownESP(0); delay (100); echoc.sleepDownESP(0); return; } // Establish TCP connection String cmd = "AT+CIPSTART=2,\"TCP\",\""; cmd += DEST_IP; cmd += "\",8080"; if (!echoc.echoCommand(cmd, "OK", CONTINUE)) { echoc.sleepDownESP(0); delay (100); echoc.sleepDownESP(0); return; } //delay(500); // Build HTTP request. cmd = "GET /json.htm?type=command¶m=switchlight&idx=25&switchcmd=On"; cmd += " HTTP/1.1\r\nHost: "; cmd += DEST_IP; cmd += ":8080\r\n\r\n"; // Send data to domoticz if (!echoc.echoCommand("AT+CIPSEND=2," + String(cmd.length()), ">", CONTINUE)) { //Serial.println("Connection timeout."); echoc.sleepDownESP(0); delay (100); echoc.sleepDownESP(0); return; } else { // Send the raw HTTP request echoc.echoCommand(cmd, "OK", CONTINUE); // GET to domoticz delay(2000); } //Connection close echoc.echoCommand("AT+CIPCLOSE=2", "OK", CONTINUE); delay(1000); //Serial.println("ESP8266 A nanna"); echoc.sleepDownESP(0); delay (100); echoc.sleepDownESP(0); }