Arduino - GR33NT0Y v1.0

Potastica

Active Member
Well let start with I'm by far a good programmer and not licensed for electrical, but have worked in both fields for many years and picked up a few things over that time that has helped me with this project.
I wanted to setup my spare room to be able to grow enough for myself plus a little extra in case friends or family pop by too...where I live we can grow 4 plants indoor.
So after a bunch of trying things and doing a bunch of tests I have gotten this far.
I built a large box and split it in to 4 sections. Each section can be controlled individually and cut off from the others. (pic 1)
Wired up some 120vac plugs to relay boards that I did a little swap of relays to 1 of them because they run 2amps and I needed 3.75-4amps. (pic 2)
Started programming the Arduino...knew a little HTML, C++ Basic and old school stuff...so its been a bit of a learning curve too...lol
I'll post code I used in next post, but I'm in process of having SD card implemented to read values from *.txt file and save readings and so on. Right now I just set the times I want in the code and write it to mega so if I want to change I have to connect to PC and re-write...been a pain when theres a bug to fix...lol
I also made up and connected 8 temperature probes...2 for each box...1 water and 1 plants canopy height.
More to come soon...lol
 

Attachments

  • 20190426_091956.jpg
    20190426_091956.jpg
    308.9 KB · Views: 92
  • 20190427_160813.jpg
    20190427_160813.jpg
    764.3 KB · Views: 99
  • 20190219_183029.jpg
    20190219_183029.jpg
    439 KB · Views: 97
Now remember I'm no pro...just learning parts as I need them...lol
And a bunch of things are edited out because I haven't figured them out properly yet or just turned it off or for some reason.

Code:
//========================================================================================================================================
//  USER SETTINGS FOR TIMERS (4 X RELAYS)
//  Use "army" time for settings...minus the "0"...example...09:00 (9am) = 9 as value....0 = Midnight/12:00am
//  00 to 23.
//  Cannot do pm to am unless you reverse digitalRead(s) & digitalWrites for that Timer/Relay # and reverse times
//  for ON/OFF, due to now setting an OFF Run Time instead of ON Run Time.
//========================================================================================================================================

//      BOX 1 - TOP LEFT

//LIGHT
int L1_S = 7;       //Starting @
int L1_E = 19;      //Ending @

//WATER PUMP
int P1_S = 2;       //Every x minutes
int P1_R = 10;      //For y seconds

int G1_D = 1;     //Day to start
int G1_M = 1;     //Month to start
int G1_Y = 2018;  //Year to start
int G1_L = 60;    //Grow for x days

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

//      BOX 2 - TOP RIGHT

//LIGHT
int L2_S = 7;       //Starting @
int L2_E = 23;      //Ending @

//WATER PUMP
int P2_S = 1;       //Every x minutes
int P2_R = 10;      //For y seconds

int G2_D = 1;     //Day to start
int G2_M = 1;     //Month to start
int G2_Y = 2018;  //Year to start
int G2_L = 60;    //Grow for x days

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

//      BOX 3 - BOTTOM LEFT

//LIGHT
int L3_S = 7;       //Starting @
int L3_E = 19;      //Ending @

//WATER PUMP
int P3_S = 1;       //Every x minutes
int P3_R = 5;      //For y seconds

int G3_D = 1;     //Day to start
int G3_M = 1;     //Month to start
int G3_Y = 2018;  //Year to start
int G3_L = 60;    //Grow for x days

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

//      BOX 4 - BOTTOM RIGHT

//LIGHT
int L4_S = 7;       //Starting @
int L4_E = 23;      //Ending @

//WATER PUMP
int P4_S = 1;       //Every x minutes
int P4_R = 5;      //For y seconds

int G4_D = 1;     //Day to start
int G4_M = 1;     //Month to start
int G4_Y = 2018;  //Year to start
int G4_L = 60;    //Grow for x days

//========================================================================================================================================

#include <TimeLib.h>
#include <Wire.h>
#include <DS1307RTC.h>
#include <UTFT.h>
#include <avr/pgmspace.h>

#define TIME_Q   'T'
#define DAY_Q   'D'
#define MONTH_Q   'M'
#define YEAR_Q   'Y'
#define hour_Q   'h'
#define minute_Q   'm'
#define second_Q   'x'
#define read_Q   'r'
#define clrScrn_Q    'c'
#define reset_Q   'R'
#define preset_Q  'p'
#define misc_Q  's'
#define menu_Q  '?'

static boolean isLongFormat = true;

extern uint8_t SmallFont[];         //40 Characters X 20 Lines (8x12 px)
extern uint8_t BigFont[];           //20 Characters X 15 Lines (16x16 px)

const char *MITY[12] = {"Dec", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov"};

String D = "";
String C = "";
int Y = 2019;
String data = "";
double TempC;
double TempF;
String TempChoice = "C";    //"C" or "F"
int CurDay = 10;

//DISPLAY TO USE
UTFT myGLCD(HX8347I,38,39,40,41);
//UTFT myGLCD(SSD1289,38,39,40,41);

void setup() 
{
  Serial.begin(9600);

  Read_RTC();

  myGLCD.InitLCD(0);   //0=Portrait 1=Landscape (default) ??=Rotate 90' (90/180/270)
  myGLCD.clrScr();

//BOX 1 - TOP LEFT
  pinMode(14, OUTPUT);    //RELAY 1 #1 - Lights
  pinMode(16, OUTPUT);    //RELAY 1 #2 - Water Pump
  pinMode(A8, INPUT);     //SENSOR #1 - Box Temp
  pinMode(A9, INPUT);     //SENSOR #2 - Water Temp
 
//BOX 2 - TOP RIGHT 
  pinMode(15, OUTPUT);    //RELAY 1 #3 - Lights
  pinMode(17, OUTPUT);    //RELAY 1 #4 - Water Pump
  pinMode(A10, INPUT);    //SENSOR #3 - Box Temp
  pinMode(A11, INPUT);    //SENSOR #4 - Water Temp
 
//BOX 3 - BOTTOM LEFT
  pinMode(8, OUTPUT);     //RELAY 2 #1 - Lights
  pinMode(10, OUTPUT);    //RELAY 2 #2 - Water Pump
  pinMode(A12, INPUT);    //SENSOR #5 - Box Temp
  pinMode(A13, INPUT);    //SENSOR #6 - Water Temp
 
//BOX 4 - BOTTOM RIGHT
  pinMode(9, OUTPUT);     //RELAY 2 #3 - Lights
  pinMode(11, OUTPUT);    //RELAY 2 #4 - Water Pump
  pinMode(A14, INPUT);    //SENSOR #7 - Box Temp
  pinMode(A15, INPUT);    //SENSOR #8 - Water Temp

  listMenu();
}

void loop()
{
  myGLCD.setColor(255, 255, 255);
  myGLCD.drawRect(0,0,239,319);     //Main outside frame
  myGLCD.drawRect(1,1,238,70);      //Top center frame
  myGLCD.drawRect(1,71,120,195);    //BOX 1 - Top Left frame
  myGLCD.drawRect(121,71,238,195);  //BOX 2 - Top Right frame
  myGLCD.drawRect(1,196,120,318);   //BOX 3 - Bottom Left frame
  myGLCD.drawRect(121,196,238,318); //BOX 4 - Bottom Right frame
 
  myGLCD.setColor(0, 0, 255);
  myGLCD.setFont(BigFont);
  myGLCD.print("GR33NT0Y v1.0", CENTER, 6);
  myGLCD.drawLine(2, 25, 237, 25);

  if (year() > Y or year() < Y) {Read_RTC();}
 
  Date(CENTER, 30);
  Clock(CENTER, 50);
 
  portCheck();
 
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

//BOX 1 - Top Left
 
  myGLCD.setFont(SmallFont);  //14 chars per line MAX
  myGLCD.setColor(255, 255, 255);
  myGLCD.print("< Plant Name >", 5, 73);
  if (L1_E - L1_S > 12) {myGLCD.print("   F Cycle    ", 5, 83);} else {myGLCD.print("   V Cycle    ", 5, 83);}
  if (CurDay < 10) {myGLCD.print(" Day 0" + String(CurDay) + " of " + String(G1_L), 5, 93);} else {myGLCD.print(" Day " + String(CurDay) + " of " + String(G1_L), 5, 93);}
  myGLCD.print("--------------", 5, 103); 
 
  myGLCD.setFont(BigFont);    //7 chars per line MAX

// Lights
  if (hour() < L1_S or hour() > L1_E - 1 && digitalRead(14) == 0) {digitalWrite(14, 1);}
  if (hour() >= L1_S && hour() <= L1_E - 1 && digitalRead(14) == 1) {digitalWrite(14, 0);}
  //if (digitalRead(14) == 0) {myGLCD.setColor(0, 255, 0);} else {myGLCD.setColor(255, 0, 0);}
  myGLCD.print(String(L1_S) + " - " + String(L1_E), 4, 118);        //LIGHT TIMER

// Box Temperature
  TempCheck(A8, 3, 133);
 
//BLANK
  myGLCD.print("", 3, 148);               

// Water Temperature
  TempCheck(A9, 3, 163);

// Water Pump
  if ((digitalRead(16) == 1) && (minute() % P1_S == 0) && (second() < P1_R)) {digitalWrite(16, 0);}
  if ((digitalRead(16) == 0) && (second() > P1_R - 1)) {digitalWrite(16, 1);}
  //if (digitalRead(16) == 1) {myGLCD.setColor(255, 0, 0);} else {myGLCD.setColor(0, 255, 0);}
  myGLCD.print(String(P1_R) + " : " + String(P1_S), 3, 178);
 
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

//BOX 2 - Top Right
 
  myGLCD.setFont(SmallFont);  //14 chars per line MAX
  myGLCD.setColor(255, 255, 255);
  myGLCD.print("< Plant Name >", 125, 73);
  if (L2_E - L2_S > 12) {myGLCD.print("   F Cycle    ", 125, 83);} else {myGLCD.print("   V Cycle    ", 125, 83);}
  if (CurDay < 10) {myGLCD.print(" Day 0" + String(CurDay) + " of " + String(G2_L), 125, 93);} else {myGLCD.print(" Day " + String(CurDay) + " of " + String(G2_L), 125, 93);}
  myGLCD.print("--------------", 125, 103);
 
  myGLCD.setFont(BigFont);    //7 chars per line MAX

// Lights
  if (hour() < L2_S or hour() > L2_E - 1 && digitalRead(15) == 0) {digitalWrite(15, 1);}
  if (hour() >= L2_S && hour() <= L2_E - 1 && digitalRead(15) == 1) {digitalWrite(15, 0);}
  //if (digitalRead(15) == 0) {myGLCD.setColor(0, 255, 0);} else {myGLCD.setColor(255, 0, 0);}
  myGLCD.print(String(L2_S) + " - " + String(L2_E), 123, 118);        //LIGHT TIMER

// Box Temperature
  TempCheck(A10, 123, 133);
 
//BLANK
  myGLCD.print("", 123, 148);               

// Water Temperature
  TempCheck(A11, 123, 163);
 
// Water Pump
  if ((digitalRead(17) == 1) && (minute() % P2_S == 0) && (second() < P2_R)) {digitalWrite(17, 0);}
  if ((digitalRead(17) == 0) && (second() > P2_R - 1)) {digitalWrite(17, 1);}
  //if (digitalRead(17) == 1) {myGLCD.setColor(255, 0, 0);} else {myGLCD.setColor(0, 255, 0);}
  myGLCD.print(String(P2_R) + " : " + String(P2_S), 123, 178);
 
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

//BOX 3 - Bottom Left
 
  myGLCD.setFont(SmallFont);  //14 chars per line MAX
  myGLCD.setColor(255, 255, 255);
  myGLCD.print("< Plant Name >", 5, 197);
  if (L3_E - L3_S > 12) {myGLCD.print("   F Cycle    ", 5, 207);} else {myGLCD.print("   V Cycle    ", 5, 207);}
  if (CurDay < 10) {myGLCD.print(" Day 0" + String(CurDay) + " of " + String(G3_L), 5, 217);} else {myGLCD.print(" Day " + String(CurDay) + " of " + String(G3_L), 5, 217);}
  myGLCD.print("--------------", 5, 227);     
 
  myGLCD.setFont(BigFont);    //7 chars per line MAX
 
// Lights
  if (hour() < L3_S or hour() > L3_E - 1 && digitalRead(8) == 0) {digitalWrite(8, 1);}
  if (hour() >= L3_S && hour() <= L3_E - 1 && digitalRead(8) == 1) {digitalWrite(8, 0);}
  //if (digitalRead(8) == 0) {myGLCD.setColor(0, 255, 0);} else {myGLCD.setColor(255, 0, 0);}
  myGLCD.print(String(L3_S) + " - " + String(L3_E), 3, 242);        //LIGHT TIMER
 
// Box Temperature
  TempCheck(A12, 3, 257);
 
//BLANK
  myGLCD.print("", 3, 272);               
 
// Water Temperature
  TempCheck(A13, 3, 287);

// Water Pump
  if ((digitalRead(10) == 1) && (minute() % P3_S == 0) && (second() < P3_R)) {digitalWrite(10, 0);}
  if ((digitalRead(10) == 0) && (second() > P3_R - 1)) {digitalWrite(10, 1);}
  //if (digitalRead(10) == 1) {myGLCD.setColor(255, 0, 0);} else {myGLCD.setColor(0, 255, 0);}
  myGLCD.print(String(P3_R) + " : " + String(P3_S), 3, 302);

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

//BOX 4 - Bottom Right
 
  myGLCD.setFont(SmallFont);  //14 chars per line MAX
  myGLCD.setColor(255, 255, 255);
  myGLCD.print("< Plant Name >", 125, 197);
  if (L4_E - L4_S > 12) {myGLCD.print("   F Cycle    ", 125, 207);} else {myGLCD.print("   V Cycle    ", 125, 207);}
  if (CurDay < 10) {myGLCD.print(" Day 0" + String(CurDay) + " of " + String(G4_L), 125, 217);} else {myGLCD.print(" Day " + String(CurDay) + " of " + String(G4_L), 125, 217);}
  myGLCD.print("--------------", 125, 227);
 
  myGLCD.setFont(BigFont);    //7 chars per line MAX
 
// Lights
  if (hour() < L4_S or hour() > L4_E - 1 && digitalRead(9) == 0) {digitalWrite(9, 1);}
  if (hour() >= L4_S && hour() <= L4_E - 1 && digitalRead(9) == 1) {digitalWrite(9, 0);}
  //if (digitalRead(9) == 0) {myGLCD.setColor(0, 255, 0);} else {myGLCD.setColor(255, 0, 0);}
  myGLCD.print(String(L4_S) + " - " + String(L4_E), 123, 242);        //LIGHT TIMER
 
// Box Temperature
  TempCheck(A14, 123, 257);
 
//BLANK
  myGLCD.print("", 123, 272);               
 
// Water Temperature
  TempCheck(A15, 123, 287);

// Water Pump
  if ((digitalRead(11) == 1) && (minute() % P4_S == 0) && (second() < P4_R)) {digitalWrite(11, 0);}
  if ((digitalRead(11) == 0) && (second() > P4_R - 1)) {digitalWrite(11, 1);}
  //if (digitalRead(11) == 1) {myGLCD.setColor(255, 0, 0);} else {myGLCD.setColor(0, 255, 0);}
  myGLCD.print(String(P4_R) + " : " + String(P4_S), 123, 302);
 
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
}

void Date(int h, int v)
{
  D = MITY[month()];
  if (day() < 10) {D = D + " 0"  + String(day());} else {D = D + " "  + String(day());}
  D = D + " " + String(year());
  myGLCD.setColor(255, 255, 255);
  myGLCD.setFont(BigFont);
  myGLCD.print(" " + D + " ", h, v);
}

void Clock(int h, int v)
{
  C = hour();
  if (hour() < 1) {C = String("12") + String(":");} else {if (hour() > 12) {if (hour() < 22) {C = String(" ") + String(hour() - 12) + String(":");} else {C = String(hour() - 12) + String(":");}} else {C = (hour()) + String(":");}}
  if (minute() < 10) {C = C + String("0") + String(minute()) + String(":");} else {C = C + String(minute()) + String(":");}
  if (second() < 10) {C = C + String("0") + String(second());} else {C = C + String(second());}
  myGLCD.setColor(255, 255, 255);
  myGLCD.setFont(BigFont);
  myGLCD.print(" " + C + " ", h, v);
}

void listMenu()
{
  Serial.println();
  Serial.println("T = Input all 10 digits.   eg T1536620390 = Sept 10 2018 @ 10:59:50pm");
  Serial.println("D = Add 1 DAY.");
  Serial.println("M = Add 1 MONTH.");
  Serial.println("Y = Add 1 YEAR.");
  Serial.println("h = Add 1 hour.");
  Serial.println("m = Add 1 minute.");
  Serial.println("x = Add 1 second.");
  Serial.println("r = Read current value.");
  Serial.println("c = Clears/Refreshes LCD screen.");
  Serial.println("R = Reset to Jan 01 1970.");
  Serial.println("p = Preset value @ 1542350000 = Nov 16 2018 @ 6:trance:20am.");
  Serial.println("s = setTime(06, 31, 00, 12, 01, 2019)");
  Serial.println("? = Show input list/info.");
}

void portCheck()
{
  if (Serial.available() > 0)
  {char Rx = Serial.read();
  if(Rx == TIME_Q) {setTime(Serial.parseInt());}
  if(Rx == DAY_Q) {setTime(now() + 86400);}
  if(Rx == MONTH_Q) {if (String(month()) == "1" or String(month()) == "3" or String(month()) == "5" or String(month()) == "7" or String(month()) == "8" or String(month()) == "10" or String(month()) == "12") {setTime(now() + 2678400);} else {if (String(month()) == "4" or String(month()) == "6" or String(month()) == "9" or String(month()) == "11") {setTime(now() + 2592000);} else {if (String(month()) == "2") {setTime(now() + 2419200);}}}}
  if(Rx == YEAR_Q) {setTime(now() + (86400*365));}
  if(Rx == hour_Q) {setTime(now() + 3600);}
  if(Rx == minute_Q) {setTime(now() + 60);}
  if(Rx == second_Q) {setTime(now() + 1);}
  if(Rx == read_Q) {Serial.println(String(now()));}
  if(Rx == clrScrn_Q) {myGLCD.clrScr();}
  if(Rx == reset_Q) {setTime(0);}
  if(Rx == preset_Q) {setTime(1542350000);} //T1542350000
  if(Rx == misc_Q)  {setTime(06, 31, 00, 12, 01, 2019);}
  if(Rx == menu_Q) {listMenu();}}
}

double TempCheck(int pin, int h, int v)
{
  double Temp;
  Temp = log(10000.0 * ((1024.0/analogRead(pin)-1)));
  Temp = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * Temp * Temp)) * Temp);
  TempC = Temp - 273.15;                // Convert Kelvin to Celcius
  TempF = ((TempC * 9) / 5) + 32.0;     // Convert Celcius to Fahrenheit
  if (TempF < 0) {TempC = 0; TempF = 0;}
  //if (TempF < 90 and TempF > 85) {myGLCD.setColor(0,255,0);} else {if (TempF < 80 or Temp > 95) {myGLCD.setColor(255,0,0);} else {myGLCD.setColor(255, 255, 0);}}
  if (TempChoice = "C") {myGLCD.print(" " + String(TempC, 0) + " C ", h, v);} else {myGLCD.print(" " + String(TempF, 0) + " F ", h, v);}
}

void Read_RTC()
{
  setSyncProvider(RTC.get);
  if (timeStatus() != timeSet)
  {Serial.println("Unable to sync with the RTC");
   myGLCD.print("             ", CENTER, 32);
   myGLCD.print("             ", CENTER, 49);}
  else
  {Serial.println("RTC is ON");}
}
 
Just shut all lights and pumps off for a minute to grab a few quick pics of each section/box.
Pics:
1...Start off 4 clones...veg 32 days. (Keep the best 2 for next box.)
2...Veg still for another 32 days....64 total. (Same amount of time needed for flowering)
3...Flowering cycle starts...32 days of 64. (Genetics say 60-65 so I'm using 64 as the closest even value)
4...Final 32 days of flower cycle...then cut down.

So basically if I used say seeds that took 60 days then I would be using 30 day intervals...see its simple...lol
Just noticed you can see the temp sensors in these pics...well top ones...other goes under black cover in to the tote/water res.
 

Attachments

  • 20190427_174118.jpg
    20190427_174118.jpg
    252.3 KB · Views: 87
  • 20190427_174130.jpg
    20190427_174130.jpg
    381.6 KB · Views: 91
  • 20190427_174146.jpg
    20190427_174146.jpg
    477.4 KB · Views: 86
  • 20190427_174206.jpg
    20190427_174206.jpg
    510.9 KB · Views: 88
Back
Top Bottom