water-sensor/water-sensor.ino

159 lines
3.5 KiB
Arduino
Raw Normal View History

2024-02-10 19:37:50 +00:00
// Board: Adafruit Feather HUZZAH ESP8266
2024-02-10 19:33:33 +00:00
#include <ArduinoMqttClient.h>
#include <ESP8266WiFi.h>
2024-02-08 21:47:49 +00:00
2024-02-10 19:33:33 +00:00
#include "secrets.h"
#define ADC_PIN A0
#define RELAY_PIN 13
#define RELAY_OFF LOW
#define RELAY_ON HIGH
#define NUM_SAMPLES 20
#define SAMPLE_TIME 100
#define WATER_THRESHOLD 750
#define MESSAGE_INTERVAL 1000 * 60 * 60 // one hour
WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);
const char broker[] = BROKER;
int port = 1883;
const char topic[] = "iot/water";
String macAddress = String(ESP.getChipId(), HEX);
String shortName = macAddress.substring(0, 4);
String deviceName = "ws_" + shortName;
2024-02-08 21:47:49 +00:00
void relayOn() {
Serial.println("Setting relay ON");
digitalWrite(RELAY_PIN, RELAY_ON);
}
void relayOff() {
Serial.println("Setting relay OFF");
digitalWrite(RELAY_PIN, RELAY_OFF);
}
bool sampleWater() {
bool waterDetected = true;
Serial.print("Samples: ");
for (int i = 0; i < NUM_SAMPLES; i++) {
int sample = analogRead(ADC_PIN);
Serial.print(sample);
Serial.print(",\t");
if (sample < WATER_THRESHOLD) {
waterDetected = false;
}
delay(SAMPLE_TIME);
}
Serial.println(waterDetected ? "POS" : "NEG");
return waterDetected;
}
2024-02-10 19:33:33 +00:00
void sendWaterLeakTrue() {
mqttClient.beginMessage(topic);
mqttClient.print("{\"id\": \"");
mqttClient.print(deviceName);
mqttClient.print("\", \"water_leak\": true}");
mqttClient.endMessage();
}
void sendWaterLeakFalse() {
mqttClient.beginMessage(topic);
mqttClient.print("{\"id\": \"");
mqttClient.print(deviceName);
mqttClient.print("\", \"water_leak\": false}");
mqttClient.endMessage();
}
2024-02-08 21:47:49 +00:00
void setup() {
2024-02-10 19:33:33 +00:00
pinMode(RELAY_PIN, OUTPUT);
2024-02-08 21:47:49 +00:00
Serial.begin(115200);
2024-02-10 19:33:33 +00:00
delay(1000);
2024-02-08 21:47:49 +00:00
Serial.println();
Serial.println();
Serial.println();
Serial.println("===== BOOT UP =====");
2024-02-10 19:33:33 +00:00
WiFi.mode(WIFI_STA);
WiFi.begin(SECRET_SSID, SECRET_PASS);
Serial.print("[WIFI] Attempting to connect to wifi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("[WIFI] Connected to the network");
Serial.println();
mqttClient.setId(deviceName);
Serial.print("[MQTT] Attempting to connect to the MQTT broker: ");
Serial.println(broker);
while (!mqttClient.connect(broker, port)) {
Serial.print("MQTT connection failed! Error code = ");
Serial.println(mqttClient.connectError());
delay(5000);
}
Serial.println("[MQTT] Connected to the MQTT broker.");
Serial.println("Turning relay on.");
2024-02-08 21:47:49 +00:00
relayOn();
}
void loop() {
2024-02-10 19:33:33 +00:00
static unsigned long last_pos_message = 0;
static unsigned long last_neg_message = 0;
bool leakDetected = sampleWater();
if (leakDetected) {
2024-02-08 21:47:49 +00:00
relayOff();
2024-02-10 19:33:33 +00:00
Serial.println("Leak detected");
}
mqttClient.poll();
if (WiFi.status() != WL_CONNECTED) {
Serial.println("[WIFI] Lost connection. Reconnecting...");
WiFi.begin(SECRET_SSID, SECRET_PASS);
return;
} else if (!mqttClient.connected()) {
Serial.print("[MQTT] Not connected! Error code = ");
Serial.println(mqttClient.connectError());
Serial.println("[MQTT] Reconnecting...");
mqttClient.connect(broker, port);
return;
}
// TODO: replace this spaghetti with a state machine
if (leakDetected) {
if (!last_pos_message || millis() - last_pos_message > MESSAGE_INTERVAL) {
last_pos_message = millis();
last_neg_message = 0;
sendWaterLeakTrue();
}
2024-02-08 21:47:49 +00:00
} else {
2024-02-10 19:33:33 +00:00
if (!last_neg_message || millis() - last_neg_message > MESSAGE_INTERVAL) {
last_pos_message = 0;
last_neg_message = millis();
sendWaterLeakFalse();
}
2024-02-08 21:47:49 +00:00
}
}