// Fisher Arduino 1.0.5 (64 Bit) // 24.Марта.2014 // Rev 1.0 #include #include #include #include #include #include "EEPROMAnything.h" // http://www.righto.com/2009/08/multi-protocol-infrared-remote-library.html // http://www.pjrc.com/teensy/td_libs_OneWire.html // http://bigbarrel.ru/eeprom/ struct config_t {     byte sRelay1;     byte sRelay2;     byte sRelay3;     byte sRelay4;     long r1;     long r2;     long r3;     long r4;     long light;     long func;         byte stat_lcd_light;     byte s1_timer_start;     byte s1_timer_stop;     byte s2_timer_start;     byte s2_timer_stop;     byte s3_timer_start;     byte s3_timer_stop;     byte s4_timer_start;     byte s4_timer_stop; } irconfig; #define RECV_PIN 11 IRrecv irrecv(RECV_PIN); decode_results results; #define PCF8563address 0x51 byte OFF = 0; byte ON = 1; #define LCD_LIGHT 7 OneWire  ds(SCK);   byte second, minute, hour, dayOfWeek, dayOfMonth, month, year; //////////////////////////////////// // set_status_relay(1...4,[OFF...ON]) // //////////////////////////////////// // D6-1 D8-2 D9-3 D10-4 void set_status_relay(int relay,byte set) {   int port = 6;   if (relay == 1) { port = 6;  irconfig.sRelay1 = set; }   if (relay == 2) { port = 8;  irconfig.sRelay2 = set; }   if (relay == 3) { port = 9;  irconfig.sRelay3 = set; }   if (relay == 4) { port = 10; irconfig.sRelay4 = set; }   if (set == OFF) digitalWrite(port,HIGH);   if (set == ON) digitalWrite(port,LOW);   EEPROM_writeAnything(0, irconfig); } void set_on_off_relay(int relay) {   boolean stat = get_status_relay(relay);    if (stat) set_status_relay(relay,OFF);     else set_status_relay(relay,ON);   } ///////////////////////////// // get_status_relay(1...4) // ///////////////////////////// boolean get_status_relay(int relay) {     if (relay == 1) { if (irconfig.sRelay1 == 1) return(true); else return(false); }     if (relay == 2) { if (irconfig.sRelay2 == 1) return(true); else return(false); }     if (relay == 3) { if (irconfig.sRelay3 == 1) return(true); else return(false); }     if (relay == 4) { if (irconfig.sRelay4 == 1) return(true); else return(false); } } byte bcdToDec(byte value) {   return ((value / 16) * 10 + value % 16); } byte decToBcd(byte value){   return (value / 10 * 16 + value % 10); } void readPCF8563()  // this gets the time and date from the PCF8563 {   Wire.beginTransmission(PCF8563address);   Wire.write(0x02);   Wire.endTransmission();   Wire.requestFrom(PCF8563address, 7);   second     = bcdToDec(Wire.read() & B01111111); // remove VL error bit   minute     = bcdToDec(Wire.read() & B01111111); // remove unwanted bits from MSB   hour       = bcdToDec(Wire.read() & B00111111);   dayOfMonth = bcdToDec(Wire.read() & B00111111);   dayOfWeek  = bcdToDec(Wire.read() & B00000111);     month      = bcdToDec(Wire.read() & B00011111);  // remove century bit, 1999 is over   year       = bcdToDec(Wire.read()); } /* void PCF8563oscOFF()  // turns off oscillator {   Wire.beginTransmission(PCF8563address);   Wire.write(0x0D);   Wire.write(0);   Wire.endTransmission(); } */ void PCF8563osc1Hz() // sets oscillator to 1 Hz {   Wire.beginTransmission(PCF8563address);   Wire.write(0x0D);   Wire.write(B10000011);   Wire.endTransmission(); } // initialize the library with the numbers of the interface pins LiquidCrystal lcd(5,13,A3,A0,A2,A1); /*  * LCD RS pin to digital pin 12  * LCD Enable pin to digital pin 11  * LCD D4 pin to digital pin 5  * LCD D5 pin to digital pin 4  * LCD D6 pin to digital pin 3  * LCD D7 pin to digital pin 2  */ void setup() {   Wire.begin();   EEPROM_readAnything(0, irconfig); //   irconfig.sRelay1 = 0; //   irconfig.sRelay2 = 0; //   irconfig.sRelay3 = 0; //   irconfig.sRelay4 = 0;   //   irconfig.r1 = 0xFD08F7; //   irconfig.r2 = 0xFD8877; //   irconfig.r3 = 0xFD48B7; //   irconfig.r4 = 0xFD28D7; //   irconfig.light = 0xFD40BF; //   irconfig.func = 0xFD00FF; //   EEPROM_writeAnything(0, irconfig);     pinMode(6,OUTPUT);  digitalWrite(6,HIGH); // OFF   pinMode(8,OUTPUT);  digitalWrite(8,HIGH); // OFF   pinMode(9,OUTPUT);  digitalWrite(9,HIGH); // OFF   pinMode(10,OUTPUT); digitalWrite(10,HIGH); // OFF   // Востановление после выключения питания   if (irconfig.sRelay1 == 1) digitalWrite(6,LOW); else digitalWrite(6,HIGH);   if (irconfig.sRelay2 == 1) digitalWrite(8,LOW); else digitalWrite(8,HIGH);   if (irconfig.sRelay3 == 1) digitalWrite(9,LOW); else digitalWrite(9,HIGH);   if (irconfig.sRelay4 == 1) digitalWrite(10,LOW); else digitalWrite(10,HIGH);   PCF8563osc1Hz();   // Serial.begin(9600);  while(!Serial) {};   Serial1.begin(38400);   // while(!Serial1) {};   // Serial1.println("Loading...");   pinMode(LCD_LIGHT, OUTPUT);   // Востановление после выключения   if (irconfig.stat_lcd_light == 1) {    digitalWrite(LCD_LIGHT,HIGH);   } else {    digitalWrite(LCD_LIGHT,LOW);   }   pinMode(4, OUTPUT);  // Мотор выключен   digitalWrite(4,LOW);   lcd.begin(8, 2);   lcd.clear();   lcd.print("Leonardo");   lcd.setCursor(0,1);   lcd.print("PCF8563");   delay(1500);   lcd.clear();   irrecv.enableIRIn();   // Serial1.println("OK"); } long previousMillis = 0; long interval_time = 1000;       byte disp = 0; //  *OPEN* //  *CLOS* byte pp = 0; char wcmd[10]; boolean cmdON = false; char b; boolean Start = false; void loop() {    /**************************/    /* Управление через WI-FI */    /**************************/     if (Serial1.available()) {       b = Serial1.read();       if (b == '*' && Start == false) {         Start = true;         pp=0;       }       if (Start && pp < (sizeof(wcmd)-2)) {        wcmd[pp++] = b;         if (b == '*' && pp != 1) {          wcmd[pp] = '\0';          Serial1.println("");          Serial1.println(wcmd);          if (strstr("*OPEN*",wcmd) && !cmdON) { cmdON = true;  }          if (strstr("*CLOS*",wcmd) && cmdON) { cmdON = false; }                    Start = false;          pp = 0;         }       }       if (pp > (sizeof(wcmd)-2)) {        Start = false;        b = '\0';        wcmd[0] = b;        pp = 0;       }      if (cmdON) wifi_menu(b);      }             unsigned long currentMillis = millis();   if(currentMillis - previousMillis > interval_time) {     previousMillis = currentMillis;           lcd_date(); // Выводим время и проверяем на включение   }    if (irrecv.decode(&results)) {     switch (results.value) {      case 0xFD08F7:       lcd_info('1');       if (get_status_relay(1)) lcd.print("Off"); else lcd.print("On");       set_on_off_relay(1);       delay(1000);       break;      case 0xFD8877:       lcd_info('2');       if (get_status_relay(2)) lcd.print("Off"); else lcd.print("On");       set_on_off_relay(2);       delay(1000);       break;         case 0xFD48B7:      lcd_info('3');      if (get_status_relay(3)) lcd.print("Off"); else lcd.print("On");      set_on_off_relay(3);      delay(1000);      break;     case 0xFD28D7:      lcd_info('4');      if (get_status_relay(4)) lcd.print("Off"); else lcd.print("On");      set_on_off_relay(4);      delay(1000);      break;     case 0xFD40BF:      if (digitalRead(LCD_LIGHT) == HIGH) {       digitalWrite(LCD_LIGHT,LOW);       irconfig.stat_lcd_light = 0;      } else {       digitalWrite(LCD_LIGHT,HIGH);       irconfig.stat_lcd_light = 1;      }      EEPROM_writeAnything(0, irconfig);            break;     case 0xFD00FF:      lcd.clear();      relay_status();      delay(2000);      break;     default:      Serial1.println(results.value, HEX);      break;     }     irrecv.resume();   } } // Выводим время и проверяем на включение void lcd_date( void ) {   lcd.setCursor(0, 0);   readPCF8563();   if (dayOfMonth < 10) lcd.print("0");   lcd.print(dayOfMonth, DEC);   lcd.print("/");   if (month < 10) lcd.print("0");   lcd.print(month, DEC);   lcd.print("/");   lcd.print(year, DEC);   lcd.setCursor(0, 1);   if (hour < 10) lcd.print("0");   lcd.print(hour, DEC);   lcd.print(":");   if (minute < 10) lcd.print("0");   lcd.print(minute, DEC);   lcd.print(":");     if (second < 10) lcd.print("0");   lcd.print(second, DEC);     if (minute == 5) {     if (irconfig.s1_timer_start == hour) {      if (!get_status_relay(1)) {       Serial1.println("Start Relay 1");       set_status_relay(1,ON);      }     }     if (irconfig.s2_timer_start == hour) {       if (!get_status_relay(2)) {         set_status_relay(2,ON);         Serial1.println("Start Relay 2");       }     }     if (irconfig.s3_timer_start == hour) {             if (!get_status_relay(3)) {         set_status_relay(3,ON);         Serial1.println("Start Relay 3");       }     }     if (irconfig.s4_timer_start == hour) {       if (!get_status_relay(4)) {         set_status_relay(4,ON);         Serial1.println("Start Relay 4");       }     }     if (irconfig.s1_timer_stop == hour) {       if (get_status_relay(1)) {         set_status_relay(1,OFF);         Serial1.println("Stop Relay 1");       }     }     if (irconfig.s2_timer_stop == hour) {       if (get_status_relay(2)) {         set_status_relay(2,OFF);         Serial1.println("Stop Relay 2");       }     }     if (irconfig.s3_timer_stop == hour) {       if (!get_status_relay(3)) {         set_status_relay(3,OFF);         Serial1.println("Stop Relay 3");       }     }     if (irconfig.s4_timer_stop == hour) {       if (get_status_relay(4)) {         set_status_relay(4,OFF);         Serial1.println("Stop Relay 4");       }     }   }   } void relay_status() {   lcd.clear();   lcd.print("1 2 3 4");   lcd.setCursor(0,1);   if (get_status_relay(1)) lcd.print(char(255)); else space();   space();   if (get_status_relay(2)) lcd.print(char(255)); else space();   space();   if (get_status_relay(3)) lcd.print(char(255)); else space();   space();   if (get_status_relay(4)) lcd.print(char(255)); else space();   space();   lcd.print(char(255)); } void space( void ) {   lcd.print(" "); } // --------------------------- Wi-Fi Меню ----------------------- void wifi_menu( char in ) {    String stop = String("Stop Time for Relay ");    String start = String("Start Time for Relay ");    switch(in) {      case '\n':       status_print();       break;      case 'w':        set_dt();        break;      case 's':       status_print();       break;      case 't':       ds18s20();       break;      case '1':       set_on_off_relay(1);       status_print();       break;      case '2':       set_on_off_relay(2);       status_print();       break;      case '3':       set_on_off_relay(3);       status_print();       break;      case '4':       set_on_off_relay(4);       status_print();       break;      case 'a':                 irconfig.s1_timer_start = enter_time(start + "1 (end #):",irconfig.s1_timer_start);       irconfig.s1_timer_stop = enter_time(stop + "1 (end #):",irconfig.s1_timer_stop);             Serial1.print("Start/Stop Time: ");       Serial1.print(irconfig.s1_timer_start);       Serial1.print("/");       Serial1.println(irconfig.s1_timer_stop);       EEPROM_writeAnything(0, irconfig);       break;      case 'b':                 irconfig.s2_timer_start = enter_time(start + "2 (end #):",irconfig.s2_timer_start);       irconfig.s2_timer_stop = enter_time(stop + "2 (end #):",irconfig.s2_timer_stop);             Serial1.print("Start/Stop Time: ");       Serial1.print(irconfig.s2_timer_start);       Serial1.print("/");       Serial1.println(irconfig.s2_timer_stop);       EEPROM_writeAnything(0, irconfig);       break;            case 'c':                 irconfig.s3_timer_start = enter_time(start + "3 (end #):",irconfig.s3_timer_start);       irconfig.s3_timer_stop = enter_time(stop + "3 (end #):",irconfig.s3_timer_stop);             Serial1.print("Start/Stop Time: ");       Serial1.print(irconfig.s3_timer_start);       Serial1.print("/");       Serial1.println(irconfig.s3_timer_stop);       EEPROM_writeAnything(0, irconfig);       break;      case 'd':                 irconfig.s4_timer_start = enter_time(start + "4 (end #):",irconfig.s4_timer_start);       irconfig.s4_timer_stop = enter_time(stop + "4 (end #):",irconfig.s4_timer_stop);             Serial1.print("Start/Stop Time: ");       Serial1.print(irconfig.s4_timer_start);       Serial1.print("/");       Serial1.println(irconfig.s4_timer_stop);       EEPROM_writeAnything(0, irconfig);       break;    } } void status_print( void ) {   String line  = "--------------------------";   Serial1.println("");   Serial1.println(line);   print_date_time();   Serial1.println(line);   Serial1.print("1=>"); if (get_status_relay(1)) Serial1.println("On"); else Serial1.println("Off");   Serial1.print("2=>"); if (get_status_relay(2)) Serial1.println("On"); else Serial1.println("Off");   Serial1.print("3=>"); if (get_status_relay(3)) Serial1.println("On"); else Serial1.println("Off");   Serial1.print("4=>"); if (get_status_relay(4)) Serial1.println("On"); else Serial1.println("Off");         Serial1.println(line);   Serial1.print("A,R1 Start=>"); Serial1.print(irconfig.s1_timer_start); Serial1.print(" Stop=>"); Serial1.println(irconfig.s1_timer_stop);   Serial1.print("B,R2 Start=>"); Serial1.print(irconfig.s2_timer_start); Serial1.print(" Stop=>"); Serial1.println(irconfig.s2_timer_stop);   Serial1.print("C,R3 Start=>"); Serial1.print(irconfig.s3_timer_start); Serial1.print(" Stop=>"); Serial1.println(irconfig.s3_timer_stop);   Serial1.print("D,R4 Start=>"); Serial1.print(irconfig.s4_timer_start); Serial1.print(" Stop=>"); Serial1.println(irconfig.s4_timer_stop);   Serial1.println(line);   Serial1.println("Menu: (s)Status,(t)Temp,(1,2,3,4)On/Off,(a,b,c,d)Set Timers,(w) Set Date/Time"); } //////////////////////////////     // Чтение времени с порта. ////////////////////////////// byte enter_time(String s, byte old) {   boolean ok = true;   byte value = 0;   unsigned long i = 0;   Serial1.print(s);   while(i<1500000) {       i++;     while (Serial1.available()) {      char in = Serial1.read();      if (isDigit(in)) value = (value * 10) + (in - '0');      if (in == '#') return(value);     }    }    return(old); } void ds18s20( void ) {   byte i;   byte present = 0;   byte data[12];   byte addr[8] = { 0x10,0xD2,0xEA,0xE8,0x1,0x8,0x0,0xBE };   ds.reset();   ds.select(addr);   ds.write(0x44,1);         // запускаем конвертацию   delay(750);     // скорее всего достаточно 750 ms   present = ds.reset();   ds.select(addr);       ds.write(0xBE);         // считываем ОЗУ датчика   for ( i = 0; i < 9; i++) {           // обрабатываем 9 байт     data[i] = ds.read();   }   // Высчитываем температуру :)   int HighByte, LowByte, TReading, Tc_100;   LowByte = data[0];   HighByte = data[1];   TReading = (HighByte << 8) + LowByte;   Tc_100 = TReading/2;   Serial1.print("T = ");   Serial1.print(Tc_100);   Serial1.println("C"); } void print_date_time( void ) {   readPCF8563();   if (dayOfMonth < 10) Serial1.print("0");   Serial1.print(dayOfMonth, DEC);   Serial1.print("/");   if (month < 10) Serial1.print("0");   Serial1.print(month, DEC);   Serial1.print("/");   Serial1.print(year, DEC);   Serial1.print(" ");   if (hour < 10) Serial1.print("0");   Serial1.print(hour, DEC);   Serial1.print(":");   if (minute < 10) Serial1.print("0");   Serial1.print(minute, DEC);   Serial1.print(":");     if (second < 10) Serial1.print("0");   Serial1.println(second, DEC);   } // Установка времени   void set_dt( void ) {   hour = enter_time("Hour (end #):",hour);   minute = enter_time("Minute (end #):",minute);   dayOfWeek = enter_time("Day of Week (end #):",dayOfWeek);   dayOfMonth = enter_time("Day (end #):",dayOfMonth);   month = enter_time("Month (end #):",month);   Wire.beginTransmission(PCF8563address);   Wire.write(0x02);   Wire.write(decToBcd(second));     Wire.write(decToBcd(minute));   Wire.write(decToBcd(hour));       Wire.write(decToBcd(dayOfMonth));   Wire.write(decToBcd(dayOfWeek));     Wire.write(decToBcd(month));   Wire.write(decToBcd(year));   Wire.endTransmission(); } void lcd_info(char n) {       lcd.clear();         lcd.print("Relay ");       lcd.print(n);       lcd.setCursor(0,1); }