Frequently I am too busy and forget to water the plants. To solve this problem, I am building a portable soil moisture meter that displays reading on an OLED display and plays some melody thru a buzzer. The reading of sensor data will also be displayed on a Cayenne dashboard. I am using recyclable plastic bottle to house the equipment. You can use other type of container or better still print a 3D enclosure.
With the mobility of the meter and convenience of a Cayenne's mobile app dashboard and alerts, I can find out if a plant needs some watering anytime and anywhere!
Hookup Soil Moisture SensorRefer to this link to setup the soil moisture sensor.
Hookup Micro OLED BreakoutRefer to this link to setup the micro OLED breakout.
Hookup ESP8266 Thing - Dev BoardRefer to this link to setup the ESP8266 Thing - Dev board. This includes setting up the Arduino IDE.
Hookup BuzzerRefer to this link to setup the buzzer.
Putting the parts togetherPlastic bottle
Assembly of parts:
Final product:
.
The Code explainedRefer to the code section for the source code.
Function setup():
void setup() {
//Serial.begin(9600); // open serial over USB
Cayenne.begin(username, password, clientID, ssid, wifiPassword);
oled.begin(); // Initialize the OLED
oled.clear(ALL); // Clear the display's internal memory
randomSeed(analogRead(A0));
pinMode(soilPower, OUTPUT);//Set D7 as an OUTPUT
digitalWrite(soilPower, LOW);//Set to LOW so no power is flowing through the sensor
pinMode(buzzerPin, OUTPUT);
}
Function loop():
If the value of val
is less than 500, the buzzer will play the notes. Currently no calibration or value normalization is implemented within the code. Raw values of sensor are displayed and commpared to the moisture threshold value of 500.
void loop() {
lastMillis = millis();
Cayenne.virtualWrite(0, val);
Cayenne.luxWrite(2, random(1024)); // this is data values for testing
showSplash();
readSoil();
showMoisture();
if (val < 500) playNotes();
delay(5000);
}
Cayenne definition:
// This example shows how to connect to Cayenne using an ESP8266 and send/receive sample data.
// Make sure you install the ESP8266 Board Package via the Arduino IDE Board Manager and select the correct ESP8266 board before compiling.
//#define CAYENNE_DEBUG
#define CAYENNE_PRINT Serial
#include <CayenneMQTTESP8266.h>
// WiFi network info.
char ssid[] = "ssid";
char wifiPassword[] = "wifiPassword";
// Cayenne authentication info. This should be obtained from the Cayenne Dashboard.
char username[] = "MQTT_USERNAME";
char password[] = "MQTT_PASSWORD";
char clientID[] = "CLIENT_ID";
unsigned long lastMillis = 0;
MicroOLED definition:
#define PIN_RESET 5 // Connect RST to pin 5
#define PIN_DC 4 // Connect DC to pin 4
#define PIN_CS 15 // Connect CS to pin 15
MicroOLED oled(PIN_RESET, PIN_DC, PIN_CS); // SPI declaration
Function showSplash():
void showSplash() {
oled.clear(PAGE);
for (int i=0; i<512; i++)
{
oled.pixel(random(oled.getLCDWidth()), random(oled.getLCDHeight()));
oled.display();
}
delay(1000);
}
Function showMoisture():
This function displays the moisture reading.
void showMoisture() {
oled.clear(PAGE); // Clear the display
oled.setCursor(0, 8); // Set cursor to top-left
oled.setFontType(0); // Smallest font
oled.print("Moisture"); // Print "A0"
oled.setCursor(0, 24);
oled.setFontType(2); // 7-segment font
oled.print(val); // Print a0 reading
oled.display();
delay(2000);
}
Moisture sensor definition:
int val = 0; //value for storing moisture value
int soilPin = A0;//Declare a variable for the soil moisture sensor
int soilPower = 0;//Variable for Soil moisture Power
Function readSoil():
This function gets the moisture sensor reading. Only power the sensor when you are taking a reading helps to extend of lifespan of your sensor. The easy way to accomplish this is using a digital pin set to HIGH value.
int readSoil()
{
digitalWrite(soilPower, HIGH);//turn D7 "On"
delay(10);//wait 10 milliseconds
val = analogRead(soilPin);//Read the SIG value form sensor
digitalWrite(soilPower, LOW);//turn D7 "Off"
return val;//send current moisture value
}
Buzzer definition:
const int buzzerPin = 16;
// We'll set up an array with the notes we want to play
// change these values to make different songs!
// Length must equal the total number of notes and spaces
const int songLength = 18;
// Notes is an array of text characters corresponding to the notes
// in your song. A space represents a rest (no tone)
char notes[] = "cdfda ag cdfdg gf "; // a space represents a rest
// Beats is an array of values for each note and rest.
// A "1" represents a quarter-note, 2 a half-note, etc.
// Don't forget that the rests (spaces) need a length as well.
int beats[] = {1,1,1,1,1,1,4,4,2,1,1,1,1,1,1,4,4,2};
// The tempo is how fast to play the song.
// To make the song play faster, decrease this value.
int tempo = 113;
Function playNotes():
This function plays notes with buzzer.
void playNotes() {
int i, duration;
for (i = 0; i < songLength; i++) // step through the song arrays
{
duration = beats[i] * tempo; // length of note/rest in ms
if (notes[i] == ' ') // is this a rest?
{
delay(duration); // then pause for a moment
}
else // otherwise, play the note
{
tone(buzzerPin, frequency(notes[i]), duration);
delay(duration); // wait for tone to finish
}
delay(tempo/10); // brief pause between notes
}
}
The Schematics diagram explainedRefer to the schema section for the diagram.
The Cayenne DashboardAdd and connect device.
Device readings.
Device settings.
Create triggers and alerts.
Mobile login.
Add device.
Moisture readings.
Cayenne projects.
Triggers and alerts:
Here is the video link. The buzzer will play melody notes if the moisture value is less than 500. While the sensor touching the damp cloth, the buzzer will not play the melody.
Comments