Sunday, August 24, 2014

Arduino: TempLogger

I’ve gotten terrible sleep the past 4-5 weeks. I wake up every night around 2 am, just hot and uncomfortable. I usually can’t get back to sleep once I wake up, either.

So time for another lifehack! I have an Arduino, I have an SD card logging shield, and I have a digital temp sensor – I decided to build a temperature logger and record the temps overnight.

WP_20140824_001[1]

Below is the code from my first attempt about a year ago. I broke it out again today and was looking at it – I found an article on the BMP085 online at Sparkfun, which when reading seems to indicate that you need to do a fair amount of calibration at startup in order to get accurate data. I went ahead and downloaded Sparkfun’s code and ran it – lo and behold, with all of its calculations it is still reporting the same 80 degrees my simple code is reading.

Lesson: you don’t need that calculation!

#include <Wire.h>
#include <Adafruit_BMP085.h>
#include <SD.h>
#include "Arduino.h"
#include "RTClib.h"

/**********************************************************************************
   TempLogger is an Arduino tool to log temperatures throughout a sustained time
   period. Ever wonder how well your heat is regulated? Tired of waking up hot at
   night? That's why I built templogger - my bedroom seemed awfully hot around 2
   am and, coincidentally, I kept waking up at 2 am.
  
   Requires an Arduino board, a GPS logging shield, and a BMP085 pressure/temp
   sensor from AdaFruit (
https://www.adafruit.com/products/391)
  
   See K7JTO.blogspot.com for this and other Arduino recipes.
**********************************************************************************/

/*
  Connect VCC - 3v
  Connect SCL - Analog pin #5
  Connect SDA - Analog pin #4
  Connect GND - GND (obviously)
*/

// Define Section
#define DEBUG 1                                    // Toggle 1/0 to en/disable serial out
#define led1Pin 5                                  // OPTIONAL: wire pin 5 to write LED
#define led2Pin 6                                  // OPTIONAL: wire pin 6 to read LED
#define BUFFSIZE 90                               // Create a buffer to store log file name

// Variables and Objects
Adafruit_BMP085 bmp;                                // ID for BMP085 unit
RTC_DS1307 RTC;                                     // Real-time clock object
const int chipSelect = 10;                          // Must be left as an output or SD library won't work
boolean gotSDCard = false;                          // Set to true if file successfully created
File logFile;                                       // File for logging data
char buffer[BUFFSIZE];                         // String buffer for the sentence
uint8_t i;                                          // usigned int for iterating
float currTemp = 0;                                 // Int for current temperature
String stringTemp = "";                             // String to hold temperature in
static char sprintfbuffer[15];                      // Buffer to convert float to string
static char dtostrfbuffer[15];                      // 2nd buffer to convert float to string

 

void setup() {
  Serial.begin(9600);
  if (!bmp.begin()) {
    Serial.println("Could not find a valid BMP085 sensor, check wiring!");
      return;
  }

  // Setting up the card means creating a new logging file for
  // each session, and initializing that logging file.
  if (setupSDCard()) {
    if (DEBUG) {
      Serial.println("card initialized.");
    }
    // Start RTC
    RTC.begin();
  }
}
 
void loop() {
  // Variables
  String nowTime = "";                                // String name for current time
  String dataString = "";                             // Store line for temp sensor
   
  // First grab the time from the RCT on the logging shield
  DateTime now = RTC.now();
 
  // Now build the timestamp. Should look like 12/25/2013 04:27:00"
  // Slight hack - sometimes the seconds value reads funny, and for
  // what we're doing, seconds aren't important, so just shove two
  // 0's in.
  nowTime += now.month(), DEC;
  nowTime += "/";
  nowTime += now.day(), DEC;
  nowTime += "/";
  nowTime += now.year(), DEC;
  nowTime += " ";
  nowTime += now.hour(), DEC;
  nowTime += ":";
  nowTime += now.minute(), DEC;
  nowTime += ":00";
 
  // Next grab the temp from the BMP. Problem is the temp comes in as an int, which
  // the Arduino can't convert to a string. So once the temp comes in, turn it into
  // a string via sprintf and dtostrf
  currTemp = ((bmp.readTemperature()*1.8)+32);
  sprintf(sprintfbuffer,"%f", currTemp);
  dtostrf(currTemp,8, 2, dtostrfbuffer);
 
  dataString = nowTime + "," + dtostrfbuffer;
  if(DEBUG) {
    Serial.println("Datastring: ") + dataString;
  }
   
  // Now write temp to logfile
  File dataFile = SD.open(buffer, FILE_WRITE);
   
    // if the file is available, write to it:
    if (dataFile) {
      // Light an LED
      digitalWrite(led1Pin, HIGH);
      digitalWrite(led2Pin, HIGH);
     
      // Write
      dataFile.println(dataString);
      dataFile.close();
     
      // Unlight the LED
      delay(1000);
      digitalWrite(led1Pin, LOW);
      digitalWrite(led2Pin, LOW);
     
      // print to serial port too:
      if (DEBUG) {
        Serial.println(dataString + " saved to data file");
      }
    }
    else {
      Serial.println("Error opening log file to write " + dataString);
    }
   
   // Now delay the device. This could be a sleep delay, if the device were running off
   // batteries, but a simple delay will suffice for externally-powered scenarios.
    delay(60000);
}

//** Sets up SD card. Returns true if no error **/
boolean setupSDCard() {
  // Now set up SD for logging
  // This code lifted from "Datalogger" sample sketch
  if (DEBUG)
    Serial.println("Initializing SD card...");
// make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(10, OUTPUT);
// see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card init. failed! chipSelect = " + chipSelect);
    error(1);
    return false;
  }
  // Now create a unique file. NOTE: IF YOU CHANGE THE FILE NAME, CHECK THAT YOUR INDEXES STILL WORK
  // (buffer[6] and buffer[7] will need to change if you change the length of the file name)
  strcpy(buffer, "TMPLOG00.TXT");
  for (i = 0; i < 100; i++) {         
    // Keep iterating till you find unique file name
    // Create if does not exist, do not open existing, write, sync after write
    buffer[6] = '0' + i/10;
    buffer[7] = '0' + i%10;
    if (! SD.exists(buffer)) {
      break;
    }
  }
  // Now open the file just created
  logFile = SD.open(buffer, FILE_WRITE);
  if( ! logFile ) {
    if (DEBUG)
    {
       Serial.print("Couldnt create "); Serial.println(buffer);
    }
    error(3);
    return false;
  }
  if (DEBUG)
  {
    Serial.print("Creating file on card: "); Serial.println(buffer);
  }
  return true;
  // Done opening log file
}

// Handling Errrs HERE
// blink out an error code
void error(uint8_t errno) {
  if (DEBUG)
  {
     Serial.print("Error encountered. Error no: ");
     Serial.print(errno);
  }
 
  // First, blink 3x fast
  blinkThrice();
 
  // Now blink errno times, slow
  for (i=0; i<=errno; i++) {
    digitalWrite(led1Pin, HIGH);
    digitalWrite(led2Pin, HIGH);
    delay(3000);
    digitalWrite(led1Pin, LOW);
    digitalWrite(led2Pin, LOW);
    delay(1000);
  }
 
  blinkThrice();
}

void blinkThrice() {
  for (i=0; i<3; i++) {
    digitalWrite(led1Pin, HIGH);
    digitalWrite(led2Pin, HIGH);
    delay(3000);
    digitalWrite(led1Pin, LOW);
    digitalWrite(led2Pin, LOW);
    delay(1000);
  }
}

/***************************************************
  Portions of this code based on Adafruit BMP085 sample code. See
  info below.

  Designed specifically to work with the Adafruit BMP085 Breakout
  ---->
https://www.adafruit.com/products/391

  These displays use I2C to communicate, 2 pins are required to interface
  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries. 
  BSD license, all text above must be included in any redistribution
****************************************************/

No comments:

Post a Comment