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

arduino

 

Data.Sparkfun

 

data

 

SD_LOG

 

txt

 

 

 

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();

}