// https://forum.arduino.cc/t/help-please-adding-code-to-smart-plant-watering-system/1462014/
#include <Adafruit_SSD1306.h> // OLED library
#define SCREEN_WIDTH 128 // using #define to give "hard" numbers meaning
#define SCREEN_HEIGHT 64
#define OLED_RESET 4
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#include "bitmaps.h" // moved the bitmaps to their own file
#include <RTClib.h> // RTC library
RTC_DS1307 RTC;
char daysOfTheWeek[][7] = { "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT" };
const int moisture_sensor_pin[] = { 14, 15, 16, 17 }; // sensor pins A0, A1, A2, A3
const int moisture_sensor_size = sizeof(moisture_sensor_pin) / sizeof(moisture_sensor_pin[0]);
const char moisture_sensor_pin_name[][moisture_sensor_size] = { "A0", "A1", "A2", "A3" };
int moisture_sensor_value[moisture_sensor_size];
int relay_pin[] = { 6, 8, 9, 10 }; // water pump relays
bool relay_state[4]; // 1:open 0:close
int pump_pin = 4; // set water pump
int pump_state = 0; // 1:open 0:close
int button_pin = 12;
bool button_state, button_state_old; // to validate oled clearing
void setup() {
// Serial.begin(115200); // start Serial comm // uncomment if using Serial Monitor
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Adafruit OLED initialization
display.clearDisplay(); // clear OLED
display.setTextColor(WHITE); // text color
draw_elecrow(); // draw Elecrow bitmap
delay(2000);
display.clearDisplay();
for (byte i = 0; i < moisture_sensor_size; i++)
pinMode(relay_pin[i], OUTPUT); // declare relay pins as output
pinMode(pump_pin, OUTPUT); // declare pump as output
pinMode(button_pin, INPUT_PULLUP); // declare switch as input with pullup resistor
if (!RTC.begin()) {
// Serial.println("Couldn't find RTC"); // uncomment if using Serial Monitor
display.print("Couldn't find RTC");
display.display();
while (true) {}; // halt code if RTC fails
}
}
void loop() {
read_moisture_sensor(); // read the value from the moisture sensors:
water_flower(); // determine if flowers need water
button_state = digitalRead(button_pin); // check button PRESSED or RELEASED
if (button_state == LOW) { // PRESSED button
drawFlower(); // write flower state to OLED buffer
drawTempHumi(); // write temperature and humidity to OLED buffer
} else { // RELEASED button
drawtime(); // write time to OLED buffer
display.setCursor(20, 55); // write cursor location to OLED buffer
display.print("www.elecrow.com");
}
display.display(); // display OLED buffer
}
void read_moisture_sensor() { // read moisture value
for (byte i = 0; i < moisture_sensor_size; i++) { // read all sensors
moisture_sensor_value[i] = map(analogRead(moisture_sensor_pin[i]), 600, 360, 0, 100);
delay(20); // let sensor settle/debounce
if (moisture_sensor_value[i] < 0) // dryer than zero is not possible, but that's the original
moisture_sensor_value[i] = 0;
}
}
void water_flower() {
for (byte i = 0; i < moisture_sensor_size; i++) {
if (moisture_sensor_value[i] < 30) { // low moisture value
digitalWrite(relay_pin[i], HIGH);
relay_state[i] = 1;
delay(50);
if (pump_state == 0) {
digitalWrite(pump_pin, HIGH); // turn pump ON
pump_state = 1;
delay(50);
}
} else if (moisture_sensor_value[i] > 55) { // very wet
digitalWrite(relay_pin[i], LOW); // turn pump OFF
relay_state[i] = 0;
delay(50);
if ((relay_state[0] == 0) && (relay_state[1] == 0) && (relay_state[2] == 0) && (relay_state[3] == 0)) {
digitalWrite(pump_pin, LOW);
pump_state = 0;
delay(50);
}
}
}
}
void draw_elecrow(void) { // the "splash" screen
display.setCursor(20, 55); // place the OLED cursor
display.print("www.elecrow.com");
display.drawBitmap(0, 5, bitmap128x32logo, logoWidth, logoHeight, WHITE); // the bitmap
display.display();
}
void drawtime(void) {
display.clearDisplay(); // clear OLED buffer for new data
DateTime now = RTC.now(); // store the date/time in "now"
if (!RTC.isrunning()) { // if the RTC stops working after the sketch starts...
display.setCursor(5, 20);
display.print("RTC is NOT running!"); // show a warning
RTC.adjust(DateTime(__DATE__, __TIME__)); // try to reset the RTC time
display.display(); // do not stop the sketch
} else {
int oledX = 5; // the "x" offset for the OLED data, the "y" offset is hard-coded
display.setCursor(oledX + 15, 11);
display.print(now.year(), DEC);
display.setCursor(oledX + 80, 11);
display.print(daysOfTheWeek[now.dayOfTheWeek()]);
display.setCursor(oledX + 38, 11);
display.print("/"); // separate year and month
display.setCursor(oledX + 43, 11);
display.print(now.month(), DEC);
if (now.month() < 10)
oledX -= 7;
display.setCursor(oledX + 57, 11);
display.print("/"); // separate month and date
display.setCursor(oledX + 63, 11);
display.print(now.day(), DEC);
oledX = 35;
display.setCursor(oledX, 33);
display.print(now.hour(), DEC);
if (now.hour() < 10)
display.print("0"); // prefix 0 for single-digits
display.setCursor(oledX + 15, 33);
display.print(":"); // separate hour and minute
display.setCursor(oledX + 21, 33);
display.print(now.minute(), DEC);
if (now.minute() < 10)
display.print("0");
display.setCursor(oledX + 36, 33);
display.print(":");
display.setCursor(oledX + 42, 33);
if (now.second() < 10)
display.print("0");
display.print(now.second(), DEC);
}
}
void drawFlower(void) {
display.clearDisplay(); // clear OLED buffer for new data
for (byte i = 0; i < moisture_sensor_size; i++) {
if (moisture_sensor_value[i] < 30) {
display.drawBitmap(i * 32, 0, bitmap32x30badflower, 32, 30, WHITE);
} else {
display.drawBitmap(i * 32, 0, bitmap32x30goodflower, 32, 30, WHITE);
}
}
}
void drawTempHumi(void) {
for (byte i = 0; i < moisture_sensor_size; i++) {
display.setCursor(i * 32 + 23, 45);
display.print("%");
display.setCursor(i * 32 + 9, 55);
display.print(moisture_sensor_pin_name[i]);
if (moisture_sensor_value[i] < 10) {
display.setCursor(i * 32 + 14, 45);
display.print(moisture_sensor_value[i]);
} else if (moisture_sensor_value[i] < 100) {
display.setCursor(i * 32 + 7, 45);
display.print(moisture_sensor_value[i]);
} else {
moisture_sensor_value[i] = 100;
display.setCursor(i * 32 + 2, 45);
display.print(moisture_sensor_value[i]);
}
}
}Loading
ssd1306
ssd1306
pump
relays
sensors
PUSH