From c5d84578012ca9030c8707925926e2ae84a0ff41 Mon Sep 17 00:00:00 2001 From: Yohan Boujon Date: Thu, 14 Dec 2023 15:19:05 +0100 Subject: [PATCH 01/10] Created LedComponent object, testing basic led. --- embedded/lib/Component/Component.hpp | 4 +--- embedded/lib/Component/LedComponent.cpp | 22 +++++++++++++++++++ embedded/lib/Component/LedComponent.hpp | 28 +++++++++++++++++++++++++ embedded/platformio.ini | 5 +++-- embedded/src/main.cpp | 5 +++++ 5 files changed, 59 insertions(+), 5 deletions(-) create mode 100644 embedded/lib/Component/LedComponent.cpp create mode 100644 embedded/lib/Component/LedComponent.hpp diff --git a/embedded/lib/Component/Component.hpp b/embedded/lib/Component/Component.hpp index 344d781..b730b9f 100644 --- a/embedded/lib/Component/Component.hpp +++ b/embedded/lib/Component/Component.hpp @@ -5,9 +5,7 @@ enum class ComponentType { Digital, - Analog, - I2C, - Serial + Analog }; class Component{ diff --git a/embedded/lib/Component/LedComponent.cpp b/embedded/lib/Component/LedComponent.cpp new file mode 100644 index 0000000..e7a3673 --- /dev/null +++ b/embedded/lib/Component/LedComponent.cpp @@ -0,0 +1,22 @@ +#include "LedComponent.hpp" + +LedComponent::LedComponent(byte pin, byte pin_clock, uint8_t led_number) + : _pin(pin), _pinClock(pin_clock), _ledNumber(led_number), _led(nullptr) +{} + +LedComponent::~LedComponent() +{ + delete _led; +} + +void LedComponent::setup() +{ + _led = new ChainableLED(_pinClock,_pin,_ledNumber); +} + +void LedComponent::setColor(uint8_t led_number, Color color) +{ + if(led_number >= _ledNumber) + return; + _led->setColorRGB(led_number,color.red,color.green,color.blue); +} \ No newline at end of file diff --git a/embedded/lib/Component/LedComponent.hpp b/embedded/lib/Component/LedComponent.hpp new file mode 100644 index 0000000..c92448e --- /dev/null +++ b/embedded/lib/Component/LedComponent.hpp @@ -0,0 +1,28 @@ +#ifndef _HEADER_COMPONENT_LED +#define _HEADER_COMPONENT_LED +#include "Component.hpp" +#include + +struct Color +{ + byte red; + byte blue; + byte green; +}; + +class LedComponent +{ +public: + LedComponent(byte pin, byte pin_clock, uint8_t led_number); + ~LedComponent(); + void setup(); + void setColor(uint8_t led_number, Color color); + +private: + byte _pin; + byte _pinClock; + uint8_t _ledNumber; + ChainableLED* _led; +}; + +#endif // _HEADER_COMPONENT_LED \ No newline at end of file diff --git a/embedded/platformio.ini b/embedded/platformio.ini index 1f38097..0cdeea9 100644 --- a/embedded/platformio.ini +++ b/embedded/platformio.ini @@ -18,5 +18,6 @@ lib_deps = bbx10/DNSServer@^1.1.0 ArduinoJson olikraus/U8g2@^2.35.7 -extra_scripts = - pre:scripts/dotenv-var.py \ No newline at end of file + seeed-studio/Grove - Chainable RGB LED@^1.0.0 +extra_scripts = + pre:scripts/dotenv-var.py diff --git a/embedded/src/main.cpp b/embedded/src/main.cpp index 42de622..163f019 100644 --- a/embedded/src/main.cpp +++ b/embedded/src/main.cpp @@ -4,6 +4,7 @@ #include "ServerHandler.hpp" #include "Component.hpp" +#include "LedComponent.hpp" #include "Screen.hpp" #ifdef SSID_CLOVER @@ -14,6 +15,7 @@ #endif Component humidity(ComponentType::Analog, PIN_A0); +LedComponent led(D8,D7,2); void setup() { @@ -26,6 +28,7 @@ void setup() pinMode(D5, OUTPUT); digitalWrite(D5, LOW); + led.setup(); } void loop() @@ -34,6 +37,8 @@ void loop() auto& serverHandler = ServerHandler::GetInstance(); auto& dataHandler = DataHandler::GetInstance(); auto& screen = Display::Screen::GetInstance(); + led.setColor(0,{255,0,0}); + led.setColor(1,{0,255,0}); // Could not connect after setup: Showing screen failure if(!serverHandler.isConnected()) From c4398dbab2b53e2499ee9b2dfd3a5826290d1245 Mon Sep 17 00:00:00 2001 From: Yohan Boujon Date: Thu, 14 Dec 2023 16:28:59 +0100 Subject: [PATCH 02/10] Added DHT sensor library, Created DHTComponent. --- embedded/lib/Component/DHTComponent.cpp | 28 +++++++++++++++++++++++++ embedded/lib/Component/DHTComponent.hpp | 23 ++++++++++++++++++++ embedded/platformio.ini | 1 + embedded/src/main.cpp | 21 +++++++------------ 4 files changed, 60 insertions(+), 13 deletions(-) create mode 100644 embedded/lib/Component/DHTComponent.cpp create mode 100644 embedded/lib/Component/DHTComponent.hpp diff --git a/embedded/lib/Component/DHTComponent.cpp b/embedded/lib/Component/DHTComponent.cpp new file mode 100644 index 0000000..76e98ee --- /dev/null +++ b/embedded/lib/Component/DHTComponent.cpp @@ -0,0 +1,28 @@ +#include "DHTComponent.hpp" + +DHTComponent::DHTComponent(uint8_t type, byte pin) + : _pin(pin), _type(type), _dht(nullptr) +{} + +DHTComponent::~DHTComponent() +{ + delete _dht; +} + +void DHTComponent::setup() +{ + _dht = new DHT_Unified(_pin, _type); + _dht->begin(); +} + +float DHTComponent::getHumidity() +{ + _dht->humidity().getEvent(&_event); + return _event.relative_humidity; +} + +float DHTComponent::getTemperature() +{ + _dht->temperature().getEvent(&_event); + return _event.temperature; +} diff --git a/embedded/lib/Component/DHTComponent.hpp b/embedded/lib/Component/DHTComponent.hpp new file mode 100644 index 0000000..0421ecf --- /dev/null +++ b/embedded/lib/Component/DHTComponent.hpp @@ -0,0 +1,23 @@ +#ifndef _HEADER_COMPONENT_DHT +#define _HEADER_COMPONENT_DHT +#include +#include +#include + +class DHTComponent +{ +public: + DHTComponent(uint8_t type, byte pin); + ~DHTComponent(); + void setup(); + float getHumidity(); + float getTemperature(); + +private: + byte _pin; + uint8_t _type; + DHT_Unified* _dht; + sensors_event_t _event; +}; + +#endif // _HEADER_COMPONENT_LED \ No newline at end of file diff --git a/embedded/platformio.ini b/embedded/platformio.ini index 0cdeea9..45b3c04 100644 --- a/embedded/platformio.ini +++ b/embedded/platformio.ini @@ -19,5 +19,6 @@ lib_deps = ArduinoJson olikraus/U8g2@^2.35.7 seeed-studio/Grove - Chainable RGB LED@^1.0.0 + adafruit/DHT sensor library@^1.4.6 extra_scripts = pre:scripts/dotenv-var.py diff --git a/embedded/src/main.cpp b/embedded/src/main.cpp index 163f019..2ba7f24 100644 --- a/embedded/src/main.cpp +++ b/embedded/src/main.cpp @@ -5,6 +5,7 @@ #include "ServerHandler.hpp" #include "Component.hpp" #include "LedComponent.hpp" +#include "DHTComponent.hpp" #include "Screen.hpp" #ifdef SSID_CLOVER @@ -16,6 +17,7 @@ Component humidity(ComponentType::Analog, PIN_A0); LedComponent led(D8,D7,2); +DHTComponent airSensor(DHT11,D3); void setup() { @@ -25,10 +27,8 @@ void setup() Serial.print("Connected to WiFi. IP address: "); Serial.println(WiFi.localIP()); - - pinMode(D5, OUTPUT); - digitalWrite(D5, LOW); led.setup(); + airSensor.setup(); } void loop() @@ -37,8 +37,8 @@ void loop() auto& serverHandler = ServerHandler::GetInstance(); auto& dataHandler = DataHandler::GetInstance(); auto& screen = Display::Screen::GetInstance(); - led.setColor(0,{255,0,0}); - led.setColor(1,{0,255,0}); + led.setColor(0,{32,0,0}); + led.setColor(1,{0,32,0}); // Could not connect after setup: Showing screen failure if(!serverHandler.isConnected()) @@ -66,8 +66,8 @@ void loop() // Data gathered from various sensors // 0 -> air(0), 0-300 -> dry(20), 300-700 -> humid (580), 700-950 -> water(940) auto soilHumidityData = static_cast(std::any_cast(humidity.getValue())); - auto airTemperatureData = random(150, 300) / 10.0; - auto airHumidityData = random(0, 1000) / 10.0; + auto airTemperatureData = airSensor.getTemperature(); + auto airHumidityData = airSensor.getHumidity(); auto lightData = random(0, 1000) / 10.0; // Updating the data handler @@ -79,18 +79,13 @@ void loop() // Screen showing screen.loop(soilHumidityData,airTemperatureData,airHumidityData,lightData); + // TODO: Add LedComponent management if (soilHumidityData < 550) { Serial.println("Soil humidity low. Please water the plant."); - digitalWrite(D5, HIGH); } else if (soilHumidityData >= 550 && soilHumidityData <= 680) { Serial.println("Idle..."); - digitalWrite(D5, LOW); } else { Serial.println("Soil too wet."); - digitalWrite(D5, LOW); - delay(400); - digitalWrite(D5, HIGH); - delay(400); } serverHandler.loop(); From 820494206d864c22d99b51347480d09b875ba41c Mon Sep 17 00:00:00 2001 From: Yohan Boujon Date: Fri, 15 Dec 2023 22:19:26 +0100 Subject: [PATCH 03/10] Deleted unused light. Setting the lights to off when booting. --- embedded/lib/Display/Screen.cpp | 3 +-- embedded/lib/Display/Screen.hpp | 2 +- embedded/src/main.cpp | 9 ++++++--- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/embedded/lib/Display/Screen.cpp b/embedded/lib/Display/Screen.cpp index 22af48d..08dd4bf 100644 --- a/embedded/lib/Display/Screen.cpp +++ b/embedded/lib/Display/Screen.cpp @@ -128,14 +128,13 @@ void Screen::boot() _screen->sendBuffer(); } -void Screen::loop(const float plantHumidity, const float airTemperature, const float airHumidity, const float light) +void Screen::loop(const float plantHumidity, const float airTemperature, const float airHumidity) { _screen->clearBuffer(); // Updating with values loopWindow.Update(0,String("Hum: ")+String(plantHumidity,1)+String("%")); loopWindow.Update(1,String("Tem: ")+String(airTemperature,1)+String("°C")); loopWindow.Update(2,String("Hum: ")+String(airHumidity,1)+String("%")); - //loopWindow.Update(3,String("Light: ")+String(light,1)+String("%")); // Component loopWindow.Display(); iconWindow.Display(); diff --git a/embedded/lib/Display/Screen.hpp b/embedded/lib/Display/Screen.hpp index c92c9c5..648bbe6 100644 --- a/embedded/lib/Display/Screen.hpp +++ b/embedded/lib/Display/Screen.hpp @@ -54,7 +54,7 @@ namespace Display void notConnected(); void connected(const char *ipaddress, uint8_t timing); void boot(); - void loop(const float plantHumidity, const float airTemperature, const float airHumidity, const float light); + void loop(const float plantHumidity, const float airTemperature, const float airHumidity); // Getters uint16_t getHeight(); uint16_t getWidth(); diff --git a/embedded/src/main.cpp b/embedded/src/main.cpp index 2ba7f24..9223e9e 100644 --- a/embedded/src/main.cpp +++ b/embedded/src/main.cpp @@ -29,6 +29,10 @@ void setup() Serial.println(WiFi.localIP()); led.setup(); airSensor.setup(); + + // Lights are off when powered + led.setColor(0,{0,0,0}); + led.setColor(1,{0,0,0}); } void loop() @@ -68,16 +72,14 @@ void loop() auto soilHumidityData = static_cast(std::any_cast(humidity.getValue())); auto airTemperatureData = airSensor.getTemperature(); auto airHumidityData = airSensor.getHumidity(); - auto lightData = random(0, 1000) / 10.0; // Updating the data handler dataHandler.updateSoilMoistureData(soilHumidityData); dataHandler.updateAirTemperatureData(airTemperatureData); dataHandler.updateAirHumidityData(airHumidityData); - dataHandler.updateLightData(lightData); // Screen showing - screen.loop(soilHumidityData,airTemperatureData,airHumidityData,lightData); + screen.loop((soilHumidityData/950.0f)*100.0f,airTemperatureData,airHumidityData); // TODO: Add LedComponent management if (soilHumidityData < 550) { @@ -86,6 +88,7 @@ void loop() Serial.println("Idle..."); } else { Serial.println("Soil too wet."); + Serial.println("Soil too wet."); } serverHandler.loop(); From ab0c2ca48cc5b82716046796f150445443367b05 Mon Sep 17 00:00:00 2001 From: Yohan Boujon Date: Fri, 15 Dec 2023 22:19:45 +0100 Subject: [PATCH 04/10] Led Off: Quick Fix --- embedded/src/main.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/embedded/src/main.cpp b/embedded/src/main.cpp index 9223e9e..4dc913d 100644 --- a/embedded/src/main.cpp +++ b/embedded/src/main.cpp @@ -21,18 +21,20 @@ DHTComponent airSensor(DHT11,D3); void setup() { - Serial.begin(9600); - Display::Screen::GetInstance().Setup(const_cast(u8g2_font_busdisplay8x5_tr)); - ServerHandler::GetInstance().setup(ssid, pswd); - - Serial.print("Connected to WiFi. IP address: "); - Serial.println(WiFi.localIP()); + // Sensors/Acuators setup led.setup(); airSensor.setup(); - // Lights are off when powered led.setColor(0,{0,0,0}); led.setColor(1,{0,0,0}); + + // Setup for screen and server + Serial.begin(9600); + Display::Screen::GetInstance().Setup(const_cast(u8g2_font_busdisplay8x5_tr)); + ServerHandler::GetInstance().setup(ssid, pswd); + // Printing server data + Serial.print("Connected to WiFi. IP address: "); + Serial.println(WiFi.localIP()); } void loop() From d4de1f6efb589e6adf5fc2a52b34a212500abb6a Mon Sep 17 00:00:00 2001 From: Yohan Boujon Date: Fri, 15 Dec 2023 23:21:27 +0100 Subject: [PATCH 05/10] Deleted Exception in platformio config. Added ServerException (dead code). Created MainComponent singleton. --- embedded/lib/Component/MainComponent.cpp | 19 +++++++++++ embedded/lib/Component/MainComponent.hpp | 34 +++++++++++++++++++ .../lib/ServerHandler/ServerException.hpp | 22 ++++++++++++ embedded/platformio.ini | 3 +- embedded/src/main.cpp | 20 ++++------- 5 files changed, 83 insertions(+), 15 deletions(-) create mode 100644 embedded/lib/Component/MainComponent.cpp create mode 100644 embedded/lib/Component/MainComponent.hpp create mode 100644 embedded/lib/ServerHandler/ServerException.hpp diff --git a/embedded/lib/Component/MainComponent.cpp b/embedded/lib/Component/MainComponent.cpp new file mode 100644 index 0000000..2ed38c5 --- /dev/null +++ b/embedded/lib/Component/MainComponent.cpp @@ -0,0 +1,19 @@ +#include "MainComponent.hpp" + +MainComponent::MainComponent() + : _humidity(ComponentType::Analog, PIN_A0), _led(D8, D7, 2), _dht(DHT11, D3) +{ +} + +MainComponent::~MainComponent() +{} + +void MainComponent::setup() +{ + _led.setup(); + _dht.setup(); +} + +Component& MainComponent::getHumidity() { return _humidity; } +LedComponent& MainComponent::getLed() { return _led; } +DHTComponent& MainComponent::getDHT() { return _dht; } diff --git a/embedded/lib/Component/MainComponent.hpp b/embedded/lib/Component/MainComponent.hpp new file mode 100644 index 0000000..e7dfe87 --- /dev/null +++ b/embedded/lib/Component/MainComponent.hpp @@ -0,0 +1,34 @@ +#ifndef _HEADER_COMPONENT_MAIN +#define _HEADER_COMPONENT_MAIN + +#include "Component.hpp" +#include "LedComponent.hpp" +#include "DHTComponent.hpp" + +class MainComponent { +public: + // Singleton + static MainComponent& GetInstance() + { + static MainComponent instance; + return instance; + } + // Public functions + void setup(); + Component& getHumidity(); + LedComponent& getLed(); + DHTComponent& getDHT(); +private: + // Singleton + MainComponent(); + ~MainComponent(); + MainComponent(const MainComponent&) = delete; + MainComponent& operator=(const MainComponent&) = delete; + + // Components + Component _humidity; + LedComponent _led; + DHTComponent _dht; +}; + +#endif // \ No newline at end of file diff --git a/embedded/lib/ServerHandler/ServerException.hpp b/embedded/lib/ServerHandler/ServerException.hpp new file mode 100644 index 0000000..d9564a0 --- /dev/null +++ b/embedded/lib/ServerHandler/ServerException.hpp @@ -0,0 +1,22 @@ +#ifndef _HEADER_SERVER_EXCEPTION +#define _HEADER_SERVER_EXCEPTION +#include +#include +#include "ServerException.hpp" + +class ServerException : public std::exception +{ + public: + ServerException(const char* msg, uint8_t code) + : _msg(msg), _code(code) + { + } + + uint8_t code() { return _code; } + const char* what() { return _msg; } + private: + const char* _msg; + uint8_t _code; +}; + +#endif // _HEADER_SERVER_EXCEPTION \ No newline at end of file diff --git a/embedded/platformio.ini b/embedded/platformio.ini index 45b3c04..b4fe499 100644 --- a/embedded/platformio.ini +++ b/embedded/platformio.ini @@ -11,7 +11,8 @@ [env:nodemcuv2] platform = espressif8266 board = nodemcuv2 -build_flags = -fexceptions +build_flags = + -std=c++11 framework = arduino lib_deps = tzapu/WiFiManager@^0.16.0 diff --git a/embedded/src/main.cpp b/embedded/src/main.cpp index 4dc913d..7f67a90 100644 --- a/embedded/src/main.cpp +++ b/embedded/src/main.cpp @@ -3,9 +3,7 @@ #include #include "ServerHandler.hpp" -#include "Component.hpp" -#include "LedComponent.hpp" -#include "DHTComponent.hpp" +#include "MainComponent.hpp" #include "Screen.hpp" #ifdef SSID_CLOVER @@ -15,16 +13,12 @@ const char* pswd = PSWD_CLOVER; #endif -Component humidity(ComponentType::Analog, PIN_A0); -LedComponent led(D8,D7,2); -DHTComponent airSensor(DHT11,D3); - void setup() { // Sensors/Acuators setup - led.setup(); - airSensor.setup(); + MainComponent::GetInstance().setup(); // Lights are off when powered + auto& led = MainComponent::GetInstance().getLed(); led.setColor(0,{0,0,0}); led.setColor(1,{0,0,0}); @@ -43,8 +37,6 @@ void loop() auto& serverHandler = ServerHandler::GetInstance(); auto& dataHandler = DataHandler::GetInstance(); auto& screen = Display::Screen::GetInstance(); - led.setColor(0,{32,0,0}); - led.setColor(1,{0,32,0}); // Could not connect after setup: Showing screen failure if(!serverHandler.isConnected()) @@ -71,9 +63,9 @@ void loop() // Data gathered from various sensors // 0 -> air(0), 0-300 -> dry(20), 300-700 -> humid (580), 700-950 -> water(940) - auto soilHumidityData = static_cast(std::any_cast(humidity.getValue())); - auto airTemperatureData = airSensor.getTemperature(); - auto airHumidityData = airSensor.getHumidity(); + auto soilHumidityData = static_cast(std::any_cast(MainComponent::GetInstance().getHumidity().getValue())); + auto airTemperatureData = MainComponent::GetInstance().getDHT().getTemperature(); + auto airHumidityData = MainComponent::GetInstance().getDHT().getHumidity(); // Updating the data handler dataHandler.updateSoilMoistureData(soilHumidityData); From 8b610a9dcc7464635ef23a07b0dfcb1120d57fd1 Mon Sep 17 00:00:00 2001 From: Yohan Boujon Date: Sat, 16 Dec 2023 00:31:58 +0100 Subject: [PATCH 06/10] LedComponent: Added operator, LedColors namespace with multiple constexpres, Added fading function. ServerHandler: Blinking led when connecting, and status led after. --- embedded/lib/Component/LedComponent.cpp | 32 +++++++++++++++++--- embedded/lib/Component/LedComponent.hpp | 10 ++++++ embedded/lib/Component/MainComponent.cpp | 3 ++ embedded/lib/Display/Screen.cpp | 6 ++++ embedded/lib/ServerHandler/ServerHandler.cpp | 20 +++++++++++- embedded/src/main.cpp | 5 +-- 6 files changed, 67 insertions(+), 9 deletions(-) diff --git a/embedded/lib/Component/LedComponent.cpp b/embedded/lib/Component/LedComponent.cpp index e7a3673..16c944d 100644 --- a/embedded/lib/Component/LedComponent.cpp +++ b/embedded/lib/Component/LedComponent.cpp @@ -1,8 +1,17 @@ #include "LedComponent.hpp" +Color Color::operator-(byte value) +{ + byte nullbyte(0); + return {(this->red - value) < 0 ? nullbyte : static_cast(this->red - value), + (this->blue - value) < 0 ? nullbyte : static_cast(this->blue - value), + (this->green - value) < 0 ? nullbyte : static_cast(this->green - value)}; +} + LedComponent::LedComponent(byte pin, byte pin_clock, uint8_t led_number) : _pin(pin), _pinClock(pin_clock), _ledNumber(led_number), _led(nullptr) -{} +{ +} LedComponent::~LedComponent() { @@ -11,12 +20,27 @@ LedComponent::~LedComponent() void LedComponent::setup() { - _led = new ChainableLED(_pinClock,_pin,_ledNumber); + _led = new ChainableLED(_pinClock, _pin, _ledNumber); } void LedComponent::setColor(uint8_t led_number, Color color) { - if(led_number >= _ledNumber) + if (led_number >= _ledNumber) return; - _led->setColorRGB(led_number,color.red,color.green,color.blue); + _led->setColorRGB(led_number, color.red, color.green, color.blue); +} + +void LedComponent::setColor(uint8_t led_number, Color color, uint16_t fading_time) +{ + if (led_number >= _ledNumber) + return; + const auto redFade = color.red / (static_cast(fading_time)); + const auto greenFade = color.green / (static_cast(fading_time)); + const auto blueFade = color.blue / (static_cast(fading_time)); + + for (uint16_t time(0); time < fading_time; time++) + { + _led->setColorRGB(led_number, static_cast(redFade * time), static_cast(greenFade * time), static_cast(blueFade * time)); + delay(1); + } } \ No newline at end of file diff --git a/embedded/lib/Component/LedComponent.hpp b/embedded/lib/Component/LedComponent.hpp index c92448e..e84ad06 100644 --- a/embedded/lib/Component/LedComponent.hpp +++ b/embedded/lib/Component/LedComponent.hpp @@ -8,8 +8,17 @@ struct Color byte red; byte blue; byte green; + + Color operator-(byte value); }; +namespace LedColors +{ + constexpr Color LED_OFF = {0,0,0}; + constexpr Color WIFI_ON = {0x18,0x28,0x36}; + constexpr Color NO_WIFI = {0x64,0x04,0x0B}; +} + class LedComponent { public: @@ -17,6 +26,7 @@ public: ~LedComponent(); void setup(); void setColor(uint8_t led_number, Color color); + void setColor(uint8_t led_number, Color color, uint16_t fading_time); private: byte _pin; diff --git a/embedded/lib/Component/MainComponent.cpp b/embedded/lib/Component/MainComponent.cpp index 2ed38c5..2247445 100644 --- a/embedded/lib/Component/MainComponent.cpp +++ b/embedded/lib/Component/MainComponent.cpp @@ -12,6 +12,9 @@ void MainComponent::setup() { _led.setup(); _dht.setup(); + // Lights are off when powered + _led.setColor(0,{0,0,0}); + _led.setColor(1,{0,0,0}); } Component& MainComponent::getHumidity() { return _humidity; } diff --git a/embedded/lib/Display/Screen.cpp b/embedded/lib/Display/Screen.cpp index 08dd4bf..712baf9 100644 --- a/embedded/lib/Display/Screen.cpp +++ b/embedded/lib/Display/Screen.cpp @@ -1,4 +1,6 @@ #include "Screen.hpp" + +#include "MainComponent.hpp" #include #include @@ -126,6 +128,10 @@ void Screen::boot() _bootFrame++; bootWindow.Update(0,CLOVER_FRAMES[(_bootFrame >= 10 ? 10 : _bootFrame)]); _screen->sendBuffer(); + + // Shutting down led when finished booting + if(_bootFrame == MAX_BOOT_FRAMES) + MainComponent::GetInstance().getLed().setColor(0,LedColors::LED_OFF); } void Screen::loop(const float plantHumidity, const float airTemperature, const float airHumidity) diff --git a/embedded/lib/ServerHandler/ServerHandler.cpp b/embedded/lib/ServerHandler/ServerHandler.cpp index 765a527..ffc9158 100644 --- a/embedded/lib/ServerHandler/ServerHandler.cpp +++ b/embedded/lib/ServerHandler/ServerHandler.cpp @@ -1,6 +1,15 @@ #include "ServerHandler.hpp" + +#include "MainComponent.hpp" #include "../Display/Screen.hpp" +inline void led_blink(LedComponent& led) +{ + led.setColor(0,LedColors::WIFI_ON); + delay(50); + led.setColor(0,LedColors::LED_OFF); +} + ServerHandler::ServerHandler() : server(80), display_time(0), _connected(false) { } @@ -11,13 +20,17 @@ void ServerHandler::setup(const char *ssid, const char *password) { // On utilise les scope resolution operator pour définir les méthodes la classe ServerHandle qui elle est dans hpp uint8_t state(0); uint16_t tryConnection(0); + auto& led = MainComponent::GetInstance().getLed(); Serial.begin(9600); WiFi.begin(ssid, password); // Testing connection while ((WiFi.status() != WL_CONNECTED) && (tryConnection < MAX_CONNECT_TRIES)) { - delay(500); + led_blink(led); + delay(50); + led_blink(led); + delay(350); Display::Screen::GetInstance().connecting(state); state >= 3 ? state = 0 : state++; tryConnection++; @@ -26,10 +39,15 @@ void ServerHandler::setup(const char *ssid, const char *password) if (tryConnection < MAX_CONNECT_TRIES) { _connected = true; + auto color = LedColors::WIFI_ON; + led.setColor(0,color-15,200); server.begin(); server.on("/", [this]() { this->handleRoot(); }); // fonction lamda pour gérer les requettes get } + else { + led.setColor(0,LedColors::NO_WIFI,200); + } } void ServerHandler::loop() diff --git a/embedded/src/main.cpp b/embedded/src/main.cpp index 7f67a90..dfa4c8e 100644 --- a/embedded/src/main.cpp +++ b/embedded/src/main.cpp @@ -17,15 +17,12 @@ void setup() { // Sensors/Acuators setup MainComponent::GetInstance().setup(); - // Lights are off when powered - auto& led = MainComponent::GetInstance().getLed(); - led.setColor(0,{0,0,0}); - led.setColor(1,{0,0,0}); // Setup for screen and server Serial.begin(9600); Display::Screen::GetInstance().Setup(const_cast(u8g2_font_busdisplay8x5_tr)); ServerHandler::GetInstance().setup(ssid, pswd); + // Printing server data Serial.print("Connected to WiFi. IP address: "); Serial.println(WiFi.localIP()); From 097209773386bea83bbb40ed7d3c753a7ec1f730 Mon Sep 17 00:00:00 2001 From: Yohan Boujon Date: Mon, 18 Dec 2023 19:25:52 +0100 Subject: [PATCH 07/10] HotFix LedComponent: Inverted Green and Blue channels. Added LedNumber Enumeration. setColor() now calls this enum. --- embedded/lib/Component/LedComponent.cpp | 12 ++++-------- embedded/lib/Component/LedComponent.hpp | 13 ++++++++++--- embedded/lib/Component/MainComponent.cpp | 4 ++-- embedded/lib/Display/Screen.cpp | 2 +- embedded/lib/ServerHandler/ServerHandler.cpp | 8 ++++---- 5 files changed, 21 insertions(+), 18 deletions(-) diff --git a/embedded/lib/Component/LedComponent.cpp b/embedded/lib/Component/LedComponent.cpp index 16c944d..8d482dc 100644 --- a/embedded/lib/Component/LedComponent.cpp +++ b/embedded/lib/Component/LedComponent.cpp @@ -23,24 +23,20 @@ void LedComponent::setup() _led = new ChainableLED(_pinClock, _pin, _ledNumber); } -void LedComponent::setColor(uint8_t led_number, Color color) +void LedComponent::setColor(LedNumber led_number, Color color) { - if (led_number >= _ledNumber) - return; - _led->setColorRGB(led_number, color.red, color.green, color.blue); + _led->setColorRGB(static_cast(led_number), color.red, color.green, color.blue); } -void LedComponent::setColor(uint8_t led_number, Color color, uint16_t fading_time) +void LedComponent::setColor(LedNumber led_number, Color color, uint16_t fading_time) { - if (led_number >= _ledNumber) - return; const auto redFade = color.red / (static_cast(fading_time)); const auto greenFade = color.green / (static_cast(fading_time)); const auto blueFade = color.blue / (static_cast(fading_time)); for (uint16_t time(0); time < fading_time; time++) { - _led->setColorRGB(led_number, static_cast(redFade * time), static_cast(greenFade * time), static_cast(blueFade * time)); + _led->setColorRGB(static_cast(led_number), static_cast(redFade * time), static_cast(greenFade * time), static_cast(blueFade * time)); delay(1); } } \ No newline at end of file diff --git a/embedded/lib/Component/LedComponent.hpp b/embedded/lib/Component/LedComponent.hpp index e84ad06..6b5380c 100644 --- a/embedded/lib/Component/LedComponent.hpp +++ b/embedded/lib/Component/LedComponent.hpp @@ -6,8 +6,8 @@ struct Color { byte red; - byte blue; byte green; + byte blue; Color operator-(byte value); }; @@ -17,16 +17,23 @@ namespace LedColors constexpr Color LED_OFF = {0,0,0}; constexpr Color WIFI_ON = {0x18,0x28,0x36}; constexpr Color NO_WIFI = {0x64,0x04,0x0B}; + constexpr Color TOO_DRY = {0xB3,0x58,0x1B}; + constexpr Color TOO_WET = {0x1B,0x09,0x3F}; } +enum class LedNumber { + LED_HARDWARE = 0, + LED_PLANT = 1 +}; + class LedComponent { public: LedComponent(byte pin, byte pin_clock, uint8_t led_number); ~LedComponent(); void setup(); - void setColor(uint8_t led_number, Color color); - void setColor(uint8_t led_number, Color color, uint16_t fading_time); + void setColor(LedNumber led_number, Color color); + void setColor(LedNumber led_number, Color color, uint16_t fading_time); private: byte _pin; diff --git a/embedded/lib/Component/MainComponent.cpp b/embedded/lib/Component/MainComponent.cpp index 2247445..da5053c 100644 --- a/embedded/lib/Component/MainComponent.cpp +++ b/embedded/lib/Component/MainComponent.cpp @@ -13,8 +13,8 @@ void MainComponent::setup() _led.setup(); _dht.setup(); // Lights are off when powered - _led.setColor(0,{0,0,0}); - _led.setColor(1,{0,0,0}); + _led.setColor(LedNumber::LED_HARDWARE,{0,0,0}); + _led.setColor(LedNumber::LED_PLANT,{0,0,0}); } Component& MainComponent::getHumidity() { return _humidity; } diff --git a/embedded/lib/Display/Screen.cpp b/embedded/lib/Display/Screen.cpp index 712baf9..ddcfb54 100644 --- a/embedded/lib/Display/Screen.cpp +++ b/embedded/lib/Display/Screen.cpp @@ -131,7 +131,7 @@ void Screen::boot() // Shutting down led when finished booting if(_bootFrame == MAX_BOOT_FRAMES) - MainComponent::GetInstance().getLed().setColor(0,LedColors::LED_OFF); + MainComponent::GetInstance().getLed().setColor(LedNumber::LED_HARDWARE,LedColors::LED_OFF); } void Screen::loop(const float plantHumidity, const float airTemperature, const float airHumidity) diff --git a/embedded/lib/ServerHandler/ServerHandler.cpp b/embedded/lib/ServerHandler/ServerHandler.cpp index ffc9158..4fe00af 100644 --- a/embedded/lib/ServerHandler/ServerHandler.cpp +++ b/embedded/lib/ServerHandler/ServerHandler.cpp @@ -5,9 +5,9 @@ inline void led_blink(LedComponent& led) { - led.setColor(0,LedColors::WIFI_ON); + led.setColor(LedNumber::LED_HARDWARE,LedColors::WIFI_ON); delay(50); - led.setColor(0,LedColors::LED_OFF); + led.setColor(LedNumber::LED_HARDWARE,LedColors::LED_OFF); } ServerHandler::ServerHandler() : server(80), display_time(0), _connected(false) @@ -40,13 +40,13 @@ void ServerHandler::setup(const char *ssid, const char *password) { _connected = true; auto color = LedColors::WIFI_ON; - led.setColor(0,color-15,200); + led.setColor(LedNumber::LED_HARDWARE,color-15,200); server.begin(); server.on("/", [this]() { this->handleRoot(); }); // fonction lamda pour gérer les requettes get } else { - led.setColor(0,LedColors::NO_WIFI,200); + led.setColor(LedNumber::LED_HARDWARE,LedColors::NO_WIFI,200); } } From f268f00f5005443d5a4c97fb6ca4f8e85eb5d308 Mon Sep 17 00:00:00 2001 From: Yohan Boujon Date: Mon, 18 Dec 2023 19:26:24 +0100 Subject: [PATCH 08/10] Added Moisture status, which change the plant led depending on the humidity state. --- embedded/src/main.cpp | 36 ++++++++++++++---------------------- embedded/src/moisture.cpp | 24 ++++++++++++++++++++++++ embedded/src/moisture.hpp | 24 ++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 22 deletions(-) create mode 100644 embedded/src/moisture.cpp create mode 100644 embedded/src/moisture.hpp diff --git a/embedded/src/main.cpp b/embedded/src/main.cpp index dfa4c8e..a440ee2 100644 --- a/embedded/src/main.cpp +++ b/embedded/src/main.cpp @@ -5,12 +5,13 @@ #include "ServerHandler.hpp" #include "MainComponent.hpp" #include "Screen.hpp" +#include "moisture.hpp" #ifdef SSID_CLOVER - const char* ssid = SSID_CLOVER; +const char *ssid = SSID_CLOVER; #endif #ifdef PSWD_CLOVER - const char* pswd = PSWD_CLOVER; +const char *pswd = PSWD_CLOVER; #endif void setup() @@ -20,9 +21,9 @@ void setup() // Setup for screen and server Serial.begin(9600); - Display::Screen::GetInstance().Setup(const_cast(u8g2_font_busdisplay8x5_tr)); + Display::Screen::GetInstance().Setup(const_cast(u8g2_font_busdisplay8x5_tr)); ServerHandler::GetInstance().setup(ssid, pswd); - + // Printing server data Serial.print("Connected to WiFi. IP address: "); Serial.println(WiFi.localIP()); @@ -31,19 +32,19 @@ void setup() void loop() { // Creating variables to access singletons - auto& serverHandler = ServerHandler::GetInstance(); - auto& dataHandler = DataHandler::GetInstance(); - auto& screen = Display::Screen::GetInstance(); + auto &serverHandler = ServerHandler::GetInstance(); + auto &dataHandler = DataHandler::GetInstance(); + auto &screen = Display::Screen::GetInstance(); // Could not connect after setup: Showing screen failure - if(!serverHandler.isConnected()) + if (!serverHandler.isConnected()) { screen.notConnected(); return; } // Server showing IP - if(!serverHandler.showBoot()) + if (!serverHandler.showBoot()) { serverHandler.showIp(); delay(250); @@ -51,7 +52,7 @@ void loop() } // When Screen can boot (isBooting) and Server finished showing IP (showBoot) - if(screen.isBooting() && serverHandler.showBoot()) + if (screen.isBooting() && serverHandler.showBoot()) { screen.boot(); delay(100); @@ -69,18 +70,9 @@ void loop() dataHandler.updateAirTemperatureData(airTemperatureData); dataHandler.updateAirHumidityData(airHumidityData); - // Screen showing - screen.loop((soilHumidityData/950.0f)*100.0f,airTemperatureData,airHumidityData); - - // TODO: Add LedComponent management - if (soilHumidityData < 550) { - Serial.println("Soil humidity low. Please water the plant."); - } else if (soilHumidityData >= 550 && soilHumidityData <= 680) { - Serial.println("Idle..."); - } else { - Serial.println("Soil too wet."); - Serial.println("Soil too wet."); - } + // Showing screen + screen.loop((soilHumidityData / 950.0f) * 100.0f, airTemperatureData, airHumidityData); + plantLedLoop(soilHumidityData); serverHandler.loop(); } \ No newline at end of file diff --git a/embedded/src/moisture.cpp b/embedded/src/moisture.cpp new file mode 100644 index 0000000..bbddea6 --- /dev/null +++ b/embedded/src/moisture.cpp @@ -0,0 +1,24 @@ +#include "moisture.hpp" + +LedMoistureStatus moisture_status(LedMoistureStatus::IDLE); + +void plantLedLoop(float soilHumidity) +{ + auto& led = MainComponent::GetInstance().getLed(); + + if ((soilHumidity < MoistureLevel::DRY) && (moisture_status == LedMoistureStatus::IDLE)) + { + moisture_status = LedMoistureStatus::WARNING; + led.setColor(LedNumber::LED_PLANT,LedColors::TOO_DRY,200); + } + else if (soilHumidity >= MoistureLevel::DRY && soilHumidity < MoistureLevel::HUMID) + { + led.setColor(LedNumber::LED_PLANT,LedColors::LED_OFF); + moisture_status = LedMoistureStatus::IDLE; + } + else if (moisture_status == LedMoistureStatus::IDLE) + { + moisture_status = LedMoistureStatus::WARNING; + led.setColor(LedNumber::LED_PLANT,LedColors::TOO_WET,200); + } +} \ No newline at end of file diff --git a/embedded/src/moisture.hpp b/embedded/src/moisture.hpp new file mode 100644 index 0000000..f1c0aa0 --- /dev/null +++ b/embedded/src/moisture.hpp @@ -0,0 +1,24 @@ +#ifndef _HEADER_MOISTURE +#define _HEADER_MOISTURE + +#include "MainComponent.hpp" +#include + +/** + * @brief See the documentation on 'https://www.mouser.com/datasheet/2/744/Seeed_101020008-1217463.pdf' + */ +namespace MoistureLevel { + constexpr uint16_t AIR = 0; + constexpr uint16_t DRY = 300; + constexpr uint16_t HUMID = 700; + constexpr uint16_t WATER = 950; +} + +enum class LedMoistureStatus { + IDLE, + WARNING, +}; + +void plantLedLoop(float soilHumidity); + +#endif // _HEADER_MOISTURE \ No newline at end of file From d58f0ec9b466d4c8dc3c3d3264f3109dff01dbc9 Mon Sep 17 00:00:00 2001 From: Yohan Boujon Date: Mon, 18 Dec 2023 19:39:47 +0100 Subject: [PATCH 09/10] Moisture Hot Fix: Added Status for WET/DRY, if status sudden change between not IDLED status, will change led color. --- embedded/src/moisture.cpp | 8 ++++---- embedded/src/moisture.hpp | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/embedded/src/moisture.cpp b/embedded/src/moisture.cpp index bbddea6..a2928f6 100644 --- a/embedded/src/moisture.cpp +++ b/embedded/src/moisture.cpp @@ -6,9 +6,9 @@ void plantLedLoop(float soilHumidity) { auto& led = MainComponent::GetInstance().getLed(); - if ((soilHumidity < MoistureLevel::DRY) && (moisture_status == LedMoistureStatus::IDLE)) + if ((soilHumidity < MoistureLevel::DRY) && (moisture_status != LedMoistureStatus::DRY)) { - moisture_status = LedMoistureStatus::WARNING; + moisture_status = LedMoistureStatus::DRY; led.setColor(LedNumber::LED_PLANT,LedColors::TOO_DRY,200); } else if (soilHumidity >= MoistureLevel::DRY && soilHumidity < MoistureLevel::HUMID) @@ -16,9 +16,9 @@ void plantLedLoop(float soilHumidity) led.setColor(LedNumber::LED_PLANT,LedColors::LED_OFF); moisture_status = LedMoistureStatus::IDLE; } - else if (moisture_status == LedMoistureStatus::IDLE) + else if ((soilHumidity >= MoistureLevel::HUMID) && (moisture_status != LedMoistureStatus::WET)) { - moisture_status = LedMoistureStatus::WARNING; + moisture_status = LedMoistureStatus::WET; led.setColor(LedNumber::LED_PLANT,LedColors::TOO_WET,200); } } \ No newline at end of file diff --git a/embedded/src/moisture.hpp b/embedded/src/moisture.hpp index f1c0aa0..6b28ee0 100644 --- a/embedded/src/moisture.hpp +++ b/embedded/src/moisture.hpp @@ -16,7 +16,8 @@ namespace MoistureLevel { enum class LedMoistureStatus { IDLE, - WARNING, + DRY, + WET }; void plantLedLoop(float soilHumidity); From d203161a1b70edc3457a8fbc74bf47e330d0347f Mon Sep 17 00:00:00 2001 From: Yohan Boujon Date: Mon, 18 Dec 2023 20:40:47 +0100 Subject: [PATCH 10/10] Renamed Moisture to Warning. Pictures: Added warning icons. Display: Added setWarningIcon(), some constexpr for icons. Warning: Added warningScreenLoop() and Renamed warningLedLoop(). --- embedded/lib/Display/Screen.cpp | 18 ++++--- embedded/lib/Display/Screen.hpp | 25 +++++++++ .../lib/Pictures/air_humidity-warning.xbm | 6 +++ embedded/lib/Pictures/humidity-warning.xbm | 6 +++ embedded/lib/Pictures/thermometer-warning.xbm | 6 +++ embedded/src/main.cpp | 5 +- embedded/src/moisture.cpp | 24 --------- embedded/src/moisture.hpp | 25 --------- embedded/src/warning.cpp | 52 +++++++++++++++++++ embedded/src/warning.hpp | 33 ++++++++++++ 10 files changed, 143 insertions(+), 57 deletions(-) create mode 100644 embedded/lib/Pictures/air_humidity-warning.xbm create mode 100644 embedded/lib/Pictures/humidity-warning.xbm create mode 100644 embedded/lib/Pictures/thermometer-warning.xbm delete mode 100644 embedded/src/moisture.cpp delete mode 100644 embedded/src/moisture.hpp create mode 100644 embedded/src/warning.cpp create mode 100644 embedded/src/warning.hpp diff --git a/embedded/lib/Display/Screen.cpp b/embedded/lib/Display/Screen.cpp index ddcfb54..7c00467 100644 --- a/embedded/lib/Display/Screen.cpp +++ b/embedded/lib/Display/Screen.cpp @@ -6,9 +6,6 @@ // XBM Files #include "../Pictures/failed.xbm" -#include "../Pictures/humidity.xbm" -#include "../Pictures/thermometer.xbm" -#include "../Pictures/air_humidity.xbm" using namespace Display; @@ -35,9 +32,9 @@ void Screen::Setup(uint8_t *font) auto plantHumidity = TextBox("plantHumidity", StyleWidth::LEFT, StyleHeight::TOP, U8G2_BTN_BW0, 0, 0); auto airTemperature = TextBox("airTemperature", StyleWidth::LEFT, StyleHeight::CENTERED, U8G2_BTN_BW0, 0, 0); auto airHumidity = TextBox("airHumidity", StyleWidth::LEFT, StyleHeight::BOTTOM, U8G2_BTN_BW0, 0, 6); - auto humidityPicture = SpriteBox(humidity_bits,humidity_width,humidity_height,StyleWidth::LEFT,StyleHeight::CENTERED); - auto thermometerPicture = SpriteBox(thermometer_bits,thermometer_width,thermometer_height,StyleWidth::LEFT,StyleHeight::CENTERED); - auto airHumidityPicture = SpriteBox(air_humidity_bits,air_humidity_width,air_humidity_height,StyleWidth::LEFT,StyleHeight::CENTERED); + auto humidityPicture = SpriteBox(ICONS[0].data,ICONS[0].width,ICONS[0].height,StyleWidth::LEFT,StyleHeight::CENTERED); + auto thermometerPicture = SpriteBox(ICONS[1].data,ICONS[1].width,ICONS[1].height,StyleWidth::LEFT,StyleHeight::CENTERED); + auto airHumidityPicture = SpriteBox(ICONS[2].data,ICONS[2].width,ICONS[2].height,StyleWidth::LEFT,StyleHeight::CENTERED); // Config Boxes plantHumidity.SetOffset(OFFSET_TEXT,12); @@ -148,6 +145,15 @@ void Screen::loop(const float plantHumidity, const float airTemperature, const f _screen->sendBuffer(); } +void Screen::setWarningIcon(Sensors sensorId, bool warning) +{ + const auto realId = static_cast(sensorId); + if(warning) + iconWindow.Update(realId,ICONS_WARNING[realId]); + else + iconWindow.Update(realId,ICONS[realId]); +} + uint16_t Screen::getHeight() { return _height; } uint16_t Screen::getWidth() { return _width; } U8G2_SSD1306_128X64_NONAME_F_HW_I2C &Screen::getScreen() { return *_screen; } diff --git a/embedded/lib/Display/Screen.hpp b/embedded/lib/Display/Screen.hpp index 648bbe6..d4ded26 100644 --- a/embedded/lib/Display/Screen.hpp +++ b/embedded/lib/Display/Screen.hpp @@ -20,6 +20,14 @@ #include "../Pictures/clover10.xbm" #include "../Pictures/clover11.xbm" +// Icons +#include "../Pictures/humidity.xbm" +#include "../Pictures/thermometer.xbm" +#include "../Pictures/air_humidity.xbm" +#include "../Pictures/humidity-warning.xbm" +#include "../Pictures/thermometer-warning.xbm" +#include "../Pictures/air_humidity-warning.xbm" + namespace Display { constexpr Picture CLOVER_FRAMES[] = { @@ -35,10 +43,26 @@ namespace Display {clover10_bits, clover10_width, clover10_height}, {clover11_bits, clover11_width, clover11_height}, }; + constexpr Picture ICONS[] = { + {humidity_bits,humidity_width,humidity_height}, + {thermometer_bits,thermometer_width,thermometer_height}, + {air_humidity_bits,air_humidity_width,air_humidity_height}, + }; + constexpr Picture ICONS_WARNING[] = { + {humidity_warning_bits,humidity_warning_width,humidity_warning_height}, + {thermometer_warning_bits,thermometer_warning_width,thermometer_warning_height}, + {air_humidity_warning_bits,air_humidity_warning_width,air_humidity_warning_height}, + }; constexpr uint8_t MAX_BOOT_FRAMES = 25; constexpr uint8_t OFFSET_ICONS = 55; constexpr uint8_t OFFSET_TEXT = 75; + enum class Sensors { + SOIL_MOISTURE = 0, + THERMOMETER, + AIR_HUMIDITY + }; + class Screen { public: @@ -55,6 +79,7 @@ namespace Display void connected(const char *ipaddress, uint8_t timing); void boot(); void loop(const float plantHumidity, const float airTemperature, const float airHumidity); + void setWarningIcon(Sensors sensorId, bool warning=true); // Getters uint16_t getHeight(); uint16_t getWidth(); diff --git a/embedded/lib/Pictures/air_humidity-warning.xbm b/embedded/lib/Pictures/air_humidity-warning.xbm new file mode 100644 index 0000000..6c0ab19 --- /dev/null +++ b/embedded/lib/Pictures/air_humidity-warning.xbm @@ -0,0 +1,6 @@ +#define air_humidity_warning_width 16 +#define air_humidity_warning_height 16 +static unsigned char air_humidity_warning_bits[] = { + 0x60, 0x00, 0x90, 0x00, 0x18, 0x01, 0x24, 0x02, 0x42, 0x0a, 0x42, 0x0a, + 0x04, 0x19, 0x90, 0x3c, 0x38, 0x3e, 0x28, 0x7f, 0x6c, 0x7f, 0x6c, 0x7e, + 0xfe, 0x3e, 0xee, 0x1e, 0xfe, 0x0e, 0x00, 0x00 }; diff --git a/embedded/lib/Pictures/humidity-warning.xbm b/embedded/lib/Pictures/humidity-warning.xbm new file mode 100644 index 0000000..6586a03 --- /dev/null +++ b/embedded/lib/Pictures/humidity-warning.xbm @@ -0,0 +1,6 @@ +#define humidity_warning_width 16 +#define humidity_warning_height 16 +static unsigned char humidity_warning_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x80, 0x01, 0x40, 0x03, 0x40, 0x03, + 0x80, 0x07, 0x90, 0x0f, 0xb8, 0x0f, 0x28, 0x1f, 0x6c, 0x1f, 0x6c, 0x1e, + 0xfe, 0x0e, 0xee, 0x06, 0xfe, 0x02, 0x00, 0x00 }; diff --git a/embedded/lib/Pictures/thermometer-warning.xbm b/embedded/lib/Pictures/thermometer-warning.xbm new file mode 100644 index 0000000..70de2e1 --- /dev/null +++ b/embedded/lib/Pictures/thermometer-warning.xbm @@ -0,0 +1,6 @@ +#define thermometer_warning_width 16 +#define thermometer_warning_height 16 +static unsigned char thermometer_warning_bits[] = { + 0x00, 0x00, 0x80, 0x01, 0x40, 0x02, 0xc0, 0x02, 0x40, 0x02, 0xc0, 0x02, + 0x40, 0x02, 0x90, 0x02, 0x38, 0x02, 0x28, 0x04, 0x6c, 0x08, 0x6c, 0x0e, + 0xfe, 0x0e, 0xee, 0x06, 0xfe, 0x02, 0x00, 0x00 }; diff --git a/embedded/src/main.cpp b/embedded/src/main.cpp index a440ee2..8ee2eac 100644 --- a/embedded/src/main.cpp +++ b/embedded/src/main.cpp @@ -5,7 +5,7 @@ #include "ServerHandler.hpp" #include "MainComponent.hpp" #include "Screen.hpp" -#include "moisture.hpp" +#include "warning.hpp" #ifdef SSID_CLOVER const char *ssid = SSID_CLOVER; @@ -72,7 +72,8 @@ void loop() // Showing screen screen.loop((soilHumidityData / 950.0f) * 100.0f, airTemperatureData, airHumidityData); - plantLedLoop(soilHumidityData); + Warning::warningLedLoop(soilHumidityData); + Warning::warningScreenLoop(soilHumidityData,airTemperatureData,airHumidityData); serverHandler.loop(); } \ No newline at end of file diff --git a/embedded/src/moisture.cpp b/embedded/src/moisture.cpp deleted file mode 100644 index a2928f6..0000000 --- a/embedded/src/moisture.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "moisture.hpp" - -LedMoistureStatus moisture_status(LedMoistureStatus::IDLE); - -void plantLedLoop(float soilHumidity) -{ - auto& led = MainComponent::GetInstance().getLed(); - - if ((soilHumidity < MoistureLevel::DRY) && (moisture_status != LedMoistureStatus::DRY)) - { - moisture_status = LedMoistureStatus::DRY; - led.setColor(LedNumber::LED_PLANT,LedColors::TOO_DRY,200); - } - else if (soilHumidity >= MoistureLevel::DRY && soilHumidity < MoistureLevel::HUMID) - { - led.setColor(LedNumber::LED_PLANT,LedColors::LED_OFF); - moisture_status = LedMoistureStatus::IDLE; - } - else if ((soilHumidity >= MoistureLevel::HUMID) && (moisture_status != LedMoistureStatus::WET)) - { - moisture_status = LedMoistureStatus::WET; - led.setColor(LedNumber::LED_PLANT,LedColors::TOO_WET,200); - } -} \ No newline at end of file diff --git a/embedded/src/moisture.hpp b/embedded/src/moisture.hpp deleted file mode 100644 index 6b28ee0..0000000 --- a/embedded/src/moisture.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef _HEADER_MOISTURE -#define _HEADER_MOISTURE - -#include "MainComponent.hpp" -#include - -/** - * @brief See the documentation on 'https://www.mouser.com/datasheet/2/744/Seeed_101020008-1217463.pdf' - */ -namespace MoistureLevel { - constexpr uint16_t AIR = 0; - constexpr uint16_t DRY = 300; - constexpr uint16_t HUMID = 700; - constexpr uint16_t WATER = 950; -} - -enum class LedMoistureStatus { - IDLE, - DRY, - WET -}; - -void plantLedLoop(float soilHumidity); - -#endif // _HEADER_MOISTURE \ No newline at end of file diff --git a/embedded/src/warning.cpp b/embedded/src/warning.cpp new file mode 100644 index 0000000..9186f1d --- /dev/null +++ b/embedded/src/warning.cpp @@ -0,0 +1,52 @@ +#include "warning.hpp" + +#include "Screen.hpp" +#include "MainComponent.hpp" + +using namespace Warning; + +LedMoistureStatus moisture_status(LedMoistureStatus::IDLE); + +void Warning::warningLedLoop(const float soilHumidity) +{ + auto& led = MainComponent::GetInstance().getLed(); + + if ((soilHumidity < MoistureLevel::DRY) && (moisture_status != LedMoistureStatus::DRY)) + { + moisture_status = LedMoistureStatus::DRY; + led.setColor(LedNumber::LED_PLANT,LedColors::TOO_DRY,200); + } + else if (soilHumidity >= MoistureLevel::DRY && soilHumidity < MoistureLevel::HUMID) + { + led.setColor(LedNumber::LED_PLANT,LedColors::LED_OFF); + moisture_status = LedMoistureStatus::IDLE; + } + else if ((soilHumidity >= MoistureLevel::HUMID) && (moisture_status != LedMoistureStatus::WET)) + { + moisture_status = LedMoistureStatus::WET; + led.setColor(LedNumber::LED_PLANT,LedColors::TOO_WET,200); + } +} + +void Warning::warningScreenLoop(const float plantMoisture, const float airTemperature, const float airHumidity) +{ + auto& display = Display::Screen::GetInstance(); + + // Plant Moisture Warning + if(plantMoisture < MoistureLevel::DRY || plantMoisture > MoistureLevel::HUMID) + display.setWarningIcon(Display::Sensors::SOIL_MOISTURE); + else + display.setWarningIcon(Display::Sensors::SOIL_MOISTURE,false); + + // Temperature Warning + if(airTemperature >= AIR_TEMPERATURE_TOO_HOT || airTemperature <= AIR_TEMPERATURE_TOO_COLD) + display.setWarningIcon(Display::Sensors::THERMOMETER); + else + display.setWarningIcon(Display::Sensors::THERMOMETER,false); + + // Humidity Warning + if(airHumidity >= AIR_HUMIDITY_SATURATED) + display.setWarningIcon(Display::Sensors::AIR_HUMIDITY); + else + display.setWarningIcon(Display::Sensors::AIR_HUMIDITY,false); +} \ No newline at end of file diff --git a/embedded/src/warning.hpp b/embedded/src/warning.hpp new file mode 100644 index 0000000..8cb43c8 --- /dev/null +++ b/embedded/src/warning.hpp @@ -0,0 +1,33 @@ +#ifndef _HEADER_WARNING +#define _HEADER_WARNING + +#include + +namespace Warning { + /** + * @brief See the documentation on 'https://www.mouser.com/datasheet/2/744/Seeed_101020008-1217463.pdf' + */ + namespace MoistureLevel { + constexpr uint16_t AIR = 0; + constexpr uint16_t DRY = 300; + constexpr uint16_t HUMID = 700; + constexpr uint16_t WATER = 950; + } + constexpr float AIR_HUMIDITY_SATURATED = 95.0f; + /** + * @brief Source : 'https://extension.umd.edu/resource/temperature-and-humidity-indoor-plants/' + */ + constexpr float AIR_TEMPERATURE_TOO_HOT = 29.0f; + constexpr float AIR_TEMPERATURE_TOO_COLD = 14.0f; + + enum class LedMoistureStatus { + IDLE, + DRY, + WET + }; + + void warningLedLoop(const float soilHumidity); + void warningScreenLoop(const float plantMoisture, const float airTemperature, const float airHumidity); +} + +#endif // _HEADER_WARNING \ No newline at end of file