element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Vertical Farming
  • Challenges & Projects
  • Design Challenges
  • Vertical Farming
  • More
  • Cancel
Vertical Farming
Blog Automated Green House Blog:18.2 - Data Logging: SD Card
  • Blog
  • Forum
  • Documents
  • Polls
  • Files
  • Events
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: m.ratcliffe
  • Date Created: 17 Nov 2015 2:18 AM Date Created
  • Views 1445 views
  • Likes 2 likes
  • Comments 7 comments
  • adapted_greenhouse
  • data
  • arduino
  • sd
  • log
Related
Recommended

Automated Green House Blog:18.2 - Data Logging: SD Card

m.ratcliffe
m.ratcliffe
17 Nov 2015

Long term data logging from our projects is a great when it comes to developing the system further, from the data we can fine tune our grow bed ratio's work on controlling any variables that vary more than we would like and attribute the causes of a exceptionally good or bad crop.

 

In another Blog we will be sending our data to the "cloud" but it is best if we make a backup version on a SD card too. DAB mentioned saving the data as plain text, a great idea and that is what we will be doing, Sd storage is cheap and it will take a hell of a lot of text to fill up the smallest SD card I have to hand.

 

What you will need:

>Arduino

>SD Card

>Arduino Sd card reader/writer [we will be using the one found on most ethernet shields]

 

Jeremy Blum has already covered this topic, much better than I could ever do. Take a look at his video on the subject:

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

[Thanks Element14 for supporting Jeremy with his arduino blogs, I found them really useful!]

 

The Code

unfortunately Jeremy's tutorials are starting to show their age a little, some of the coding syntax has changed since he wrote his tutorial, but we can use his code as a base for our own and even make it a little better.

Some small improvements:

>Functions to flip between using SD slot and ethernet [cant run both at the same time]

>Sd writing survives a Sd card removal and replacement

>We are logging variables that dont need external hardware [good for a quick test]

 

Header 1

 

 

 

/*

This script measures the enviroment withing a greenhouse

 

 

 

 

Sends data to SD Card with Time Stamp

 

 

 

 

 

 

 

 

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>

 

 

 

 

//*******************************User Defined Variables **********************************//

const int Spacing=10; //how long in sconds to wait between logging data

 

 

// what we will print at the top of log [collums]

String header = "Seconds, Analog_Average, Ram,";

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

 

 

 

 

 

 

 

 

int Ram=0;

float  max_Ram=0;

 

 

 

 

#define SS_SD_CARD   4

#define SS_ETHERNET 10

 

 

 

 

float Analog_Value=0;

 

 

 

 

//Some stuff for making second readings

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

};

//******************************************************************//

 

 

 

 

 

 

 

 

 

 

 

 

//*****************************Setup Loop *************************************//

void setup() {

  // Open serial communications

  Serial.begin(9600);

 

 

digitalWrite(SS_ETHERNET, HIGH); // Ethernet not active

digitalWrite(SS_SD_CARD, LOW);  // SD Card ACTIVE

 

 

 

 

  Serial.print("Initializing SD card...");

 

 

 

 

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

    dataFile.println(header);

 

    dataFile.close();

 

 

  }

  // if the file isn't open, pop up an error:

  else {

    Serial.println("error opening datalog.txt");

  }

 

 

 

 

 

 

}

//********************************* End Of Setup ********************************//

 

 

 

 

//********************************* Main Loop **********************************//

void loop() {

 

 

Second=millis()/1000;

//Taking one reading every second

if(Second!=Last_Second){

   Analog_Value=(analogRead(A0)+ Analog_Value);

   Last_Second=Second;

   Reading++ ;

   }

//Checking how much ram we are using

if(freeRam()>=Ram){

             Ram=(freeRam());

             max_Ram=(((Total_Ram-Ram)/Total_Ram)*100);

};

 

 

 

 

//Averaging Readings and calling the logging functions [see below code]

if(Second%Spacing==0 && Second!=Last_Send){

   Last_Send= Second;

     Analog_Value=Analog_Value/Reading;

     Reading=0; //setting things back ready for more readigs

     Second=millis()/1000;

     Activate_SD();

     Log_SD();

     Activate_Eth();

     Analog_Value=0;

}

 

 

 

 

};

//********************************* End Of Main **********************************//

 

 

 

 

//*************** Activating Sd Card **************************//

void Activate_SD(){

  digitalWrite(SS_ETHERNET, HIGH); // Ethernet not active

  digitalWrite(SS_SD_CARD, LOW);  // SD Card ACTIVE

delay(10);

if (!SD.begin(SS_SD_CARD)) {

    Serial.println("Card failed, or not present");

    // don't do anything more:

  }

   else Serial.println("card initialized.");

 

 

 

 

 

 

};

 

 

 

 

//**************** 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.print("");

    dataFile.print(Second);

    dataFile.print(",  ");

    dataFile.print(Analog_Value);

    dataFile.print(",  ");

    dataFile.println(max_Ram);

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

    Serial.print("Seconds: ");

    Serial.println(Second);

    Serial.println("Data Logged");

 

  }

  // if the file isn't open, pop up an error:

  else {

    Serial.println("error opening datalog.txt");

  }

 

 

};

 

 

 

 

A Example of SD-Card Log

The logging system works just as we expected, and adding a SD.begin before every write means we dont have to reboot every time we remove the sd card for backup. You can import the text file into Exel by special pasting and using commas as cell breaks.

image

 

 

A Example of transporting the data to excel

Here is a plot for the same code, logging temperature near my PC fan as it warms up before removing it to cool:

image

 

Keep an eye out for the next blogs on where else we can store arduino related data.

  • Sign in to reply
  • DAB
    DAB over 9 years ago in reply to m.ratcliffe

    Unfortunately my current medication level does not allow me to do reliable math.

     

    I know, it sucks, I even have to let my wife use the credit card at restaurants to calculate the tip.

     

    Hopefully someone else will check it for you.

     

    DAB

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • m.ratcliffe
    m.ratcliffe over 9 years ago in reply to DAB

    I just checked out how much memory it uses, 5 data logs of 3 readings and the file is 137 bytes.

     

    Some of this will be the actual file itself I think, it is low enough for my project that has 25 data points logged every 5 minutes. Going off the above data it will use around 24x010^6 bytes of data for a years worth of logging 24mb per year. It is that low I am in a little doubt about my maths, care to verify my maths DAB?

     

    Number of readings per year = 365*24*12*25   [days in year*hours in day* number of logs in a hour * number of data points]

    bytes per reading =137/15    [file size/number of readings in the file]

    Rough estimate of memory = No readings* bytes per reading

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • DAB
    DAB over 9 years ago in reply to m.ratcliffe

    I wonder if they are using the old Microsoft blocking factor.

    You might be writing 4K byte blocks for each update, which would quickly fill up your card.

     

    DAB

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • m.ratcliffe
    m.ratcliffe over 9 years ago in reply to DAB

    Thanks DAB,

    It looks like it will need a little bit of debugging, the Max Ram should be around 12%, something is a miss in the code.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • DAB
    DAB over 9 years ago

    I like it, nice and simple, easy to debug.

     

    DAB

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
>
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube