// 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