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 de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *