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