A plant that will detect your presence and let you know it's current emotional (water) state.
Plants are often overlooked, forgotten and taken for granted. Considering the number of plants we kill everyday by failing to water them, the project aims to build a product that provides the owner with a subtle reminder to nourish these creatures, nudging them to water them through sound and light signals. The intention of the project is to build a relationship between the plant and the owner to ensure the plant's healthy growth and connect to its emotions through human touch.
The solution was designed around the idea that owner should be reminded to water the plants in a non-intrusive manner. To implement this, the plant interacts only when the owner passes by, and explains the condition of the water level: dry, appropriate or water logged, through sound and light signals.
- If the condition is dry, the plant cries and signals via a red light. This prompts the owner to water the plant.
- If the condition is appropriate for the plant, it stops crying and gives a thumbs up via a green light.
- If the plant becomes dank, it starts crying again and signals a blue light, nudging the owner to stop watering.
- This information is also sent across to the owner via sms if they are not around the plant.
Furthermore, to create an emotional bond between the plant and the owner, the product introduces the concept of human touch. When the owner touches the plant pot, the crying ceases, hence making it feel better.
The design approach of the project was inspired by ambient products. There are products that trigger the users to water plants through intrusive reminders that builds a frustrating environment. In order to resolve this and provide the relevant information in a non-distractive manner, the product (plant) reacts to the motion of the user and then conveys its state, hence, demanding attention only when the owner is around.
Additionally, the manner in which the information is provided is through sound and light, while being expressive about the plant's emotions: crying and happy, and how it stops when the owner touches it.
The initial idea was to use the motion detection that will assist the plant towards a healthy growth. To implement this, I used the motion detector; once the motion is detected, soil moisture sensor detects the water level and coveys the state via piezo sensors and LED.
The information is displayed by also expressing the emotions of the plant at the same time:
LOW WATER- RED LED- CRYING TONE
OPTIMUM WATER-GREEN LED-HAPPY TONE
EXTRA WATER-BLUE LED-NO TONE
The major challenge encountered was the extra sensitivity of the motion detector, which made it difficult to gauge the accurate results. Eventually, the design decision was to consider the state: motion detected at all times and work on the further conditions.
The process evolved when trying to resolve the issue of making the tones stop. This was analogous to empathising with the plant through the touch, hence, the fsr sensor came in picture. In addition to stopping the tone, the idea was to also put a happy/lively/excited LED, that is, RGB, which talks about the state of the plant when the owner is around to nourish it.
Another challenge was to make the RGB work on the fsr sensor and how to convert the fsr sensor into a button such that the output changes once there is no force reading on the fsr pin (no one is touching the fsr). This was resolved by adding a toggle variable (0 and 1 value) and using it with every changing state.
Following is the design process flow:
Wave-to-water from saumya sharma on Vimeo.
There is a lot of scope for improvement in the project, especially in terms of providing clearer signals and prototyping it further.
- The plant can have more sensors such as heat, temperature and gas sensors to provide with data that will support its healthy growth
- The plant can display the information in a more expressive by merging emoticons (such as Lua planter) with LEDs
- Instead of the motion detector, I was thinking of using Piezo electronic force sensor as the alternative for the footsteps detection, that will retain the initial concept of the project but will give more accurate results
- In the initial stages of the project, I tried to understand the basics of circuit-design and how to write the code to make it work, using different components and sensors. It took me some time to learn how to merge the design ideas with circuit and coding segments, but that is a major skill I acquired through this process.
- Another important learning was how to go one step a time in the process of building a circuit and designing it in a legible format, with appropriate commenting in the code. There were times, when I had to redo the entire circuit because I was unable to debug the problem.
- To understand the function of the product and the value it is going to create is the first step to move ahead, and then building up with the secondary ideas and additions to that main functionality.
- https://www.hackster.io/gr1m/particle-photon-pir-sensor-and-event-reporting-268aa0
- https://www.indiegogo.com/projects/lua-the-smart-planter-with-feelings#/
- https://www.kickstarter.com/projects/fyta/fyta-beam-the-smart-plant-sensor
dioT references:
- https://diotlabs.daraghbyrne.me/docs/working-with-sensors/fsrs/
- https://diotlabs.daraghbyrne.me/docs/controlling-outputs-sound/piezo/
- https://diotlabs.daraghbyrne.me/docs/ifttt
//Code for the DioT_SmartPlant
int ledPinR = D2; // define a variable to display low moisture level
int ledPinG = D3; // define a variable to display optimum moisturelevel
int ledPinB = D4; // define a variable to display water-logged level
int ledBrightness = 0; // define a variable to read analog value; intial value=0
int redPin = A2; // RED pin of the RGBLED
int greenPin = A3; // GREEN pin of the RGBLED
int bluePin = A4; // BLUE pin of the RGBLED
int redValue = 255; // Full brightness for an Cathode RGB LED is 0, and off 255
int greenValue = 255; // Full brightness for an Cathode RGB LED is 0, and off 255
int blueValue = 255; // Full brightness for an Cathode RGB LED is 0, and off 255
int moistPin = A1; // define a variable to detect the soil moisture
int moistVal = 0; // define a variable to read the analog value of moisture sensor
int speakerPin = D5; // variable for the piezo pin
int melody[] = {100,200,100,200,100,300,500,300,500,100,200,100,200,100,300,500,300,500,100}; // create an array for the notes in the melody 1:
int melody2[] = {2500,3000,5000,4000,3000,2500,2000,3000,4000,4000,3000,2000,2500,3000,4000,5000,3000,2500};//{2500,2500,3000,5000,4000,3000,2500,2500,1900,3000,1000,1000,3000,1900,2500,2500,3000,4000,5000,3000,2500,2500}; // create an array for the notes in the melody 2:
int noteDurations[] = {4,4,6,6,6,6,8,8,8,8,8,8,6,6,6,6,4,4}; //create an array for the duration of notes.
int inputPin = D6; // variable for the input pin (for PIR sensor)
int pirState = LOW; // to start, assuming no motion detected
int val = 0; // variable for reading the PIR pin status
int fsrPin = A5; // define a variable to detect the fsr force
int fsrReading = 0; // define a variable to read the analog value of fsr
int toggle=0; // variable for switch button for fsr
int toggle_2=0; // variable for second switch button for fsr
int calibrateTime = 5000;// wait for the thingy to calibrate
int last_published = -1;
void setup() {
pinMode(speakerPin, OUTPUT);
pinMode(ledPinR, OUTPUT); // declare red pin as output for detecting moisture
pinMode(ledPinG, OUTPUT); // declare green pin as output for detecting moisture
pinMode(ledPinB, OUTPUT); // declare green pin as output for detecting moisture
pinMode(inputPin, INPUT_PULLUP); // declare PIR sensor as input
Particle.variable( "soilMoisture", moistVal ); // put the soil moisture value on the cloud
pinMode(redPin, OUTPUT); // declare red pin as output for RGB
pinMode(bluePin, OUTPUT); // declare blue pin as output for RGB
pinMode(greenPin, OUTPUT); // declare green pin as output for RGB
Particle.variable("fsrForce", &fsrReading, INT); // put the fsr force value on the cloud
// turn them all off
analogWrite( redPin, redValue);
analogWrite( greenPin, greenValue);
analogWrite( bluePin, blueValue);
}
void loop()
{
// if the sensor is calibrated
if (calibrated())
{
// get the data from the sensor
readTheSensor();
// report it out, if the state has changed
reportTheData();
}
moistVal = analogRead(moistPin); // read the analog value from the soil moisture sensor
fsrReading = analogRead(fsrPin); // to read the analog value from the fsr sensor
}
void readTheSensor() {
val = digitalRead(inputPin); // to detect the motion
}
bool calibrated() {
return millis() - calibrateTime > 0; // condition to start the process
}
void setRedLED() {
digitalWrite(ledPinR, HIGH); // turn red led pin on
}
void setGreenLED2(){
digitalWrite(ledPinG, HIGH); // turn green led pin on
}
void setBlueLED3(){
digitalWrite(ledPinB, HIGH); // turn blue led pin on
}
void setLEDoff()
{
// turn all of them off...
digitalWrite(ledPinR,LOW);
digitalWrite(ledPinG,LOW);
digitalWrite(ledPinB,LOW);
}
void reportTheData() {
if (val == HIGH) {
// the current state is no motion
// i.e. it's just changed
// announce this change by publishing an event
if (pirState == LOW)
{
// we have just turned on
Particle.publish("PhotonMotion", "Motion Detected", PRIVATE);
// Update the current state
if(moistVal>3600 && fsrReading <100)
{
toggle_2=0;
setLEDoff();
setRedLED();
if(toggle==0)
playNotes1();
}
else if (moistVal>0 && moistVal < 1900 && fsrReading <100)
{
toggle_2=0;
toggle=0;
setLEDoff();
setBlueLED3();
}
else if (moistVal>1900 && moistVal <3600 && fsrReading <100)
{
setLEDoff();
setGreenLED2();
if(toggle_2==0)
playNotes2();
toggle=0;
}
pirState = HIGH;
}
else if (fsrReading >100)
{
noTone(speakerPin);
toggle=1;
toggle_2=1;
redValue=rand()%255+1; //getting random value for red between 0 and 255(including the limits)
greenValue=rand()%255+1; //getting random value for green between 0 and 255(including the limits)
blueValue=rand()%255+1; //getting random value for blue between 0 and 255(including the limits)
analogWrite(redPin, redValue); //output the red led
analogWrite(greenPin, greenValue);//output the green led
analogWrite(bluePin, blueValue);//output the blue led
// turn them all off...
delay(100);
}
analogWrite( redPin, 255);
analogWrite( greenPin, 255);
analogWrite( bluePin, 255);
}
else {
//digitalWrite(ledPin, LOW);
if (pirState == HIGH) {
// we have just turned of
// Update the current state
Particle.publish("PhotonMotion", "Off", PRIVATE);
pirState = LOW;
noTone(speakerPin);
}
}
}
//void reportTheData() {
// if (val == HIGH) {
// the current state is no motion
// i.e. it's just changed
// announce this change by publishing an event
// if (pirState == LOW) {
// we have just turned on
// Particle.publish("PhotonMotion", "Motion Detected", PRIVATE);
// Update the current state
// pirState = HIGH;
// if(moistVal>1500) {
// setRedLED(pirState);
// playNotes1();
//}else if (moistVal <900);{
//setBlueLED3(pirState);
//playNotes1();
// } }else if (900 < moistVal <1500 ){
// setGreenLED2(pirState);
// playNotes2();
//}
// } else {
//digitalWrite(ledPin, LOW);
// if (pirState == HIGH) {
// we have just turned of
// Update the current state
// Particle.publish("PhotonMotion", "Off", PRIVATE);
// pirState = LOW;
// setRedLED(pirState);
// }
// }
//}
void playNotes1()
{
// iterate over the notes of the melody:
for (int thisNote = 0; thisNote < 8; thisNote++) {
// to calculate the note duration, take one second
// divided by the note type.
//e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
int noteDuration = 1000/noteDurations[thisNote];
tone(speakerPin, melody[thisNote],noteDuration);
// to distinguish the notes, set a minimum time between them.
// the note's duration + 30% seems to work well:
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
// stop the tone playing:
noTone(speakerPin);
}
}
void playNotes2()
{
// iterate over the notes of the melody:
for (int thisNote = 0; thisNote < 8; thisNote++) {
// to calculate the note duration, take one second
// divided by the note type.
//e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
int noteDuration = 1000/noteDurations[thisNote];
tone(speakerPin, melody2[thisNote],noteDuration);
// to distinguish the notes, set a minimum time between them.
// the note's duration + 30% seems to work well:
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
// stop the tone playing:
noTone(speakerPin);
}
}
Click to Expand
A hands-on introductory course exploring the Internet of Things and connected product experiences.
A plant that will detect your presence and let you know it's current emotional (water) state.
November 6th, 2019