Temp logger

  1. /*
  2.  * Author: Tomas Borovicka, ok4bx
  3.  * Date: February 2016
  4.  *
  5.  * ====Resources:
  6.  * DS18B20                      file://C:/Users/Tomas/Desktop/Datasheets/DS18B20.pdf
  7.  * DS3231                       file://C:/Users/Tomas/Desktop/Datasheets/DS3231-DS3231S.pdf
  8.  * AT24C32              file://C:/Users/Tomas/Desktop/Datasheets/AT24C32.pdf
  9.  * ATMega328            file://C:/Users/Tomas/Desktop/Datasheets/atmega328.pdf
  10.  * Pinout               file://C:/Users/Tomas/Desktop/Datasheets/nanopdf.png
  11.  * RTC schematic        http://i0.wp.com/woodsgood.ca/projects/wp-content/uploads/RTC-schematic.jpg
  12.  *
  13.  * ====Pin assigment:
  14.  * D7 - DS18B20
  15.  * A4 - SDA  <> DS3231
  16.  * A5 - SCL  -> DS3231
  17.  * D2 - INT0 <- DS3231 SQW
  18.  * D3 - INT1 --/\/\/\--+     220Ohm jumper
  19.  * D0 - RX0  ----------+     Wake on serial
  20.  *
  21.  * ====Notes:
  22.  * Drain - Modry, Source - Cerveny, Gate - Zluty
  23.  *
  24.  * ===Temp:
  25.  * raw + 880
  26.  * 0xFFFF = -1 =
  27.  * -2
  28.  * -3
  29.  */
  30. #include <Wire.h>
  31. #include <OneWire.h>
  32. #include <EEPROM.h>
  33. #include <avr/sleep.h>
  34. #include "morse.h"
  35.  
  36. #define INTERNAL_EEPROM 0x00
  37. #define DS3231_I2C_ADDRESS 0x68
  38. #define AT24C32_I2C_ADDRESS 0x57
  39.  
  40.  
  41. #define CW_PIN A0
  42. #define LED_PIN 13
  43. #define RTC_POWER_PIN 9
  44. #define ADC_PIN A1
  45. #define ADC_CONTROL_PIN 8
  46.  
  47. #define ADDRESS_16BIT 1
  48. #define ADDRESS_8BIT 0
  49.  
  50. #define TIMEOUT_TIME 90000
  51.  
  52. const char hextable[] PROGMEM = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
  53.  
  54. OneWire ds(7);  
  55. String buffer;
  56. String msg;
  57. byte x,rx;
  58. int ch,i;
  59. int cwspeed = SPEED_WPM27;
  60. int eepPtr = 0;
  61. long activityTime = millis();
  62.  
  63. struct Mydatetime {
  64.         byte second;
  65.         byte minute;
  66.         byte hour;
  67.         byte day;
  68.         byte month;
  69.         byte year;
  70.         byte dow;
  71. } datetime;
  72.  
  73. typedef struct  {
  74.         byte day;
  75.         byte month;
  76.         int year;
  77. } Mydate;
  78.  
  79. #define storageLen 5
  80. int16_t storage[storageLen];
  81.  
  82. volatile int state = LOW;
  83.  
  84. byte decToBcd(byte val){
  85.     return( (val/10*16) + (val%10) );
  86. }
  87.  
  88. byte bcdToDec(byte val){
  89.     return( (val/16*10) + (val%16) );
  90. }
  91.  
  92. // Print withing leading 0
  93. void print0(byte b) {
  94.         if(b<10)
  95.                 Serial.print(F("0"));
  96.         Serial.print(b);
  97. }
  98.  
  99. void printHex(byte n) {
  100.         Serial.print((char)pgm_read_byte(hextable + (n >> 4)));
  101.         Serial.print((char)pgm_read_byte(hextable + (n & 0x0F)));
  102. }
  103.  
  104. void eraseEeprom(int address, int pages) {
  105.         for(int page=0; page<pages; page++) {
  106.                 Serial.println(page);
  107.                 Wire.beginTransmission(address);
  108.                 Wire.write(highByte(page*16));
  109.                 Wire.write(lowByte(page*16));                          
  110.                 for(int xx=0;xx<16;xx++)
  111.                         Wire.write(0xFF);
  112.                 Serial.flush();
  113.                 Wire.endTransmission();
  114.                 delay(25);
  115.         }                      
  116. }
  117.  
  118. void dump(int deviceAddress, int address, int length, int adrWord) {
  119.         int requestSize;
  120.         int tmpLength;
  121.         int curAddress;
  122.         Serial.println(F("       0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F"));
  123.        
  124.         address &= 0xFFF0;
  125.         for(int block=0; block <= length/16; block++) {
  126.                 tmpLength = (block+1)*16;
  127.                 requestSize =  (tmpLength<length) ? 16 : 16 - (tmpLength - length);
  128.                
  129.                 if(requestSize) {
  130.                         //print address
  131.                         curAddress = address + block*16;
  132.                         printHex(highByte(curAddress));
  133.                         printHex(lowByte(curAddress));
  134.                         Serial.print(F(": "));
  135.                        
  136.                         //I2C device, 0 = Internal EEPROM
  137.                         if(deviceAddress) {                                                    
  138.                                 //I2C set address
  139.                                 Wire.beginTransmission(deviceAddress);
  140.                                 if(adrWord==HIGH)
  141.                                         Wire.write(highByte(curAddress));
  142.                                 Wire.write(lowByte(curAddress));
  143.                                 Wire.endTransmission();
  144.                                
  145.                                 //I2C read data
  146.                                 Wire.requestFrom(deviceAddress, requestSize);
  147.                                 Wire.endTransmission();
  148.                         }
  149.                        
  150.                         for(int adr=0; adr < requestSize; adr++) {                             
  151.                                 printHex((deviceAddress) ? Wire.read() : EEPROM.read(curAddress + adr));
  152.                                 Serial.print( (adr != 7) ? F(" ") : F("|") );                   //print | after 8 bytes
  153.                         }
  154.                         Serial.println();                      
  155.                 }
  156.                 Serial.flush();
  157.         }
  158. }
  159.  
  160. void setRtcAlarm() {
  161.         Wire.beginTransmission(DS3231_I2C_ADDRESS);
  162.         Wire.write(0x07);
  163. /*      Wire.write(0x00);                       // each minute
  164.         Wire.write(0x80);
  165.         Wire.write(0x80);
  166.         Wire.write(0x80); */
  167.         Wire.write(0x05);                       // XX:00:05
  168.         Wire.write(0x00);
  169.         Wire.write(0x80);
  170.         Wire.write(0x80);      
  171.         Wire.endTransmission();
  172.         Wire.beginTransmission(DS3231_I2C_ADDRESS);
  173.         Wire.write(0x0E);
  174.         Wire.write(0x05);
  175.         Wire.endTransmission();
  176. }
  177.  
  178. void clearRtcAlarm() {
  179.         Wire.beginTransmission(DS3231_I2C_ADDRESS);
  180.         Wire.write(0x0F);
  181.         Wire.write(0x00);
  182.         Wire.endTransmission();
  183. }
  184.  
  185. void getRtcTime(struct Mydatetime *dt) {
  186.         Wire.beginTransmission(DS3231_I2C_ADDRESS);
  187.         Wire.write(0);
  188.         Wire.endTransmission();
  189.         Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
  190.         dt->second = bcdToDec(Wire.read());
  191.         dt->minute = bcdToDec(Wire.read());
  192.         dt->hour = bcdToDec(Wire.read() & 0x3f);
  193.         dt->dow = Wire.read();
  194.         dt->day = bcdToDec(Wire.read());
  195.         dt->month = bcdToDec(Wire.read() & 0x1f);
  196.         dt->year = bcdToDec(Wire.read());
  197. }
  198.  
  199. void setRtcTime(struct Mydatetime *dt) {
  200.         Wire.beginTransmission(DS3231_I2C_ADDRESS);
  201.         Wire.write(0);
  202.         Wire.write(decToBcd(dt->second & 0x7F));
  203.         Wire.write(decToBcd(dt->minute & 0x7F));
  204.         Wire.write(decToBcd(dt->hour & 0x3F));
  205.         Wire.write(dt->dow & 0x07);
  206.         Wire.write(decToBcd(dt->day & 0x3F));
  207.         Wire.write(decToBcd(dt->month & 0x1F));
  208.         Wire.write(decToBcd(dt->year));
  209.         Wire.endTransmission();
  210. }
  211.  
  212. int16_t getTemp() {
  213.         byte i;
  214.         byte present = 0;
  215.         byte type_s = 0;    //sensor type 0=DS18B20
  216.         byte data[12];
  217.         byte addr[8] = { 0x28, 0xE3, 0x7E, 0xE4, 0x00, 0x00, 0x00, 0xE6}; //sensor ID
  218.         float celsius;
  219.  
  220.         if (OneWire::crc8(addr, 7) != addr[7])          //Address CRC is not valid!
  221.                 return -2;
  222.  
  223.  
  224.         ds.reset();
  225.         ds.select(addr);
  226.         ds.write(0x44, 1);        // start conversion, with parasite power on at the end
  227.  
  228.         delay(1000);    // maybe 750ms is enough, maybe not
  229.                                         // we might do a ds.depower() here, but the reset will take care of it.
  230.  
  231.         present = ds.reset();
  232.         ds.select(addr);    
  233.         ds.write(0xBE);             // Read Scratchpad
  234.  
  235.         for ( i = 0; i < 9; i++) {  // we need 9 data bytes
  236.                 data[i] = ds.read();
  237.         }
  238.  
  239.         if(OneWire::crc8(data,8) != data[8])            //Data CRC is not valid
  240.                 return -3;
  241.  
  242.  
  243.         int16_t raw = (data[1] << 8) | data[0];
  244.         byte cfg = (data[4] & 0x60);
  245.         if (cfg == 0x00) raw = raw & ~7;        // 9 bit resolution, 93.75 ms
  246.         else if (cfg == 0x20) raw = raw & ~3;   // 10 bit res, 187.5 ms
  247.         else if (cfg == 0x40) raw = raw & ~1;   // 11 bit res, 375 ms
  248.                                                                                         // default is 12 bit resolution, 750 ms conversion time
  249.         celsius = (float)raw / 16.0;
  250.         Serial.print(F("Temperature = "));
  251.         Serial.print(celsius);
  252.         Serial.println();
  253.         return raw + 880;
  254. }
  255.  
  256. int getVoltage(void) {
  257.         int voltage;
  258.        
  259.         digitalWrite(ADC_CONTROL_PIN,LOW);              //connect source
  260.         delay(5);
  261.         voltage = analogRead(ADC_PIN);
  262.         voltage = analogRead(ADC_PIN);
  263.         delay(10);
  264.         ADCSRA &= ~(1<<ADEN);                                   //disable ADC
  265.         digitalWrite(ADC_CONTROL_PIN,HIGH);             //disconnect source
  266.         return 4400*x/1024;
  267. }
  268.  
  269. long JulianDate(int year, int month, int day) {
  270.         //1)http://quasar.as.utexas.edu/BillInfo/JulianDatesG.html
  271.         //2) http://forum.arduino.cc/index.php?topic=94925.0
  272.         //3) OK http://netcdf4-python.googlecode.com/svn/trunk/docs/netcdftime.netcdftime-pysrc.html
  273.         year = 2000 + year;
  274.         if(month < 3) {
  275.                 month += 12;
  276.                 year -= 1;             
  277.         }
  278.         long centuries = year/100;
  279.         long leaps = centuries/4;                              
  280.         long leapDays = 2 - centuries + leaps;      // note is negative!!
  281.         long yearDays = 365.25 * (year + 4716);     // days until 1 jan this year
  282.         long monthDays = 30.6001 * (month + 1);         // days until 1st month
  283.         long jd = leapDays + day + monthDays + yearDays -1524.5;
  284.         jd += 1; //correction due wrong "round" of .5
  285.         return jd;
  286. }
  287.  
  288. void GregorianDate(long jd, Mydate *d) {
  289.         //http://php.net/manual/en/function.jdtogregorian.php  
  290.         long calc1, calc2, calc3;
  291.         long year, month, day; 
  292.  
  293.     jd = jd - 1721119;
  294.         calc1 = 4 * jd - 1;
  295.         year = (calc1 / 146097);
  296.         jd = (calc1 - 146097 * year);
  297.         day = (jd / 4);
  298.         calc2 = 4 * day + 3;
  299.         jd = (calc2 / 1461);
  300.         day = calc2 - 1461 * jd;
  301.         day = ((day + 4) / 4);
  302.         calc3 = 5 * day - 3;
  303.         month = (calc3 / 153);
  304.         day = calc3 - 153 * month;
  305.         day = ((day + 5) / 5);
  306.     year = 100 * year + jd;
  307.         if (month < 10) {
  308.                 month = month + 3;
  309.         }
  310.         else {
  311.                 month = month - 9;
  312.                 year = year + 1;
  313.         }
  314.    
  315. /*      Serial.print(year);
  316.         print0(month);
  317.         print0(day);
  318.         //Serial.println(); */
  319.         d->day = day;
  320.         d->month = month;
  321.         d->year = year;
  322. }
  323.  
  324. void intAlarm() {
  325.         state = HIGH;
  326.         return;
  327. }
  328.  
  329. void intWakeSerial() {
  330.         detachInterrupt(digitalPinToInterrupt(3));
  331.         return;
  332. }
  333.  
  334. void cwOn() {
  335.         digitalWrite(LED_PIN,HIGH);
  336.         digitalWrite(CW_PIN,LOW);      
  337. }  
  338.  
  339. void cwOff() {
  340.         digitalWrite(LED_PIN,LOW);
  341.         digitalWrite(CW_PIN,HIGH);     
  342. }
  343.  
  344. void sendCW(byte letter) {
  345.         int bits = 16;
  346.         int mode;
  347.        
  348.         word signs = pgm_read_word(morse + letter);
  349.        
  350.         if(signs!=0) {
  351.                 Serial.println(signs,BIN);
  352.                 mode = signs >> 14;
  353.                 signs &= 0x3FFF;
  354.                 //Serial.println(mode);
  355.                
  356.                 while(!(signs & 0x8000) && bits) {             
  357.                         signs <<= 1;
  358.                         bits--;        
  359.                 }      
  360.                 signs <<= 1;
  361.                 bits--;
  362.                
  363.                 switch(mode) {
  364.                         case 0:
  365.                                 while(bits) {
  366.                                         cwOn();
  367.                                         if (signs & 0x8000)
  368.                                                 delay(DAH*cwspeed);
  369.                                         else
  370.                                                 delay(DIT*cwspeed);
  371.                                         cwOff();
  372.                                         signs <<= 1;
  373.                                         bits--;
  374.                                         if (bits>0) delay(DIT*cwspeed);                
  375.                                 }
  376.                                 delay(CHAR_DELAY*cwspeed);
  377.                                 break;
  378.                        
  379.                         case 2:
  380.                                 signs >>= 3;                                   
  381.                                 cwOn();
  382.                                 delay(signs*100);
  383.                                 cwOff();                               
  384.                                 break;
  385.                        
  386.                         case 3:
  387.                                 while(bits) {
  388.                                         Serial.println(signs,BIN);
  389.                                         if (signs & 0x8000)
  390.                                                 cwOn();
  391.                                         else
  392.                                                 cwOff();
  393.                                         delay(DIT*cwspeed);
  394.                                         signs <<= 1;
  395.                                         bits--;                        
  396.                                 }
  397.                 }
  398.         }
  399. }
  400.  
  401. void sendData() {
  402.         String message = F("***  QTC DE OK1RIG/B  VVV VVV VVV = ");
  403.         for(int cnt=0; cnt<message.length(); cnt++)
  404.                 sendCW(message[cnt]);
  405.                        
  406.         int cnt = 0;
  407.         while (cnt<storageLen and storage[cnt]>-2000) {
  408.                 Serial.println(storage[cnt],DEC);
  409.                 long cTemp = (long)storage[cnt]*625/1000;
  410.                 if(storage[0]<0)
  411.                         msg = String("m" + cTemp);
  412.                 else
  413.                         msg = String(cTemp);
  414.                
  415.                 for(int t=0; t<msg.length(); t++)
  416.                                 sendCW(msg[t]);
  417.                        
  418.                 sendCW(' ');
  419.                 sendCW(' ');
  420.                 sendCW(' ');
  421.                 cnt++;
  422.         }
  423.         sendCW('.');   
  424. }  
  425.  
  426. void rtcOn() {
  427.         pinMode(RTC_POWER_PIN,OUTPUT);
  428.         digitalWrite(RTC_POWER_PIN, HIGH);     
  429. }
  430.  
  431. void rtcOff() {
  432.         pinMode(RTC_POWER_PIN, INPUT);
  433.         digitalWrite(RTC_POWER_PIN, LOW);
  434. }
  435.  
  436. void sleepBaby() {
  437.         rtcOff();
  438.         attachInterrupt(digitalPinToInterrupt(3), intWakeSerial, LOW );
  439.         set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  440.         sleep_enable();
  441.         sleep_bod_disable();
  442.         sei();
  443.         sleep_cpu();
  444.         sleep_disable();
  445.         rtcOn();
  446. }
  447.  
  448. int readTemperature(int day, byte hour) {
  449.         int address = day * 50 + hour * 2 + 2;
  450.         int temp;
  451.        
  452.         Wire.beginTransmission(AT24C32_I2C_ADDRESS);
  453.         Wire.write(highByte(address));
  454.         Wire.write(lowByte(address));
  455.         Wire.endTransmission();
  456.         Wire.requestFrom(AT24C32_I2C_ADDRESS, 2);
  457.        
  458.         temp = Wire.read();
  459.         return Wire.read() << 8 | temp;        
  460. }
  461.  
  462. void pastValues(int samples) {
  463.         struct Mydatetime dt;
  464.         long start,today;
  465.         int hour;
  466.        
  467.         getRtcTime(&dt);
  468.         today = JulianDate(dt.year, dt.month, dt.day);
  469.         EEPROM.get(0, start);
  470.         start = today - start;
  471.         hour = dt.hour;
  472.         while(samples && start) {
  473.                 Serial.println(readTemperature(start, hour)-880);
  474.                 hour--;
  475.                 if (hour<0) {   //or if(--hour < 0) {
  476.                         hour = 23;
  477.                         start--;
  478.                 }
  479.                 samples--;
  480.         }
  481. }
  482.  
  483. void setup() { 
  484.         rtcOn();                                                                //power RTC On
  485.  
  486.         //CW
  487.         pinMode(LED_PIN, OUTPUT);                               //onboard Led  
  488.         digitalWrite(LED_PIN, LOW);    
  489.         pinMode(CW_PIN, OUTPUT);                                //Buzzer
  490.         digitalWrite(CW_PIN,HIGH);
  491.  
  492.         //ADC
  493.         pinMode(ADC_CONTROL_PIN, OUTPUT);               //connect Voltage on ADC       
  494.         digitalWrite(ADC_CONTROL_PIN,HIGH);
  495.         pinMode(ADC_PIN, INPUT);                                //Battery meassure  
  496.         analogReference(INTERNAL);  
  497.  
  498.         Serial.begin(19200);
  499.         Wire.begin();
  500.        
  501.         while (!Serial); // wait for serial port to connect. Needed for native USB port only
  502.  
  503.         for(int x=storageLen-1; x>=0; x--)      //loop down is less code in ASM
  504.                 storage[x] = 0x8000;                            // 0°C is valid value !
  505.  
  506.         //Serial.setTimeout(50);
  507.         buffer = "";
  508.         Serial.println(F("Console ready."));
  509.  
  510.         attachInterrupt(digitalPinToInterrupt(2), intAlarm, FALLING );  
  511.         clearRtcAlarm();
  512.         setRtcAlarm();
  513. }
  514.  
  515. void loop() {
  516.         long jd;       
  517.         Mydate date;
  518.        
  519.  
  520.         if (Serial.available() > 0) {
  521.                 activityTime = millis();                                        //timeout handling
  522.                 ch = Serial.read();
  523.                 if (ch==8) {                                //BS
  524.                         if (buffer.length()>0) {                //if something in buffer
  525.                           buffer.remove(buffer.length()-1,1);        
  526.                           Serial.write(127);                    //echo backspace 127 in PuTTY
  527.                         }
  528.                 }
  529.                 else if (ch==13) {
  530.                         Serial.println();
  531.                         if(buffer.equals(F("clear"))) {
  532.                                 clearRtcAlarm();
  533.                         }
  534.                         else if(buffer.equals(F("temps"))) {
  535.                                 for(int x=0; x<storageLen; x++)
  536.                                         Serial.println((float)storage[x]/16);            
  537.                         }
  538.                         else if(buffer.equals(F("cw"))) {
  539.                                 sendData();
  540.                         }
  541.                         /*else if(buffer.equals(F("st"))) {
  542.                                 for(int y=1; y!=10; y++) {
  543.                                         Wire.beginTransmission(AT24C32_I2C_ADDRESS);
  544.                                         Wire.write(0);
  545.                                         Wire.write(30);
  546.                                         Wire.endTransmission(false);                                    //FLUSH, STOP and continue
  547.                                         Wire.requestFrom(AT24C32_I2C_ADDRESS, 1, true); //STOP
  548.                                         rx = Wire.read();
  549.                                         Serial.println(rx);
  550.                                         Serial.flush();
  551.                                 }
  552.                         } */
  553.                         else if(buffer.equals(F("dumprtc"))) {
  554.                                 dump(DS3231_I2C_ADDRESS, 0, 19, ADDRESS_8BIT);
  555.                         }
  556.                         else if(buffer.startsWith(F("dumpeep"))) {
  557.                                 int addr = 0;
  558.                                 buffer.remove(0,7);
  559.                                 buffer.trim();
  560.                                 if (buffer.length()>0 and buffer.length()<=4) {
  561.                                         for(int lp=0; lp<buffer.length();lp++) {
  562.                                                 if (buffer[lp]>='A' and buffer[lp]<='F')
  563.                                                         addr = (addr << 4) | ((byte)buffer[lp]-55);
  564.                                                 else if(buffer[lp]>='a' and buffer[lp]<='f')
  565.                                                         addr = (addr << 4) | ((byte)buffer[lp]-87);
  566.                                                 else if(buffer[lp]>='0' and buffer[lp]<='9')
  567.                                                         addr = (addr << 4) | ((byte)buffer[lp]-48);
  568.                                         }
  569.                                 }
  570.                                 dump(AT24C32_I2C_ADDRESS, addr, 256, ADDRESS_16BIT);
  571.                         }
  572.                         else if(buffer.startsWith(F("dumpint"))) {
  573.                                 dump(INTERNAL_EEPROM, 0, 256, ADDRESS_8BIT);
  574.                         }
  575.                         else if(buffer.equals(F("volt"))) {
  576.                                 Serial.print(F("Analog value:"));
  577.                                 Serial.println(getVoltage());                                  
  578.                         }
  579.                         /*else if(buffer.equals(F("jd"))){
  580.                                 Serial.println(JulianDate(16, 1 , 1));
  581.                                 Serial.println(JulianDate(16, 12 , 31));
  582.                                 Serial.println(JulianDate(15, 1 , 1));
  583.                                 Serial.println(JulianDate(15, 12 , 31));
  584.                         } */
  585.                         else if(buffer.equals(F("temprtc"))) {
  586.                                 Wire.beginTransmission(DS3231_I2C_ADDRESS);
  587.                                 Wire.write(0x11);
  588.                                 Wire.endTransmission();
  589.                                 Wire.requestFrom(DS3231_I2C_ADDRESS, 2);
  590.                                 int temp2 = Wire.read();
  591.                                 temp2 <<= 2;
  592.                                 temp2 |= (Wire.read() >> 6);
  593.                                 Serial.println((float)temp2/4);                        
  594.                         }
  595.                         else if(buffer.equals(F("cleareep"))) {                
  596.                                 eraseEeprom(AT24C32_I2C_ADDRESS, 256);
  597.                                 Serial.println(F("Eeprom erased."));
  598.                         }
  599.                         else if(buffer.equals(F("time"))) {
  600.                                 getRtcTime(&datetime);
  601.                                 print0(datetime.year); Serial.print(F("-"));
  602.                                 print0(datetime.month); Serial.print(F("-"));
  603.                                 print0(datetime.day); Serial.print(F("  "));
  604.                                 print0(datetime.hour); Serial.print(F(":"));
  605.                                 print0(datetime.minute); Serial.print(F(":"));
  606.                                 print0(datetime.second); Serial.print(F(" "));
  607.                                 print0(datetime.dow);
  608.                                 Serial.println();
  609.                         }
  610.                         else if(buffer.startsWith(F("settime "))) {
  611.                                 buffer.remove(0,7);
  612.                                 buffer.trim();
  613.                                 if(buffer.length() == 6) {
  614.                                         getRtcTime(&datetime);
  615.                                         datetime.hour = (buffer[0]-48) * 10 + (buffer[1]-48);
  616.                                         datetime.minute = (buffer[2]-48) * 10 + (buffer[3]-48);
  617.                                         datetime.second = (buffer[4]-48) * 10 + (buffer[5]-48);
  618.                                         setRtcTime(&datetime);
  619.                                 } else Serial.println(F("Bad format, should be HHMMSS"));
  620.                         }
  621.                         else if(buffer.startsWith(F("setdate "))) {
  622.                                 buffer.remove(0,7);
  623.                                 buffer.trim();
  624.                                 if(buffer.length() == 6) {
  625.                                         getRtcTime(&datetime);
  626.                                         datetime.year = (buffer[0]-48) * 10 + (buffer[1]-48);
  627.                                         datetime.month = (buffer[2]-48) * 10 + (buffer[3]-48);
  628.                                         datetime.day = (buffer[4]-48) * 10 + (buffer[5]-48);
  629.                                         setRtcTime(&datetime);
  630.                                 } else Serial.println(F("Bad format, should be YYMMDD"));
  631.                         }
  632.                         else if(buffer.startsWith(F("setdow "))) {
  633.                                 buffer.remove(0,6);
  634.                                 buffer.trim();
  635.                                 if(buffer.length() == 1) {
  636.                                         getRtcTime(&datetime);
  637.                                         datetime.dow = buffer[0]-48;
  638.                                         setRtcTime(&datetime);
  639.                                 } else Serial.println(F("Bad format, should be D"));                                   
  640.                         }
  641. /*                              else if(buffer.equals(F("rtcon"))) {
  642.                                 rtcOn();
  643.                         }
  644.                         else if(buffer.equals(F("rtcoff"))) {                                  
  645.                                 rtcOff();
  646.                         } */
  647.                         else if(buffer.equals(F("storedate"))) {
  648.                                 getRtcTime(&datetime);
  649.                                 jd = JulianDate(datetime.year, datetime.month, datetime.day);
  650.                                 EEPROM.put(0, jd);
  651.                         }
  652.                         else if(buffer.equals(F("loaddate"))) {
  653.                                 EEPROM.get(0, jd);
  654.                                 Serial.println(jd);
  655.                                 GregorianDate(jd, &date);
  656.                                 Serial.print(date.year);
  657.                                 print0(date.month);
  658.                                 print0(date.day);
  659.                         }
  660. /*                              else if(buffer.equals(F("greg"))) {                                    
  661.                                 EEPROM.get(0, jd);
  662.                                 Serial.println(jd);
  663.                                 GregorianDate(jd);
  664.                                 GregorianDate(2457389);
  665.                                 GregorianDate(2457754);
  666.                                 GregorianDate(2457024);
  667.                                 GregorianDate(2457388);
  668.                         } */
  669.                         else if(buffer.equals(F("list"))) {
  670.                                 EEPROM.get(0, jd);
  671.                                 getRtcTime(&datetime);
  672.                                 long today = JulianDate(datetime.year, datetime.month, datetime.day);
  673.                                 Serial.println(today);
  674.                                 long toDay = today - jd;
  675.                                 Serial.println(toDay);
  676.                                 int fromDay = toDay - 2;                                       
  677.                                 if (fromDay<0) fromDay = 0;
  678.                                 Serial.println(fromDay);
  679.                                
  680.                                 for(int d=fromDay; d<=toDay; d++) {
  681.                                         for(int h=0; h < 24; h++) {
  682.                                                 GregorianDate(jd+d, &date);
  683.                                                 Serial.print(date.year);
  684.                                                 print0(date.month);
  685.                                                 print0(date.day);
  686.                                                 Serial.print(F(" "));
  687.                                                 print0(h);
  688.                                                 Serial.print(F(":00"));
  689.                                                 Serial.print(F(" "));
  690.                                                 int tmpTemp = readTemperature(d,h);
  691.                                                 if (tmpTemp>0 and tmpTemp<2880) {
  692.                                                         Serial.println((float)(tmpTemp-880)/16.0);
  693.                                                 }
  694.                                                 else Serial.println();
  695.                                         }
  696.                                 }                                      
  697.                         }
  698.                         else if (buffer.equals("")) {
  699.                                 //nil - avoid error message on enter
  700.                         }
  701.                         else Serial.println(F("Error."));
  702.                         Serial.print(F(">>"));
  703.                         buffer = "";        
  704.                 } else {
  705.                         buffer.concat((char)ch);
  706.                         Serial.write(ch);          
  707.                 }
  708.         }
  709.        
  710.         //In case if millis overflow (once per ~50 days)
  711.         if(activityTime>millis())
  712.                 activityTime = millis();
  713.        
  714.         //Timeout - sleep
  715.         if(millis() > (activityTime + TIMEOUT_TIME))  {
  716.                 sleepBaby();
  717.                 activityTime = millis();
  718.         }
  719.  
  720.         if (state==HIGH) {
  721.                 rtcOn();
  722.                 Serial.println(F("Interrupt invoked"));
  723.                 getRtcTime(&datetime);
  724.                
  725.                 Serial.print(F("Day offset:"));
  726.                 int tmpDayOffset = JulianDate(datetime.year,datetime.month,datetime.day) - EEPROM.get(0, jd);
  727.                 Serial.println(tmpDayOffset);
  728.                 Serial.print(F("In day add:"));
  729.                 Serial.println((datetime.hour*2)+2);
  730. /*                      delay(50);      
  731.                 for(int x=storageLen-1; x>0; x--)     //shift data
  732.                         storage[x] = storage[x-1];
  733.                 storage[0] = getTemp();
  734. */
  735.  
  736.                 if (datetime.minute == 0) {
  737.                         int temperature = getTemp();
  738.                         eepPtr = (tmpDayOffset * 50) + (datetime.hour * 2) + 2;
  739.                         Serial.println(eepPtr);
  740.                         Serial.println(temperature);
  741.                         Wire.beginTransmission(AT24C32_I2C_ADDRESS);
  742.                         Wire.write(highByte(eepPtr));
  743.                         Wire.write(lowByte(eepPtr));
  744.                         Wire.write(lowByte(temperature));
  745.                         Wire.write(highByte(temperature));
  746.                         Wire.endTransmission();
  747.                 }
  748.                 Serial.flush();                       //wait until all serial data are out before sleep
  749.                 clearRtcAlarm();
  750.                 state=LOW;
  751.                 sleepBaby();
  752.         }
  753. }