The Previose blogs showed how to log data in seperate ways.
Blog:18.1 - On-line Data Logging [data.sparkfun]
Blog:18.2 - Data Logging: SD Card
Blog:18.3 - On line data Viewer [arduino, Ethernet]
It will be useful to have all three methods implemented on the same board, this is a bit tricky because we need to power up the sd card to load data, then configure the data.sparkfun push the data and leave the web_server script running until the next sd and sparkfun log. It is a bit messy but possible to do it this way. The screen shots are from the code below.
The Web_Page
Data.Sparkfun
SD_LOG
The Code
Dont use on Uno [very little memory left]
You will need to change the settings in each function [we cant just declare them at the top when running the ethernet this way]
Header 1 |
---|
/* This script measures the enviroment withing a greenhouse
Sends data to SD Card, data.sparkfun and hosts a webpage all in the same script. We cannot use the conventional areduino script of definitions so you will have to alter the mac adress ip etc in the functions below the code.
DONT USE ON UNO: This takes quite a lot of emory and could brick your uno, mega is fine because it has much more memory
Michael Ratcliffe mike@michaelratcliffe.com
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
>Arduino >Ethernet shield Arduino Ethernet shield R3 with micro SD connector
Much of this code is largely based on Jeremy Blum's Tutorials Thanks for the great work!
*/
#include <SPI.h> #include <SD.h> #include <Ethernet.h>
//*******************************User Defined Variables **********************************//
const int Spacing=10; //how long in sconds to wait between logging data
//This will stop you uploading to an uno int Dont_Use_Script_ON_UNO = A12;
// Enter a MAC address and IP address for your controller below. // The IP address will be dependent on your local network: byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; IPAddress ip(192, 168, 9, 10);
// Initialize the Ethernet server library // with the IP address and port you want to use // (port 80 is default for HTTP): EthernetServer server(80);
const int SparkFunIP[4] = {54,86,132,254}; const int ArduinoIP[4]={192,168,9,10}; const int SeverPort =80;
//*** Your data.sparkfun account const String publicKey = "4XXXXXXXXXXXXXXXXXXXXX"; const String privateKey = "XXXXXXXXXXXXXXXXXXX";
//********* How Many colums you want to log const byte NUM_FIELDS = 3; //The Names for the collum headers, make sure its the same order, spelling and no capitals as your data.sparkfun accunt const String fieldNames[NUM_FIELDS] = {"analog","ram","seconds"}; String fieldData[NUM_FIELDS]; // //analog,ram,seconds [what you paste into data.sparkfun
//******** Change Value Below For Board Of Choice *********// /* ATMega168 ATMega328P ATmega1280 ATmega2560 SRAM 1024 bytes 2048 bytes 8192 Bytes 8192 Bytes */
const int Total_Ram = 8192 ; //change this value for the correct one from above data
//******************** End of Recomended Changes ****************************//
#define SS_SD_CARD 4 #define SS_ETHERNET 10
float Analog_Value=0; unsigned long Second=0; unsigned long Last_Send= 0;
//Some stuff for making second readings long Last_Second=0; int Reading=0;
//****************************Seting up the Ram check**************************************// int freeRam () { extern int __heap_start, *__brkval; int v; return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); };
//********Just Some variables we use to convert to % ************// float Ram=3; float Ram_Ussage=0; int Ram_error=0;
//******************************************************************//
//*****************************Setup Loop *************************************// void setup() { // Open serial communications Serial.begin(9600);
Activate_SD(); delay(100); Init_SD();
Activate_Eth(); delay(100); WebServer_int();
} //********************************* End Of Setup ********************************//
//********************************* Main Loop **********************************// void loop() {
Second=millis()/1000; if(Second!=Last_Second){ Analog_Value=(analogRead(A0)+ Analog_Value); Last_Second=Second; Reading++ ; Post_Web(); }
Max_Ram(); // We need to call this at multiple points in the main loop, Sram Ussage will change thru the loop
if(Second%Spacing==0 && Second!=Last_Send){
Activate_SD(); Table_Data(); Last_Send= Second; Reading=0; //setting things back ready for more readigs
Serial.println("Posting to sparkfun");
// Calling the postData() function does all the work, Serial.println("Pushing to SD"); Log_SD(); Activate_Eth(); postSparkFunData(); WebServer_int();
}
}; //********************************* End Of Main **********************************//
// ***************** Function to put data intro matrix/table ********************// void Table_Data(){
Analog_Value=Analog_Value/Reading;
// Gather data, dont forget you specified the number of data points at the top of the code fieldData[0] = String(Analog_Value); fieldData[1] = String(Ram_Ussage); fieldData[2] = String(Second);
Analog_Value=0;
};
//*************** Activating Sd Card **************************// void Activate_SD(){
digitalWrite(SS_ETHERNET, HIGH); // Ethernet not active digitalWrite(SS_SD_CARD, LOW); // SD Card ACTIVE delay(10);
};
//**************** Function To activate ethernet *************// void Activate_Eth(){ digitalWrite(SS_ETHERNET, LOW); // Ethernet not active digitalWrite(SS_SD_CARD, HIGH); // SD Card ACTIVE };
//**************** Function to Log SD **********************// void Log_SD(){ File dataFile = SD.open("datalog.txt", FILE_WRITE);
// if the file is available, write to it one variable at a time if (dataFile) { dataFile.println(" "); for (int i=0; i<NUM_FIELDS; i++) { dataFile.print(", "); dataFile.print(fieldData[i]); }
dataFile.close(); // print to the serial port too:
Serial.println("Posting!"); Serial.print("Analog_Average: "); Serial.println(Analog_Value); Serial.print("Max_Ram: "); Serial.println(Ram_Ussage); Serial.print("Seconds: "); Serial.println(Second);
} // if the file isn't open, pop up an error: else { Serial.println("error opening datalog.txt"); }
};
//************* Loop for calculating Ram Ussage, called from main loop***//
void Max_Ram(){
if(freeRam()>=Ram){ Ram=(freeRam()); Ram_Ussage=(((Total_Ram-Ram)/Total_Ram)*100); };
if(Ram_Ussage>=70){ Ram_error=1; // Use this set flag to warn the user of a potential Ram ussage problem, or reset the arduino if it becomes true };
};
//******************************* Setting up SD text file ******************************// void Init_SD(){
// see if the card is present and can be initialized: if (!SD.begin(SS_SD_CARD)) { Serial.println("Card failed, or not present"); // don't do anything more: } else Serial.println("card initialized.");
//Printing the file header File dataFile = SD.open("datalog.txt", FILE_WRITE);
// if the file is available, write a header to it: if (dataFile) { dataFile.println(" ");
for (int i=0; i<NUM_FIELDS; i++) { dataFile.print(", "); dataFile.print(fieldNames[i]);
} dataFile.close();
} // if the file isn't open, pop up an error: else { Serial.println("error opening datalog.txt"); } }
//************************* Setting up Ethernet webserver ********************************// void WebServer_int(){
IPAddress ip(192, 168, 9, 10);
// Initialize the Ethernet server library // with the IP address and port you want to use // (port 80 is default for HTTP): EthernetServer server(80);
// start the Ethernet connection and the server: Ethernet.begin(mac, ip); server.begin(); Serial.print("server is at "); Serial.println(Ethernet.localIP()); };
//*********************** Send dats to web server *****************************************// void Post_Web(){ // listen for incoming clients EthernetClient client = server.available(); if (client) { Serial.println("new client"); // an http request ends with a blank line boolean currentLineIsBlank = true; while (client.connected()) { if (client.available()) { char c = client.read(); Serial.write(c); // if you've gotten to the end of the line (received a newline // character) and the line is blank, the http request has ended, // so you can send a reply if (c == '\n' && currentLineIsBlank) { // send a standard http response header client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connection: close"); // the connection will be closed after completion of the response client.println("Refresh: 5"); // refresh the page automatically every 5 sec client.println(); client.println("<!DOCTYPE HTML>"); client.println("<html>"); // output the value of each analog input pin for (int i=0; i<NUM_FIELDS; i++) {
client.print(fieldNames[i]); client.print("="); client.print(fieldData[i]); client.println("<br />"); }
client.println("</html>"); break; } if (c == '\n') { // you're starting a new line currentLineIsBlank = true; } else if (c != '\r') { // you've gotten a character on the current line currentLineIsBlank = false; } } } // give the web browser time to receive the data delay(1); // close the connection: client.stop(); Serial.println("client disconnected"); } }
//********************* Function to push data to server ******************// void postSparkFunData() {
IPAddress server(54,86,132,254); // numeric IP for data.sparkfun.com //char server[] = "data.sparkfun.com"; // name address for data.sparkFun (using DNS) // Set the static IP address to use if the DHCP fails to assign IPAddress ip(192,168,9,10);
// Initialize the Ethernet client library that you want to connect to (port 80 is default for HTTP): EthernetClient client;
Serial.println("Setting up Ethernet..."); // start the Ethernet connection: if (Ethernet.begin(mac) == 0) { Serial.println(F("Failed to configure Ethernet using DHCP")); // no point in carrying on, so do nothing forevermore: // try to congifure using IP address instead of DHCP: Ethernet.begin(mac, ip); } Serial.print("My IP address: "); Serial.println(Ethernet.localIP()); // give the Ethernet shield a second to initialize: delay(100);
// Make a TCP connection to remote host if (client.connect(server, 80)) { // Post the data! Request should look a little something like: // GET /input/publicKey?private_key=privateKey&light=1024&switch=0&name=Jim HTTP/1.1\n // Host: data.sparkfun.com\n // Connection: close\n // \n client.print("GET /input/"); client.print(publicKey); client.print("?private_key="); client.print(privateKey); for (int i=0; i<NUM_FIELDS; i++) { client.print("&"); client.print(fieldNames[i]); client.print("="); client.print(fieldData[i]); } client.println(" HTTP/1.1"); client.print("Host: "); client.println(server); client.println("Connection: close"); client.println(); } else { Serial.println(F("Connection failed")); }
// Check for a response from the server, and route it
while (client.connected()) { if ( client.available() ) { char c = client.read(); Serial.print(c); } } Serial.println(); client.stop(); } |
Top Comments