Plant Bartender
This project was completed by Alexandra Pittiglio & Christelle Feghali for our Computational Design and Digital Fabrication 'Useless Machine' Project, Semester 2, ITECH M.Sc Programme
--------
We present Plant Bartender, a 2-axis robot that senses and waters in the most inefficient way.
This device utilizes soil moisture sensors to identify the thirst levels of multiple plants in a radial placement, waters them according to their need, and helps to express their status to the gardener caring for them through Super Mario theme song tunes and LEDs.
Concept
Material Needed
Electronics:
Arduino UnoController Board Breadboard
Motors:
Stepper Motor + ULN2003 Driver Test Module Board
Sensor:
3x Soil Moisture and Humidity Sensor
Power Source:
Body:
- 3x Plants
- Plastic cup for water reservoir: we used an old chewing gum container such as this
- Thin wire or string: taped to underside of water reservoir and fed to the rotational arm on the servo
- Axle for turning water reservoir: we used a small metal axle that was included with one of the motors
- Nails / screws as required for your wooden frame build
- Crazy Glue: used in some areas to secure components together where nails / screws were too large
- Wood for the Robotic Arm: This part is really up to the user. We opted to use salvaged wood from an old drawer set that a neighbour had put to the curb, to save on material and environmental cost. The wood was a thin plywood, and therefore light enough to not weigh down the function of the stepper motor at the base. Ensure to check torque against the expected weight of the robotic arm.
Arduino Circuit
Pin 8: Stepper iN1
Pin 10: Stepper iN2
Pin 9: Stepper iN3
Pin 11:Stepper iN4
Pin 12: Servo
Analog PIN A0: Humidity sensor1 at 45 Degrees
Analog PIN A1: Humidity sensor2 at 135 Degrees
Analog PIN A2: Humidity sensor3 at 315 Degrees
Code & Logic
#include <pitches.h>
#include <Servo.h>
#include <Stepper.h>
// SENSOR HUMIDITY
int SENSE1= 0; // Soil Sensor input at Analog PIN A0
int value1= 0;
int SENSE2= 1; // Soil Sensor input at Analog PIN A2
int value2= 0;
int SENSE3= 2; // Soil Sensor input at Analog PIN A3
int value3= 0;
//Melody
#define REST 0
#define NOTE_C5 523
#define NOTE_G4 392
#define NOTE_E4 330
//int speakerPin = 13;
int buzzer=8;
int melody[]={
NOTE_C5,-4, NOTE_G4,-4, NOTE_E4,4 //45 ;
};
int tempo= 200;
int notes = sizeof(melody) / sizeof(melody[0]) / 2;
// this calculates the duration of a whole note in ms
int wholenote = (60000 * 4) / tempo;
int divider = 0, noteDuration = 0;
int length = 1;
// MOTOR
int numberofstep = 48;
Stepper myStepper(numberofstep, 8, 10, 9, 11);
Servo myservo2;
void setup()
{
Serial.begin(9600);
delay(10000);
Serial.println("ROBOT READY...");
Serial.println("-----------------------------");
delay(5000);
Serial.println("SOIL MOISTURE SENSOR");
Serial.println("-----------------------------");
delay(5000);
myStepper.step(0);
myStepper.setSpeed(200);
myservo2.attach(12);
//myservo2.write(75);
}
void loop()
{
value1= analogRead(SENSE1);
value1= value1/10;
value2= analogRead(SENSE2);
value2 =value2/10;
value3= analogRead(SENSE3);
value3= value3/10;
int Moist[3] = {value1,value2,value3};
//MOVING BASE MOTOR
for( int i=0 ;i<=2;i++){
if (i == 0) {
myStepper.step(-500);
Serial.println("Moving to Plant Base 0");
delay(5000);}
if (i == 1) {
myStepper.step(-450);
Serial.println("Moving to Plant Base 1");
delay(5000);}
if (i == 2) {
myStepper.step(-650);
Serial.println("Moving to Plant Base 2");
delay(5000);}
//READING HUMIDITY
Serial.print("Moisture of plant ");
Serial.print(i);
Serial.print(": ");
Serial.print(Moist[i]);
Serial.print(" % ");
if (Moist[i] <= 20) {
Serial.println("Not moist enough");
// Play NEGATIVE Melody
for (int thisNote = 0; thisNote < notes * 2; thisNote = thisNote + 2) {
divider = melody[thisNote + 1];
if (divider > 0) {
noteDuration = (wholenote) / divider;
} else if (divider < 0) {
noteDuration = (wholenote) / abs(divider);
noteDuration *= 1.5; // increases the duration in half for dotted notes
tone(buzzer, melody[thisNote], noteDuration * 0.9);
delay(noteDuration);
noTone(buzzer);}
}
//WATER DROPPING
myservo2.write(15);
delay(3000);
// Play 1-up sound FINISHING TO DRINK
tone(8,NOTE_E6,125);
delay(130);
tone(8,NOTE_G6,125);
delay(130);
tone(8,NOTE_E7,125);
delay(130);
tone(8,NOTE_C7,125);
delay(130);
tone(8,NOTE_D7,125);
delay(130);
tone(8,NOTE_G7,125);
delay(125);
noTone(8);
delay(3000); // pause 3 seconds
myservo2.write(75);}
if ( Moist[i]> 20) {
Serial.println("Perfect Moisture!");
// WHEN Moist
tone(8,660,100);
delay(150);
tone(8,660,100);
delay(300);
tone(8,660,100);
delay(300);
tone(8,510,100);
delay(100);
tone(8,660,100);
delay(300);
tone(8,770,100);
delay(550);
tone(8,380,100);
delay(575);
tone(8,510,100);
delay(450);
tone(8,380,100);
delay(400);
tone(8,320,100);
delay(500);
tone(8,440,100);
delay(300);
tone(8,480,80);
delay(330);
tone(8,450,100);
delay(150);
tone(8,430,100);
delay(300);
tone(8,380,100);
delay(200);
tone(8,660,80);
delay(200);
tone(8,760,50);
delay(150);
tone(8,860,100);
delay(300);
tone(8,700,80);
delay(150);
tone(8,760,50);
delay(350);
tone(8,660,80);
delay(300);
tone(8,520,80);
delay(150);
tone(8,580,80);
delay(150);
tone(8,480,80);
delay(500);
tone(8,510,100);
delay(450);
tone(8,380,100);
delay(400);
tone(8,320,100);
delay(500);
tone(8,440,100);
delay(300);
tone(8,480,80);
delay(330);
tone(8,450,100);
delay(150);
tone(8,430,100);
delay(300);
tone(8,380,100);
delay(200);
tone(8,660,80);
delay(200);
tone(8,760,50);
delay(150);
tone(8,860,100);
delay(300);
tone(8,700,80);
delay(150);
tone(8,760,50);
delay(350);
tone(8,660,80);
delay(300);
tone(8,520,80);
delay(150);
tone(8,580,80);
delay(150);
tone(8,480,80);
delay(500);
}
if (i == 2) {
myStepper.step(1600);
Serial.println("Moving Back to Base");
delay(10000);}
}
}
Downloads
Testing of Components
Before building the whole circuit, test a few key elements of the project:
1- Check the accuracy of the soil moisture measurements through the serial monitor, some soil sensors requires calibration.
2- Check your servo motor's 0 --> 180 degree rotation points.
3- Check your stepper motor's rotation (PLEASE NOTE THE CORRECT PIN CONNECTIONS: Pin 8: Stepper iN1, Pin 10: Stepper, iN2 Pin 9: Stepper iN3 Pin 11:Stepper iN4).
4- Check that your rotational arm attached to the servo motor is of the correct length to flip the water basin once it pulls the wire, some tweaking of you device may be required. We connected a wire from the rotational arm to the front of the water basin to ensure it had enough movement to rotate at least 100 degrees and drop the water.
Testing of Sound
Check the SuperMario Bros sounds coming out of the Stepper module.
You can use the below script as a Test:
#include
// must include open source pitches.h found online in libraries folder
#include
Stepper myStepper(numberofstep, 8, 10, 9, 11);
void setup() {
Serial.begin(9600);
}
void loop() {
// Play 1-up sound FINISHING TO DRINK
tone(8,NOTE_E6,125);
delay(130);
tone(8,NOTE_G6,125);
delay(130);
tone(8,NOTE_E7,125);
delay(130);
tone(8,NOTE_C7,125);
delay(130);
tone(8,NOTE_D7,125);
delay(130);
tone(8,NOTE_G7,125);
delay(125);
noTone(8);
delay(2000); // pause 2 seconds
}
Body Components
Wooden 2-Axis Robot
You can have some fun with this part and make use of materials you have lying around, such as old wood. Some key things to keep in mind:
1 - Ensure the stepper motor is securely fixed to the base of the robotic arm. We drilled out a tight fitting hole for the turning mechanism, and also applied some self-expanding crazy glue.
2 - Ensure the servo motor gear is securely fixed to the extended rotational arm. We drilled out a tight fitting hole for the gear and also applied some self-expanding crazy glue.
3 - Drill out opposite holes into the water reservoir that are slightly larger in diameter than the axle, therefore allowing the axle and reservoir to rotate independently of one another without friction (ie. do not fix this connection point with glue)
4 - Drill out a small hole through the side of the rotational arm fixed to the servo. Feed a thin wire or thread through this hole and tie a knot. The opposite end of that wire or thread should attach to the underside of the water reservoir using duct tape.