This repository hold the software for a controller for an automated ebb flow hydroponic grow system. The controller runs on an ESP32 and can be configured via MQTT. The MQTT connection is additionally used to send status information and data for monitoring to an overall system.
Use the script scripts/download_and_flash_release.sh to download and flash the newest released software version to your ESP32 Board.
Scan the QR Code to connect to the Wifi.
Scan the QR Code to show the Configuration Website.
There are two different apps built for this project.
The factory application does not hold the normal application. It only serves for a first initial configuration and downloading the latests main application. It starts an Wifi Access point and host a webpage to configure the device for the first time. The Wifi and webpage can be joind by scanning the qr-codes shown here. After submitting the correct configuration it downloads the latest version of the main application and starts it.
The main application is running always. It serves all the implemented features. It can be updated over the air by having always teo copies of the application. Always when a new version is released it is downloaded automatically at around midnight and is written on en extra partition. Be aware that it never overrides the factory app. After a successful update the new code needs to run for more than 24h to be considered valid. A restart during this timeframe would consider the update as invalid and the old app would be booted again.
If you do not need any special configuration you can just download and flash the prebuild release version with the script located scripts/download_and_flash_release.sh.
If you need to change anything the easiest way to build the software is to run the Docker devcontainer. Inside the container you can use the espressif idf build environment.
For building the factory or main application the profile files can be used. The following list shows the how to use them.
- Build application:
idf.py @profiles/app build - Flash application:
idf.py @profiles/app flash - Build factory:
idf.py @profiles/factory build - Flash factory:
idf.py @profiles/factory flash
For configuration use the idf configuration environment. See the paragraph about the configuration for more details.
The controller runs on a ESP32 with additional Hardware.
- ESP32 Controller
- Relay Board
- Nutrition Pump
graph TD
WIFI(WIFI)
MQTT(MQTT)
NutritionPump(Nutrition Pump)
RelayBoard(Relay Board GPIO)
EbbFlowControl(Ebb Flow Controller)
MQTT <--> WIFI;
WIFI <--> EbbFlowControl;
EbbFlowControl --> RelayBoard
RelayBoard --> NutritionPump
There are two different configurations. The build configuration which needs to be set before building the code for the controller and the runtime configuration which can be changed during runtime via MQTT messages.
The build configuration is done via the espressif idf configuration tool.
Run idf.py menuconfigto configure the build.
The most important configurations can be found in the main menu under Application Configuration the more less important one are inside the Component Configuration.
The current configuration is saved in a persistent storage such that it is kept after an power cycle.
Always after connecting to an MQTT broker the current configuration is published via the MQTT_CONFIG_SEND_TOPIC (default: ef/efc/static/config)
The controller can be configured during runtime via a MQTT message. The message needs to be send to the MQTT_CONFIG_RECEIVE_TOPIC(default: ef/efc/config/set). The message needs to be formatted as json. After each attempt to change the configuration the new configuration is published.
If the configuration of a specific controller needs to be changed the config file needs to contain a id field with the board id of the controller.
Only the specified fields are update. If a key is not present in the configuration the current configuration is kept.
Example: Setting the Pumping time to 120 seconds.
{
"id": 0,
"pump_cycles": {
"pump_time_s": 120
}
}Key: id
The board id as uint_8 value. A number between 0 and 255. If no board id is present all boards are updated. Else only the specified board is updated.
Key: pump_cycles
| Key | Typ | Description |
|---|---|---|
| pump_time_s | unsigned short | Seconds the nutrition pump is on |
| nr_pump_cycles | unsigned short | The length of "times_minutes_per_day" list. Number needs to be between 0 and MAX_NUMBER_PUMP_CYCLES_PER_DAY(default: 24) |
| times_minutes_per_day | List[unsigned short] | The actual timepoints the pump needs to run during a day in minutes of the day in local time. e.g. [8*60, 13*60, 20*60+30] relates to running the pump at 08:00, 13:00 and 20:30. |
The controller sends current data via MQTT to monitor the functionality. To use the data you need to subscribe to the specific channels.
Channel: MQTT_CONFIG_SEND_TOPIC (default: ef/efc/static/config)
Data-Format: json
See the paragraph about the Configuration Values for more details.
Channel: MQTT_STATUS_TOPIC (default: ef/efc/static/status)
Data-Format: json
Data:
| Key | Typ | Description |
|---|---|---|
| id | uint_8 | Id of the specific board Integer between 0 and 255 |
| connection | string | Current connection status to the MQTT Broker. "connected" or "disconnected" |
| rssi_level | int | Connection strength of the Wifi connection. -100 if an error occurs. |
| version | string | Version string of the current running version. |
Example:
{
"id": 0,
"connection": "connected"
}Channel: MQTT_PUMP_STATUS_TOPIC (default: ef/efc/timed/pump)
Data-Format: json
Data:
| Key | Typ | Description |
|---|---|---|
| id | uint_8 | Id of the specific board Integer between 0 and 255 |
| ts | string | Current timestamp in ISO 8601 format including microseconds |
| status | string | "start" when starting to pump and "stop" when stopping |

