Plant Bartender

by ChristelleFeghali in Circuits > Arduino

1444 Views, 6 Favorites, 0 Comments

Plant Bartender

CDDF - Useless Machine Project - Summer 2021

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

Useless Machine (1).png

Material Needed

Image1_Components.png

Electronics:

Arduino Uno

Arduino UnoController Board Breadboard

Jumper Wires

Motors:

Servo SG90

Stepper Motor + ULN2003 Driver Test Module Board

Sensor:

3x Soil Moisture and Humidity Sensor

Power Source:

9V Battery

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

newnew.png
Untitled Sketch6t_bb_3.png

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

Useless Machine (1).png

#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);}

}

}

Testing of Components

GIF - Data Collection.gif
ezgif-2-5445be11c208.gif
ezgif.com-gif-maker (2).gif

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

Useless Machine (1).png

Wooden 2-Axis Robot

Image3_WoodenFrame.png

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.