Skip to content

Instantly share code, notes, and snippets.

@compnski
Created June 11, 2020 02:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save compnski/55f84c486b73c9abafec6ef652b5feb1 to your computer and use it in GitHub Desktop.
Save compnski/55f84c486b73c9abafec6ef652b5feb1 to your computer and use it in GitHub Desktop.
Robo-Plant Keeper. Water plants every few days.
#include <SoftwareSerial.h>
const int led_g = 2;
const int led_r = 9;
const int relay_1 = 4;
const int relay_2 = 5;
const int serial_tx = 11;
const int sw_top = 12;
const int sw_bottom = 13;
const int WAIT = 0;
const int WATER = 1;
int state = 0;
unsigned long lastWatered = 0;
unsigned long startedWatering = 0;
unsigned long totalWaterSec = 0;
unsigned long totalTimeSec = 0;
unsigned long lastRun = 0;
const int delayTime = 1000;
const long WATER_TIME_SEC = 30;
const long WAIT_TIME_SEC = (long)3600*72;
SoftwareSerial mySerial = SoftwareSerial(0, serial_tx, 1);
const char clearScreen[ ] = {
254,1,254,128,0};
void setup() {
// put your setup code here, to run once:
pinMode(led_r, OUTPUT);
pinMode(led_g, OUTPUT);
pinMode(relay_1, OUTPUT);
pinMode(relay_2, OUTPUT);
digitalWrite(relay_1, LOW);
digitalWrite(relay_2, LOW);
digitalWrite(led_r, LOW);
digitalWrite(led_g, LOW);
pinMode(sw_top, INPUT_PULLUP);
pinMode(sw_bottom, INPUT_PULLUP);
digitalWrite(serial_tx, LOW); // Stop bit state for inverted serial
pinMode(serial_tx, OUTPUT);
mySerial.begin(9600); // Set the data rate
lastRun = millis();
setStatus("Hello Claire!");
}
void setStatus(char* msg) {
mySerial.print(clearScreen);
mySerial.print(msg);
}
void startWatering() {
digitalWrite(led_r, HIGH);
startedWatering = millis();
digitalWrite(relay_1, HIGH);
digitalWrite(relay_2, HIGH);
state = WATER;
}
void stopWatering() {
digitalWrite(led_r, LOW);
lastWatered = millis();
totalWaterSec += max(lastWatered - startedWatering,1000) / 1000;
digitalWrite(relay_1, LOW);
digitalWrite(relay_2, LOW);
state = WAIT;
}
bool timeToWater() {
return nextWaterSec() < 0;
}
bool doneWatering() {
return (millis() > startedWatering + WATER_TIME_SEC*1000);
}
unsigned long lastWateredSec() {
return (millis() - lastWatered)/1000;
}
long nextWaterSec() {
return WAIT_TIME_SEC - lastWateredSec();
}
void updateScreen() {
char message[256];
//Last Watered: xx seconds ago
//Next Water in: xx seconds
//Total water time since restart??
snprintf(message, 256, "Last: %ld:%02ld\xFE\xC0Next: %ld:%02ld", lastWateredSec()/60,lastWateredSec()%60, nextWaterSec()/60,nextWaterSec()%60);
setStatus(message);
}
bool swTopState() {
return digitalRead(sw_top) == LOW;
}
bool swBottomState() {
return digitalRead(sw_bottom) == LOW;
}
void love() {
char message[256];
snprintf(message, 256, "<3 I love you <3\xFE\xC0%ld/%ld", totalWaterSec, totalTimeSec);
setStatus(message);
delay(1000);
}
void loop() {
totalTimeSec += max(millis() - lastRun, delayTime)/1000;
lastRun = millis();
// put your main code here, to run repeatedly:
if(swTopState()) {
if(swBottomState()) {
love();
return;
}
startWatering();
}
else if(swBottomState()) {
stopWatering();
}
switch(state) {
case WAIT:
if(timeToWater()) {
startWatering();
}
break;
case WATER:
if(doneWatering()) {
stopWatering();
}
break;
}
updateScreen();
delay(delayTime);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment