//////////////////////////////////////////////////////////////////////////////////
// 1.1.2 removed rtc,
// 1.1.3 added 2 commas in non bms record. added bms updates to web server mlaas and mlarr records
// 1.1.4 added dynamic file names based on coledate from exp1 record
//////////////////////////////////////////////////////////////////////////////////
#include <SPI.h>
#include <SD.h>
#include <DS1307RTC.h>
#include <Time.h>
#include <Wire.h>
#include <Ethernet.h>
#include <utility/w5100.h>
//#define ethernetON
#define ServerDEBUG
//Ethernet Setup Info
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEC };
IPAddress ip( 192,168,0,10 ); // AJ1 Network
IPAddress gateway( 192,168,0,254 ); //blue TP-Link Router, AJ1
IPAddress subnet( 255,255,255,0 );
EthernetServer server(80);
const char legalChars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890/.-_~";
unsigned int requestNumber = 0;
const int chipSelect = 4; //sd card cs pin
String logFileExt = "000.csv";
String logFileString;
char logFile[] = "logfile0.csv"; //file name to store into
//ColeTime Variables
float ColeTimeSecond;
int ColeTimeYear;
long fakeSecond;
int LeapDays = 0;
//SD file write intermediate records
String expRecord1 = ("");
String expRecord2 = (",,,,,,,,,,,,,,,,,,,,,,"); // 22 commas
String expRecord3 = ("");
String expRecord = ("");
unsigned long ExpDelay = 0;
int ExpReady = 0;
//Serial input read strings
String inData;
char inChar=-1;
String inData2;char inChar2=-1;
String inData3;
char inChar3 =-1;
void setup()
{
// Serial Ports Setup
Serial.begin(19200); // USB Monitoring Port
Serial1.begin(4800); // input from Sensor module, includes all Insturment input
//Serial2.begin(19200); // EXP records from BMS module
Serial3.begin(38400); // Output to other systems
//Begin Sensor Initialization
#ifdef ServerDEBUG
Serial.println("DEBUG ON");
delay(3000);
#endif
delay(2000); //wait
//announce yourself to the modules ///
Serial.println (" Distribution Module Version 1.1.4 SD, SensorPac S1-4800, NO RTC, ETHERNET BMS S2-19200, S3-38400");
Serial1.println(" Distribution Module Version 1.1.4 SD, SensorPac S1-4800, NO RTC, ETHERNET BMS S2-19200, S3-38400");
Serial3.println(" Distribution Module Version 1.1.4 SD, SensorPac S1-4800, NO RTC, ETHERNET BMS S2-19200, S3-38400");
//SD Card setup and Initialization
pinMode(10,OUTPUT); //setup to disable 5200 during SD statrup
digitalWrite(10,HIGH); //Enet disable
Serial.print(".....Initializing SD card.....");
pinMode(4, OUTPUT); //CS line for SD card, disables ethernet
if (!SD.begin(chipSelect))
{
Serial.println("NO SD Card");
return;
}
Serial.print("SD Setup Sucessful. Ethernet Setup Begins......");
Ethernet.begin(mac, ip, gateway, gateway, subnet);
digitalWrite(10,HIGH);
delay(2000);
#ifdef ethernetON
server.begin();
Serial.println(F("Server Ready"));
#endif
int loopCount = 0;
} //end of setup
void loop()
//This loop checks the server for activity and reads from the sensors on Serial1, BMS module on Serial2, and SD write Records on Serial3 outputs a combined stream to port 3, writes logs to the SD card.
{
//check for network client activity
#ifdef ethernetON
checkServer();
#endif
//Combined II Sensor port IN
while (Serial1.available() > 0) //Port 1 Has NKE Instruments, remove HDG, ZDA, GLL MTA, VWR and VTG from output stream as the data conflicts with the GPS data.
{
char recieved = Serial1.read();
inData += recieved;
if (recieved == '\n') // Process message when new line character is recieved
{
#ifdef ServerDEBUG
Serial.print("port 1: ");
#endif
Serial.print(inData); //send all messages to USB
Serial3.print(inData); //send all messages to Output
//Serial2.print(inData);
//Serial1.print(inData);
inData = ""; // Clear recieved buffer
} //end /N EOL line processing
} //end while port available
//BMS 3v Transfer Port
while (Serial2.available() > 0)
{
char recieved2 = Serial2.read();
inData2 += recieved2;
if (recieved2 == '\n') // Process message when new line character is recieved
{
//#ifdef ServerDEBUG
Serial.print("port 2: ");
Serial.print(inData2);
// #endif
if (inData2.substring(1,6) =="MEXP2") //Read the Expedition Sentence
{
int poundloc = inData2.indexOf(',#');
int poundloc2 = inData2.indexOf('#', poundloc+1);
String exp02 = inData2.substring(poundloc+1,poundloc2);
expRecord2 = exp02;
}
else // forward all other sentences
{
Serial.print(inData2); //send all remaining messages to USB
Serial3.print(inData2); //send all remaining messages to output port
} //end sentence print
inData2 = ""; // Clear recieved buffer
}
}
//expedition record Port in, Vesper port out
while (Serial3.available() > 0) //Port 3 Has Expedition data records only
{
char recieved3 = Serial3.read();
inData3 += recieved3;
if (recieved3 == '\n') // Process message when new line character is recieved
{
#ifdef ServerDEBUG
Serial.print("port 3: ");
Serial.print(inData3);
#endif
if (inData3.substring(1,6) =="MEXP1") //Read the first Expedition Record
{
int poundloc = inData3.indexOf(',#');
int poundloc2 = inData3.indexOf('#', poundloc+1);
String exp01 = inData3.substring(poundloc+1,poundloc2);
String cDate = exp01.substring(0,5);
logFileString = cDate+ logFileExt;
#ifdef ServerDEBUG
Serial.print("**********************************************date***********************");
Serial.println(logFileString);
#endif
expRecord1 = exp01;
}
else if (inData3.substring(1,6) =="MEXP3") //Trigger for Expedition Record Write
{
int poundloc = inData3.indexOf(',#');
int poundloc2 = inData3.indexOf('#', poundloc+1);
String exp03 = inData3.substring(poundloc+1,poundloc2);
expRecord3 = exp03;
inData3 = ""; // Clear recieved buffer
#ifdef ServerDEBUG
Serial.print("ExpReady Count ");
Serial.println(ExpReady);
#endif
if (ExpReady >= 3)
{
LogExpeditionInfo();
}
}
//Serial.print(inData3); //send all remaining messages to USB
//Serial3.print(inData3); //send all remaining messages to output port
//Serial1.print(inData3); //send all remaining messages to II port
ExpReady = ExpReady+1;
inData3 = ""; // Clear recieved buffer
}
} //end port read
}//end main loop
void LogExpeditionInfo()
{
expRecord = expRecord1+expRecord2+expRecord3; //combine the 3 records
logFileString.toCharArray(logFile,13);
File dataFile = SD.open(logFile, FILE_WRITE);
dataFile.println(expRecord);
dataFile.close();
#ifdef ServerDEBUG
Serial.print(logFile);
Serial.println(" Written to SD*************************************************************************");
Serial.println(expRecord);
#endif
expRecord = "";
expRecord1 = "";
//expRecord2 = "";
expRecord3 = "";
}
void checkServer() {
EthernetClient client = server.available();
if(client) {
boolean currentLineIsBlank = true;
boolean currentLineIsGet = true;
int tCount = 0;
char tBuf[64];
int r,t;
char *pch;
char methodBuffer[8];
char requestBuffer[48];
char pageBuffer[48];
char paramBuffer[48];
char protocolBuffer[9];
char fileName[32];
char fileType[4];
int clientCount = 0;
requestNumber++;
#ifdef ServerDEBUG
Serial.print(F("\r\nClient request #"));
Serial.print(requestNumber);
Serial.print(F(": "));
#endif
// this controls the timeout
int loopCount = 0;
while (client.connected()) {
while(client.available()) {
// if packet, reset loopCount
// loopCount = 0;
char c = client.read();
if(currentLineIsGet && tCount < 63)
{
tBuf[tCount] = c;
tCount++;
tBuf[tCount] = 0;
}
if (c == '\n' && currentLineIsBlank) {
#ifdef ServerDEBUG
Serial.print(tBuf);
#endif
// Serial.print(F("POST data: "));
while(client.available()) client.read();
int scanCount = sscanf(tBuf,"%7s %47s %8s",methodBuffer,requestBuffer,protocolBuffer);
if(scanCount != 3) {
#ifdef ServerDEBUG
Serial.println(F("bad request"));
#endif
sendBadRequest(client);
return;
}
char* pch = strtok(requestBuffer,"?");
if(pch != NULL) {
strncpy(fileName,pch,31);
strncpy(tBuf,pch,31);
pch = strtok(NULL,"?");
if(pch != NULL) {
strcpy(paramBuffer,pch);
}
else paramBuffer[0] = 0;
}
strtoupper(requestBuffer);
strtoupper(tBuf);
for(int x = 0; x < strlen(requestBuffer); x++) {
if(strchr(legalChars,requestBuffer[x]) == NULL) {
Serial.println(F("bad character"));
sendBadRequest(client);
return;
}
}
#ifdef ServerDEBUG
Serial.print(F("file = "));
Serial.println(requestBuffer);
#endif
pch = strtok(tBuf,".");
if(pch != NULL) {
pch = strtok(NULL,".");
if(pch != NULL) strncpy(fileType,pch,4);
else fileType[0] = 0;
//#ifdef ServerDEBUG
Serial.print(F("file type = "));
Serial.println(fileType);
if(fileType == "LOG") {ExpReady = 0; Serial.println("trapped LOG");} //
//#endif
}
#ifdef ServerDEBUG
Serial.print(F("method = "));
Serial.println(methodBuffer);
#endif
if(strcmp(methodBuffer,"GET") != 0 && strcmp(methodBuffer,"HEAD") != 0) {
sendBadRequest(client);
return;
}
#ifdef ServerDEBUG
Serial.print(F("params = "));
Serial.println(paramBuffer);
Serial.print(F("protocol = "));
Serial.println(protocolBuffer);
#endif
// if dynamic page name
if(strcmp(requestBuffer,"/MYTEST.PHP") == 0) {
#ifdef ServerDEBUG
Serial.println(F("dynamic page"));
#endif
}
else {
if(strcmp(fileName,"/") == 0) {
strcpy(fileName,"/INDEX.HTM");
strcpy(fileType,"HTM");
#ifdef ServerDEBUG
Serial.print(F("Home page "));
#endif
}
#ifdef ServerDEBUG
Serial.println(F("SD file"));
#endif
if(strlen(fileName) > 30) {
#ifdef ServerDEBUG
Serial.println(F("filename too long"));
#endif
sendBadRequest(client);
return;
}
else if(strlen(fileType) > 3 || strlen(fileType) < 1) {
#ifdef ServerDEBUG
Serial.println(F("file type invalid size"));
#endif
sendBadRequest(client);
return;
}
else {
#ifdef ServerDEBUG
Serial.println(F("filename format ok"));
#endif
if(SD.exists(fileName)) {
#ifdef ServerDEBUG
Serial.print(F("file found.."));
#endif
File myFile = SD.open(fileName);
ExpReady = 0;
if(!myFile) {
#ifdef ServerDEBUG
Serial.println(F("open error"));
#endif
sendFileNotFound(client);
return;
}
#ifdef ServerDEBUG
else Serial.print(F("opened.."));
#endif
strcpy_P(tBuf,PSTR("HTTP/1.0 200 OK\r\nContent-Type: "));
// client.write(tBuf);
// client.print(F("HTTP/1.0 200 OK\r\nContent-Type: "));
// send Content-Type
if(strcmp(fileType,"HTM") == 0) strcat_P(tBuf,PSTR("text/html"));
else if(strcmp(fileType,"PHP") == 0) strcat_P(tBuf,PSTR("text/html"));
else if(strcmp(fileType,"TXT") == 0) strcat_P(tBuf,PSTR("text/plain"));
else if(strcmp(fileType,"CSS") == 0) strcat_P(tBuf,PSTR("text/css"));
else if(strcmp(fileType,"GIF") == 0) strcat_P(tBuf,PSTR("image/gif"));
else if(strcmp(fileType,"JPG") == 0) strcat_P(tBuf,PSTR("image/jpeg"));
else if(strcmp(fileType,"JS") == 0) strcat_P(tBuf,PSTR("application/javascript"));
else if(strcmp(fileType,"ICO") == 0) strcat_P(tBuf,PSTR("image/x-icon"));
else if(strcmp(fileType,"PNG") == 0) strcat_P(tBuf,PSTR("image/png"));
else if(strcmp(fileType,"PDF") == 0) strcat_P(tBuf,PSTR("application/pdf"));
else if(strcmp(fileType,"ZIP") == 0) strcat_P(tBuf,PSTR("application/zip"));
else strcat_P(tBuf,PSTR("text/plain"));
strcat_P(tBuf,PSTR("\r\nConnection: close\r\n\r\n"));
client.write(tBuf);
if(strcmp(methodBuffer,"GET") == 0) {
#ifdef ServerDEBUG
Serial.print(F("send.."));
#endif
while(myFile.available()) {
tBuf[clientCount] = myFile.read();
clientCount++;
tBuf[clientCount] = 0;
if(clientCount > 63) {
client.write((byte*)tBuf,64);
clientCount = 0;
}
}
if(clientCount > 0) {
client.write((byte*)tBuf,clientCount);
}
}
myFile.close();
#ifdef ServerDEBUG
Serial.println(F("closed"));
#endif
client.stop();
#ifdef ServerDEBUG
Serial.println(F("disconnected"));
#endif
return;
}
else {
#ifdef ServerDEBUG
Serial.println(F("File not found"));
#endif
sendFileNotFound(client);
return;
}
}
}
pch = strtok(paramBuffer,"&");
while(pch != NULL)
{
if(strncmp(pch,"t=",2) == 0)
{
t = atoi(pch+2);
Serial.print("$MLAAC,"); Serial.print(t); Serial.println(",*23" ); //modifies bat capacity remaining
#ifdef ServerDEBUG
Serial.print("t=");
Serial.println(t,DEC);
#endif
}
if(strncmp(pch,"r=",2) == 0)
{
r = atoi(pch+2);
Serial.print("$MLARR,"); Serial.print(r); Serial.println(",*23" ); //modifies bat capacity remaining
#ifdef ServerDEBUG
Serial.print("r=");
Serial.println(r,DEC);
#endif
}
pch = strtok(NULL,"& ");
}
#ifdef ServerDEBUG
Serial.println(F("Sending response"));
#endif
client.print(F("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"));
if(strcmp(methodBuffer,"GET") == 0) {
strcpy_P(tBuf,PSTR("<html><head><script type=\"text/javascript\">"));
client.write(tBuf);
strcpy_P(tBuf,PSTR("function show_alert() {alert(\"are you sure\");}"));
client.write(tBuf);
strcpy_P(tBuf,PSTR("</script></head>"));
client.write(tBuf);
strcpy_P(tBuf,PSTR("<body><H1>BMS MODIFICATION PAGE</H1><form method=GET onSubmit=\"show_alert()\">"));
client.write(tBuf);
strcpy_P(tBuf,PSTR("AVAILABLE: <input type=text name=t><br>"));
client.write(tBuf);
strcpy_P(tBuf,PSTR("RATE: <input type=text name=r><br><input type=submit></form></body></html>"));
client.write(tBuf);
}
client.stop();
}
else if (c == '\n') {
currentLineIsBlank = true;
currentLineIsGet = false;
}
else if (c != '\r') {
currentLineIsBlank = false;
}
}
loopCount++;
// if 1000ms has passed since last packet
if(loopCount > 1000) {
// close connection
client.stop();
#ifdef ServerDEBUG
Serial.println("\r\nTimeout");
#endif
}
// delay 1ms for timeout timing
delay(1);
}
#ifdef ServerDEBUG
Serial.println(F("disconnected"));
#endif
}
}
void sendFileNotFound(EthernetClient thisClient) {
char tBuf[64];
strcpy_P(tBuf,PSTR("HTTP/1.0 404 File Not Found\r\n"));
thisClient.write(tBuf);
strcpy_P(tBuf,PSTR("Content-Type: text/html\r\nConnection: close\r\n\r\n"));
thisClient.write(tBuf);
strcpy_P(tBuf,PSTR("<html><body><H1>FILE NOT FOUND</H1></body></html>"));
thisClient.write(tBuf);
thisClient.stop();
#ifdef ServerDEBUG
Serial.println(F("disconnected"));
#endif
}
void sendBadRequest(EthernetClient thisClient) {
char tBuf[64];
strcpy_P(tBuf,PSTR("HTTP/1.0 400 Bad Request\r\n"));
thisClient.write(tBuf);
strcpy_P(tBuf,PSTR("Content-Type: text/html\r\nConnection: close\r\n\r\n"));
thisClient.write(tBuf);
strcpy_P(tBuf,PSTR("<html><body><H1>BAD REQUEST</H1></body></html>"));
thisClient.write(tBuf);
thisClient.stop();
#ifdef ServerDEBUG
Serial.println(F("disconnected"));
#endif
}
void strtoupper(char* aBuf) {
for(int x = 0; x<strlen(aBuf);x++) {
aBuf[x] = toupper(aBuf[x]);
}
}
byte socketStat[MAX_SOCK_NUM];
void ShowSockStatus()
{
for (int i = 0; i < MAX_SOCK_NUM; i++) {
Serial.print(F("Socket#"));
Serial.print(i);
uint8_t s = W5100.readSnSR(i);
socketStat[i] = s;
Serial.print(F(":0x"));
Serial.print(s,16);
Serial.print(F(" "));
Serial.print(W5100.readSnPORT(i));
Serial.print(F(" D:"));
uint8_t dip[4];
W5100.readSnDIPR(i, dip);
for (int j=0; j<4; j++) {
Serial.print(dip[j],10);
if (j<3) Serial.print(".");
}
Serial.print(F("("));
Serial.print(W5100.readSnDPORT(i));
Serial.println(F(")"));
}
}