// ARDUINO MEGA 2560 + DATALOGGER (SD+CLOCK) + ETHERNET // OK!!! #pragma GCC optimize ("-Os") #include #include #include LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7,3,POSITIVE); #include #include #include #include #include #include #include #include #include RTC_DS1307 RTC; OneWire ds(5); DallasTemperature sensors(&ds); // enkoder MOD-16.Z #define S1A 2 // S1B GND #define S2 18 #define S3 19 #ifdef MEGA #define SS_SD_CARD 53 #else #define SS_SD_CARD 4 #endif #define SS_ETHERNET 10 int restart; unsigned long int starttime; unsigned long int nexttime; int sample_rate=10; // [s] volatile int display=17; byte backlight=1; byte mac[]={0xDE,0xAD,0xBE,0xEF,0xFE,0xED}; // MAC address IPAddress ip(192,168,31,222); // IP address // IPAddress ip(192,168,1,99); // IP address EthernetServer server(80); // port 80 is default for HTTP float adc[16]; void set_backlight(int i) { if(!i) lcd.noBacklight(); else lcd.backlight(); } void eeprom_write_float(int address,float value) { int i; char *c; c=(char*)&value; for(i=0;i<4;i++) { EEPROM.write(address+i,*c); c++; } } float eeprom_read_float(int address) { int i; char *c; float f; c=(char*)&f; for(i=0;i<4;i++) { *c=EEPROM.read(address+i); c++; } return(f); } void eeprom_write_int(int address,int value) { int i; char *c; c=(char*)&value; for(i=0;i<2;i++) { EEPROM.write(address+i,*c); c++; } } int eeprom_read_int(int address) { int i; char *c; int f; c=(char*)&f; for(i=0;i<2;i++) { *c=EEPROM.read(address+i); c++; } return(f); } byte decToBcd(byte val) { return ((val/10*16) + (val%10)); } byte bcdToDec(byte val) { return ((val/16*10) + (val%16)); } /* s1 - Napis s2 - jednostka v - wartość dv - zmienność wartości min - wartość minimalna max - wartość maksymalna d - wyświetlana liczba cyfr po przecinku hex - wyświetlanie hexadecymalne: 0: nie qu - automatyczne wyjście po 1 minucie: 0: nie */ float edit(char * s1,char * s2,float v,float dv,float min,float max,int d,int hex,int qu) { lcd.clear(); lcd.setCursor(0,0); lcd.print(s1); lcd.setCursor(0,1); lcd.print(v,d); lcd.print(s2); while(!digitalRead(S1A)); unsigned long int s=millis(); do { if(digitalRead(S2)) { while(digitalRead(S2)); v-=dv; if(vmax) v=max; lcd.setCursor(0,1); if(!hex) lcd.print(v,d); else lcd.print((byte)v,HEX); lcd.print(s2); s=millis(); } if(!qu) s=millis(); }while(digitalRead(S1A)&&(millis()-s)<60000); for(int i=0;i<10;i++) { while(!digitalRead(S1A)); delay(100); } while(!digitalRead(S1A)); return(v); } /* EEPROM: 0-3 : adres IP 4-9 : numer MAC 10-11 : sample_rate 12 : backlight */ void lcd_date() { lcd.setCursor(0,0); lcd.print(date_string()); lcd.setCursor(0,1); lcd.print(time_string()); } /* 6-15 : wejścia analogowe [mV] 16 : temperatura DS18B20 17 : czas */ void isr0() { if(backlight) backlight=0; else backlight=1; } void isr1() { display++; if(display>17) display=6; } void isr2() { display--; if(display<6) display=17; } void logger_display() { if(display<16) { lcd.clear(); lcd.print("ADALOG"); lcd.setCursor(0,1); lcd.print("A"); lcd.print(display); lcd.print(": "); lcd.print(adc[display]); lcd.print(" mV"); } else if(display==16) { sensors.requestTemperatures(); float f=sensors.getTempCByIndex(0); lcd.clear(); lcd.print("ADALOG"); lcd.setCursor(0,1); lcd.print(f); lcd.print(" C deg."); } else { lcd.clear(); lcd_date(); } } void time_setup() { float f; byte year,month,day,hour,weekday,minute,second; DateTime now=RTC.now(); f=now.year(); f=edit("Year:"," ",f,1,0,99,0,0,0); year=f-2000; f=now.month(); f=edit("Month:"," ",f,1,1,12,0,0,0); month=f; f=now.day(); f=edit("Day:"," ",f,1,1,31,0,0,0); day=f; f=now.hour(); f=edit("Hour:"," ",f,1,0,23,0,0,0); hour=f; f=now.minute(); f=edit("Minute:"," ",f,1,0,59,0,0,0); minute=f; weekday=second=0; const int DS1307=0x68; Wire.beginTransmission(DS1307); Wire.write(byte(0)); Wire.write(decToBcd(second)); Wire.write(decToBcd(minute)); Wire.write(decToBcd(hour)); Wire.write(decToBcd(weekday)); Wire.write(decToBcd(day)); Wire.write(decToBcd(month)); Wire.write(decToBcd(year)); Wire.write(byte(0)); Wire.endTransmission(); for(int i=0;i<10;i++) { lcd_date(); delay(500); } } void ip_setup() { float f; f=ip[0]; f=edit("IP 0:"," ",f,1,0,255,0,0,0); ip[0]=(byte)f; f=ip[1]; f=edit("IP 1:"," ",f,1,0,255,0,0,0); ip[1]=(byte)f; f=ip[2]; f=edit("IP 2:"," ",f,1,0,255,0,0,0); ip[2]=(byte)f; f=ip[3]; f=edit("IP 3:"," ",f,1,0,255,0,0,0); ip[3]=(byte)f; EEPROM.write(0,ip[0]); EEPROM.write(1,ip[1]); EEPROM.write(2,ip[2]); EEPROM.write(3,ip[3]); } void mac_setup() { float f; f=mac[0]; f=edit("MAC 0:"," ",f,1,0,255,0,1,0); mac[0]=(byte)f; f=mac[1]; f=edit("MAC 1:"," ",f,1,0,255,0,1,0); mac[1]=(byte)f; f=mac[2]; f=edit("MAC 2:"," ",f,1,0,255,0,1,0); mac[2]=(byte)f; f=mac[3]; f=edit("MAC 3:"," ",f,1,0,255,0,1,0); mac[3]=(byte)f; f=mac[4]; f=edit("MAC 4:"," ",f,1,0,255,0,1,0); mac[4]=(byte)f; f=mac[5]; f=edit("MAC 5:"," ",f,1,0,255,0,1,0); mac[5]=(byte)f; EEPROM.write(4,mac[0]); EEPROM.write(5,mac[1]); EEPROM.write(6,mac[2]); EEPROM.write(7,mac[3]); EEPROM.write(8,mac[4]); EEPROM.write(9,mac[5]); } void sample_rate_setup() { float f; f=sample_rate; f=edit("sample_rate:"," [s] ",f,1,0,60,0,0,0); sample_rate=(int)f; eeprom_write_int(10,sample_rate); } void backlight_setup() { float f; f=backlight; f=edit("Backlight:"," ",f,1,0,1,0,0,0); backlight=f; EEPROM.write(12,backlight); } void reset_settings() { ip[0]=192; ip[1]=168; ip[2]=31; ip[3]=222; EEPROM.write(0,ip[0]); EEPROM.write(1,ip[1]); EEPROM.write(2,ip[2]); EEPROM.write(3,ip[3]); mac[0]=0x54; mac[1]=0x55; mac[2]=0x58; mac[3]=0x10; mac[4]=0x00; mac[5]=0x25; EEPROM.write(4,mac[0]); EEPROM.write(5,mac[1]); EEPROM.write(6,mac[2]); EEPROM.write(7,mac[3]); EEPROM.write(8,mac[4]); EEPROM.write(9,mac[5]); sample_rate=10; eeprom_write_int(10,sample_rate); backlight=1; EEPROM.write(12,backlight); lcd.clear(); lcd.print("Done!"); delay(3000); } #define SAMPLE_RATE 0 #define BACKLIGHT 1 #define DATE 2 #define IP 3 #define MAC 4 #define RESET 5 #define QUIT 6 void service_setup() { int pp,p=SAMPLE_RATE; lcd.clear(); lcd.setCursor(0,0); lcd.print("SETUP"); delay(1000); /* while(1) // sprawdzenie działania enkodera { lcd.clear(); lcd.setCursor(0,0); if(digitalRead(S1A)) lcd.print("1"); else lcd.print("0"); lcd.setCursor(2,0); if(digitalRead(S2)) lcd.print("1"); else lcd.print("0"); lcd.setCursor(4,0); if(digitalRead(S3)) lcd.print("1"); else lcd.print("0"); delay(10); } */ while(!digitalRead(S1A)); do { pp=-1; do { if(digitalRead(S2)) { while(digitalRead(S2)); p--; if(pQUIT) p=SAMPLE_RATE; } if(p!=pp) { switch(p) { case SAMPLE_RATE : lcd.clear(); lcd.setCursor(0,0); lcd.print("> Set rec rate"); break; case BACKLIGHT : lcd.clear(); lcd.setCursor(0,0); lcd.print("> Set backlight"); break; case DATE : lcd.clear(); lcd.setCursor(0,0); lcd.print("> Set time"); break; case IP : lcd.clear(); lcd.setCursor(0,0); lcd.print("> Set IP"); break; case MAC : lcd.clear(); lcd.setCursor(0,0); lcd.print("> Set MAC"); break; case RESET: lcd.clear(); lcd.setCursor(0,0); lcd.print("> Reset settings"); break; case QUIT : lcd.clear(); lcd.setCursor(0,0); lcd.print("> Quit"); break; } pp=p; } }while(digitalRead(S1A)); switch(p) { case SAMPLE_RATE : sample_rate_setup(); break; case BACKLIGHT : backlight_setup(); break; case DATE : time_setup(); break; case IP : ip_setup(); break; case MAC : mac_setup(); break; case RESET: reset_settings(); break; case QUIT : break; } }while(digitalRead(S1A)); for(int i=0;i<10;i++) { while(!digitalRead(S1A)); delay(100); } while(!digitalRead(S1A)); } void logger_setup() { if(!digitalRead(S1A)) service_setup(); } void stop() { for(;;){} } void setup() { Serial.begin(9600); detachInterrupt(0); ip[0]=EEPROM.read(0); ip[1]=EEPROM.read(1); ip[2]=EEPROM.read(2); ip[3]=EEPROM.read(3); mac[0]=EEPROM.read(4); mac[1]=EEPROM.read(5); mac[2]=EEPROM.read(6); mac[3]=EEPROM.read(7); mac[4]=EEPROM.read(8); mac[5]=EEPROM.read(9); sample_rate=eeprom_read_int(10); if(sample_rate<1||sample_rate>60) sample_rate=10; backlight=EEPROM.read(12); if(backlight>1) backlight=1; pinMode(S1A,INPUT_PULLUP); // przerwanie #0 - przycisk enkodera pinMode(S2,INPUT_PULLUP); pinMode(S3,INPUT_PULLUP); pinMode(6,OUTPUT); // zasilanie dla LM35 digitalWrite(6,HIGH); lcd.begin(16,2); lcd.clear(); lcd.print("ADALOG"); lcd.setCursor(0,1); lcd.print("Arduino logger"); delay(3000); const int chipSelect=10; lcd.clear(); if(!SD.begin(chipSelect)) { lcd.print("SD card failed."); stop(); } else lcd.print("SD card ok."); delay(333); Wire.begin(); RTC.begin(); lcd.clear(); lcd.clear(); if(!RTC.isrunning()) { lcd.print("RTC failed."); delay(3000); service_setup(); } else lcd.print("RTC ok."); delay(333); logger_setup(); lcd.clear(); lcd.print("."); Ethernet.begin(mac,ip); // start the Ethernet connection and the server: delay(1000); lcd.print("."); server.begin(); delay(1000); lcd.print("."); digitalWrite(SS_SD_CARD,HIGH); // no active digitalWrite(SS_ETHERNET,LOW); // active DeviceAddress daddr; sensors.getAddress(daddr,0); sensors.setResolution(daddr,12); sensors.requestTemperatures(); sensors.getTempCByIndex(0); restart=1; set_backlight(backlight); attachInterrupt(digitalPinToInterrupt(2),isr0,FALLING); attachInterrupt(digitalPinToInterrupt(19),isr1,RISING); attachInterrupt(digitalPinToInterrupt(18),isr2,RISING); } char * date_string() { static char date[12]; strcpy(date,""); DateTime now=RTC.now(); if(now.day()<10) sprintf(date,"%s%d",date,0); sprintf(date,"%s%d",date,now.day()); sprintf(date,"%s%c",date,'.'); if(now.month()<10) sprintf(date,"%s%d",date,0); sprintf(date,"%s%d",date,now.month()); sprintf(date,"%s%c",date,'.'); sprintf(date,"%s%d",date,now.year()); return(date); } char * time_string() { static char time[12]; strcpy(time,""); DateTime now=RTC.now(); if(now.hour()<10) sprintf(time,"%s%d",time,0); sprintf(time,"%s%d",time,now.hour()); sprintf(time,"%s%c",time,'.'); if(now.minute()<10) sprintf(time,"%s%d",time,0); sprintf(time,"%s%d",time,now.minute()); sprintf(time,"%s%c",time,'.'); if(now.second()<10) sprintf(time,"%s%d",time,0); sprintf(time,"%s%d",time,now.second()); return(time); } void sd() { if(restart||(millis()>=nexttime)) // 10 s { Serial.print("starttime: "); Serial.println(starttime); Serial.print("nexttime: "); Serial.println(nexttime); Serial.println(); File logfile; unsigned long int sec; if(restart) starttime=nexttime=millis(); restart=0; sec=(millis()-starttime)/1000; nexttime+=((unsigned long int)sample_rate*1000); Serial.print(">"); Serial.println(nexttime); if(!(logfile=SD.open("log.dat",FILE_WRITE))) { lcd.clear(); lcd.home(); lcd.print("File: error!"); delay(1000); } else { DateTime now=RTC.now(); sensors.requestTemperatures(); logfile.print(date_string()); logfile.print(" "); logfile.print(time_string()); logfile.print(" "); logfile.print(sec); logfile.print(" "); for(int i=6;i<16;i++) { logfile.print(adc[i]); logfile.print(" "); } logfile.println(sensors.getTempCByIndex(0)); logfile.flush(); logfile.close(); } if(!(logfile=SD.open("log.arc",FILE_WRITE))) { lcd.clear(); lcd.home(); lcd.print("File: error!"); delay(1000); } else { DateTime now=RTC.now(); sensors.requestTemperatures(); logfile.print(date_string()); logfile.print(" "); logfile.print(time_string()); logfile.print(" "); logfile.print(sec); logfile.print(" "); for(int i=6;i<16;i++) { logfile.print(adc[i]); logfile.print(" "); } logfile.println(sensors.getTempCByIndex(0)); logfile.flush(); logfile.close(); } SD.remove("lastlog.dat"); if(!(logfile=SD.open("lastlog.dat",FILE_WRITE))) { lcd.clear(); lcd.home(); lcd.print("File: error!"); delay(1000); } else { DateTime now=RTC.now(); sensors.requestTemperatures(); logfile.print(date_string()); logfile.print(" "); logfile.print(time_string()); logfile.print(" "); logfile.print(sec); logfile.print(" "); for(int i=6;i<16;i++) { logfile.print(adc[i]); logfile.print(" "); } logfile.println(sensors.getTempCByIndex(0)); logfile.flush(); logfile.close(); } } } void ethernet() { digitalWrite(SS_ETHERNET, LOW); // Ethernet ACTIVE #define BUFSIZE 100 char clientline[BUFSIZE]=""; unsigned long int wdt=millis(); EthernetClient client=server.available(); // listen for incoming clients if(client) { boolean currentLineIsBlank=true; // an http request ends with a blank line set_backlight(!backlight); while(client.connected()) { if((millis()-wdt)>5000) { while(client.connected()) client.stop(); set_backlight(backlight); return; } if(client.available()) { char c=client.read(); // Serial.write(c); if(c!='\n'&&c!='\r') { if(strlen(clientline)<99) sprintf(clientline,"%s%c",clientline,c); continue; // continue to read more data! } // Serial.write(c); if(c=='\n'&¤tLineIsBlank) // if received a newline and the line is blank, the http request has ended; send a reply { if(strstr(clientline,"GET / ")) { //Serial.print("[["); //Serial.print(clientline); //Serial.println("]]"); client.println("HTTP/1.1 200 OK"); // send a standard http response header client.println("Content-Type: text/html"); client.println("Connection: close"); // the connection will be closed after completion of the response client.println("Refresh: 10"); // refresh the page automatically every 10 sec client.println(); client.println(""); client.println(""); client.println("ADALOG - Arduino Mega 2560 Logger"); client.println(""); client.print("

"); client.print("ADALOG

Arduino Mega 2560 R3
Datalogger Shield SD+RTC
Ethernet Shield W5100"); client.print("

"); // client.print("

"); // client.print(clientline); // client.print("

"); client.print("

"); client.print(date_string()); client.print("
"); client.print(time_string()); client.print("
"); client.print("
"); client.print("Recording time: "); { unsigned long int s=(millis()-starttime)/1000; int h=s/3600; s-=h*3600; int m=s/60; s-=m*60; if(h<10) client.print("0"); client.print(h); client.print(":"); if(m<10) client.print("0"); client.print(m); client.print(":"); if(s<10) client.print("0"); client.print(s); } client.print("
"); client.print("
"); client.print("Sample rate: "); client.print(sample_rate); client.print(" s"); client.print("

"); for(int i=6;i<16;i++) // output the value of each analog input pin { client.print("analog input "); client.print(i); client.print(": "); client.print(adc[i]); client.print(" mV "); client.println("
"); } client.println("
"); sensors.requestTemperatures(); client.print("Temperature DS18B20: "); client.print(sensors.getTempCByIndex(0),1); client.print(" C"); client.println("
"); //client.print("Temperature LM35CAZ: "); //client.print(adc[15]/10.0,1); //client.print(" C"); //client.println("
"); client.println("
"); client.println("Log
"); client.println("Last record
"); client.println("











"); client.println("Erase log files
"); client.println("
"); client.println(""); client.println(""); break; } else if(strstr(clientline,"GET /log.dat")) // GET /log.dat { client.println("HTTP/1.1 200 OK"); //send new page client.println("Content-Type: text/plain"); client.println(); File logfile=SD.open("log.dat"); if(logfile) { byte clientBuf[64]; int clientCount=0; while(logfile.available()) { clientBuf[clientCount]=logfile.read(); clientCount++; if(clientCount>63) { client.write(clientBuf,64); clientCount=0; sd(); } } //final <64 byte cleanup packet if(clientCount>0) client.write(clientBuf,clientCount); // close the file: logfile.close(); } else { client.println(); client.println("Can not read the \"log.dat\" file."); } break; } else if(strstr(clientline,"GET /lastlog.dat")) // GET /lastlog.dat { client.println("HTTP/1.1 200 OK"); //send new page client.println("Content-Type: text/plain"); client.println(); File lastlogfile=SD.open("lastlog.dat"); if(lastlogfile) { byte clientBuf[64]; int clientCount=0; while(lastlogfile.available()) { clientBuf[clientCount]=lastlogfile.read(); clientCount++; if(clientCount>63) { client.write(clientBuf,64); clientCount=0; sd(); } } //final <64 byte cleanup packet if(clientCount>0) client.write(clientBuf,clientCount); // close the file: lastlogfile.close(); } else { client.println(); client.println("Can not read the \"lastlog.dat\" file."); } break; } else if(strstr(clientline,"GET /clearlogger")) // GET /clearlogger { client.println("HTTP/1.1 200 OK"); //send new page client.println("Content-Type: text/html"); client.println("Connection: close"); // the connection will be closed after completion of the response client.println(); client.println(""); client.println(); client.println(""); client.println(""); if(SD.remove("log.dat")&&SD.remove("lastlog.dat")&&SD.remove("log.arc")) { client.println("All log files removed."); restart=1; } else client.println("Error."); client.println(""); client.println(""); break; } else if(strstr(clientline,"GET /clearlog")) // GET /clearlog { client.println("HTTP/1.1 200 OK"); //send new page client.println("Content-Type: text/html"); client.println("Connection: close"); // the connection will be closed after completion of the response client.println(); client.println(""); client.println(); client.println(""); client.println(""); if(SD.remove("log.dat")&&SD.remove("lastlog.dat")) { client.println("Log files removed."); restart=1; } else client.println("Error."); client.println(""); client.println(""); break; } } if(c=='\n') { currentLineIsBlank=true; // you're starting a new line } else if(c!='\r') { currentLineIsBlank=false; // you've gotten a character on the current line } } } set_backlight(backlight); delay(10); // give the web browser time to receive the data while(client.connected()) client.stop(); // close the connection: } while(client.connected()) client.stop(); digitalWrite(SS_ETHERNET, HIGH); // Ethernet not active } void date() { lcd.clear(); lcd.setCursor(0,0); DateTime now=RTC.now(); if(now.day()<10) lcd.print('0'); lcd.print(now.day(),DEC); lcd.print('.'); if(now.month()<10) lcd.print('0'); lcd.print(now.month(),DEC); lcd.print('.'); lcd.print(now.year(), DEC); lcd.print(" "); lcd.setCursor(0,1); if(now.hour()<10) lcd.print('0'); lcd.print(now.hour(),DEC); lcd.print('.'); if(now.minute()<10) lcd.print('0'); lcd.print(now.minute(),DEC); lcd.print(':'); if(now.second()<10) lcd.print('0'); lcd.print(now.second(),DEC); lcd.print(" "); } void adcr() { #define N 100 delay(10); for(int i=6;i<16;i++) { adc[i]=0; for(int j=0;j