Particle IO Code
//Created by Langley Vogt
//https://diotlabs.daraghbyrne.me/docs/controlling-outputs-motors/servo/#step-2-controlling-a-servo
//https://docs.particle.io/tutorials/hardware-projects/maker-kit/
//CONSIDERED WATER LEVELS
//Good Example= 1327
//Bad < 800
//Very watered > 1800
int lowMoistThres = 600;
int highMoistThres = 1800;
//Define servo motor and name
Servo spinnerServo;
int servoPin = A0;
int servoPos = 0; //intialize at zero
//LED declarations
int ledGreen = D7;
int ledRed = D6;
int ledBlue = D5;
int ledYellow = D4;
//soil
int moistPin = A1;
int moistVal = 0;
//Speaker piezo
int speakerPin = D2;
//push button
int buttonPin = D8;
int buttonState;
//Note Definitions
int NOTE_C = 1046;
int NOTE_D = 1174;
int NOTE_E = 1318;
int lowNOTE_C = 1046/2;
int lowNOTE_E = 1318/2;
int yayMelody[] = {NOTE_C, NOTE_C, NOTE_C, NOTE_C, NOTE_D, NOTE_C, NOTE_D, NOTE_E};
int noteDuration[] = {4, 8, 8, 4, 4, 4, 4, 2};
int badMelody[] = {lowNOTE_E, lowNOTE_C};
int noteDuration2[] = {2, 2};
// store the last time published
int last_published = -1;
int last_publishedSMS = -1;
//*********************************************************************//
void setup() {
//Define which pin the servo is connected to
spinnerServo.attach(A0);
//Call function so person can enter angle on app
Particle.function("servo", servoControl); //control via cloud
//Push variable to console
Particle.variable("MoistureReading", moistVal);
Particle.variable("buttonState", buttonState);
//Declare led as output
pinMode(ledGreen, OUTPUT);
pinMode(ledRed, OUTPUT);
pinMode(ledBlue, OUTPUT);
pinMode(ledYellow, OUTPUT);
//Initialize leds off
digitalWrite(ledRed, LOW);
digitalWrite(ledGreen, LOW);
digitalWrite(ledBlue, LOW);
digitalWrite(ledYellow, LOW);
//define pin mode input/ouputs for non-leds
pinMode(moistPin, INPUT);
pinMode(buttonPin, INPUT_PULLUP);
}
void loop() {
//send published data to spreadsheet every minute
writeToSpreadsheet();
//initialize led lights off
digitalWrite(ledRed, LOW);
digitalWrite(ledGreen, LOW);
digitalWrite(ledBlue, LOW);
digitalWrite(ledYellow, LOW);
//Variable definitions
moistVal = analogRead(moistPin);
buttonState = digitalRead(buttonPin);
//if the soil is not moist enough, shine red led
if (moistVal < lowMoistThres) {
digitalWrite(ledRed, HIGH);
delay(100);
//send SMS to remind user to water plant
sendSMS();
}
//Soil is adequately moist, green
else if (moistVal > lowMoistThres && moistVal < highMoistThres) {
//digitalWrite(ledPin, HIGH);
digitalWrite(ledGreen, HIGH);
delay(100);
}
//Very moist soil, blue light indicator
else if (moistVal > highMoistThres) {
//digitalWrite(ledPin_3, HIGH);
digitalWrite(ledBlue, HIGH);
delay(100);
}
//else just turn off all the lights
else {
digitalWrite(ledGreen, LOW);
digitalWrite(ledRed, LOW);
digitalWrite(ledBlue, LOW);
digitalWrite(ledYellow, LOW);
}
//If the user presses the button and the plant was watered adequately, flash lights, play music and spin
if ( (moistVal > lowMoistThres) && (buttonState == LOW)) {
//flash lights
digitalWrite(ledRed, HIGH);
delay(300);
digitalWrite(ledGreen, HIGH);
delay(300);
digitalWrite(ledBlue, HIGH);
delay(300);
digitalWrite(ledYellow, HIGH);
delay(300);
//flash lights
digitalWrite(ledRed, LOW);
delay(300);
digitalWrite(ledGreen, LOW);
delay(300);
digitalWrite(ledBlue, LOW);
delay(300);
digitalWrite(ledYellow, LOW);
delay(300);
//play melody
playNotes();
//flash lights
digitalWrite(ledRed, HIGH);
delay(300);
digitalWrite(ledGreen, HIGH);
delay(300);
digitalWrite(ledBlue, HIGH);
delay(300);
digitalWrite(ledYellow, HIGH);
delay(300);
//flash lights
digitalWrite(ledRed, LOW);
delay(300);
digitalWrite(ledGreen, LOW);
delay(300);
digitalWrite(ledBlue, LOW);
delay(300);
digitalWrite(ledYellow, LOW);
delay(300);
//turn all on
digitalWrite(ledRed, HIGH);
digitalWrite(ledGreen, HIGH);
digitalWrite(ledBlue, HIGH);
digitalWrite(ledYellow, HIGH);
//Swivel forward
for (int angle = 0; angle < 180; angle++) {
spinnerServo.write(angle);
delay(10);
}
//pause
delay(200);
//Swivel backward
for (int angle2 = 180; angle2 > 0; angle2--) {
spinnerServo.write(angle2);
delay(10);
}
delay(100);
//Spin faster, 2 rounds
spinnerServo.write(90);
delay(800);
spinnerServo.write(0);
delay(800);
spinnerServo.write(90);
delay(800);
spinnerServo.write(0);
delay(800);
//turn all on
digitalWrite(ledRed, LOW);
digitalWrite(ledGreen, LOW);
digitalWrite(ledBlue, LOW);
digitalWrite(ledYellow, LOW);
//flash lights
digitalWrite(ledRed, HIGH);
delay(300);
digitalWrite(ledGreen, HIGH);
delay(300);
digitalWrite(ledBlue, HIGH);
delay(300);
digitalWrite(ledYellow, HIGH);
delay(300);
//flash lights
digitalWrite(ledRed, LOW);
delay(300);
digitalWrite(ledGreen, LOW);
delay(300);
digitalWrite(ledBlue, LOW);
delay(300);
digitalWrite(ledYellow, LOW);
delay(300);
delay(100);
}
//Button pressed but not enough moisture
else if ((moistVal < lowMoistThres) && (buttonState == LOW)) {
//change light to yay
digitalWrite(ledRed, LOW);
delay(10);
digitalWrite(ledRed, LOW);
delay(10);
digitalWrite(ledRed, LOW);
playBadNotes();
delay(100);
}
else {
//do nothing
}
delay(100);
}
//Melody that plays when plant is watered adequately
void playNotes()
{
//for loop for melody, total 26 notes
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 newNoteDurations = 1000/noteDuration[thisNote];
tone(speakerPin, yayMelody[thisNote],newNoteDurations);
// to distinguish the notes, set a minimum time between them.
// the note's duration + 30% seems to work well:
int pauseBetweenNotes = newNoteDurations * 1.30;
delay(pauseBetweenNotes);
//no tone
noTone(speakerPin);
}
}
void playBadNotes()
{
//for loop for melody, total 26 notes
for (int thisNote2 = 0; thisNote2 < 2; thisNote2++) {
// 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 newNoteDurations2 = 1000/noteDuration2[thisNote2];
tone(speakerPin, badMelody[thisNote2],newNoteDurations2);
// to distinguish the notes, set a minimum time between them.
// the note's duration + 30% seems to work well:
int pauseBetweenNotes2 = newNoteDurations2 * 1.30;
delay(pauseBetweenNotes2);
//no tone
noTone(speakerPin);
}
}
//Have user set angle for viewing position
int servoControl (String command) {
int newPos = command.toInt();
servoPos = constrain(newPos, 0, 180);
spinnerServo.write(servoPos);
return 1;
}
//Write data to spreadsheet
void writeToSpreadsheet() {
// check if 1 minute has elapsed
if( last_published + 60000 < millis() ){
Particle.publish( "writeToSpreadsheet", String(moistVal) );
last_published = millis();
}
}
//Notify plant owner via text message that their plant is thirsty
void sendSMS() {
// check if 1 minute has elapsed
//10 minutes is 6e8
if( last_publishedSMS + 60000 < millis() ){
Particle.publish( "sendSMS", String("Water your Plant!") );
last_publishedSMS = millis();
}
}
Click to Expand
Content Rating
Is this a good/useful/informative piece of content to include in the project? Have your say!
You must login before you can post a comment. .