User Tools

Site Tools


en:big_one

All-in-One

The most complex box this time. It can measure time, pH, EC, temperature, humidity and temperature of solution. It has also two plugs. One for light which can switch on and off by set time and the second one for fun with triak regulation (this time without PID control). Output to LCD and when SD card is pluged it saves data on it.

Schéma

This box is one of the earliest so there can be some little differences from schemats in each sections. Especialy in EC schema. There is a little tricky with pH signal which is converted to frequency (LM331) and led by optocoupler to arduino digital input PIN, which with combination with stand-alone power supply leeds to electric isolation of pH circuit. This solution was necessary because of problem with working pH and EC metr in same solution. Much more easy solution is use od capacitors in EC metru (look at EC).

!!! There is a problem with changed first and second pin on TRIAC in schema. This can lead to destruction of triac. So there is a recomandation of changing the pins. (innput to outer pin and output to middle pin)!!!

PCB layout

The use of two colours does not means the bottom and front side (both colors are BOTTOM). It just denotes on separated grounds.


Kód

There was a big problem with RAM on arduinu UNO. So there is no possibility of running serial communication with this code.

BigOne.ino
#include <avr/io.h>
#include <avr/interrupt.h>
#include <nokia_3310_lcd.h>
#include <SD.h> //SD card
#include "avr_bmp.h" //AVR bitmap for LCD
#include <DS1302.h>
#include <DHT.h>
#include <EEPROM.h>
#include "EEPROMAnything.h"
#include <string.h>
#include <avr/pgmspace.h>
 
 
#define TriakLamp 0
#define TriakRegul 1
#define DHTInput 4
#define ECInput 5
#define PHInput 6
#define SDisConected 7
#define ZeroPointDetect 2
#define MenuHideButton 3
#define WTempInput A1
#define Buttons A2
#define CS_LCD 10
#define CS_SD 8
#define CE_PIN A3  
#define IO_PIN  A4    
#define SCLK_PIN A5
 
#define KeyUp    30
#define KeyDown  40
#define KeySel   50
#define KeyInv   60   //invalid key value
 
#define PULSE 10   //trigger pulse width (counts)
#define DHTTYPE DHT11
#define FREQSAMPLES 1024
 
#define MainMenuB 0
#define MainMenuE 4
#define TimeMenuB 7
#define TimeMenuE 12
#define PeriodMenuB 14
#define PeriodMenuE 16
#define RegulMenuB 18
#define RegulMenuE 20
#define CalibMenuB 26
#define CalibMenuE 28
#define ConectMenuB 38
#define ConectMenuE 41
#define MainMenu_P 6
#define TimeMenu_P 13
#define PeriodMenu_P 17
#define RegulMenu_P 21
#define CalibMenu_P 29
#define ConectMenu_P 42
#define YearSubMenu 11
#define MonthSubMenu 10
#define DaySubMenu 9
#define HourSubMenu 7
#define MinuteSubMenu 8
#define SubPeriodMenuB 7
#define SubPeriodMenuE 8
#define SubPeriodMenuWakeUpType 18
#define SubPeriodMenuSleepType 19
#define SubRegulMenuDay 18 
#define SubRegulMenuNight 19 
#define SubRegulMenuB 22
#define SubRegulMenuE 25
#define SubSubRegulMenuTemp 23
#define SubSubRegulMenuHum  22
#define SubCalibMenuB 30
#define SubCalibMenuE 31
#define SubCalibMenuEC 26
#define SubCalibMenuPH 27
#define ECCalib 26
#define PHCalib 27
#define SubConectedMenuB 43
#define SubConectedMenuE 44
#define SubConectedMenuDHT 38
#define SubConectedMenuEC 39
#define SubConectedMenuPH 40
#define HourSubSubPeriodMenuType 7
#define MinuteSubSubPeriodMenuType 8
#define SuccessfulyDone 47
 
int i=483;
 
long delayTime;
 
float PHa;
float PHb;
float ECa;            
float ECb;
 
Nokia_3310_lcd lcd=Nokia_3310_lcd();
 
/* Create a DS1302 object */
DS1302 rtc(CE_PIN, IO_PIN, SCLK_PIN);
 
DHT dht(DHTInput, DHTTYPE);
 
float temperature;
long humidity;
float ec;
float ph;
float WTemp;
 
float dayCondition;
float nightCondition;
 
Time t;
 
boolean SDbegin;  //check if SD begin
 
boolean dayON;   //check if regulate when day
boolean nightON; //check if regulate when night
boolean dayONtemp; //when regualte, check if regulate by temp(if false regulate by humidity)
boolean nightONtemp; //when regualte, check if regulate by temp(if false regulate by humidity)
boolean LAMPON; //setting TraikLamp status
boolean DHTconected; 
boolean ECconected; 
boolean PHconected;
boolean WTempconected;
 
boolean showStatus;
 
int WakeUpHour;
int WakeUpMinute;
 
int SleepHour;
int SleepMinute;
 
//int regulace=483; // debuging
 
char tmp[8];
 
//Flash based string table. Necessary because otherwise the strings will take up all of our ram.
//Use either PrintLCDAt_P or PrintLCD_P to print these strings to the LCD.
prog_char string_0[] PROGMEM =   "1. CONECTED";  //0
prog_char string_1[] PROGMEM =   "2. SET TIME";  //1
prog_char string_2[] PROGMEM =   "3. SET PERIOD";  //2
prog_char string_3[] PROGMEM =   "4. SET REGULATOR";  //3
prog_char string_4[] PROGMEM =   "5. CALIBRATION";  //4
prog_char string_5[] PROGMEM =   "RETURN";  //5,12,16,20,25,28,31,33,35,41
prog_char string_6[] PROGMEM =   "MAIN MENU";  //6
prog_char string_7[] PROGMEM =   "1. HOUR";  //7
prog_char string_8[] PROGMEM =   "2. MINUTE";  //8
prog_char string_9[] PROGMEM =   "3. DAY";  //9
prog_char string_10[] PROGMEM =   "4. MONTH";  //10
prog_char string_11[] PROGMEM =   "5. YEAR";  //11
prog_char string_12[] PROGMEM =   "TIME MENU";  //13
prog_char string_13[] PROGMEM =   "1. WAKE UP";  //14
prog_char string_14[] PROGMEM =   "2. SLEEP";  //15
prog_char string_15[] PROGMEM =   "PERIOD";  //17
prog_char string_16[] PROGMEM =   "1. DAY";  //18
prog_char string_17[] PROGMEM =   "2. NIGHT";  //19
prog_char string_18[] PROGMEM =   "REGULATION";  //21
prog_char string_19[] PROGMEM =   "1. HUMIDITY";  //22
prog_char string_20[] PROGMEM =   "2. TEMPERATURE";  //23
prog_char string_21[] PROGMEM =   "3. OFF";  //24
prog_char string_22[] PROGMEM =   "1. EC";  //26
prog_char string_23[] PROGMEM =   "2. pH";  //27
prog_char string_24[] PROGMEM =   "CALIBRATION";  //29
prog_char string_25[] PROGMEM =   "1. START";  //30
prog_char string_26[] PROGMEM =   "LOW";  //32
prog_char string_27[] PROGMEM =   "HIGH";  //34
prog_char string_28[] PROGMEM =   "GET LOW";  //36
prog_char string_29[] PROGMEM =   "GET HIGH";  //37
prog_char string_30[] PROGMEM =   "1. DHT";  //38
prog_char string_31[] PROGMEM =   "2. EC";  //39
prog_char string_32[] PROGMEM =   "3. pH";  //40
prog_char string_33[] PROGMEM =   "CONECTED";  //42
prog_char string_34[] PROGMEM =   "YES";  //43
prog_char string_35[] PROGMEM =   "NOT";  //44
prog_char string_36[] PROGMEM =   "STANDART";  //45
prog_char string_37[] PROGMEM =  "VALUE"; //46
prog_char string_38[] PROGMEM =  "reading..."; //47
 
PROGMEM const char *StringTable[] = {
  string_0, //0
  string_1, //1
  string_2, //2
  string_3, //3         
  string_4, //4
  string_5, //5
  string_6, //6
  string_7, //7
  string_8, //8
  string_9, //9 
  string_10, //10
  string_11, //11
  string_5, //12 
  string_12, //13
  string_13, //14
  string_14, //15
  string_5, //16  
  string_15, //17
  string_16, //18
  string_17, //19
  string_5, //20
  string_18, //21
  string_19, //22
  string_20, //23
  string_21, //24
  string_5, //25
  string_22, //26
  string_23, //27
  string_5, //28
  string_24, //29
  string_25, //30
  string_5, //31
  string_26, //32
  string_5, //33
  string_27, //34
  string_5, //35
  string_28, //36
  string_29, //37
  string_30, //38
  string_31, //39
  string_32, //40
  string_5, //41
  string_33, //42
  string_34, //43
  string_35, //44
  string_36,  //45
  string_37, //46
  string_38 //47
};
 
byte offset=MainMenuB, whichkey;
 
void setup()                    // run once, when the sketch starts
{
pinMode(CS_SD, OUTPUT);
pinMode( CS_LCD , OUTPUT );
pinMode(TriakLamp,OUTPUT);
pinMode(TriakRegul,OUTPUT);  
pinMode(DHTInput,INPUT);  
pinMode(ECInput,INPUT);
pinMode(PHInput,INPUT);
pinMode(SDisConected,INPUT);
pinMode(ZeroPointDetect,INPUT);
pinMode(MenuHideButton,INPUT);
 
digitalWrite(ZeroPointDetect, HIGH);
 
digitalWrite(CS_LCD, LOW);    //SD CS LOW
digitalWrite(CS_SD, HIGH);    //LCD CS LOW
 
EEPROM_readAnything(32, PHa);
EEPROM_readAnything(40, PHb);
EEPROM_readAnything(48, ECa);
EEPROM_readAnything(56, ECb);
EEPROM_readAnything(70, dayON);
EEPROM_readAnything(80, nightON);
EEPROM_readAnything(90, dayONtemp);
EEPROM_readAnything(100, nightONtemp);
EEPROM_readAnything(110, WakeUpHour);
EEPROM_readAnything(120, WakeUpMinute);
EEPROM_readAnything(130, SleepHour);
EEPROM_readAnything(140, SleepMinute);
EEPROM_readAnything(150, dayCondition);
EEPROM_readAnything(160, nightCondition);
EEPROM_readAnything(170, DHTconected);
EEPROM_readAnything(180, ECconected);
EEPROM_readAnything(190, PHconected);
EEPROM_readAnything(200, delayTime);
EEPROM_readAnything(210, WTempconected);
 
rtc.write_protect(false);
rtc.halt(false);
 
lcd.init();
lcd.clear();
 
digitalWrite(CS_LCD, HIGH);    //SD CS LOW
digitalWrite(CS_SD, HIGH);    //LCD CS LOW
   //   ------------------SD card initialise ----------------------------------
/*
 if(SDconected()) {
  // Serial.print("In");
 if(!SD.begin(CS_SD)) {
 // Serial.println("IN f");
 }else{
 // Serial.println("IN OK");
  SDbegin=true;
 }
 }
 */
  digitalWrite(CS_LCD, HIGH);    //SD CS LOW
  digitalWrite(CS_SD, HIGH);    //LCD CS LOW
 
  OCR1A = 100;      //initialize the comparator
  TIMSK1 = 0x03;    //enable comparator A and overflow interrupts
  TCCR1A = 0x00;    //timer control registers set for
  TCCR1B = 0x00;
 
attachInterrupt(0,zeroCrossingInterrupt, RISING); 
attachInterrupt(1,show, RISING); 
// Time zac(2009, 5, 19, 21, 16, 37, 3);
//  rtc.time(zac);
 
dht.begin();
    //Serial.begin(9600);
    DHTconected=true;
    ECconected=true;
   PHconected=true;
    WTempconected=true;   
delay(2000);
   // mainMenu();
 
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void zeroCrossingInterrupt(){ //zero cross detect   
  TCCR1B=0x04; //start timer with divide by 256 input
  TCNT1 = 0;   //reset timer - count from zero
}
 
ISR(TIMER1_COMPA_vect){ //comparator match
  digitalWrite(TriakRegul,HIGH);  //set triac gate to high
  TCNT1 = 65536-PULSE;      //trigger pulse width
}
 
ISR(TIMER1_OVF_vect){ //timer1 overflow
  digitalWrite(TriakRegul,LOW); //turn off triac gate
  TCCR1B = 0x00;          //disable timer stopd unintended triggers
}
 
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
void loop()                  
{
 // regulace--;
//OCR1A = regulace;     //set the compare register brightness desired.
//if (regulace<65){regulace=483;}  
 
 if(showStatus)mainMenu();
 t = rtc.time();
 if (DHTconected){
 temperature=dht.readTemperature();
 humidity=dht.readHumidity(); 
 }
 
 if (WTempconected){
 WTemp=WTempread();
 }
 
if (ECconected) {
ec=ECread();
}
 
if (PHconected) {
ph=PHread();
}
/////////////////////////////////////////////////////////////////////////////   
if (WakeUpHour > SleepHour){
 
if (WakeUpHour<=t.hr || SleepHour>= t.hr){  
LAMPON=true;
if(WakeUpHour==t.hr && WakeUpMinute>=t.min )LAMPON=false;
if(SleepHour==t.hr && SleepMinute<=t.min )LAMPON=false;
}else LAMPON=false;
}
 
if (WakeUpHour<SleepHour){
if (WakeUpHour<=t.hr && SleepHour>= t.hr){  
LAMPON=true;
if(WakeUpHour==t.hr && WakeUpMinute>=t.min )LAMPON=false;
if(SleepHour==t.hr && SleepMinute<=t.min )LAMPON=false;
}else LAMPON=false;
}
 
if(LAMPON){
digitalWrite(TriakLamp, HIGH);
if(dayON){
  if(dayONtemp){
  i=468-(temperature-dayCondition);
  }else{
  i=468-(humidity-dayCondition);
  }
}else i=0;
}
else {
digitalWrite(TriakLamp, LOW);
if(nightON){
  if(nightONtemp){
  i=468-(temperature-nightCondition);
  }else{
  i=468-(humidity-nightCondition);
  }
}else i=0;
}
 
/////////////////////////////////////////////////////////////////////////////////////
//OCR1A = i; 
//OCR1A = 60;
/////////////////////////////////////////////////////////////////////////////////////
 
 if (SDconected()){
   if (!SDbegin) SD.begin(CS_SD);
 File dataFile = SD.open("data.txt", FILE_WRITE);
     if (dataFile) {
     dataFile.print(t.min);
     dataFile.print("\t");
     dataFile.print(temperature);
      dataFile.print("\t");
     dataFile.print(humidity);
     dataFile.print("\t");
     dataFile.print(ec);
      dataFile.print("\t");
     dataFile.print(ph);
     dataFile.print("\n");
       dataFile.close();  
      }
    else
    {
      // Serial.println("er");
    }
 }else if(SDbegin) SDbegin=false;
 
 
   lcd.gotoXY( 0,0 );
   dtostrf(temperature,1,1,tmp);
  lcd.print(tmp);
  lcd.writeChar(123,MENU_NORMAL);
  lcd.print("C");
 
  lcd.gotoXY( 43,0 );
  lcd.print(humidity);
  lcd.print("%");
 
  lcd.gotoXY( 70,0 );
  if(SDconected()) lcd.print("Y");
  else lcd.print("N");
//Serial.println(temperature); // debuging
//Serial.println(humidity);  // debuging
lcd.gotoXY( 1,1 );
lcd.print("EC:");
 
lcd.gotoXY( 30,1 );
lcd.print("pH:");
 
lcd.gotoXY( 55,1 );
lcd.print("WTmp:");
 
lcd.gotoXY( 1,2 );
dtostrf(ec,1,1,tmp);
lcd.print(tmp);
//Serial.println(ec);  // debuging
 
lcd.gotoXY( 30,2 );
dtostrf(ph,1,1,tmp);
lcd.print(tmp);
//Serial.println(ph);  // debuging
 
lcd.gotoXY( 55,2 );
dtostrf(WTemp,1,1,tmp);
lcd.print(tmp);
 
lcd.gotoXY( 0,3 );
if(WakeUpHour<10){
lcd.print("0");
lcd.print(WakeUpHour);
}else lcd.print(WakeUpHour);
lcd.gotoXY( 11,3 );
lcd.print(":");
lcd.gotoXY( 15,3 );
if(WakeUpMinute<10){
lcd.print("0");
lcd.print(WakeUpMinute);
}else lcd.print(WakeUpMinute);
 
lcd.gotoXY( 35,3 );
if(dayON){
if(dayONtemp) lcd.print("Temp");
else lcd.print("Hum");
lcd.gotoXY( 60,3 );
dtostrf(dayCondition,1,1,tmp);
lcd.print(tmp);
}else lcd.print("N");
 
lcd.gotoXY( 35,4 );
if(nightON){
if(nightONtemp) lcd.print("Temp");
else lcd.print("Hum");
lcd.gotoXY( 60,4 );
dtostrf(nightCondition,1,1,tmp);
lcd.print(tmp);
}else lcd.print("N");
 
lcd.gotoXY( 0,4 );
if(SleepHour<10){
lcd.print("0");
lcd.print(SleepHour);
}else lcd.print(SleepHour);
lcd.gotoXY( 11,4 );
lcd.print(":");
lcd.gotoXY( 15,4 );
if(SleepMinute<10){
lcd.print("0");
lcd.print(SleepMinute);
}else lcd.print(SleepMinute);
 
printTime();
 
lcd.gotoXY( 40,5 );
lcd.print(OCR1A);
 
lcd.gotoXY( 65,5 );
if(LAMPON) lcd.print("ON");
else lcd.print("OFF");
lcd.update();
delay(delayTime); 
}
 
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
void show(){
detachInterrupt(1); 
showStatus=!showStatus;
lcd.clear(); 
delay(50);
attachInterrupt(1,show, RISING); 
}
 
void done(){
lcd.clear(); 
PrintLCD_P(SuccessfulyDone);
delay(500);
mainMenu();
}
 
void printTime(){
lcd.gotoXY( 0,5 );
if(t.hr<10){
lcd.print("0");  
lcd.print(t.hr);
} else lcd.print(t.hr);
lcd.gotoXY( 13,5 );
lcd.print(":");
lcd.gotoXY( 17,5 );
if(t.min<10){
lcd.print("0");
lcd.print(t.min);
}else lcd.print(t.min);
}
 
void mainMenu() {
  showStatus=true;
  offset=MainMenuB;
  do {
    lcd.clear();
    PrintLCD_P(MainMenu_P); 
    PrintLCDAt_P(offset, 0, 2);
    whichkey = PollKey();
    switch(whichkey) {
       case KeyDown:
         if (offset < MainMenuB+1) offset=MainMenuE;
          else offset--;
          break;
       case KeyUp:
          if (offset > MainMenuE-1) offset=MainMenuB;
          else offset++;
          break;
       case KeySel:
          switch (offset) {
             case MainMenuB:ConectedMenu();break;
             case MainMenuB+1:TimeMenu();break;
             case MainMenuB+2:PeriodMenu();break;
             case MainMenuB+3:RegulMenu();break;
             case MainMenuB+4:CalibMenu();break;
            }
          break;
    }
 
  } while (showStatus);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
void ConectedMenu() {
  offset=ConectMenuB;
  do {
    lcd.clear();
    PrintLCD_P(ConectMenu_P); 
    PrintLCDAt_P(offset, 0, 2);
    whichkey = PollKey();
    switch(whichkey) {
       case KeyDown:
         if (offset < ConectMenuB+1) offset=ConectMenuE;
          else offset--;
          break;
       case KeyUp:
          if (offset > ConectMenuE-1) offset=ConectMenuB;
          else offset++;
          break;
       case KeySel:
          switch (offset) {
             case ConectMenuB:SubConectedMenu(SubConectedMenuDHT);break;
             case ConectMenuB+1:SubConectedMenu(SubConectedMenuEC);break;
             case ConectMenuB+2:SubConectedMenu(SubConectedMenuPH);break;
             case ConectMenuB+3:mainMenu();break;
 
            }
          break;
    }
 
  } while (showStatus);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
void SubConectedMenu(char type) {
  offset=SubConectedMenuB;
  do {
    lcd.clear();
    PrintLCD_P(type); 
    PrintLCDAt_P(offset, 0, 2);
 
    whichkey = PollKey();
    switch(whichkey) {
       case KeyDown:
         if (offset < SubConectedMenuB+1) offset=SubConectedMenuE;
          else offset--;
          break;
       case KeyUp:
          if (offset > SubConectedMenuE-1) offset=SubConectedMenuB;
          else offset++;
          break;
       case KeySel:
          switch (offset) {
             case SubConectedMenuB:switch(type) {
                     case SubConectedMenuDHT: DHTconected=true; EEPROM_writeAnything(170, DHTconected); break;
                     case SubConectedMenuEC: ECconected=true; EEPROM_writeAnything(180, ECconected); break;
                     case SubConectedMenuPH: PHconected=true; EEPROM_writeAnything(190, PHconected); break;
             } done();break;
 
             case SubConectedMenuB+1:switch(type) {
                     case SubConectedMenuDHT: DHTconected=false;break;
                     case SubConectedMenuEC: ECconected=false;break;
                     case SubConectedMenuPH: PHconected=false;break;
             } done();break;
 
            }
          break;
    }
 
  } while (showStatus);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
void TimeMenu() {
   offset=TimeMenuB;
  do {
    lcd.clear();
    PrintLCD_P(TimeMenu_P); //"      Main Menu     "
    PrintLCDAt_P(offset, 0, 2);
    whichkey = PollKey();
    switch(whichkey) {
       case KeyDown:
         if (offset < TimeMenuB+1) offset=TimeMenuE;
          else offset--;
          break;
       case KeyUp:
          if (offset > TimeMenuE-1) offset=TimeMenuB;
          else offset++;
          break;
       case KeySel:
          switch (offset) {
             case TimeMenuB:SubTimeMenu(HourSubMenu);break;
             case TimeMenuB+1:SubTimeMenu(MinuteSubMenu);break;
             case TimeMenuB+2:SubTimeMenu(DaySubMenu);break;
             case TimeMenuB+3:SubTimeMenu(MonthSubMenu);break;
             case TimeMenuB+4:SubTimeMenu(YearSubMenu);break;
             case TimeMenuB+5:mainMenu();break;
            }
          break;
    }
 
  } while (showStatus);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
void SubTimeMenu(char type) {
  int time;
  int upLimit;
  int DownLimit;
  switch (type){
  case YearSubMenu:
  time=t.yr;
  upLimit=2099;
  DownLimit=2000;break;
  case MonthSubMenu:
  time=t.mon;
  upLimit=12;
  DownLimit=1;break;
  case DaySubMenu:
  time=t.date;
  upLimit=30;
  DownLimit=1;break;
  case HourSubMenu:
  time=t.hr;
  upLimit=23;
  DownLimit=0;break;
  case MinuteSubMenu:
  time=t.min;
  upLimit=59;
  DownLimit=0;break;
  }
  do {
    lcd.clear();
    PrintLCD_P(type); 
    lcd.gotoXY( 0,5 );
    lcd.print(time);
    whichkey = PollKey();
    switch(whichkey) {
       case KeyDown:
         if (time < DownLimit)time=upLimit;
          else time--;
          break;
       case KeyUp:
          if (time > upLimit) time=DownLimit;
          else time++;
          break;
       case KeySel:
       switch(type){
       case YearSubMenu:rtc.year(time);
                        done();break;
       case MonthSubMenu:rtc.month(time);
                         done();break;
       case DaySubMenu:rtc.date(time);
                           done();break;
       case HourSubMenu:rtc.hour(time);
                        done();break;
       case MinuteSubMenu:rtc.minutes(time);
                          done();break;
 
       }        
          break;
    }
 
  } while (showStatus);
 
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
void PeriodMenu() {
  offset=PeriodMenuB;
  do {
    lcd.clear();
    PrintLCD_P(PeriodMenu_P); 
    PrintLCDAt_P(offset, 0, 2);
 
    whichkey = PollKey();
    switch(whichkey) {
       case KeyDown:
         if (offset < PeriodMenuB+1) offset=PeriodMenuE;
          else offset--;
          break;
       case KeyUp:
          if (offset > PeriodMenuE-1) offset=PeriodMenuB;
          else offset++;
          break;
       case KeySel:
          switch (offset) {
             case PeriodMenuB:SubPeriodMenu(SubPeriodMenuWakeUpType);break;
             case PeriodMenuB+1:SubPeriodMenu(SubPeriodMenuSleepType);break;
             case PeriodMenuB+2:mainMenu();break;
           }
          break;
    }
 
  } while (showStatus);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
void SubPeriodMenu(char type) {
  offset=SubPeriodMenuB;
  do {
    //delay(1000);
    lcd.clear();
    PrintLCD_P(type); //"      Main Menu     "
    PrintLCDAt_P(offset, 0, 2);
    whichkey = PollKey();
    switch(whichkey) {
       case KeyDown:
         if (offset < SubPeriodMenuB+1) offset=SubPeriodMenuE;
          else offset--;
          break;
       case KeyUp:
          if (offset > SubPeriodMenuE-1) offset=SubPeriodMenuB;
          else offset++;
          break;
       case KeySel:
          switch (offset) {
             case SubPeriodMenuB:SubSubPeriodMenu(type,HourSubSubPeriodMenuType);break;
             case SubPeriodMenuB+1:SubSubPeriodMenu(type,MinuteSubSubPeriodMenuType);break;
             case SubPeriodMenuB+2:mainMenu();break;
           }
          break;
    }
 
  } while (showStatus);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
void SubSubPeriodMenu(char type,char what){
  int time;
  int upLimit;
  int DownLimit;
  if(type==SubPeriodMenuWakeUpType){
  switch(what){
  case HourSubSubPeriodMenuType:
  time=WakeUpHour;
  upLimit=23;
  DownLimit=0;break;
  case MinuteSubSubPeriodMenuType:
  time=WakeUpMinute;
  upLimit=59;
  DownLimit=0;break;
 
}
  }else{
  switch(what){
  case HourSubSubPeriodMenuType:
  time=SleepHour;
  upLimit=23;
  DownLimit=0;break;
  case MinuteSubSubPeriodMenuType:
  time=SleepMinute;
  upLimit=59;
  DownLimit=0;break;
 
} 
  }
  do {
    lcd.clear();
    PrintLCD_P(what); 
    lcd.gotoXY( 20,2 );
    lcd.print(time);
    whichkey = PollKey();
    switch(whichkey) {
       case KeyDown:
         if (time < DownLimit+1) time=upLimit;
          else time--;
          break;
       case KeyUp:
          if (time > upLimit-1) time=DownLimit;
          else time++;
          break;
       case KeySel:
  if(type==SubPeriodMenuWakeUpType){
  switch(what){
  case HourSubSubPeriodMenuType:WakeUpHour=time;
                                EEPROM_writeAnything(110, WakeUpHour);
                                done();break;
  case MinuteSubSubPeriodMenuType: WakeUpMinute=time;
                                    EEPROM_writeAnything(120, WakeUpMinute);
                                   done();break;
}
  }else{
    switch(what){
  case HourSubSubPeriodMenuType:SleepHour=time;
                               EEPROM_writeAnything(130, SleepHour);
                                done();break;
  case MinuteSubSubPeriodMenuType: SleepMinute=time;
                                  EEPROM_writeAnything(140, SleepMinute);
                                done();break;
}  
  }
          break;
    }
 
  } while (showStatus);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
void RegulMenu() {
  offset=RegulMenuB;
  do {
    lcd.clear();
    PrintLCD_P(RegulMenu_P); 
    PrintLCDAt_P(offset, 0, 2);
    whichkey = PollKey();
    switch(whichkey) {
       case KeyDown:
         if (offset < RegulMenuB+1) offset=RegulMenuE;
          else offset--;
          break;
       case KeyUp:
          if (offset > RegulMenuE-1) offset=RegulMenuB;
          else offset++;
          break;
       case KeySel:
          switch (offset) {
             case RegulMenuB:SubRegulMenu(SubRegulMenuDay);break;
             case RegulMenuB+1:SubRegulMenu(SubRegulMenuNight);break;
             case RegulMenuB+2:mainMenu();break;
           }
          break;
    }
 
  } while (showStatus);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
void SubRegulMenu(char type) {
  offset=SubRegulMenuB;
  do {
    lcd.clear();
    PrintLCD_P(type);
    PrintLCDAt_P(offset, 0, 2);
    whichkey = PollKey();
    switch(whichkey) {
       case KeyDown:
         if (offset < SubRegulMenuB+1) offset=SubRegulMenuE;
          else offset--;
          break;
       case KeyUp:
          if (offset > SubRegulMenuE-1) offset=SubRegulMenuB;
          else offset++;
          break;
       case KeySel:
          switch (offset) {
             case SubRegulMenuB:SubSubRegulMenu(type,SubSubRegulMenuHum);break;
             case SubRegulMenuB+1:SubSubRegulMenu(type,SubSubRegulMenuTemp);break;
             case SubRegulMenuB+2:if(type==SubRegulMenuDay) dayON=false;
                     else nightON=false; break;
             case SubRegulMenuB+3:mainMenu();break;
           }
          break;
    }
 
  } while (showStatus);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
void SubSubRegulMenu(char type,char what){
  int value;
  int upLimit=100;
  int DownLimit=5;
  if(type==SubRegulMenuDay) value=dayCondition;
  else value=nightCondition;
    do {
    lcd.clear();
    PrintLCD_P(what);
    lcd.gotoXY(30,2); 
    lcd.print(value);
    whichkey = PollKey();
    switch(whichkey) {
       case KeyDown:
         if (value < DownLimit) value=upLimit;
          else value-=0.1;
          break;
       case KeyUp:
          if (value > upLimit) value=DownLimit;
          else value+=0.1;
          break;
       case KeySel:
  if(type==SubRegulMenuDay){  
  dayON=true;
  EEPROM_writeAnything(70, dayON);    
  if(what==SubSubRegulMenuTemp) dayONtemp=true;
  else dayONtemp=false;
  EEPROM_writeAnything(90, dayONtemp);
  dayCondition=value;
  EEPROM_writeAnything(150, dayCondition);
  }else{
  nightON=true;
  EEPROM_writeAnything(80, nightON);
  if(what==SubSubRegulMenuTemp) nightONtemp=true;
  else nightONtemp=false;
  EEPROM_writeAnything(100, nightONtemp);
  nightCondition=value;
  EEPROM_writeAnything(160, nightCondition);
  } 
  done();
  break;
    }
 
  } while (showStatus);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void CalibMenu() {
  offset=CalibMenuB;
  do {
    //delay(1000);
    lcd.clear();
    PrintLCD_P(CalibMenu_P); 
    PrintLCDAt_P(offset, 0, 2);
    whichkey = PollKey();
    switch(whichkey) {
       case KeyDown:
         if (offset < CalibMenuB+1) offset=CalibMenuE;
          else offset--;
          break;
       case KeyUp:
          if (offset > CalibMenuE-1) offset=CalibMenuB;
          else offset++;
          break;
       case KeySel:
          switch (offset) {
             case CalibMenuB:SubCalibMenu(SubCalibMenuEC);break;
             case CalibMenuB+1:SubCalibMenu(SubCalibMenuPH);break;
             case CalibMenuB+2:mainMenu();break;
            }
          break;
    }
 
  } while (showStatus);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
void SubCalibMenu(char type) {
  offset=SubCalibMenuB;
  do {
    //delay(1000);
    lcd.clear();
    PrintLCD_P(type); //"      Main Menu     "
    PrintLCDAt_P(offset, 0, 2);
    whichkey = PollKey();
    switch(whichkey) {
       case KeyDown:
         if (offset < SubCalibMenuB) offset=SubCalibMenuE;
          else offset--;
          break;
       case KeyUp:
          if (offset > SubCalibMenuE) offset=SubCalibMenuB;
          else offset++;
          break;
       case KeySel:
          switch (offset) {
             case SubCalibMenuB: CalibFirstStep(type);break;
             case SubCalibMenuB+1:CalibMenu();break;
            }
          break;
    }
 
  } while (showStatus);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
void CalibFirstStep(char type) {
 int lowStandart;
  if(type==SubCalibMenuEC) lowStandart=2;
  else lowStandart=4;
  do {
    lcd.clear();
    PrintLCD_P(32);
    PrintLCD_P(45); 
    lcd.gotoXY(0,2);
    lcd.print(lowStandart);
    whichkey = PollKey();
    switch(whichkey) {
       case KeyDown:lowStandart--;break;
       case KeyUp:lowStandart++;break;
       case KeySel:CalibSecondStep(type, lowStandart);break;
    }
 
  } while (showStatus);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
void CalibSecondStep(char type, int lowStandart) {
 int highStandart;
  if(type==SubCalibMenuEC) highStandart=6;
  else highStandart=7;
  do {
    lcd.clear();
    PrintLCD_P(34);
    PrintLCD_P(45); 
    lcd.gotoXY(0,2);
    lcd.print(highStandart);
    whichkey = PollKey();
    switch(whichkey) {
       case KeyDown:highStandart--;break;
       case KeyUp:highStandart++;break;
       case KeySel:CalibThirdStep(type, lowStandart, highStandart);break;
    }
 
  } while (showStatus);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
void CalibThirdStep(char type, int lowStandart, int highStandart ) {
  float lowValue;
 
  do {
    if(type==SubCalibMenuEC) lowValue=getFrequency(ECInput);
    else lowValue=getFrequency(PHInput);
    lcd.clear();
    PrintLCD_P(32);
    PrintLCD_P(46); 
    lcd.gotoXY(0,2);
    lcd.print(lowValue);
    whichkey = PollKey();
 
  } while (whichkey!=KeySel);
 lcd.clear();
 PrintLCD_P(47);
 delay(1500);
 CalibFourthStep(type, lowStandart, highStandart, lowValue);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
void CalibFourthStep(char type, int lowStandart, int highStandart, float  lowValue) {
  float highValue;
  do {
    if(type==SubCalibMenuEC) highValue=getFrequency(ECInput);
    else highValue=getFrequency(PHInput);
    lcd.clear();
    PrintLCD_P(34);
    PrintLCD_P(46); 
    lcd.gotoXY(0,2);
    lcd.print(highValue);
    whichkey = PollKey();     
  } while (whichkey!=KeySel);
 if(type==SubCalibMenuEC){
 setECConstants(((highValue-lowValue)/(highStandart-lowStandart)),(highStandart-(highValue/((highValue-lowValue)/(highStandart-lowStandart)))));
 } else  setPHConstants(((highValue-lowValue)/(highStandart-lowStandart)),(highStandart-(highValue/((highValue-lowValue)/(highStandart-lowStandart)))));
 lcd.clear();
 PrintLCD_P(47);
 delay(1500);
 CalibMenu();
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
void PrintLCDAt(char *inStr, char x, char y) {
   lcd.gotoXY( x,y ); 
   delay(20);
   lcd.print(inStr);
   delay(40);
}
 
void PrintLCDAt_P(int which, char x, char y) {
   lcd.gotoXY( x,y );  
   delay(20);
   PrintLCD_P(which);  
}
 
void PrintLCD_P(int which) {
   char buffer[21];
   strcpy_P(buffer, (char*)pgm_read_word(&(StringTable[which])));
   lcd.print(buffer);
   delay(40);
}
 
char KeyScan() {
   int which, which2, diff,retVal;
   which = analogRead(Buttons);
   delay(0);
   which2 = analogRead(Buttons);
   retVal = KeyInv;
   diff = abs(which - which2);
   if (diff < 12) {
 
      if (which > 900 && which < 1024) retVal =  KeySel;
      if (which > 300  && which < 360) retVal =  KeyDown;
      if (which > 480 && which < 520) retVal =  KeyUp;
   }
   return retVal;
}
 
char PollKey() {
  char Whichkey;
    do {
     Whichkey = KeyScan();
     delay(30);
  } while ((Whichkey==KeyInv) && showStatus);
  delay(80);
  return Whichkey;
}
 
boolean SDconected(){
if (digitalRead(SDisConected)==0) return true;
else return false;
}
 
float WTempread(){
int reading = analogRead(WTempInput);
float temp = (((reading * 5.0)/1024)-0.5)*100;   
return temp; 
}
 
float ECread(){
float ECf;
ECf=(getFrequency(ECInput)/ECa)+ECb;
return ECf; 
}
 
 
float PHread(){
float PHf;
PHf=(getFrequency(PHInput)/PHa)+PHb;
return PHf; 
}
 
long getFrequency(int pin) {
long freqhigh = 0;
long freqlow =0;
long frequency=0;
for(unsigned int j=0; j<FREQSAMPLES; j++){
freqhigh+= pulseIn(pin, HIGH);
freqlow+= pulseIn(pin, LOW);
}
frequency = 1000000 / ( (freqhigh / FREQSAMPLES) + (freqlow / FREQSAMPLES) );
return frequency;
}
 
void setWakeUpHour(int time)
{
WakeUpHour=time;  
EEPROM_writeAnything(110, time);
}
 
void setWakeUpMinute(int time)
{
WakeUpMinute=time;    
EEPROM_writeAnything(120, time);
}
 
void setSleepHour(int time)
{
SleepHour=time;  
EEPROM_writeAnything(130, time);
}
 
void setSleepMinute(int time)
{
SleepMinute=time;    
EEPROM_writeAnything(140, time);
}
 
void setECConstants(float a, float b)
{
  ECa=a;
  ECb=b; 
EEPROM_writeAnything(48, a);
EEPROM_writeAnything(56, b);
}
 
void setPHConstants(float a, float b)
{
  PHa=a;
  PHb=b; 
EEPROM_writeAnything(32, a);
EEPROM_writeAnything(40, b);
}

Box

en/big_one.txt · Last modified: 2018/01/29 10:12 (external edit)