Alarme d’inondation connectée

Alarme d’inondation connectée

Après avoir surveillé la température et l’ouverture de la porte du frigo, on reste dans la cuisine pour cette fois ci détecter les éventuels problèmes de lave-vaisselle, de mauvais refoulement de lave-linge ou autre joint de raccord de robinetterie fatigué, voir de ballon d’eau chaude tirant sa révérence.

La base du circuit reste identique, un Atmega328p( qui utilise l’horloge interne) comme microcontrôleur, un module radio nrf24l01+ et un petit transducteur piezzo pour l’alerte sonore. La détection de l’eau se fait via l’ADC qui mesure la tension au milieu d’un pont diviseur de tension composé d’une résistance élevée de 2MΩ et d’une « résistance variable » encore plus élevée composé d’air (si tout se passe bien) ou bien plus faible composée d’eau (si la fuite se présente). Dans ce cas, la tension mesurée chute fortement et l’alerte est donnée.

 

Le circuit

Le programme

 

Pour vérifier la présence d’eau, l’ADC mesure périodiquement  la tension aux bornes du capteur. Toutes les 8 secondes, l’atmega sort de veille, effectue une mesure, donne l’alerte si nécessaire, et se rendort pour une période de 8s afin d’économiser au maximum la batterie.  La tension de la pile est envoyée tous les 105 cycles soit environ chaque quart d’heure afin d’avoir un état du capteur régulier. En cas de détection d’eau, un message radio est envoyé, et une alerte sonore se fait entendre durant une minute. Une nouvelle mesure d’eau est effectuée, si elle est toujours positive un nouveau message radio est envoyé, et l’alerte sonore repart pour une minute, et ainsi de suite tant que l’eau est toujours présente.

 

#include <LowPower.h>
#include <nRF24L01.h>
#include <printf.h>
#include <RF24.h>
#include <RF24_config.h>
#include <stdint.h>


/* COMMON CONFIG*/
#define RF24_CH 1
#define DEBUG 0
/* ------- */

#define SLEEP_B 105
#define VT_PIN 14
#define RF24_ON 6
#define LED_PIN 5

#define WATER_PIN 17
#define BUZ_PIN 15
#define MAX_DIFF 100

/* COMMON */
uint16_t nodeId = NODE_ID;
uint8_t node_address[5] = {"1Node"};
uint8_t server_address[5] = {"2Node"};
/* ------- */

RF24 radio(9,10);
uint8_t plainRadioBuffer[32] = {0};
uint16_t cntB = SLEEP_B;
int16_t waterAvg = 0;
int16_t waterDifference = 0;

void setup_radio(){
radio.begin();
radio.setChannel(RF24_CH);
radio.setDataRate(RF24_250KBPS);
radio.setPALevel(RF24_PA_MAX);
radio.setCRCLength(RF24_CRC_16);
radio.setRetries(3, 15);
radio.setAutoAck(1);
radio.openReadingPipe(1, node_address);
radio.openWritingPipe(server_address);

#if DEBUG==1
radio.printDetails();
#endif
}

void setup() {

pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);

//flash led
digitalWrite(LED_PIN, HIGH);
delay(250);
digitalWrite(LED_PIN, LOW);

analogReference(INTERNAL);

pinMode(RF24_ON, OUTPUT);
digitalWrite(RF24_ON, HIGH);

pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);

pinMode(BUZ_PIN, OUTPUT);
digitalWrite(BUZ_PIN, LOW);

//calibrate sensor
for(uint8_t i = 0 ; i < 8 ; i++)
{
waterAvg += analogRead(WATER_PIN);
delay(50);
}
waterAvg /= 8;

#if DEBUG==1
Serial.begin(115200);
printf_begin();
Serial.print("Avg: ");
Serial.println(waterAvg);
#endif

//flash led
digitalWrite(LED_PIN, HIGH);
delay(250);
digitalWrite(LED_PIN, LOW);

}


void loop() {

//Check for water
waterDifference = abs(analogRead(WATER_PIN) - waterAvg);

#if DEBUG==1
Serial.print("Diff: ");
Serial.println(waterDifference);
#endif

while(waterDifference > MAX_DIFF){
#if DEBUG==1
Serial.println("Water detected !");
#endif

memcpy(plainRadioBuffer, "FLOOD-ALERT", 11);
memset(plainRadioBuffer+11, 0, 21);


//power on radio
digitalWrite(RF24_ON, LOW);
delay(100);
setup_radio();

#if DEBUG==1
Serial.println(F("powered Up"));
#endif

radio.write(plainRadioBuffer, 32);

//power down radio
radio.powerDown();
digitalWrite(RF24_ON, HIGH);

//alarm
for(uint8_t iAlarm = 0; iAlarm < 30; ++iAlarm){
tone(BUZ_PIN, 3000, 1000);
delay(2000);
}

//Check for water again...
waterDifference = abs(analogRead(WATER_PIN) - waterAvg);
}

if(cntB >= SLEEP_B){
float voltage = analogRead(VT_PIN);
voltage = voltage * 1.1 * ((1670000.0)/470000.0) / 1024.0;

#if DEBUG==1
Serial.print(F("Voltage : "));
Serial.print(voltage);
Serial.println("V");
#endif

memcpy(plainRadioBuffer, "VOLT", 4);
memcpy(plainRadioBuffer+4, &voltage, 4);
memset(plainRadioBuffer+8, 0, 24);

//power on radio
digitalWrite(RF24_ON, LOW);
delay(100);
setup_radio();


if(radio.write(plainRadioBuffer, 32)){
cntB = 0;
}
else{
if(cntB >= (SLEEP_B+2)){
cntB = 0;
}
}

//power down radio
radio.powerDown();
digitalWrite(RF24_ON, HIGH);

}

++cntB;

//flash led
digitalWrite(LED_PIN, HIGH);
delay(25);
digitalWrite(LED_PIN, LOW);

#if DEBUG==1
Serial.println(F("Sleep for 8 seconds"));
delay(1000);
#endif
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);

}
Flood.ino

 

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *