Created
January 12, 2016 16:49
-
-
Save dwblair/ebd74133694101bcae6e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <JeeLib.h> | |
#include <Wire.h> | |
#include <SPI.h> | |
#include <RTClib.h> | |
#include <RTC_DS3231.h> | |
#include<stdlib.h> | |
#include <SD.h> | |
#include <OneWire.h> | |
//sleeping stuff | |
ISR(WDT_vect) { Sleepy::watchdogEvent(); } | |
//RTC stuff | |
RTC_DS3231 RTC; | |
//led | |
#define led 9 | |
//battery stuff | |
#define batteryAnalogMeasurePin A3 | |
#define batteryReadCircuitSwitch 4 | |
// OneWire DS18S20 stuff | |
int DS18S20_Pin = 2; //DS18S20 Signal pin on digital 2 | |
//Temperature chip i/o | |
OneWire ds(DS18S20_Pin); // on digital pin 2 | |
// debugging -- only do Serial output if debuggin | |
#define debug 1 // 0: don't print anything out; 1: print out debugging statements | |
// how long to sleep between measurements | |
#define sleepSeconds 3 | |
// SD card details ----------------------- | |
const int chipSelect = 7; | |
int SDpower = 6; | |
// Sensor board power pin | |
int sensorBoard = 8; // the pin that powers the sensorboard circuit | |
void setup() { | |
if (debug) { | |
Serial.begin(115200); | |
Serial.println("Debugging on."); | |
} | |
pinMode(SDpower,OUTPUT); | |
digitalWrite(SDpower,LOW); | |
if (!SD.begin(chipSelect)) { | |
if (debug) Serial.println("Card failed, or not present"); | |
// don't do anything more: | |
for (int j=0;j<20;j++) { | |
digitalWrite(led,HIGH); | |
delay(10); | |
digitalWrite(led,LOW); | |
} | |
} | |
else if(debug) { Serial.println("SD Card present.");} | |
// begin I2C protocol (necessary for RTC, and any other I2C on board | |
Wire.begin(); | |
// RTC ------------------------- | |
initialize_RTC(); // NOTE: need to initialize I2C first -- but also for any other I2C library | |
// Note -- will say "RTC is NOT running" when debugging -- | |
// set mode for battery circuit control pin, and turn the circuit off | |
pinMode(batteryReadCircuitSwitch,OUTPUT); | |
digitalWrite(batteryReadCircuitSwitch, HIGH); | |
pinMode(led, OUTPUT); | |
// turn external sensor on | |
pinMode(sensorBoard,OUTPUT); //turns on the 555 timer and thermistor subcircuit | |
digitalWrite(sensorBoard,LOW); //turns on the 555 timer and thermistor subcircuit | |
} | |
void loop () { | |
uint8_t i; | |
//measure the battery -------------------- | |
digitalWrite(batteryReadCircuitSwitch, LOW); //turn on battery measurement circuit | |
int batteryLevel = analogRead(batteryAnalogMeasurePin); | |
digitalWrite(batteryReadCircuitSwitch, HIGH); //turn off the battery measurement circuit | |
//measure temp ------------------------- | |
float temperature = getTemp(); | |
// Get onboard temp from the RTC ------------- | |
float rtcTemp = RTC.getTempAsFloat(); | |
//get the time from the RTC ----------------- | |
DateTime now = RTC.now(); | |
long unixNow = now.unixtime(); | |
// Write to SD card ------------------------------------- | |
// make a string for assembling the data to log: | |
String dataString = ""; | |
// dataString += String(unixNow); | |
dataString += now.unixtime(); | |
dataString += ","; | |
dataString += now.year(); | |
dataString += "-"; | |
dataString += padInt(now.month(), 2); | |
dataString += "-"; | |
dataString += padInt(now.day(), 2); | |
dataString += " "; | |
dataString += padInt(now.hour(), 2); | |
dataString += ":"; | |
dataString += padInt(now.minute(), 2); | |
dataString += ":"; | |
dataString += padInt(now.second(), 2); | |
dataString += ","; | |
char buffer[10]; | |
dataString += dtostrf(rtcTemp, 5, 2, buffer); | |
dataString += ","; | |
dataString += dtostrf(temperature,5,2,buffer); | |
dataString += ","; | |
dataString += String(batteryLevel); | |
// open the file. note that only one file can be open at a time, | |
// so you have to close this one before opening another. | |
File dataFile = SD.open("datalog.txt", FILE_WRITE); | |
// if the file is available, write to it: | |
if (dataFile) { | |
dataFile.println(dataString); | |
dataFile.close(); | |
// print to the serial port too: | |
if(debug) Serial.println(dataString); | |
digitalWrite(led, HIGH); | |
delay(20); | |
digitalWrite(led, LOW); | |
} | |
// if the file isn't open, pop up an error: | |
else { | |
//Serial.println("error opening datalog.txt"); | |
} | |
// Finished with everything -- go to sleep | |
go_to_sleep_seconds(sleepSeconds); // | |
} | |
// Useful Functions -------------- ------------ | |
void go_to_sleep_seconds(int seconds) { | |
int LOG_INTERVAL_BASE = 1000; // 1 sec | |
for (int k=0;k<seconds;k++) { | |
Sleepy::loseSomeTime(LOG_INTERVAL_BASE); //-- will interfere with serial, so don't use when debugging | |
} | |
} | |
// RTC functions | |
int initialize_RTC() { | |
RTC.begin(); | |
// check on the RTC | |
if (! RTC.isrunning()) { | |
if (debug) Serial.println("RTC is NOT running!"); | |
// following line sets the RTC to the date & time this sketch was compiled | |
RTC.adjust(DateTime(__DATE__, __TIME__)); | |
} | |
DateTime now = RTC.now(); | |
DateTime compiled = DateTime(__DATE__, __TIME__); | |
if (now.unixtime() < compiled.unixtime()) { | |
if(debug) Serial.println("RTC is older than compile time! Updating"); | |
RTC.adjust(DateTime(__DATE__, __TIME__)); | |
} | |
} | |
String padInt(int x, int pad) { | |
String strInt = String(x); | |
String str = ""; | |
if (strInt.length() >= pad) { | |
return strInt; | |
} | |
for (int i=0; i < (pad-strInt.length()); i++) { | |
str += "0"; | |
} | |
str += strInt; | |
return str; | |
} | |
String int2string(int x) { | |
// formats an integer as a string assuming x is in 1/100ths | |
String str = String(x); | |
int strLen = str.length(); | |
if (strLen <= 2) { | |
str = "0." + str; | |
} else if (strLen <= 3) { | |
str = str.substring(0, 1) + "." + str.substring(1); | |
} else if (strLen <= 4) { | |
str = str.substring(0, 2) + "." + str.substring(2); | |
} else { | |
str = "-9999"; | |
} | |
return str; | |
} | |
float getTemp(){ | |
//returns the temperature from one DS18S20 in DEG Celsius | |
byte data[12]; | |
byte addr[8]; | |
if ( !ds.search(addr)) { | |
//no more sensors on chain, reset search | |
ds.reset_search(); | |
return -1000; | |
} | |
if ( OneWire::crc8( addr, 7) != addr[7]) { | |
Serial.println("CRC is not valid!"); | |
return -1000; | |
} | |
if ( addr[0] != 0x10 && addr[0] != 0x28) { | |
Serial.print("Device is not recognized"); | |
return -1000; | |
} | |
ds.reset(); | |
ds.select(addr); | |
ds.write(0x44,1); // start conversion, with parasite power on at the end | |
byte present = ds.reset(); | |
ds.select(addr); | |
ds.write(0xBE); // Read Scratchpad | |
for (int i = 0; i < 9; i++) { // we need 9 bytes | |
data[i] = ds.read(); | |
} | |
ds.reset_search(); | |
byte MSB = data[1]; | |
byte LSB = data[0]; | |
float tempRead = ((MSB << 8) | LSB); //using two's compliment | |
float TemperatureSum = tempRead / 16; | |
return TemperatureSum; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Requirements
Procedure:
Expected Output
The code is set up to measure temperature from the onboard RTC, temperature via the thermistor, the current battery level, and write these values to the SD card.
The format is:
Typical output to serial terminal when debug = 1: