firmware - v0.1.0 - really this time! added configurable display rotation
This commit is contained in:
parent
60fc811bf6
commit
2a6d1df66a
4 changed files with 103 additions and 20 deletions
|
@ -31,7 +31,6 @@ bool NeedRestart;
|
||||||
bool FirstRun;
|
bool FirstRun;
|
||||||
// which screen should be actually displayed
|
// which screen should be actually displayed
|
||||||
byte ScreenToDisplay = 0;
|
byte ScreenToDisplay = 0;
|
||||||
byte DisplayScreenDuration = 3;
|
|
||||||
// how many seconds actual screen got displayed
|
// how many seconds actual screen got displayed
|
||||||
byte ScreenIterationPassed = 0;
|
byte ScreenIterationPassed = 0;
|
||||||
|
|
||||||
|
@ -115,7 +114,7 @@ bool OutputInvert;
|
||||||
unsigned short SoilmoistureWet;
|
unsigned short SoilmoistureWet;
|
||||||
unsigned short SoilmoistureDry;
|
unsigned short SoilmoistureDry;
|
||||||
unsigned short PWMFrequency = 13370;
|
unsigned short PWMFrequency = 13370;
|
||||||
|
byte DisplayScreenDuration = 3;
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -113,7 +113,8 @@ bool loadEEPROM() {
|
||||||
* 248 PinFAN2PWM (1 byte)
|
* 248 PinFAN2PWM (1 byte)
|
||||||
* 249 HumiditySensor_Type (1 byte)
|
* 249 HumiditySensor_Type (1 byte)
|
||||||
* 250 PWMFrequency (2 byte)
|
* 250 PWMFrequency (2 byte)
|
||||||
* 252 ...
|
* 252 DisplayScreenDuration (1 byte)
|
||||||
|
* 253
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -187,6 +188,10 @@ bool loadEEPROM() {
|
||||||
EEPROM.get(246, SoilmoistureDry);
|
EEPROM.get(246, SoilmoistureDry);
|
||||||
// size is 1 byte
|
// size is 1 byte
|
||||||
EEPROM.get(249, HumiditySensor_Type);
|
EEPROM.get(249, HumiditySensor_Type);
|
||||||
|
// size is 2 byte
|
||||||
|
EEPROM.get(250, PWMFrequency);
|
||||||
|
// size is 1 byte
|
||||||
|
EEPROM.get(252, DisplayScreenDuration);
|
||||||
}
|
}
|
||||||
// TODO auth does not work atm
|
// TODO auth does not work atm
|
||||||
// EEPROM.get(160, WebUiUsername);
|
// EEPROM.get(160, WebUiUsername);
|
||||||
|
@ -227,8 +232,7 @@ bool loadEEPROM() {
|
||||||
EEPROM.get(242, PumpIntervalBloom);
|
EEPROM.get(242, PumpIntervalBloom);
|
||||||
// size is 1 byte
|
// size is 1 byte
|
||||||
EEPROM.get(248, PinFAN2PWM);
|
EEPROM.get(248, PinFAN2PWM);
|
||||||
// size is 2 byte
|
|
||||||
EEPROM.get(250, PWMFrequency);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -609,8 +613,12 @@ void displayScreens() {
|
||||||
display.println("s");
|
display.println("s");
|
||||||
} else {
|
} else {
|
||||||
// in this switch case the single screens gets defined
|
// in this switch case the single screens gets defined
|
||||||
//switch(ScreenToDisplay) {
|
// when DisplayScreenDuration is 0, always show 0
|
||||||
switch(0) {
|
if(DisplayScreenDuration == 0) {
|
||||||
|
ScreenToDisplay = 0;
|
||||||
|
}
|
||||||
|
switch(ScreenToDisplay) {
|
||||||
|
// switch(0) { // just for testing, show screen 0 only
|
||||||
case 0:
|
case 0:
|
||||||
display.print("Humidity: ");
|
display.print("Humidity: ");
|
||||||
display.print(valHumidity);
|
display.print(valHumidity);
|
||||||
|
|
|
@ -588,6 +588,14 @@ void WEBsystemSettings() {
|
||||||
body += "<option value='0'" + returnStrSelected(UsePump, 0) + ">No</option>\n";
|
body += "<option value='0'" + returnStrSelected(UsePump, 0) + ">No</option>\n";
|
||||||
body += "</select><br>\n";
|
body += "</select><br>\n";
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// OutputInvert bool
|
||||||
|
body += "Invert Outputs: <select id='OutputInvert' name='OutputInvert' required>\n";
|
||||||
|
if(configured == false){body += "<option disabled value='' selected hidden>---</option>\n";}
|
||||||
|
body += "<option value='1'" + returnStrSelected(OutputInvert, 1) + ">Yes</option>\n";
|
||||||
|
body += "<option value='0'" + returnStrSelected(OutputInvert, 0) + ">No</option>\n";
|
||||||
|
body += "</select><br>\n";
|
||||||
|
|
||||||
// PumpMode byte
|
// PumpMode byte
|
||||||
body += "Pump mode: <select id='UsePump' name='UsePump' required>\n";
|
body += "Pump mode: <select id='UsePump' name='UsePump' required>\n";
|
||||||
if(configured == false){body += "<option disabled value='' selected hidden>---</option>\n";}
|
if(configured == false){body += "<option disabled value='' selected hidden>---</option>\n";}
|
||||||
|
@ -599,24 +607,15 @@ void WEBsystemSettings() {
|
||||||
<b>2:</b> Water if the soil moisture falls below <i>Soilmoisture low</i> value<br> \
|
<b>2:</b> Water if the soil moisture falls below <i>Soilmoisture low</i> value<br> \
|
||||||
<b>3:</b> Water every few days if the soil moisture falls below <i>Soilmoisture low</i> value.</p>\n";
|
<b>3:</b> Water every few days if the soil moisture falls below <i>Soilmoisture low</i> value.</p>\n";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// OutputInvert bool
|
|
||||||
body += "Invert Outputs: <select id='OutputInvert' name='OutputInvert' required>\n";
|
|
||||||
if(configured == false){body += "<option disabled value='' selected hidden>---</option>\n";}
|
|
||||||
body += "<option value='1'" + returnStrSelected(OutputInvert, 1) + ">Yes</option>\n";
|
|
||||||
body += "<option value='0'" + returnStrSelected(OutputInvert, 0) + ">No</option>\n";
|
|
||||||
body += "</select><br>\n";
|
|
||||||
|
|
||||||
// UseLEDrelais bool
|
// UseLEDrelais bool
|
||||||
body += "Use relais for LED: <select id='UseLEDrelais' name='UseLEDrelais' required>\n";
|
body += "Use relais for LED (disable PWM): <select id='UseLEDrelais' name='UseLEDrelais' required>\n";
|
||||||
if(configured == false){body += "<option disabled value='' selected hidden>---</option>\n";}
|
if(configured == false){body += "<option disabled value='' selected hidden>---</option>\n";}
|
||||||
body += "<option value='1'" + returnStrSelected(UseLEDrelais, 1) + ">Yes</option>\n";
|
body += "<option value='1'" + returnStrSelected(UseLEDrelais, 1) + ">Yes</option>\n";
|
||||||
body += "<option value='0'" + returnStrSelected(UseLEDrelais, 0) + ">No</option>\n";
|
body += "<option value='0'" + returnStrSelected(UseLEDrelais, 0) + ">No</option>\n";
|
||||||
body += "</select><br>\n";
|
body += "</select><br>\n";
|
||||||
|
|
||||||
// UseFANrelais bool
|
// UseFANrelais bool
|
||||||
body += "Use relais for FAN: <select id='UseFANrelais' name='UseFANrelais' required>\n";
|
body += "Use relais for FAN (disable PWM): <select id='UseFANrelais' name='UseFANrelais' required>\n";
|
||||||
if(configured == false){body += "<option disabled value='' selected hidden>---</option>\n";}
|
if(configured == false){body += "<option disabled value='' selected hidden>---</option>\n";}
|
||||||
body += "<option value='1'" + returnStrSelected(UseFANrelais, 1) + ">Yes</option>\n";
|
body += "<option value='1'" + returnStrSelected(UseFANrelais, 1) + ">Yes</option>\n";
|
||||||
body += "<option value='0'" + returnStrSelected(UseFANrelais, 0) + ">No</option>\n";
|
body += "<option value='0'" + returnStrSelected(UseFANrelais, 0) + ">No</option>\n";
|
||||||
|
@ -694,6 +693,12 @@ void WEBsystemSettings() {
|
||||||
body += PWMFrequency;
|
body += PWMFrequency;
|
||||||
body += "' required> Hz<br>\n";
|
body += "' required> Hz<br>\n";
|
||||||
|
|
||||||
|
// DisplayScreenDuration byte
|
||||||
|
body += "Display rotation interval: <input class='inputShort' type='number' name='DisplayScreenDuration' min='0' max='255' value='";
|
||||||
|
body += DisplayScreenDuration;
|
||||||
|
body += "' required> s<br>\n";
|
||||||
|
body += "<p class='helpbox'><b>0</b> will always show sensor value screen</p>";
|
||||||
|
|
||||||
body += "ESP32-Cam IP (optional): <input type='text' name='Esp32CamIP' maxlength='16' value='";
|
body += "ESP32-Cam IP (optional): <input type='text' name='Esp32CamIP' maxlength='16' value='";
|
||||||
body += Esp32CamIP;
|
body += Esp32CamIP;
|
||||||
body += "' ><br>\n";
|
body += "' ><br>\n";
|
||||||
|
@ -897,6 +902,7 @@ void POSTsystemSettings() {
|
||||||
SoilmoistureDry = webserver.arg("SoilmoistureDry").toInt();
|
SoilmoistureDry = webserver.arg("SoilmoistureDry").toInt();
|
||||||
HumiditySensor_Type = webserver.arg("HumiditySensor_Type").toInt();
|
HumiditySensor_Type = webserver.arg("HumiditySensor_Type").toInt();
|
||||||
PWMFrequency = webserver.arg("PWMFrequency").toInt();
|
PWMFrequency = webserver.arg("PWMFrequency").toInt();
|
||||||
|
DisplayScreenDuration = webserver.arg("DisplayScreenDuration").toInt();
|
||||||
|
|
||||||
// when configured is false, set it to true and ensure outputs are set
|
// when configured is false, set it to true and ensure outputs are set
|
||||||
if(configured == false) {
|
if(configured == false) {
|
||||||
|
@ -933,6 +939,7 @@ void POSTsystemSettings() {
|
||||||
EEPROM.put(246, SoilmoistureDry);
|
EEPROM.put(246, SoilmoistureDry);
|
||||||
EEPROM.put(249, HumiditySensor_Type);
|
EEPROM.put(249, HumiditySensor_Type);
|
||||||
EEPROM.put(250, PWMFrequency);
|
EEPROM.put(250, PWMFrequency);
|
||||||
|
EEPROM.put(252, DisplayScreenDuration);
|
||||||
|
|
||||||
// write data to EEPROM
|
// write data to EEPROM
|
||||||
EEPROM.commit();
|
EEPROM.commit();
|
||||||
|
|
73
README.md
73
README.md
|
@ -9,13 +9,82 @@ An easy to use DIY grow controller firmware (for cannabis).
|
||||||
![Screenshot_WebUI_root.png](Arduino/CanGrow/Screenshot_WebUI_root.png)
|
![Screenshot_WebUI_root.png](Arduino/CanGrow/Screenshot_WebUI_root.png)
|
||||||
![CanGrow_PCB_Front.png](KiCad/CanGrow/CanGrow_PCB_Front_small.png)
|
![CanGrow_PCB_Front.png](KiCad/CanGrow/CanGrow_PCB_Front_small.png)
|
||||||
|
|
||||||
# WORK IN PROGRESS
|
## WORK IN PROGRESS
|
||||||
|
|
||||||
## Motivation
|
## Motivation
|
||||||
I havn't found an already existing grow controller project within the ESP / Arduino Core eco system which
|
I havn't found an already existing grow controller project within the ESP / Arduino Core eco system which
|
||||||
met my personal requirements.
|
met my personal requirements.
|
||||||
Those are an easy DIY, using low cost parts, Arduino Core sourcecode to hack own things together, having a WebUI, grab some Metrics for monitoring, standalone and my very special need that the Hardware should run completely with 12V.
|
Those are an easy DIY, using low cost parts, Arduino Core sourcecode to hack own things together, having a WebUI, grab some Metrics for monitoring, standalone and my very special need that the Hardware should run completely with 12V.
|
||||||
|
|
||||||
|
### Update 09.12.2024 - Release of CanGrow firmware v0.1.0
|
||||||
|
|
||||||
|
After some feedback of users from the forum [grower.ch](https://grower.ch) (thank you guys!) I somewhat finalized firmware version v0.1 so this would be in a usable state for others to use.
|
||||||
|
Work on v0.2 is progressing slowly, so it is better when the code, which already exists, exists in usable way :)
|
||||||
|
|
||||||
|
**Release notes:**
|
||||||
|
|
||||||
|
First non-dev release of CanGrow Firmware v0.1 branch
|
||||||
|
|
||||||
|
I would call this the first "official" release, which is usable. It does not (yet) contain all functions and features I planned to implement, but those will come with v0.2 of the firmware, which is already in progress for about a month now.
|
||||||
|
|
||||||
|
CanGrow Firmware v0.1.0 is made for the CanGrow PCB, but you can of course run it with your own hardware. Firmware v0.2 will be fully platform independent.
|
||||||
|
|
||||||
|
|
||||||
|
# Setup
|
||||||
|
|
||||||
|
## Perform a factory reset, after you have flashed the firmware to your ESP8266 (for the first time or having problem like crash loops)!
|
||||||
|
|
||||||
|
You perform a factory reset (wipe) by connecting Pin D4 with GND (WIPE on the CanGrow PCB) when the builtin LED of the ESP8266 blinks three times during start. Hold for three seconds, then release. The builtin LED should now flash faster and the ESP should restart.
|
||||||
|
Now you will see an open unprotected Wifi called `CanGrow-unconfigured`, connect to it and open the address [http://192.168.4.20](http://192.168.4.20) and you can now start setup up your CanGrow device :)
|
||||||
|
|
||||||
|
|
||||||
|
# Features
|
||||||
|
|
||||||
|
- Gather Values from sensors
|
||||||
|
- Temperature
|
||||||
|
- Humidity
|
||||||
|
- Soilmoisture
|
||||||
|
- Time based (ntp) Light control
|
||||||
|
- Smooth Fade in and fade out configurable
|
||||||
|
- Control of two Fans
|
||||||
|
- FAN1 is controlled by PWM supply Voltage
|
||||||
|
- FAN2 is controlled by PWM 4 Pin Fan header
|
||||||
|
- Simple watering control
|
||||||
|
- 3 modes for water plan
|
||||||
|
- By soilmoisture value
|
||||||
|
- by time (every n days, different interval for vegetation and bloom phase)
|
||||||
|
- both combined
|
||||||
|
- Define the different phases of your grow
|
||||||
|
- Set amount of days for vegetation and bloom phase.
|
||||||
|
- After bloom phase CanGrow enters harvest mode by its own, which means the light and watering system gets disabled
|
||||||
|
- Maintenance Mode
|
||||||
|
- When using LED PWM, you can activate Maintenance Mode, which dimms the light. (at night it will turn on when enabling maintenance mode)
|
||||||
|
- ESP32Cam integration on the Dashboard
|
||||||
|
- Support for SSD1306 128x64 I2C OLED display
|
||||||
|
- rotates through three different screens
|
||||||
|
- Get measured values as json
|
||||||
|
- `GET /api/sensors`
|
||||||
|
|
||||||
|
# Supported Sensors
|
||||||
|
- Analog capacitive soilmoisture
|
||||||
|
- I2C Chirp (https://wemakethings.net/chirp/)
|
||||||
|
- Soilmoisture
|
||||||
|
- Temperature
|
||||||
|
- I2C BME280
|
||||||
|
- Temperature
|
||||||
|
- Humidity
|
||||||
|
- I2C SHT31
|
||||||
|
- Temperature
|
||||||
|
- Humidity
|
||||||
|
- Analog water level indicator
|
||||||
|
- Builtin on CanGrow PCB
|
||||||
|
- simple voltage devider, check out https://deltalima.org/blog/index.ph...e-step-water-level-indicator-for-arduino-esp/
|
||||||
|
|
||||||
|
# Todo
|
||||||
|
This version branch v0.1.x will receive only bugfixes and small changes. Work on the next v0.2 has already began, which is a complete rewrite. If you are curious , check out the branch "firmware_v0.2-dev", any feedback is welcome!
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
### Update 14.09.2024 - Code Rewrite v0.2
|
### Update 14.09.2024 - Code Rewrite v0.2
|
||||||
|
|
||||||
I took some "summer break" from the project, and had the opportunity to talk to different people about it.
|
I took some "summer break" from the project, and had the opportunity to talk to different people about it.
|
||||||
|
@ -58,7 +127,7 @@ and let the user decide at which pin which output, sensor or whatever will be co
|
||||||
- MQTT support
|
- MQTT support
|
||||||
- API
|
- API
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
## Old v0.1 Features / ToDo List
|
## Old v0.1 Features / ToDo List
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue