// Images used for display #include "cat-grass.h" // cat_grass #include "catnip.h" // catnip #include "christmas-cactus.h" // christmas_cactus #include "tarragon.h" // tarragon #include "humidity.h" // humidity #include "temp_humidity.h" // temp_humidity #include "temperature.h" // temperature #include "battery_0.h" // 0% battery #include "battery_25.h" // 25% battery #include "battery_50.h" // 50% battery #include "battery_75.h" // 75% battery #include "battery_100.h" // 100% battery #include "warning.h" // warning (filled in) // Adafruit temp/humidity sensor // We are using the SHT10 // Humid accuracy +/- 5% // Steady accuracy between 10-80 // example at 10/90 +/- 6%, 0/100 +/- 7.5% #include "SHT1x.h" #define dataPin A5 #define sckPin A1 //serial clock SHT1x th_sensor(dataPin, sckPin); // 2.9" Waveshare 3-color (red) e-ink setup // mapping suggestion for Arduino DUE // BUSY -> 7, RST -> 9, DC -> 8, CS-> 77, CLK -> 76, DIN -> 75 // SPI pins are on 6 pin 2x3 SPI header // mapping suggestion for ESP32, e.g. LOLIN32, see .../variants/.../pins_arduino.h for your board // NOTE: there are variants with different pins for SPI ! CHECK SPI PINS OF YOUR BOARD // BUSY -> 21, RST -> 14, DC -> 15, CS -> 27, CLK -> SCK(5), DIN -> MOSI(18), GND -> GND, 3.3V -> 3.3V // base class GxEPD2_GFX can be used to pass references or pointers to the display instance as parameter, uses ~1.2k more code // enable or disable GxEPD2_GFX base class #define ENABLE_GxEPD2_GFX 1 #include #include #include "DejaVuSansMono-Bold.8.h" #define MAX_DISPAY_BUFFER_SIZE 15000ul // ~15k is a good compromise #define MAX_HEIGHT(EPD) (EPD::HEIGHT <= MAX_DISPAY_BUFFER_SIZE / (EPD::WIDTH / 8) ? EPD::HEIGHT : MAX_DISPAY_BUFFER_SIZE / (EPD::WIDTH / 8)) #define MAX_HEIGHT_3C(EPD) (EPD::HEIGHT <= (MAX_DISPAY_BUFFER_SIZE / 2) / (EPD::WIDTH / 8) ? EPD::HEIGHT : (MAX_DISPAY_BUFFER_SIZE / 2) / (EPD::WIDTH / 8)) //GxEPD2_3C display(GxEPD2_290c(/*CS=77*/ SS, /*DC=*/ 8, /*RST=*/ 9, /*BUSY=*/ 7)); GxEPD2_3C display(GxEPD2_290c(/*CS*/ 27, /*DC=*/ 15, /*RST=*/ 14, /*BUSY=*/ 21)); // Fuel Gauge #include "MAX17043.h" float batt_voltage; float batt_percent; // Delay cheats const unsigned long SECOND = 1000; const unsigned long HOUR = 3600 * SECOND; // Temp/Humidity reading vars float temp_c; float humid; void setup() { // Initialize Fuel Gauge FuelGauge.begin(); delay(100); FuelGauge.reset(); delay(100); FuelGauge.quickstart(); delay(100); // Initialize display display.init(115200); display.setFullWindow(); display.setRotation(1); display.setFont(&DejaVuSansMono_Bold8pt7b); display.setTextColor(GxEPD_BLACK); } void loop() { // Clear and reset display for first run display.firstPage(); display.clearScreen(); while (display.nextPage()); display.firstPage(); display.setCursor(0, 0); // Wake Fuel Gauge if (FuelGauge.isSleeping()) { FuelGauge.wake(); } // Battery Level display.println(); batt_voltage = FuelGauge.voltage(); batt_percent = FuelGauge.percent(); if (batt_percent > 95) { display.drawInvertedBitmap(0, 0, battery_100, 32, 32, GxEPD_BLACK); } else if (batt_percent > 75) { display.drawInvertedBitmap(0, 0, battery_75, 32, 32, GxEPD_BLACK); } else if (batt_percent > 50) { display.drawInvertedBitmap(0, 0, battery_50, 32, 32, GxEPD_BLACK); } else if (batt_percent > 25) { display.drawInvertedBitmap(0, 0, battery_25, 32, 32, GxEPD_RED); } else { display.drawInvertedBitmap(0, 0, battery_0, 32, 32, GxEPD_RED); } display.print(" "); display.print(batt_percent); display.print("% / "); display.print(batt_voltage); display.println("V"); // Show battery alert if active if (FuelGauge.alertIsActive()) { display.drawInvertedBitmap(265, 0, warning, 32, 32, GxEPD_RED); } // Sleep Fuel Gauge to save power FuelGauge.sleep(); // Read values from the sensor humid = th_sensor.readHumidity(); // Since the humidity reading requires the temperature we simply // retrieve the reading capture from the readHumidity() call. See the lib. temp_c = th_sensor.retrieveTemperatureC(); display.drawInvertedBitmap(0, 35, temperature, 32, 32, GxEPD_BLACK); display.println(); display.print(" "); display.print(temp_c * 9 / 5 + 32); display.print("F"); display.print(" / "); display.print(temp_c); display.println("C"); display.drawInvertedBitmap(0, 67, humidity, 32, 32, GxEPD_BLACK); display.println(); display.print(" "); display.print(humid); display.println("%"); // Draw icons for plant status display.drawInvertedBitmap(0, 96, cat_grass, 32, 32, GxEPD_BLACK); display.drawInvertedBitmap(37, 96, catnip, 32, 32, GxEPD_BLACK); display.drawInvertedBitmap(74, 96, tarragon, 32, 32, GxEPD_BLACK); display.drawInvertedBitmap(111, 96, christmas_cactus, 32, 32, GxEPD_BLACK); display.drawInvertedBitmap(148, 96, cat_grass, 32, 32, GxEPD_RED); display.drawInvertedBitmap(185, 96, catnip, 32, 32, GxEPD_RED); display.drawInvertedBitmap(222, 96, tarragon, 32, 32, GxEPD_RED); display.drawInvertedBitmap(259, 96, christmas_cactus, 32, 32, GxEPD_RED); // Flush display output while (display.nextPage()); // Hibernate the display to save power display.hibernate(); // Delay looping (deep sleep goes here in the future) delay(10*60*SECOND); }