Initial commit
This commit is contained in:
commit
4646a78a93
BIN
MultiSoilMoistureSensor.fzz
Normal file
BIN
MultiSoilMoistureSensor.fzz
Normal file
Binary file not shown.
113
MultiSoilMoistureSensor.ino
Normal file
113
MultiSoilMoistureSensor.ino
Normal file
|
@ -0,0 +1,113 @@
|
|||
//#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);
|
||||
}
|
BIN
MultiSoilMoistureSensor_bb.png
Normal file
BIN
MultiSoilMoistureSensor_bb.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 148 KiB |
75
README.md
Normal file
75
README.md
Normal file
|
@ -0,0 +1,75 @@
|
|||
# Multiple Soil Moisture Sensors with ESP32
|
||||
|
||||
## Parts
|
||||
|
||||
- ESP32 or similar low-power WiFi-enabled board. I used this: https://www.sparkfun.com/products/23386
|
||||
- Simple soil moisture sensors that are readable with either analog voltage or digital (1/0) output. There are others that use i.e. RS-485 but this guide doesn't cover that. I used these: https://www.amazon.com/dp/B0C6XGRKS5
|
||||
- Optional: Qwiic OLED screen to view moisture without another device. I used this: https://www.sparkfun.com/products/22495 however in the future I'll likely go without in order to save battery power.
|
||||
|
||||
## Code
|
||||
|
||||
See the .ino file in this repo.
|
||||
|
||||
## Installation
|
||||
|
||||
- Edit the .ino file to modify the WiFi and MQTT settings to fit your environment.
|
||||
- Set the IDE to use the "ESP32 Dev Module" board, or whatever fits your hardware.
|
||||
- Upload the code to the board. You may need to hold a button after resetting to enter into flashing mode (see the hardware instructions).
|
||||
- Plug in your moisture sensors according to this Fritzing wiring diagram (the 3-pin connectors represent the sensors; adjust accordingly to match the pins on your actual sensors. The ESP32 also may not match your ESP32; check the correct pinout for Analog Inputs):
|
||||
![MultiSoilMoistureSensor_bb.png](MultiSoilMoistureSensor_bb.png)
|
||||
- Plug the ESP32 into power if not already. Test the sensors with a piece of metal or a damp finger. The measurements should output via serial, OLED screen, and MQTT. By default it will refresh every 10 seconds, however in the future I'll likely greatly reduce this or even put the hardware into a long low-power sleep to save battery.
|
||||
- Add the following to your Home Assistant configuration (presuming you have the MQTT integration configured and running properly; use MQTT Explorer to test):
|
||||
|
||||
```
|
||||
mqtt:
|
||||
sensor:
|
||||
- name: "Plant 1 Water"
|
||||
unique_id: esp_plant1
|
||||
state_topic: "esp/plants/1"
|
||||
qos: 2
|
||||
unit_of_measurement: "%"
|
||||
device_class: moisture
|
||||
state_class: measurement
|
||||
value_template: "{{ value }}"
|
||||
- name: "Plant 2 Water"
|
||||
unique_id: esp_plant2
|
||||
state_topic: "esp/plants/2"
|
||||
qos: 2
|
||||
unit_of_measurement: "%"
|
||||
device_class: moisture
|
||||
state_class: measurement
|
||||
value_template: "{{ value }}"
|
||||
- name: "Plant 3 Water"
|
||||
unique_id: esp_plant3
|
||||
state_topic: "esp/plants/3"
|
||||
qos: 2
|
||||
unit_of_measurement: "%"
|
||||
device_class: moisture
|
||||
state_class: measurement
|
||||
value_template: "{{ value }}"
|
||||
- name: "Plant 4 Water"
|
||||
unique_id: esp_plant4
|
||||
state_topic: "esp/plants/4"
|
||||
qos: 2
|
||||
unit_of_measurement: "%"
|
||||
device_class: moisture
|
||||
state_class: measurement
|
||||
value_template: "{{ value }}"
|
||||
```
|
||||
- Restart Home Assistant.
|
||||
- Create a HA graph Card:
|
||||
```
|
||||
chart_type: line
|
||||
period: 5minute
|
||||
type: statistics-graph
|
||||
entities:
|
||||
- sensor.plant_1_water
|
||||
- sensor.plant_2_water
|
||||
- sensor.plant_3_water
|
||||
- sensor.plant_4_water
|
||||
stat_types:
|
||||
- mean
|
||||
days_to_show: 1
|
||||
```
|
||||
|
||||
PRs, suggestions, and project photos welcome!
|
Loading…
Reference in New Issue
Block a user