MultiSoilMoistureSensor/MultiSoilMoistureSensor.ino
2025-01-05 18:16:31 -08:00

114 lines
3.4 KiB
C++

//#include <Wire.h>
//#include <SFE_MicroOLED.h> //Click here to get the library: http://librarymanager/All#SparkFun_Micro_OLED
#include <SparkFun_Qwiic_OLED.h> // http://librarymanager/All#SparkFun_Qwiic_OLED
#include "EspMQTTClient.h" // http://librarymanager/All#EspMQTTClient https://github.com/plapointe6/EspMQTTClient
EspMQTTClient client(
"Your WiFi SSID",
"Your WiFi Password",
"192.168.1.100", // homeassistant mqtt
"espmqtt", // Can be omitted if not needed
"Your MQTT Password", // Can be omitted if not needed
"espmqtt" // Client name that uniquely identify your device
);
#define reportingInterval 10000 // how often to sample/publish, in milliseconds
#define PIN_RESET 4
#define LED_BUILTIN 0 // ESP32
//#define LED_BUILTIN 13 // Teensy
//MicroOLED oled(PIN_RESET); // The TwoWire I2C port is passed to .begin instead
QwiicMicroOLED oled;
//int plant1Pin = A0; // Teensy
int plantPin[] = {35,34,39,38}; // ESP32
int maxSensorValue = 4095; // ESP32
// Qwiic Pro Mini pins
int pin_SDA = 15;
int pin_SCL = 5;
unsigned long last_run = 0;
void onConnectionEstablished() {
client.publish("esp/status", "{\"status\": \"connected\"}");
}
// the setup function runs once when you press reset or power the board
void setup() {
Serial.begin(115200);
Serial.println("Running MultiSoilMoistureSensor on: ");
pinMode(LED_BUILTIN, OUTPUT);
// esp32 doesn't have analog pullups
// for(int i=0;i<(sizeof(plantPin)/sizeof(plantPin[0]));i++){
// pinMode(plantPin[i],INPUT_PULLUP);
// }
Serial.begin(115200);
// Wire.begin(); // Teensy
// oled.begin(0x3D, Wire);
Wire.begin(pin_SDA, pin_SCL); //Qwiic Pro Mini
if (!oled.begin()){
Serial.println("Failed to initialize OLED");
}
delay(1000); // Delay 1000 ms
}
// 0-based index read
// returns false for no water
bool readAndPublishSensor(int i) {
int n = i+1; // plant number
// maxSensorValue (1023,4095) is bad, 1 is good, 0 is no connection
int sensorValue = analogRead(plantPin[i]);
// invert the values so 1.0 is good and 0.01 or value==0 is bad
int sensorPercent = round(100.0*(maxSensorValue-sensorValue)/maxSensorValue);
if (sensorValue == 0) {
sensorPercent = 0;
}
char sensorText[32];
snprintf(sensorText, 31, "%d", sensorPercent); // send MQTT 0 thru 100
char topic[32];
snprintf(topic, 31, "esp/plants/%d", n); // 1-based plant number
client.publish(topic, sensorText);
Serial.print(topic);
Serial.print(": ");
Serial.print(sensorValue);
Serial.print(" - ");
Serial.println(sensorText);
// show on LED with 1-based plant number and 0-100%
snprintf(sensorText, 31, "%d: %d%%", n, sensorPercent);
oled.text(0, n*8, sensorText);
return sensorPercent > 50; // over 50% is true/good, under 50% is false/bad
}
// the loop function runs over and over again forever
void loop() {
unsigned long time_trigger = millis();
if (last_run == 0 || time_trigger-last_run > reportingInterval) {
oled.erase();
oled.text(0, 0, "Water:");
bool showLed = false;
// read + output plant sensors
for(int i=0;i<(sizeof(plantPin)/sizeof(plantPin[0]));i++){
if (!readAndPublishSensor(i)) {
showLed = true;
};
}
if (showLed) {
digitalWrite(LED_BUILTIN, HIGH);
} else {
digitalWrite(LED_BUILTIN, LOW);
}
oled.display();
last_run = time_trigger;
}
client.loop();
sleep(1);
}