Unlocking Bonsai Brilliance
Unleashing the Power of IoT for Seamless Watering and Optimal Growth.

Search for a command to run...
Unleashing the Power of IoT for Seamless Watering and Optimal Growth.

No comments yet. Be the first to comment.
PyData Skopje Chapter After a significant pause of this chapter, it's finally revived. So if you are located in close geographic proximity or are interested to remotely follow the events, join the official Meetup Group. Reflecting on the exhilarating...

Background Historically speaking, people have always craved to discover patterns within their environments. The simplest form of pattern recognition can be identified in the earliest days of mankind. Centuries later, starting in the third industrial ...

What is Hyperparameter Optimization? In machine learning, hyperparameter optimization or tuning is the problem of choosing a set of optimal hyperparameters for a learning algorithm. A hyperparameter is a parameter whose value is used to control the l...

Introduction Recently, at the international convention MIPRO 2021, I presented the full research paper titled "Leveraging Smartphones for Distributed Global Navigation Satellite System Post Processing". The research span for 6 months and I was the ma...

In the realm of software development, the pursuit of observability and data-driven decision-making has become a fundamental aspect of building and maintaining robust microservices architectures. Drawing inspiration from this ethos, I sought to apply these principles to a rather unexpected domain - the care and cultivation of my cherished Bonsai tree.
Similar to the complex systems we engineer, the art of growing a Bonsai tree involves a multitude of parameters that must be carefully balanced for optimal results. However, fine-tuning these variables can be a time-consuming process. Fortunately, certain rules of thumb exist within this horticultural art form that provide valuable guidance in our quest for nurturing these miniature living masterpieces.
Be sure not to water your tree if the soil is still wet, but don't let the tree dry out either.
As a beginner, use your fingers at about one centimeter deep, (0.4") to check the soil moisture. If it's slightly dry, go ahead and water your tree.
followed by:
Avoid watering all of your trees on a daily routine, until you know exactly what you are doing.
This sounds not too exact (for me at least) given my objective is to have a good-looking tree on my desk with healthy and green leaves
To get started you'll need:
Arduino-like Board
Soil-Moisture Sensor
Wi-Fi module (optional)
In this project, NodeMCU V2 ESP8266 paired with Soil Moisture Hygrometer Detection Humidity Sensor was used.
The schematics are pretty straight-forward and as follows:

I've settled on analogous mode for the sensor.
The prerequisites of this step are to connect your development board to a serial monitor and decide on a Baud Rate (in this example 9600). The source code is available on Aleksandar1932/overkill-bonsai.
The next step is to write a lib that provides an API to the soil moisture sensor.
Stating by taking defining a few constants in lib/Constants /Constants.cpp:
#define sensorPower 0
#define sensorPin A0
#define WET_THRESHOLD 500 // Define max value we consider soil 'wet'
#define DRY_TREHSHOLD 750 // Define min value we consider soil 'dry'
#define MEASURE_INTERVAL 1000 // Define how often we check soil moisture (milliseconds)
Next is the lib/Moisture /Moisture.cpp:
#include <Arduino.h>
#include <Constants.h>
int readSensor()
{
digitalWrite(sensorPower, HIGH);
delay(10);
int val = analogRead(sensorPin);
digitalWrite(sensorPower, LOW);
return val;
}
void setupSoilMoistureSensor()
{
pinMode(sensorPower, OUTPUT);
digitalWrite(sensorPower, LOW);
}
void logMoisture(int moisture)
{
Serial.print("Analog Output: ");
Serial.println(moisture);
// Determine status of our soil
if (moisture < WET_THRESHOLD)
{
Serial.println("Status: Soil is too wet");
}
else if (moisture >= WET_THRESHOLD && moisture < DRY_TREHSHOLD)
{
Serial.println("Status: Soil moisture is perfect");
}
else
{
Serial.println("Status: Soil is too dry - time to water!");
}
}
At this point, the core API is defined, and the reset is implementing the presentation layer that will allow us to interact with the sensor. For this I've used ESP8266WebServer for the web server and ESP8266WiFiMulti for Wi-Fi connectivity.
The web server implements two handlers
on / will return json response containing the soil-moisture reading alongside the status (wet, perfect and dry) determined by the thresholds.
on /display will return an HTML response containing the Moisture and some "prettier" UI.
The presentation layer alongside rest of the logic is as follows:
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266mDNS.h>
#include <Moisture.h>
#include <Constants.h>
ESP8266WebServer server(80);
ESP8266WiFiMulti wifiMulti;
void handleMeasurement();
void handleDisplayHTML();
void connectToWifi();
void handleDisplayPrettyHTML();
void setup()
{
Serial.begin(9600);
connectToWifi();
setupSoilMoistureSensor();
server.on("/", handleMeasurement);
server.on("/display", handleDisplayHTML);
server.begin();
}
void loop()
{
int moisture = readSensor();
logMoisture(moisture);
delay(MEASURE_INTERVAL);
server.handleClient();
}
void handleMeasurement()
{
int moisture = readSensor();
server.send(200, "application/json", "{\"moisture\": " + String(moisture) + ", \"status\": \"" + (moisture < WET_THRESHOLD ? "wet" : (moisture >= WET_THRESHOLD && moisture < DRY_TREHSHOLD ? "perfect" : "dry")) + "\"}");
}
void handleDisplayHTML()
{
server.send(200, "text/html", "<html><head><title>ESP8266 Soil Moisture Sensor</title></head><body><h1>Aleksandar's Bonsai</h1><p>Moisture: " + String(readSensor()) + "</p></body></html>");
}
void connectToWifi()
{
wifiMulti.addAP(getenv("WIFI_SSID"), getenv("WIFI_PASSWORD"));
Serial.println("Connecting ...");
while (wifiMulti.run() != WL_CONNECTED)
{
delay(250);
Serial.print('.');
}
Serial.println('\n');
Serial.print("Connected to ");
Serial.println(WiFi.SSID());
Serial.print("IP address:\t");
Serial.println(WiFi.localIP());
if (MDNS.begin(getenv("MDNS_HOSTNAME")))
{
Serial.println("mDNS responder started");
}
else
{
Serial.println("Error setting up MDNS responder!");
}
}
Additionally, I've used mDNS for development purposes.
To determine the thresholds I've used this chart as a reference, but the freedom is yours to fine-tune to achieve optimal results (whatever your objective is).
The integrated solution turned out to look as:

This implementation serves as an initial foundation for an IoT project, with future plans to expand its capabilities. I intend to enhance the system by integrating a water pump and canister, enabling automated watering when the soil moisture threshold is low. Moreover, I plan to incorporate a feedback loop using a photo-sensor directed at the leaves, providing insights into the tree's performance and enabling the determination of an optimal threshold.
In addition to these advancements, I aim to integrate the board into the Tuya platform, replacing the existing presentation layer. This integration will seamlessly incorporate the Bonsai care system into my smart-home ecosystem, enhancing its accessibility and integration with other connected devices.