Skip to content

Instantly share code, notes, and snippets.

@dwblair
Created January 12, 2016 16:49
Show Gist options
  • Save dwblair/ebd74133694101bcae6e to your computer and use it in GitHub Desktop.
Save dwblair/ebd74133694101bcae6e to your computer and use it in GitHub Desktop.
#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;
}
@dwblair
Copy link
Author

dwblair commented Jan 12, 2016

Requirements

Procedure:

  1. Place a CR1220 coin cell battery into the holder, with the "+" side facing "up"
  2. Place a microSD card into the microSD card holder
  3. Connect a 1-wire sensor to the Riffle as per above
  4. Upload the above .ino code using "Arduino UNO" as the board profile

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:

UnixTime, HumanReadableTime, RTC_temp, 1wire_temp, battery_level

  • RTC_temp and 1wire_temp are in celcius
  • battery_volts = 3.3 * battery_level / 512

Typical output to serial terminal when debug = 1:

1452599597,2016-01-12 11:53:17,27.00,24.25,578
1452599600,2016-01-12 11:53:20,27.00,24.25,578
1452599604,2016-01-12 11:53:24,27.00,24.25,578
1452599607,2016-01-12 11:53:27,27.00,24.25,579
1452599611,2016-01-12 11:53:31,27.00,24.25,578
1452599614,2016-01-12 11:53:34,27.00,24.25,579
1452599618,2016-01-12 11:53:38,27.00,24.25,578

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment