Check my grow controller code?

Hi!

I am making a grow controller that is going to control lights,humidity,temperature, check that the room has negative pressure etc. and want you to check out my code and see if you can come with suggestions of other ways of doing things.
I am planning to use PID for temperature control and triacs for adjusting fan speed at inlet and exhaust.
Later I am going to add a PH controller, with a nice ph-probe that can be submerged for a whole year without recalibration and peristaltic pumps for ph+ and -.

I dont have much arduino experience, I almost instantly started working on this controller. But I am learning alot on the way :slight_smile:

//        Libraries        //

#include <DHT22.h>
#include <SimpleTimer.h>
#include <MenuBackend.h>
#include <LiquidCrystal_I2C.h>
#include <DS1307.h>
#include <Wire.h> 
#include <BMP085.h>
#include <phi_interfaces.h>
#include <SD.h>
//-------------------------//


//       Rotary encoders   //
#define Encoder1ChnA 18  
#define Encoder1ChnB 19
#define Encoder2ChnA 16
#define Encoder2ChnB 17
#define EncoderDetent 20

char mapping1[]={'1','2'}; // Character mapping for rotary encoder
char mapping2[]={'3','4'};

phi_rotary_encoders my_encoder1(mapping1, Encoder1ChnA, Encoder1ChnB, EncoderDetent);
phi_rotary_encoders my_encoder2(mapping2, Encoder2ChnA, Encoder2ChnB, EncoderDetent);

multiple_button_input* dial1=&my_encoder1;
multiple_button_input* dial2=&my_encoder2;
//--------------------------//


//         MISC             //
BMP085 bmp;
SimpleTimer timer;
char* monthOfYear;
char* dayOfWeek;
char* ukedag[]={"Man", "Tir", "Ons", "Tors", "Fre", "Lor", "Son"};
char* maned[]={"Januar              ", "Februar             ", "Mars               ", "April               ", "Mai                 ", "Juni               ", "Juli                ", "August               ", "September            ", "Oktober              ", "November             ", "Desember             "};
//---------------------------//


/*             Pins         //
SD on miso,mosi and sck.
LCD and RTC on SDA and SCL.*/
const int DHT22_PIN       =   8;      //Temp/RH pin
const int humPin          =  43;      //Humidifier
const int heaterPin       =  44;      //Oven
const int fanPin          =  45;    
const int hpsPin          =  46;
const int ledPin          =  47;
//---------------------------//

//---------------SD---------------//
const int chipSelect = 53;       // SS output on Arduino/CS pin on SD module. 10 on nano / 53 on mega.
    
DHT22 myDHT22(DHT22_PIN);
//---------------------------//


//---------------Pushbuttons---------------//
const int buttonPinLeft = 8;      //Not in use, ESC/ENTER dont work without LEFT/RIGHT added. 
const int buttonPinRight = 9;    // Problem with phi_interfaces or menubackend
const int buttonPinEsc = 11;     // pin for the Esc button
const int buttonPinEnter = 12;   // pin for the Enter button
int lastButtonPushed = 0;        
int lastButtonEnterState = HIGH;   // the previous reading from the Enter input pin
int lastButtonEscState = HIGH;   // the previous reading from the Esc input pin
long lastEnterDebounceTime = 0;  // the last time the output pin was toggled
long lastEscDebounceTime = 0;  // the last time the output pin was toggled
long debounceDelay = 40;    // the debounce time, how long you need to press the button for it to take action.
//---------------------------------//



//---------------Temperature---------------//
float tempDay         = 24.0;     // Day temp
float tempNight       = 22.0;     // Night temp
float margUp          = 2;      // Margin on temp. up
float margDown        = 0;      // Margin on temp. down

//------------------Oven------------------//
int ovenNightStart  = 21.0;     // Temperature heater turns on at night.
int ovenNightStop   = 22.0;    
int ovenDayStart    = 22.0;     // Temperature heater turns on at day.
int ovenDayStop     = 24.0; 

//---------------Humidity---------------//
int humDay          = 65.0;     // Day humidity
int humNight        = 65.0;     // Night humidity
int humMargUp       = 5.0;      // Humidity margin up
int humMargDown     = 5.0;      // Humidity margin down

//---------------Time/Clock---------------//
int   dayTime       = 8;        // What time to turn ON lights
int   nightTime     = 20;       // What time to turn OFF lights
int   rtcHour;                  // For storing clock hour
int   rtcMin;                   // Minutes
int   rtcMonth;                   
int   rtcDate;
int   rtcDow;                   // Day of week

int lDRR=0;

//Booleans, False/True
boolean isDay;                  // Day = True/false
boolean fanIsOn;                // fanIsOn = True !fanIsOn=False
boolean humIsOn;                
boolean heaterIsOn;
boolean hpsIsOn;
boolean hpsOn;
boolean relayHps=true;               // To be able to turn of HPS via LCD even if isDay=true, needs to be set as true at startup or else lightcheck will fail.

//Misc
float growTemp;                 // Store temperature as decimal value
float growRh;                   // Same for RH

//Setup LCD
LiquidCrystal_I2C lcd(0x27, 20,4);
int    lcdDelay         = 1300;    // Delay on messages when turning on/off relays etc.


 //Timers
 
int startTimers(){                            // This is the function you add timers to
  timer.setInterval(2000, dhtTimer);           // After 2seconds, run dhtRead()
  timer.setInterval(60000, sdTimer);         // After 60seconds, run sdLogger().
  timer.setInterval(2200, ldrTimer);}
  
 // These functions are used for doing something when the timer is triggered.
void dhtTimer(){
  dhtRead();}

void sdTimer(){
  sdLogger();}
  
void ldrTimer(){
  lDR();}
 
  
  
//Menu variables
MenuBackend menu = MenuBackend(menuUsed,menuChanged);
//initialize menuitems
    MenuItem menu1Item1 = MenuItem("Item1");
      MenuItem menuItem1SubItem1 = MenuItem("Item1SubItem1");
      MenuItem menuItem1SubItem2 = MenuItem("Item1SubItem2");
      MenuItem menuItem1SubItem3 = MenuItem("Item1SubItem3");
      MenuItem menuItem1SubItem4 = MenuItem("Item1SubItem4");
    MenuItem menu1Item2 = MenuItem("Item2");
      MenuItem menuItem2SubItem1 = MenuItem("Item2SubItem1");
      MenuItem menuItem2SubItem2 = MenuItem("Item2SubItem2");
      MenuItem menuItem2SubItem3 = MenuItem("Item2SubItem3");
      MenuItem menuItem2SubItem4 = MenuItem("Item2SubItem4");
    MenuItem menu1Item3 = MenuItem("Item3");
      MenuItem menuItem3SubItem1 = MenuItem("Item3SubItem1");
      MenuItem menuItem3SubItem2 = MenuItem("Item3SubItem2");
      MenuItem menuItem3SubItem3 = MenuItem("Item3SubItem3");
    MenuItem menu1Item4 = MenuItem("Item4");
      MenuItem menuItem4SubItem1 = MenuItem("Item4SubItem1");
      MenuItem menuItem4SubItem2 = MenuItem("Item4SubItem2");

int sdStartUp(){
     if (!SD.begin(chipSelect)) {
    lcd.setCursor(5,1);
    lcd.print("Feil med SD");    // SD error.
    delayClear(); }
  lcd.setCursor(5,1);
  lcd.print("SD Startet");
    File dataFile = SD.open("GROWLOG.CSV", FILE_WRITE);
    String header = "Klokke,Dato,Mnd, Temp , RH ,  hPa, Vifte, Fukter,Ovn,HPS";
    dataFile.println(header);
    dataFile.close();
    delayClear();}
    
       //------------------Menu layout-------------------//
  int setUpMenu(){
    menu.getRoot().add(menu1Item1);
  menu1Item1.addRight(menu1Item2).addRight(menu1Item3).addRight(menu1Item4);
  menu1Item1.add(menuItem1SubItem1).addRight(menuItem1SubItem2).addRight(menuItem1SubItem3).addRight(menuItem1SubItem4);
  menu1Item2.add(menuItem2SubItem1).addRight(menuItem2SubItem2).addRight(menuItem2SubItem3).addRight(menuItem2SubItem4);
  menu1Item3.add(menuItem3SubItem1).addRight(menuItem3SubItem2).addRight(menuItem3SubItem3);
  menu1Item4.add(menuItem4SubItem1).addRight(menuItem4SubItem2);
  menu.toRoot();}
  //-------------------------------------------------//
  
void setup()
{
  Serial.begin(9600);            // Start serial connection at 9600 baud.
  lcd.begin();  // initialize the lcd 
  lcd.backlight();
  bmp.begin();
  pinMode(ledPin, OUTPUT);       // Set digital line as output.
  pinMode(humPin, OUTPUT);       
  pinMode(fanPin, OUTPUT);
  pinMode(heaterPin, OUTPUT);
  pinMode(hpsPin, OUTPUT);
  pinMode(buttonPinEnter, INPUT);
  pinMode(buttonPinEsc, INPUT);
  pinMode(chipSelect, OUTPUT);
  setUpMenu();
  startTimers();
  clockStuff();
  sdStartUp();
  dhtRead();
}
void loop()   
{
lcdDisplay();
navigateMenus();
readButtons();
currentMenu();
  timer.run();
  clockStuff();
  humCheck(growRh);
  fanCheck(growTemp);
  ovenCheck(growTemp);
  if(relayHps){hpsCheck();}else if(!relayHps){hpsIsOn=false;digitalWrite(hpsPin,LOW);} /*To oversteer dayOrNot() function, enabling to turn of HPS via LCD even if isDay=true. If relayHps=false, hpsCheck() wont be run and hpsPin set to LOW.*/
  if(hpsOn){hpsIsOn=true,digitalWrite(hpsPin,HIGH);}else if(!hpsOn){hpsIsOn=false,digitalWrite(hpsPin,LOW);}
}
// FUNCTIONS!  
int lDR(){
  lDRR = analogRead(0);
  return lDRR;}
  
void lcdDisplay(){
  //Line 1!
  lcd.setCursor(0, 0);          // Set to start at line 1
  printClock(RTC.get(DS1307_HR,true),RTC.get(DS1307_MIN,false));
  lcd.setCursor(11,0);          // start at character 11, line 1
  lcd.print(bmp.readPressure()/100);
  lcd.print(" hPa");
  
  //Line 2!
  lcd.setCursor(0,1);
  lcd.print(dayOfWeek);
  lcd.print(' ');
  lcd.print(rtcDate);
  lcd.setCursor(15,1);
  lcd.print(growTemp, 1);       // Print float growTemp with 1 decimal
  lcd.print('C');
  
  //Line 3!
  lcd.setCursor(15, 2);          
  lcd.print(growRh, 1);
  lcd.print('%');
  
  //Line 4!
  lcd.setCursor(17,3);
  lcd.print(lDRR);
relaysOn();
    
}
 
 void currentMenu(){
  MenuItem currentMenu=menu.getCurrent();
  if(currentMenu.getName() == "Item1SubItem1"){
   int just;
   just=dial1->getKey();
   switch (just){
    case 49: tempDay-=0.5;break;
    case 50: tempDay+=0.5;break;}
   lcd.setCursor(10,2);
   lcd.print(tempDay,1);
}else if(currentMenu.getName() == "Item1SubItem2"){
   int just;
   just=dial1->getKey();
   switch (just){
    case 49: tempNight-=0.5;break;
    case 50: tempNight+=0.5;break;}
   lcd.setCursor(10,2);
   lcd.print(tempNight,1);
}else if(currentMenu.getName() == "Item1SubItem3"){
    int just;
    just=dial1->getKey();
    if(margUp<0){margUp==0;};
    switch (just){
     case 49: margUp-=0.5;break;
     case 50: margUp+=0.5;break;}
   lcd.setCursor(11,2);
   lcd.print(margUp,1);
}else if(currentMenu.getName() == "Item1SubItem4"){
    if(margDown<0){margDown==0;};
    int just;
    just=dial1->getKey();
    switch (just){
      case 49: margDown-=0.5;break;
      case 50: margDown+=0.5;break;}
      lcd.setCursor(11,2);
      lcd.print(margDown,1);
}else if(currentMenu.getName() == "Item2SubItem1"){
     int just;
     just=dial1->getKey();
     switch (just){
       case 49: humDay-=2;break;
       case 50: humDay+=2;break;}
       lcd.setCursor(10,2);
       lcd.print(humDay);
       lcd.print('%');
}else if(currentMenu.getName() == "Item2SubItem2"){
      int just;
      just=dial1->getKey();
      switch (just){
        case 49: humNight-=2;break;
        case 50: humNight+=2;break;}
        lcd.setCursor(10,2);
        lcd.print(humNight);
        lcd.print('%');
}else if(currentMenu.getName() == "Item2SubItem3"){
       int just;
       just=dial1->getKey();
       switch (just){
         case 49: humMargUp--;break;
         case 50: humMargUp++;break;}
         lcd.setCursor(10,2);
         lcd.print(humMargUp);
         lcd.print('%');
}else if(currentMenu.getName() == "Item2SubItem4"){
       int just;
       just=dial1->getKey();
       switch (just){
         case 49: humMargDown--;break;
         case 50: humMargDown++;break;}
         lcd.setCursor(10,2);
         lcd.print(humMargDown);
         lcd.print('%');
}else if(currentMenu.getName() == "Item3SubItem1"){
       int just;
       just=dial1->getKey();
       switch (just){
         case 49: hpsOn=false;relayHps=false;lcd.clear();break;
         case 50: relayHps=true;lcd.clear();break;}
         lcd.setCursor(10,2);
         
         switch (hpsIsOn){
           case 0: lcd.setCursor(10,2);lcd.print("Av");break;
           case 1: lcd.setCursor(10,2);lcd.print("Pa");break;}
       }else if(currentMenu.getName() == "Item4SubItem1"){
    int just;
    just=dial1->getKey();
    if (dayTime>24){dayTime=0;}
    if (dayTime<0){dayTime=24;}
    switch (just){
     case 49: dayTime-=1;lcd.clear();break;
     case 50: dayTime+=1;lcd.clear();break;}
   lcd.setCursor(10,2);
   lcd.print(dayTime);
}else if(currentMenu.getName() =="Item4SubItem2"){
    int just;
    if (nightTime>24){nightTime=0;}
    if (nightTime<0){nightTime=24;}
    just=dial1->getKey();
    switch (just){
     case 49: nightTime-=1;break;
     case 50: nightTime+=1;break;}
   lcd.setCursor(10,2);
   lcd.print(nightTime);}}


void menuChanged(MenuChangeEvent changed){
  MenuItem newMenuItem=changed.to; //get the destination menu
  lcd.setCursor(0,2); //set the start position for lcd printing to the second row
  if(newMenuItem.getName()==menu.getRoot()){
      lcd.print(monthOfYear);
  }else if(newMenuItem.getName()=="Item1"){
      lcd.print("Temperatur      ");
  }else if(newMenuItem.getName()=="Item1SubItem1"){
      lcd.print("Dag         ");
    }else if(newMenuItem.getName()=="Item1SubItem2"){
      lcd.print("Natt        ");
    }else if(newMenuItem.getName()=="Item1SubItem3"){
      lcd.print("Margin opp   ");
    }else if(newMenuItem.getName()=="Item1SubItem4"){
      lcd.print("Margin ned    ");
  }else if(newMenuItem.getName()=="Item2"){
      lcd.print("Fuktighet    ");
  }else if(newMenuItem.getName()=="Item2SubItem1"){
      lcd.print("Fukt dag      ");
  }else if(newMenuItem.getName()=="Item2SubItem2"){
      lcd.print("Fukt natt     ");
  }else if(newMenuItem.getName()=="Item2SubItem3"){
      lcd.print("Margin opp    ");
  }else if(newMenuItem.getName()=="Item2SubItem4"){
      lcd.print("Margin ned    ");
  }else if(newMenuItem.getName()=="Item3"){
      lcd.print("Releer         ");
  }else if(newMenuItem.getName()=="Item3SubItem1"){
    lcd.print("HPS     ");
  }else if(newMenuItem.getName()=="Item3SubItem2"){
    lcd.print("Vifte      ");
  }else if(newMenuItem.getName()=="Item3SubItem3"){
    lcd.print("Fukter       ");
  }else if(newMenuItem.getName()=="Item4"){
    lcd.print("Lys             ");
  }else if(newMenuItem.getName()=="Item4SubItem1"){
    lcd.print("HPS pa:      ");
  }else if(newMenuItem.getName()=="Item4SubItem2"){
    lcd.print("HPS av:     ");
  }
}
void menuUsed(MenuUseEvent used){
  lcd.setCursor(0,2); 
  lcd.print(used.item.getName());
  delay(1000);  //delay to allow message reading
  menu.toRoot();  //back to Main
}
void  readButtons(){  //read buttons status
  int reading;
  int buttonEnterState=HIGH;             // the current reading from the Enter input pin
  int buttonEscState=HIGH;             // the current reading from the input pin
                  //ENTER
                  reading = digitalRead(buttonPinEnter);
                  if (reading != lastButtonEnterState) {
                    lastEnterDebounceTime = millis();
                  } 
                  
                  if ((millis() - lastEnterDebounceTime) > debounceDelay) {
                    buttonEnterState=reading;
                    lastEnterDebounceTime=millis();
                  }
                  lastButtonEnterState = reading;
                  
                  //ESC
                  reading = digitalRead(buttonPinEsc);
                  if (reading != lastButtonEscState) {
                    lastEscDebounceTime = millis();
                  } 
                  
                  if ((millis() - lastEscDebounceTime) > debounceDelay) {
                    buttonEscState = reading;
                    lastEscDebounceTime=millis();
                  }
                  
                  lastButtonEscState = reading; 
                 
                  if (buttonEnterState==LOW){
                    lastButtonPushed=buttonPinEnter;

                  }else if(buttonEscState==LOW){
                    lastButtonPushed=buttonPinEsc;

                  }else{
                    lastButtonPushed=0;
                  }                  
}
void navigateMenus() {
  int still;
  still=dial2->getKey(); // Use the phi_interfaces to access the same keypad
  switch (still){
    case 51: lastButtonPushed=buttonPinLeft;break;
    case 52: lastButtonPushed=buttonPinRight;break;}
    MenuItem currentMenu=menu.getCurrent();
  switch (lastButtonPushed){
    case buttonPinEnter:
      if(!(currentMenu.moveDown())){  //if the current menu has a child and has been pressed enter then menu navigate to item below
        menu.use();
      }else{  //otherwise, if menu has no child and has been pressed enter the current menu is used
        menu.moveDown(); 
      }
        break;
    case buttonPinEsc:
      menu.toRoot(); break;
    case buttonPinRight:
      menu.moveRight(); break;      
    case buttonPinLeft:
      menu.moveLeft(); break;      
  }
  
  lastButtonPushed=0; //reset the lastButtonPushed variable
}
//Function for comparing temperature against variables and taking actions based on them.
void fanCheck(int canopyTemp){
  if ( ( (canopyTemp >= tempDay+margUp) && isDay) || ( (canopyTemp >= tempNight+margUp) && !isDay) ) {    // If canopyTemp equals or is bigger than tempDay/Night+margUp
    if (!fanIsOn) {    //then check if fanIsOn=false
      relayOn(3);}}  //if it is turn on relay (3)!  
  else if ( ( (canopyTemp <= tempDay-margDown) && isDay) || ( (canopyTemp <= tempNight-margDown) && !isDay) ){ // or if canopyTemp equals or is lower than tempDay/Night-margDown
    if (fanIsOn){ // And if fanIsOn=true
      relayOff(3);}}}  // Turn off relay 3 @ relayOn(){ case 3!

//Oven
void ovenCheck(int canopyTemp){
  if (((canopyTemp >= ovenDayStop) && isDay) || ((canopyTemp >= ovenNightStop) && !isDay))  {
    if (heaterIsOn) {
      relayOff(2);}}
  else if (((canopyTemp <= ovenDayStart) && isDay || ((canopyTemp <= ovenNightStart) && !isDay))){
   if (!heaterIsOn)
  relayOn(2);}} 
  
//Humidity
void humCheck(int humSensor){
  if ( ( (humSensor >= humDay+humMargUp)) && isDay || ( (humSensor >= humNight+humMargUp) && !isDay) ) {
    if (humIsOn) { 
      relayOff(1);}} 
  else if ( ( (humSensor <= humDay-humMargDown) && isDay) || ( (humSensor <= humNight-humMargDown) && !isDay) ){
    if (!humIsOn){   
      relayOn(1);}}}
    
//HPS
void hpsCheck(){
  if (isDay){            //If isDay is set to true at function clockStuff().
   if (!hpsIsOn) {       //and hpsIsOn=false
    hpsOn=true; }}       //relayOn(4) triggers case: 4 at function relayOn()
    else if (!isDay){    //or if it's night
      if (hpsIsOn){      //and hpsIsOn=true
        hpsOn=false; }}} //Turn off relay with relayOff case: 4.

//Function for powering relays ON
int relayOn(int relayOnNumber){
  switch (relayOnNumber){
  case 1:                             // if relayOn(1) is called case 1: will go until break;
    lcd.clear();
    lcd.setCursor(5,1);
    lcd.print("Fukter pa");           //Humidifier on
    humIsOn=true;
    digitalWrite(humPin, HIGH);
    delayClear();
    break;
  case 2:
    lcd.clear();
    lcd.setCursor(5,1);
    lcd.print("Ovn pa");              //Oven on
    heaterIsOn=true;
    digitalWrite(heaterPin, HIGH);
    delayClear();
    break;
  case 3:
    lcd.clear();
    lcd.setCursor(5,1);
    lcd.print("Vifte pa");            //Fan on
    fanIsOn=true;
    digitalWrite(fanPin, HIGH);
    delayClear();
    break;
   case 4:
    lcd.clear();
    lcd.setCursor(5,1);
    lcd.print("HPS pa");
    hpsIsOn=true;
    digitalWrite(hpsPin, HIGH);
    delayClear();
    break;
  } }
  
// Function for powering relays OFF!
int relayOff(int relayOffNumber){
  switch (relayOffNumber){
  case 1:                 // If relayOff(1), do stuff until break;
    lcd.clear();
    lcd.setCursor(5,1);
    lcd.print("Fukter av");
    humIsOn=false;
    digitalWrite(humPin, LOW);
    delayClear();
    break;
  case 2:                       
    lcd.clear();
    lcd.setCursor(5,1);
    lcd.print("Ovn av");
    heaterIsOn=false;
    digitalWrite(heaterPin, LOW);
    delayClear();
    break;
  case 3:
    lcd.clear();
    lcd.setCursor(5,1);
    lcd.print("Vifte av");
    fanIsOn=false;
    digitalWrite(fanPin, LOW);
    delayClear();
    break;
   case 4:
    lcd.clear();
    lcd.setCursor(5,1);
    lcd.print("HPS av");
    hpsIsOn=false;
    digitalWrite(hpsPin, LOW);
    delayClear();
    break; }}
    
    //This is for reading a DHT22 temperature/humidity sensor.
int dhtRead(){
  DHT22_ERROR_t errorCode;
  errorCode = myDHT22.readData();	
  switch(errorCode)
  {
  case DHT_ERROR_NONE:; 
    growTemp = myDHT22.getTemperatureC();
    growRh   = myDHT22.getHumidity(); 
    break;
  case DHT_ERROR_CHECKSUM:
    Serial.println("Checksum ERROR ");
    break;
  case DHT_BUS_HUNG:
    Serial.println("BUS Hung ");
    break;
  case DHT_ERROR_NOT_PRESENT:
    Serial.println("Not Present ");
    break;
  case DHT_ERROR_ACK_TOO_LONG:
    Serial.println("ACK time out ");
    break;
  case DHT_ERROR_SYNC_TIMEOUT:
    Serial.println("Sync Timeout ");
    break;
  case DHT_ERROR_DATA_TIMEOUT:
    Serial.println("Data Timeout ");
    break;
  case DHT_ERROR_TOOQUICK:
    Serial.println("Polled to quick ");
    break;  }}
    
  
  int clockStuff(){
  rtcHour     = RTC.get(DS1307_HR,true);
  rtcMin      = RTC.get(DS1307_MIN,false);
  rtcDate     = RTC.get(DS1307_DATE,false);
  rtcMonth    = RTC.get(DS1307_MTH,false);
  rtcDow      = RTC.get(DS1307_DOW,false);
  whatDayMonth();
  //DayOrNot
  if ((rtcHour >= dayTime) && (rtcHour < nightTime)){   //Compares the input night/day variables with RTC and decides if isDay so lights will be turned on.
    isDay=true;}else{isDay=false; }}
  

 void printClock(int hours,int minutes){           //Adds a 0 when minutes is under 10 so clock shows 19:07 instead of 19:7
  if(hours < 10){lcd.print('0');}
   lcd.print(hours);
   lcd.print(':');
  if(minutes < 10){
    lcd.print('0');}
    lcd.print(minutes);}
    
    void delayClear(){            //Function for delay and clearing lcd
    delay(lcdDelay);
    lcd.clear();}
    
    
    void relaysOn(){
      if(hpsIsOn){lcd.setCursor(0,3);lcd.print("HPS");}
      if(humIsOn){lcd.setCursor(4,3);lcd.print('F');}
      if(fanIsOn){lcd.setCursor(6,3);lcd.print('V');}
      if(heaterIsOn){lcd.setCursor(8,3);lcd.print('O');}}
      
  int whatDayMonth(){
  switch (rtcMonth){
case 1: monthOfYear=maned[0]; break;
case 2: monthOfYear=maned[1]; break;
case 3: monthOfYear=maned[2]; break;
case 4: monthOfYear=maned[3]; break;
case 5: monthOfYear=maned[4]; break;
case 6: monthOfYear=maned[5]; break;
case 7: monthOfYear=maned[6]; break;
case 8: monthOfYear=maned[7]; break;
case 9: monthOfYear=maned[8]; break;
case 10: monthOfYear=maned[9]; break;
case 11: monthOfYear=maned[10]; break;
case 12: monthOfYear=maned[11]; break;}
switch (rtcDow){
case 1: dayOfWeek=ukedag[0]; break;
case 2: dayOfWeek=ukedag[1]; break;
case 3: dayOfWeek=ukedag[2]; break;
case 4: dayOfWeek=ukedag[3]; break;
case 5: dayOfWeek=ukedag[4]; break;
case 6: dayOfWeek=ukedag[5]; break;
case 7: dayOfWeek=ukedag[6]; break;}}

int sdLogger(){
    int barometer;
    int fukter      = digitalRead(humPin);              //For reading relay states.
    int vifteovn    = digitalRead(heaterPin);
    int vifte       = digitalRead(fanPin);
    int hps         = digitalRead(hpsPin);
    rtcDate         = RTC.get(DS1307_DATE,false);
    rtcMonth        = RTC.get(DS1307_MTH,false);
    rtcHour         = RTC.get(DS1307_HR,true);
    rtcMin          = RTC.get(DS1307_MIN,false);
    barometer       = bmp.readPressure()/100;
    
  File dataFile = SD.open("GROWLOG.CSV", FILE_WRITE);
  if (dataFile) {
    dataFile.print(rtcHour);
    if (rtcMin < 10){
    dataFile.print('0');}
    dataFile.print(rtcMin);
    dataFile.print(" ,  ");
    dataFile.print(rtcDate);
    dataFile.print(" , ");
    dataFile.print(rtcMonth);
    dataFile.print(" , ");
    dataFile.print(growTemp,1);
    dataFile.print(", ");
    dataFile.print(growRh,1);
    dataFile.print(" , ");
    dataFile.print(barometer);
    dataFile.print(" , ");
    dataFile.print(vifte);
    dataFile.print("   ,  ");
    dataFile.print(fukter);
    dataFile.print("  ,  ");
    dataFile.print(vifteovn);
    dataFile.print(" , ");
    dataFile.println(hps);             
    dataFile.close();}  
  else {
    lcd.print("Error!");
    delayClear();  } }

I'll have a look, but the weird formatting isn't helping.


Rob

Replace

 switch (rtcMonth){
	case 1: monthOfYear=maned[0]; break;
	case 2: monthOfYear=maned[1]; break;
	case 3: monthOfYear=maned[2]; break;
	case 4: monthOfYear=maned[3]; break;
	case 5: monthOfYear=maned[4]; break;
	case 6: monthOfYear=maned[5]; break;
	case 7: monthOfYear=maned[6]; break;
	case 8: monthOfYear=maned[7]; break;
	case 9: monthOfYear=maned[8]; break;
	case 10: monthOfYear=maned[9]; break;
	case 11: monthOfYear=maned[10]; break;
	case 12: monthOfYear=maned[11]; break;}

with

monthOfYear = maned[rtcMonth-1];

And similar in other places.


Rob

Please try running your code through the auto-format tool in the IDE. And comments. Add comments, and not ones like lastButtonPushed=0; //reset the lastButtonPushed variable

Any time you see a lot of repeated code you should think about using arrays and combining functions. For example

    //Function for powering relays ON
int relayOn(int relayOnNumber){
  switch (relayOnNumber){
  case 1:                             // if relayOn(1) is called case 1: will go until break;
    lcd.clear();
    lcd.setCursor(5,1);
    lcd.print("Fukter pa");           //Humidifier on
    humIsOn=true;
    digitalWrite(humPin, HIGH);
    delayClear();
    break;
  case 2:
    lcd.clear();
    lcd.setCursor(5,1);
    lcd.print("Ovn pa");              //Oven on
    heaterIsOn=true;
    digitalWrite(heaterPin, HIGH);
    delayClear();
    break;
  case 3:
    lcd.clear();
    lcd.setCursor(5,1);
    lcd.print("Vifte pa");            //Fan on
    fanIsOn=true;
    digitalWrite(fanPin, HIGH);
    delayClear();
    break;
   case 4:
    lcd.clear();
    lcd.setCursor(5,1);
    lcd.print("HPS pa");
    hpsIsOn=true;
    digitalWrite(hpsPin, HIGH);
    delayClear();
    break;
  } }
  
// Function for powering relays OFF!
int relayOff(int relayOffNumber){
  switch (relayOffNumber){
  case 1:                 // If relayOff(1), do stuff until break;
    lcd.clear();
    lcd.setCursor(5,1);
    lcd.print("Fukter av");
    humIsOn=false;
    digitalWrite(humPin, LOW);
    delayClear();
    break;
  case 2:                       
    lcd.clear();
    lcd.setCursor(5,1);
    lcd.print("Ovn av");
    heaterIsOn=false;
    digitalWrite(heaterPin, LOW);
    delayClear();
    break;
  case 3:
    lcd.clear();
    lcd.setCursor(5,1);
    lcd.print("Vifte av");
    fanIsOn=false;
    digitalWrite(fanPin, LOW);
    delayClear();
    break;
   case 4:
    lcd.clear();
    lcd.setCursor(5,1);
    lcd.print("HPS av");
    hpsIsOn=false;
    digitalWrite(hpsPin, LOW);
    delayClear();
    break; }}

can be replaced with

char * relayNames [] =  {"Fukter ", "Ovn ", "Vifte ", "HPS "};
int relayPins [] = {humPin, heaterPin, fanPin, hpsPin};
boolean fansStatus [] = {FALSE, FALSE, FALSE, FALSE};

int relayOnOff(int relayNumber, boolean onoff){

    lcd.clear();
    lcd.setCursor(5,1); 
    lcd.print (relayNames[relayNumber]);
    lcd.print (onoff ? "av" : "pa");
    digitalWrite(relayPins[relayNumber], onoff ? LOW : HIGH);
    fansStatus [relayNumber] = onoff;
    delayClear();
}

Note that this can't simply be plugged in because changes are needed where you called relayOn() and relayOff(). But you can see that things can be done a lot smaller with some thought.

You really need to look at the formatting though as AWOL said. For example

 if(hpsOn){hpsIsOn=true,digitalWrite(hpsPin,HIGH);}else if(!hpsOn){hpsIsOn=false,digitalWrite(hpsPin,LOW);}

Is unreadable and has a redundant test.

 if (hpsOn) {
   hpsIsOn=true;
   digitalWrite(hpsPin,HIGH);
} else {
   hpsIsOn=false;
   digitalWrite(hpsPin,LOW);
}

Is better and could still be improved


Rob

Thank you so much!

I will rewrite the code with your suggestions. I just wrote the code I could get to work with the knowledge I had, but I will make it more plug-and-play later when I get all the functions I want working like they should.

I have tried it, and it runs fine. 7 or 8 days was the longest test I had. Lights wasn't connected though, but the hpsPin was powered on when it was day, and off when it was night.

I will be making alot of changes in time, as I learn new things all the time. But I just thought I needed to get some other peoples opinion, nothing is better.. :)