Made a really big sketch today 🙂 I used an Arduino Uno, ethernet shield with sd slot, DS1307 RTC and 2 temperature sensors for this sketch. I used 2 different temperature sensors, one is a DHT22 sensor which can also sense the humidity and the other is a DS18B20 sensor. To get all this to work I needed no less then 8 libraries, the ethernet and sd library take up a lot of space which makes this sketch so big. After compiling the sketch the size is 23634 bytes (of a 32256 byte maximum). It was pretty easy to code, I started from the various examples that come with the Arduino IDE and put them together. I would never have gotten this to work if I had to start from scratch.
The temperature sensors are polled once every 5 seconds, there is not much point in polling them more often to get room temperatures. I did not use the delay or millis function for this but the time from the DS1307. The date, time, and temperature values are written to a CSV file on the SD card every 5 seconds. A CSV file is easily imported in a spreadsheet. All the data is also made available on a webserver. If you need ethernet and a sd slot for a project the latest official ethernet shield is very handy as it has both. I bought mine from the official Arduino shop. You can find similar shields on ebay from Chinese sellers. But there seem to be quite a lot of topics on the Arduino forum of people having trouble with them.
There is one thing this sketch needs to make it better and that’s an automatic update from a timeserver to sync the time with the DS1307 RTC. The DS1307 is not the most accurate chip, even after a day the time will be of by a couple of seconds.
/* http://www.bajdi.com SD card datalogger and webserver with DS1307 RTC. This sketch shows how to log data from a DHT22 and DS18B20 sensor to an SD card using the SD library. The data from the sensors is updated every 5 seconds and written to the SD card in a CSV file. Time stamp is taken from a DS1307 RTC. The data of the DHT22, DS18B20 and RTC is also available on a webserver. */ #include <SPI.h> #include <Ethernet.h> #include <Wire.h> #include "RTClib.h" #include <dht.h> #include <SD.h> #include <OneWire.h> #include <DallasTemperature.h> const int ONE_WIRE_BUS = 3; // signal pin of DS18B20 connected to pin 3 OneWire ourWire(ONE_WIRE_BUS); DallasTemperature sensors(&ourWire); dht DHT; RTC_DS1307 RTC; #define DHTTYPE DHT22 // Sensor type #define DHT22_PIN 2 // DHT22 signal on pin 2 byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; byte ip[] = { 192,168,1, 10 }; int lastTime = -1; float temp; // float for temperature value from DS18B20 Server server(80); const int chipSelect = 4; // CS for SD card void setup() { Serial.begin(9600); Ethernet.begin(mac, ip); server.begin(); Wire.begin(); sensors.begin(); // for DS18B20 sensor RTC.begin(); RTC.adjust(DateTime(__DATE__, __TIME__)); Serial.print("Initializing SD card..."); pinMode(10, OUTPUT); // see if the card is present and can be initialized: if (!SD.begin(chipSelect)) { Serial.println("Card failed, or not present"); // don't do anything more: return; } Serial.println("card initialized."); } void loop() { DateTime now = RTC.now(); // get time from RTC int time = now.second(); if (abs(time - lastTime) > 5) { int chk = DHT.read22(DHT22_PIN); // get data from DHT22 sensors.requestTemperatures(); // get data from DS18B20 temp = sensors.getTempCByIndex(0); File dataFile = SD.open("datalog.CSV", FILE_WRITE); // if the file is available, write to it: if (dataFile) { dataFile.print(now.day(), DEC); dataFile.print('/'); dataFile.print(now.month(), DEC); dataFile.print('/'); dataFile.print(now.year(), DEC); dataFile.print(" , "); dataFile.print(now.hour(), DEC); dataFile.print(':'); dataFile.print(now.minute(), DEC); dataFile.print(" , "); dataFile.print((float)DHT.temperature); dataFile.print(" , "); dataFile.println((float)temp); dataFile.close(); // print to the serial port too: Serial.print("DHT = "); Serial.println(DHT.temperature); Serial.print("DS18B20 = "); Serial.println(temp); } // if the file isn't open, pop up an error: else { Serial.println("error opening datalog.CSV"); } lastTime = time; } Client client = server.available(); if (client) { // an http request ends with a blank line boolean currentLineIsBlank = true; while (client.connected()) { if (client.available()) { char c = client.read(); 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(); client.print(now.day(), DEC); client.print('/'); client.print(now.month(), DEC); client.print('/'); client.print(now.year(), DEC); client.print(' '); client.print(now.hour(), DEC); client.print(':'); client.print(now.minute(), DEC); client.println("<br />"); client.print("Arduino powered webserver"); client.println("<br />"); client.print("Serving temperature and humidity values from a DHT22 and DS18B20 sensor"); client.println("<br />"); client.print("Inside temperature (oC): "); client.print(DHT.temperature); client.println("<br />"); client.print("Humidity (%): "); client.print(DHT.humidity); client.println("<br />"); client.print("Outside temperature (oC): "); client.print(temp); client.println("<br />"); 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(); } }
[…] last data logging sketch was missing one feature to make it complete. Since I use a DS1307 RTC which is not very accurate, […]
very cool
great work done, thanks
Hi Bajdi,
I hope you don’t mind me posting this here.
Your code has been very helpful! I have made some additions. I have added support for logging the data from the DS18B20 to a Phant.io server. Specifically the one hosted by data.sparkfun.com. I’ve added to the webserver part of your code a Google Charts JavaScript graph of the sensor output.
Here is a link to my project and the modified code (with plenty of references back to this page and your work):
https://nickstuff.wordpress.com/portfolio/temperature-data-logger-using-arduino-with-phant-and-google-charts/
There’s a link on that post where you can see the Google Chart in action. Let me know what you think.
Thanks again for your efforts!
Hi Badji, I’m testing your code, without sensors, only the command to read the RTC and write in the SD.
The code is compiled and loaded without problems, but when it runs the output in the SD is like: 165/165/2165 165:165:85
do you know why?
The RTC is syncronized, and can read it if I used only the Arduino Uno R3, but if I use Arduino whith ethernet shield, the RTC don’t run.