Giving Life to Plants: an Arduino Plant Emotion Project (Plant Decoration)

by Mayur-Pagote in Circuits > Arduino

308 Views, 3 Favorites, 0 Comments

Giving Life to Plants: an Arduino Plant Emotion Project (Plant Decoration)

Intro 1.jpg
Intro 2.jpg
Test 1.jpg
Test 2.jpg
Test 3.jpg
Test 4.jpg
Intro 3.jpg

Hello everyone, at some point in life you might have heard someone saying that plants have life, but we cannot talk to them. They can't show emotion, they can't convey messages, then how will we get to know? So, in this project, we will give life to a plant and we can see the plant's emotion.

Just think of giving a life to you favourite plant....

There are many aspects which need to be taken into consideration, i.e., water content, gas, nutrients, nitrogen purity, fertilizer, chemicals in soil. But we will keep it simple as I don't have enough components. So, for this project, we will generate emotion by calculating the water content of the soil.

So let's go and let's give our favorite plant a life.

Supplies

Supply 5.jpg
Arduino Nano.jpeg
Supply 1.jpg
Supply 2.jpg
Supply 3.jpg
Supply 4.jpg
Wiring Oled.jpg

The supplies we need for this project are:

  1. A simple Pringles-like container
  2. OLED Display
  3. Arduino Nano
  4. Jumper wires
  5. Male and female DC jacks
  6. A 3.7-volt lithium-ion battery
  7. A lithium-ion compatible battery holder
  8. A soil moisture sensor
  9. A cutter
  10. Hot glue sticks
  11. Wallpaper or any decorative paper

Building Base

Base Cut 0.jpg
Base Cut 1.jpg
Base cut 2.jpg
Base cut 3.jpg

I want my project to be compatible with a wide variety of plants, and for that we will create a separate base setup on which we can keep other plants.

The cylindrical container which I am using has a diameter of nearly 7.5 cm, and the base which we will cut will have a height of 3.5 cm, which is enough to accommodate all our components.

Please take reference from the above images.

Base Designing

Window Cut 1.jpg
DC Cut 1.jpg
Deco 1.jpg
Deco2.jpg

Now we will cut a window of height 2.2 cm and width 2.8 cm. In simple words, the window cut should be enough to fit the OLED display. Along with that, on the exact opposite side of the window cutout, we will punch two holes: one hole for the female DC jack, and just above that, a small hole to take two wires out from it.

After making the necessary cutouts, I decorated it with wooden finish wallpaper.


Battery Pack

Battery Pack 1.jpg
Battery Pack.jpg

In this step, we will build a 3.7 V battery pack using a single lithium-ion battery. Connect the positive and negative wires to the male DC jack. These positive and negative wires should then be connected to the lithium-ion battery holder respectively.

I want to use this same battery in multiple projects, so rather than permanently accommodating it in the base with the charging module, I decided to keep it separately.

Programming Arduino Nano

Screenshot 2026-01-10 220734.png

1. Include Libraries and Define Pins

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_ADDR 0x3C
int sensor_pin = A0;
  1. Wire.h: Used for I²C communication between Arduino and the OLED display.
  2. Adafruit_GFX.h & Adafruit_SSD1306.h: Libraries to control the OLED display and draw graphics.
  3. SCREEN_WIDTH & SCREEN_HEIGHT: Resolution of the OLED screen.
  4. OLED_ADDR: I²C address of the OLED display (commonly 0x3C).
  5. sensor_pin: The analog pin (A0) where the soil moisture sensor is connected.

2. Calibration Values

const int DRY_VALUE = 950;
const int WET_VALUE = 400;
  1. These are calibration constants for the soil sensor.
  2. When the soil is completely dry, the sensor reads ~950.
  3. When the soil is completely wet, the sensor reads ~400.
  4. You might need to adjust these values depending on your sensor and soil type.

3. Initialize OLED Display

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
  1. Creates a display object that allows you to control the OLED.

4. Face Parameters

int cx = 64;
int cy = 32;
int r = 28;
  1. cx, cy: Center coordinates of the face on the OLED screen.
  2. r: Radius of the face circle.

5. Setup Function

void setup() {
Serial.begin(9600);
pinMode(sensor_pin, INPUT);
Wire.begin();
display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR);
display.clearDisplay();
}
  1. Initializes the serial communication for debugging.
  2. Sets the sensor_pin as input.
  3. Starts I²C communication (Wire.begin()) for the OLED.
  4. Initializes the OLED display and clears it.

6. Drawing Functions

These functions draw different facial expressions on the OLED depending on moisture level.

6.1 Base Face

void drawFaceBase() {
display.drawCircle(cx, cy, r, SSD1306_WHITE);
display.fillCircle(cx - 10, cy - 8, 3, SSD1306_WHITE); // Left eye
display.fillCircle(cx + 10, cy - 8, 3, SSD1306_WHITE); // Right eye
}
  1. Draws a circle for the face and two eyes.
  2. This is used as the base for most expressions.

6.2 Happy Face

void drawHappy() {
display.clearDisplay();
drawFaceBase();
// Smile
display.drawLine(cx - 12, cy + 6, cx - 6, cy + 10, SSD1306_WHITE);
display.drawLine(cx - 6, cy + 10, cx + 6, cy + 10, SSD1306_WHITE);
display.drawLine(cx + 6, cy + 10, cx + 12, cy + 6, SSD1306_WHITE);
display.display();
}
  1. Clears the display, draws the base face, and then adds a smile using three lines.

6.3 Sad Face

void drawSad() {
display.clearDisplay();
drawFaceBase();
// Sad mouth
display.drawLine(cx - 12, cy + 12, cx - 6, cy + 8, SSD1306_WHITE);
display.drawLine(cx - 6, cy + 8, cx + 6, cy + 8, SSD1306_WHITE);
display.drawLine(cx + 6, cy + 8, cx + 12, cy + 12, SSD1306_WHITE);
display.display();
}
  1. Draws a sad mouth (an upside-down curve).

6.4 Crying Face

void drawCrying() {
drawSad();
// Tear
display.drawLine(cx - 10, cy - 2, cx - 10, cy + 10, SSD1306_WHITE);
display.display();
}
  1. Similar to sad face but adds a tear.

6.5 Choking Face

void drawChoking() {
display.clearDisplay();
display.drawCircle(cx, cy, r, SSD1306_WHITE);
// X eyes
display.drawLine(cx - 14, cy - 12, cx - 6, cy - 4, SSD1306_WHITE);
display.drawLine(cx - 6, cy - 12, cx - 14, cy - 4, SSD1306_WHITE);
display.drawLine(cx + 14, cy - 12, cx + 6, cy - 4, SSD1306_WHITE);
display.drawLine(cx + 6, cy - 12, cx + 14, cy - 4, SSD1306_WHITE);
// Small mouth
display.drawCircle(cx, cy + 12, 4, SSD1306_WHITE);
display.display();
}
  1. Draws a face with X-shaped eyes and a small circular mouth to indicate “overwatered” or choking.

7. Loop Function

void loop() {
int sensor_data = analogRead(sensor_pin);
int moisturePercent = map(sensor_data, DRY_VALUE, WET_VALUE, 0, 100);
moisturePercent = constrain(moisturePercent, 0, 100);

if (moisturePercent < 30){
drawCrying();
delay(5000);
}
else if (moisturePercent >= 30 && moisturePercent <= 49) {
drawSad();
delay(5000);
}
else if (moisturePercent >= 50 && moisturePercent <= 94){
drawHappy();
delay(5000);
}
else if (moisturePercent >= 95){
drawChoking();
delay(5000);
}
}

Step-by-step:

  1. Read sensor value: analogRead(sensor_pin) gives a number from 0–1023.
  2. Convert to percentage: map() converts the sensor reading to a 0–100% scale based on dry/wet calibration.
  3. Limit values: constrain() ensures it stays between 0–100.
  4. Display expression based on soil moisture:
  5. <30% → Crying (soil too dry)
  6. 30–49% → Sad (soil slightly dry)
  7. 50–94% → Happy (soil moisture good)
  8. ≥95% → Choking (soil too wet)
  9. delay(5000) pauses for 5 seconds before updating the display again.


Circuit Design

Screenshot 2026-01-10 224505.png

Connections are as follow:

1). Soil Sensor

VCC ---> Battery + (or Arduino 3.3V/5V)

GND ---> GND

A0 ---> Arduino A0


2). OLED Display (I2C)

VCC ---> Battery + (or Arduino 3.3V/5V)

GND ---> GND

SDA ---> Arduino A4

SCL ---> Arduino A5


3). Battery

+ ---> Arduino Vin / VCC (I have connected it with 5v Pin on Arduino)

- ---> Arduino GND

Assembly

Wiring DC Female.jpg
Wiring Oled.jpg
Wiring Sensor.jpg
DC Jack assembly 2.jpg
DC Jack Assembly 1.jpg
Assembly 3.jpg
Assembly 4.jpg
Assembly 5.jpg
Assembly 6.jpg
Assembly 7.jpg
Assembly 8.jpg
IMG20260110171316.jpg

Now we will start the assembly part, beginning with wiring. I did the wiring for the DC jack, then the OLED display, and then the soil moisture sensor. I installed the female DC jack on the base, then inserted the OLED panel into the window, and then added the soil moisture sensor. At the end, I made the necessary connections with the Arduino Nano and closed the base.

And at the end, I did a small check to see if everything is running fine.

Building Pot for Plant

IMG20260110184154.jpg
IMG20260110184334.jpg
WhatsApp Image 2026-01-10 at 22.52.57.jpeg

Now, with the remaining container, I will create a separate custom pot. I cut 7 cm off the height and added a plastic container inside to prevent water leakage. I also applied a wood-texture wallpaper decoration before planting my plant. Since this is a custom plant setup, I can easily create multiple pots with different plants and use them with the same base system.

Final Test

Test 1.jpg
Test 2.jpg
Test 3.jpg
Test 4.jpg

The above images show how water influences the emotion system:

  1. <30% → Crying (soil too dry)
  2. 30–49% → Sad (soil slightly dry)
  3. 50–94% → Happy (soil moisture good)
  4. ≥95% → Choking (soil too wet)

Conclusion

Intro 1.jpg
Intro 2.jpg
Intro 3.jpg

Plants play a crucial role in our lives. Without them, we cannot survive. Through this project, we try to understand plant-related problems. In future versions, I will incorporate various aspects such as gas levels, nutrient value, nitrogen content, etc., to make it a perfect companion for your favorite plant. I hope you like it, and please let me know your thoughts in the comments down below.