41
DESERT CODE CAMP 2013.1 Datalogging on an Arduino Presented by Don Doerres Embedded Pro Guy [email protected]

2013 1 arduino_datalogger

Embed Size (px)

DESCRIPTION

This is my slide show for the 2013.1 Desert Code Camp Code should be posted to Github soon

Citation preview

Page 1: 2013 1 arduino_datalogger

DESERT CODE CAMP 2013.1Datalogging on an Arduino

Presented by Don DoerresEmbedded Pro [email protected]

Page 2: 2013 1 arduino_datalogger

TODAY’S TAKEAWAYS

The Arduino is a good starting point for a data logger, a device used to obtain and store data over a long period of time

The Arduino with a few add-ins is capable of Storing data with time tags Displaying data in real time Doing these tasks without tying up a

bigger computer

Page 3: 2013 1 arduino_datalogger

IDEA WAS TO LOG WEATHER

I started with a barometer (BMP085) and a humidity sensor (DHT11)

Both of these also provide temperature information

Power came from a desktop computer through USB cable to Arduino, Arduino to breadboard

Page 4: 2013 1 arduino_datalogger

FIRST BREADBOARD

Page 5: 2013 1 arduino_datalogger

SERIOUS WEATHER…

Page 6: 2013 1 arduino_datalogger

WEATHER WATCHING…

Observing an approaching dust storm, I realized that I didn’t want to leave the computer or sensors outside

Barometric pressure turned out to be adequate for storm tracking

Indoors, humidity did not change much So, I decided to record barometric

pressure and temperature

Page 7: 2013 1 arduino_datalogger

ORIGINALLY USED PC

Used Tera Term (Terminal Emulator) to log data

Tera Term added time stamp from PC clock

Once prototype was working, wanted to move time keeping function and data logging to Arduino and not tie up PC

Page 8: 2013 1 arduino_datalogger

ARDUINO TIMING SIX MINUTES, WRITING TO SERIAL PORT

Tera Term Screen

Tera Term Log File—Adds Time Stamp

Page 9: 2013 1 arduino_datalogger

ORIGINAL PLAN: CHRONODOT & SD BREAKOUT

Chronodot is a highly accurate clock with battery backup

SD Breakout allows simple connection to SD card

However, the combination would simply not fit on an Arduino breakout shield, let alone any sensors

Page 10: 2013 1 arduino_datalogger

DOT AND SD ON ARDUINO BREADBOARD

This picture shows the Dot and the SD card breakout

This works as a breadboard, but is too big for a shield

Dot

SD breakout

Page 11: 2013 1 arduino_datalogger

ADAFRUIT INTRODUCED A DATA LOGGER SHIELD

About the time I realized that my logger would not fit on a prototype shield, Adafruit introduced their new logger shield

This had a slightly lower accuracy clock than the Dot, but it had everything else in surface mount parts

All I had to do was add the pressure sensor and a connection to a 16X2 LCD display

Page 12: 2013 1 arduino_datalogger

ADAFRUIT LOGGER SHIELD

Adafruit logger shield Surface mount parts left prototype area quite

large enough for sensors Add an I2C 16X2 LCD display

SD HolderDS1307 RTC

Battery Holder

Page 13: 2013 1 arduino_datalogger

SENSOR SELECTION

This is the BMP085 pressure sensor This is a sensitive barometer/altimeter

and temperature sensor It runs on 5V It has an I2C interface

Page 14: 2013 1 arduino_datalogger

I2C BUS

This is a very simple serial Inter-Integrated Circuit connection bus, hence I2C

The interface consists of Clock, Data, and ground

Multiple devices can be hooked to the same bus as long as they have different addresses

The devices I used, pressure sensor (address 0x77) and display (address 0), do have different addresses

Page 15: 2013 1 arduino_datalogger

BMP085 CONNECTION TO ARDUINO

Page 16: 2013 1 arduino_datalogger

16X2 LCD DISPLAY WITH I2C BACKPACK This is a back view showing the four

wire connections—same connections as BMP085

DAT to A4CLK to A5

5V To 5V

GND To GND

Page 17: 2013 1 arduino_datalogger

OTHER CONNECTIONS

The SD breakout and the Clock are already wired up on the shield

The pressure sensor I soldered to the I2C connection pads on the shield

The LCD display I simply plugged in to the shield

The BMP and the LCD display have different I2C addresses, so there is no conflict

Page 18: 2013 1 arduino_datalogger

TYPICAL DISPLAY

Date (Year not shown), local time Temperature in F, Pressure in mmHG Display updates every 5 seconds Data is stored to SD card every 6

minutes

Page 19: 2013 1 arduino_datalogger

WHAT GOES ON THE SD CARD

The log is Comma Separated Values (CSV) of Time, Temperature, Pressure

Time is stored as a ‘C’ time stamp (more about this in two slides)

Temperature is degrees F Pressure is in millimeters of Mercury

(mmHg)

Page 20: 2013 1 arduino_datalogger

SAMPLE OF LOG FILE1363516494,79.0,691.01363516868,79.0,691.01363517243,79.0,691.01363517617,79.1,691.11363517991,79.1,691.11363518365,79.1,691.11363518740,79.1,691.11363519114,79.2,691.21363519488,79.2,691.21363519862,79.2,691.21363520237,79.2,691.21363520611,79.1,691.11363520985,79.2,691.21363521359,79.1,691.11363521734,79.1,691.11363522108,79.2,691.21363522482,79.2,691.21363522857,79.2,691.21363523231,79.2,691.21363523605,79.2,691.21363523979,79.2,691.21363524354,79.2,691.21363524728,79.1,691.11363525102,79.1,691.11363525476,79.1,691.1

Page 21: 2013 1 arduino_datalogger

THE CTIME STAMP

The C language uses as a time stamp the number of seconds since January 1, 1970

A 32 bit signed integer allows counting seconds until January 19, 2038 at 03:14:07 GMT

…by then, we will likely switch to 64 bit integers

And, yes, the value is a signed integer so that comparisons can be readily made

Page 22: 2013 1 arduino_datalogger

DISPLAYING IN EXCEL OR OTHER SPREADSHEET

It is simple to convert ctime to Excel time

The macro is, using ‘A2’ as a sample cell:

Display format is controlled with Excel

formattingCTIME Increase Delta Day Date Time Deg F mmHg

1363504243 0 0 Sun Mar 17, 2013 07:10:43 74.2 691.21363506389 2146 2146 Sun Mar 17, 2013 07:46:29 75.4 691.41363506764 2521 375 Sun Mar 17, 2013 07:52:44 76.7 691.71363507138 2895 374 Sun Mar 17, 2013 07:58:58 77.5 691.51363507512 3269 374 Sun Mar 17, 2013 08:05:12 77.4 691.41363507886 3643 374 Sun Mar 17, 2013 08:11:26 77.3 691.31363508261 4018 375 Sun Mar 17, 2013 08:17:41 77.3 691.3

=DATE(1970,1,1)+(A2)/86400

Page 23: 2013 1 arduino_datalogger

LIBRARIES

Page 24: 2013 1 arduino_datalogger

UNITS

The units of the BMP085 pressure sensor are Degrees C and pressure in Pascals

Conversions are in order

tempy = bmp.readTemperature();tempy = (tempy * 9.0 / 5.0) + 32.0;

press = bmp.readPressure();fpress = (float)press* 0.007500616827042;

Page 25: 2013 1 arduino_datalogger

TIMESET.INO, 1 OF 2

// timeSet.ino

#include <Wire.h>#include <RTClib.h>#include <LiquidCrystal.h>

LiquidCrystal lcd(0);RTC_DS1307 RTC;DateTime now;

void setup(){Serial.begin(57600);Wire.begin();RTC.begin();RTC.adjust(DateTime(__DATE__, __TIME__)); lcd.begin(16, 2);lcd.setBacklight(HIGH); //HIGH is ON, LOW is OFF}

Page 26: 2013 1 arduino_datalogger

TIMESET.INO, 2 OF 2

void loop(){ now = RTC.now(); lcd.setCursor(0, 0); lcd.print(now.year(), DEC); lcd.print('/'); if(now.month() < 10) lcd.print("0"); lcd.print(now.month(), DEC); lcd.print('/'); if(now.day() < 10) lcd.print("0"); lcd.print(now.day(), DEC); lcd.setCursor(0, 1); if(now.hour() < 10) lcd.print("0"); lcd.print(now.hour(), DEC); lcd.print(':'); if(now.minute() < 10) lcd.print("0"); lcd.print(now.minute(), DEC); lcd.print(':'); if(now.second() < 10) lcd.print("0"); lcd.print(now.second(), DEC); delay(2000);}

Page 27: 2013 1 arduino_datalogger

AUGUST 11, 2012 STORM IN PHOENIX About 10 hours of plot

0 100 200 300 400 500 600717.80

718.00

718.20

718.40

718.60

718.80

719.00

719.20

719.40

719.60

BMP_mmHg

Page 28: 2013 1 arduino_datalogger

0 200 400 600 800 1000 1200 1400 1600 1800688

690

692

694

696

698

700

702

704

706

39 HOTEL FLOORS AT LAS VEGAS FOUR SEASONS

Stepped up the logging rate to once per second

Three round trips

Page 29: 2013 1 arduino_datalogger

FUTURE WORK

Add time setting over serial while running

Seems to be a small temperature rise of about 2 degrees F with the display running

Add fancier display, perhaps a 1 hour plot of data on a dot matrix display

Page 30: 2013 1 arduino_datalogger

DCC_DATALOGGER_3.INO 1 OF 9// DCC_DataLogger.ino#include <Wire.h>#include <RTClib.h>#include <Adafruit_BMP085.h>#include <LiquidCrystal.h>#include <SD.h>

// On display, connect via i2c, default address #0 (A0-A2 not jumpered)LiquidCrystal lcd(0);

RTC_DS1307 RTC;Adafruit_BMP085 bmp;const int chipSelect = 10;

File dataFile;

unsigned long int press; // press is a longfloat tempy; // temperature is a floatfloat fpress;int loopSec = 0;int loopMin = 0;int num;// make a string for assembling the data to log:String dataString = "";

DateTime now;

Page 31: 2013 1 arduino_datalogger

DCC_DATALOGGER_3.INO 2 OF 9void setup(){Serial.begin(57600);Wire.begin();RTC.begin();bmp.begin();

// set up the LCD's number of rows and columns:lcd.begin(16, 2);lcd.setBacklight(HIGH); //HIGH is ON, LOW is OFF

if (! RTC.isrunning()) { Serial.println("RTC is NOT running!"); // following line sets the RTC to the date & time this sketch was compiled RTC.adjust(DateTime(__DATE__, __TIME__)); }Serial.print("Initializing SD card..."); // make sure that the default chip select pin is set to // output, even if you don't use it:pinMode(SS, OUTPUT);

Page 32: 2013 1 arduino_datalogger

DCC_DATALOGGER_3.INO 3 OF 9// 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: while (1) ; }Serial.println("card initialized.");

// Open up the file we're going to log to! // This is an APPEND opendataFile = SD.open("datalog.txt", FILE_WRITE);if (! dataFile) { Serial.println("error opening datalog.txt"); // Wait forever since we can't write data while (1) ; }}

Page 33: 2013 1 arduino_datalogger

DCC_DATALOGGER_3.INO 4 OF 9void loop(){static int i;

if ( (loopSec % 5) == 0) { //Serial.println(__DATE__, __TIME__); tempy = bmp.readTemperature(); tempy = (tempy * 9.0 / 5.0) + 32.0; press = bmp.readPressure(); fpress = (float)press* 0.007500616827042;

now = RTC.now();

Serial.print(now.year(), DEC); Serial.print('/'); if(now.month() < 10) Serial.print("0"); Serial.print(now.month(), DEC); Serial.print('/'); if(now.day() < 10) Serial.print("0"); Serial.print(now.day(), DEC); Serial.print(' ');

Page 34: 2013 1 arduino_datalogger

DCC_DATALOGGER_3.INO 5 OF 9if(now.hour() < 10) Serial.print("0"); Serial.print(now.hour(), DEC); Serial.print(':'); if(now.minute() < 10) Serial.print("0"); Serial.print(now.minute(), DEC); Serial.print(':'); if(now.second() < 10) Serial.print("0"); Serial.print(now.second(), DEC); Serial.println();

Serial.print("C time is = "); Serial.println(now.unixtime());

lcd.setCursor(0, 0); // lcd.print(now.year(), DEC); // lcd.print('/'); if(now.month() < 10) lcd.print("0"); lcd.print(now.month(), DEC); lcd.print('/'); if(now.day() < 10) lcd.print("0"); lcd.print(now.day(), DEC); lcd.print(" ");

Page 35: 2013 1 arduino_datalogger

DCC_DATALOGGER_3.INO 6 OF 9 if(now.hour() < 10) lcd.print("0"); lcd.print(now.hour(), DEC); lcd.print(':'); if(now.minute() < 10) lcd.print("0"); lcd.print(now.minute(), DEC); lcd.print(':'); if(now.second() < 10) lcd.print("0"); lcd.print(now.second(), DEC);

lcd.setCursor(0, 1); lcd.print(tempy,1); lcd.print("F");

lcd.print(" "); lcd.print(fpress,1); lcd.print("mmHg");

Serial.print(tempy,1); Serial.print(" Deg F, "); Serial.print(fpress,1); Serial.println(" mmHg\n"); }

Page 36: 2013 1 arduino_datalogger

DCC_DATALOGGER_3.INO 7 OF 9delay(1000);loopSec+=1;

if(loopSec == 360) // 6 minutes { static bool lcdStatus = true; // LCD light on or off loopSec = 0;

lcd.clear(); lcd.setCursor(0, 0); lcd.print("Writing SD...");

dataString = String(now.unixtime()); dataString += ","; num = tempy; dataString += String(num); dataString += "."; tempy-=num; tempy+=0.05; tempy*=10.0; num=tempy; dataString+=String(num); dataString += ","; num = fpress; dataString += String(num);

Page 37: 2013 1 arduino_datalogger

DCC_DATALOGGER_3.INO 8 OF 9dataString += "."; fpress-=num; fpress+=0.05; fpress*=10.0; num = tempy; dataString +=String(num);

dataFile.println(dataString);

// The following line will 'save' the file to the SD card after every // line of data - this will use more power and slow down how much data // you can read but it's safer! // If you want to speed up the system, remove the call to flush() and it // will save the file only every 512 bytes - every time a sector on the // SD card is filled with data. dataFile.flush(); delay(1000); lcd.clear();

// To check out if display LED was causing warming, // cycle it off/on every six minutes // #define LEDONOFF #ifdef LEDONOFF lcdStatus = !lcdStatus;

Page 38: 2013 1 arduino_datalogger

DCC_DATALOGGER_3.INO 9 OF 9if(lcdStatus) { lcd.setBacklight(HIGH); //HIGH is ON, LOW is OFF } else { lcd.setBacklight(LOW); //HIGH is ON, LOW is OFF } #endif }}

Page 39: 2013 1 arduino_datalogger

DOWNLOADS 1

Grateful to Lady Ada!!!! Adafruit SD library:https://github.com/adafruit/SD Adafruit RTC library:https://github.com/adafruit/RTClib Adafruit logging shield tutorial:http://learn.adafruit.com/adafruit-data-logger-shield

Page 40: 2013 1 arduino_datalogger

DOWNLOADS 2

LCD i2c backpack tutorial http://learn.adafruit.com/i2c-spi-lcd-bac

kpack Liquid Crystal control library https://github.com/adafruit/LiquidCryst

al

Page 41: 2013 1 arduino_datalogger

QUESTIONS?

Find more slides from Don atwww.slideshare.net/dondoerres