Skip to content

Instantly share code, notes, and snippets.

@PhirePhly
Created October 19, 2009 05:49
Show Gist options
  • Save PhirePhly/213128 to your computer and use it in GitHub Desktop.
Save PhirePhly/213128 to your computer and use it in GitHub Desktop.
// 2009 Kenneth Finnegan
// kennethfinnegan.blogspot.com
#include <Wire.h>
#include <LiquidCrystal.h>
//// PINS ////
#define LEDPIN 13
LiquidCrystal lcd(2,3,4,5,6,7);
//// I2C ADDRESSES ////
// DS1307 RTC chip
#define RTCI2C (B1101000)
// DS1631 Temp sensor
#define TEMPI2C (B1001000)
// AT24C1024B EEPROM
#define EEPROMI2C (B1010000)
// TEMP SENSOR OP CODES
#define STARTTEMP 0x51
#define READTEMP 0xAA
byte oldminute, temp[2];
byte second, minute, hour, day, month, year;
unsigned int tempreadcount=0;
void updatedata();
void writetemp();
void setup() {
lcd.begin(16,2);
Wire.begin();
pinMode(LEDPIN, OUTPUT);
digitalWrite(LEDPIN, HIGH);
// Make sure the clock has valid data
Wire.beginTransmission(RTCI2C);
Wire.send(0x00);
Wire.endTransmission();
Wire.requestFrom(RTCI2C, 1);
byte runningflag = Wire.receive();
// Make sure that at least the clock didn't lose power
// by checking the CH (Clock Halt) flag
if (runningflag & (1<<7)) {
lcd.setCursor(0,0);
lcd.print("ERROR: RTC DEAD!");
// We don't want to do anything without valid data
int ledflag = 1;
while (1) {
delay(500);
digitalWrite(LEDPIN, ledflag = !ledflag);
}
}
// Extract the read count from the clock's battery backed
// SRAM to make sure we don't overwrite data on the EEPROM
// after power loss.
Wire.beginTransmission(RTCI2C);
Wire.send(0x08);
Wire.endTransmission();
Wire.requestFrom(RTCI2C, 2);
tempreadcount = Wire.receive() << 8; // MSB
tempreadcount += Wire.receive(); // LSB
lcd.setCursor(0,0);
lcd.print("READ CNT: 0x");
lcd.print(tempreadcount, HEX);
// Start the thermostat temp conversions
Wire.beginTransmission(TEMPI2C);
Wire.send(STARTTEMP);
Wire.endTransmission();
// Wait for first temp conversion to finish (750ms)
delay(800);
lcd.clear();
digitalWrite(LEDPIN, LOW);
updatedata();
}
void loop() {
oldminute = minute;
updatedata();
if (oldminute != minute) {
writetemp();
}
delay(100);
}
void updatedata() {
char time[] = "XX:XX:XX";
char date[] = "XX/XX/XX";
// Update time
Wire.beginTransmission(RTCI2C);
Wire.send(0x00);
Wire.endTransmission();
Wire.requestFrom(RTCI2C, 7);
second = Wire.receive() & 0x7f;
minute = Wire.receive();
hour = Wire.receive() & 0x3f;
Wire.receive(); // ignore day of week
day = Wire.receive();
month = Wire.receive();
year = Wire.receive();
// Update temp
Wire.beginTransmission(TEMPI2C);
Wire.send(READTEMP);
Wire.endTransmission();
Wire.requestFrom(TEMPI2C, 2);
temp[0] = Wire.receive(); // MSB
temp[1] = Wire.receive(); // LSB
time[0] = '0' + (hour >> 4 & 0xf);
time[1] = '0' + (hour & 0xf);
time[3] = '0' + (minute >> 4 & 0xf);
time[4] = '0' + (minute & 0xf);
time[6] = '0' + (second >> 4);
time[7] = '0' + (second & 0xf);
date[0] = '0' + (month >> 4 & 0xf);
date[1] = '0' + (month & 0xf);
date[3] = '0' + (day >> 4 & 0xf);
date[4] = '0' + (day & 0xf);
date[6] = '0' + (year >> 4 & 0xf);
date[7] = '0' + (year & 0xf);
lcd.setCursor(4,0);
lcd.print(time);
lcd.setCursor(0,1);
lcd.print(date);
lcd.setCursor(10,1);
lcd.print(temp[0], DEC);
lcd.print(".");
lcd.print(temp[1] / 25, DEC); // fractional degree
lcd.write(B11011111); // degree symbol
lcd.print("C");
}
void writetemp() {
digitalWrite(LEDPIN, HIGH);
long wordaddr = ((long)tempreadcount) * 2;
// AT24C1024B adds the 17th addr bit to I2C addr
byte eei2caddr = EEPROMI2C | (wordaddr>>16);
// Write out tempurature to EEPROM
Wire.beginTransmission(eei2caddr);
Wire.send((byte)(wordaddr>>8) & 0xFF);
Wire.send((byte)(wordaddr) & 0xFF);
Wire.send(temp[0]);
Wire.send(temp[1]);
Wire.endTransmission();
// Update read count here and in clock's SRAM
tempreadcount++;
Wire.beginTransmission(RTCI2C);
Wire.send(0x08);
Wire.send((byte)(tempreadcount>>8) & 0xFF);
Wire.send((byte)(tempreadcount) & 0xFF);
Wire.endTransmission();
delay(10);
digitalWrite(LEDPIN, LOW);
}
// 2009 Kenneth Finnegan
// kennethfinnegan.blogspot.com
// Use this to dump contents of EEPROM to Serial
//// NOTE ////
// Some of these commands are still broken. Once
// I got the D command working, didn't really care
// about the rest...
// Commands:
// Tyymmddhhmmss - set the current date/time
// t - print current time
// D - dump the EEPROM
// Z - Zero out RTC RAM
#include <Wire.h>
// DS1307 RTC chip
#define RTCI2C (B1101000)
// AT24C1024B EEPROM
#define EEPROMI2C (B1010000)
#define DECTOBCD(a) ((a/10)*16 + (a%10))
#define BCDTODEC(a) ((a/16)*10 + (a%16))
unsigned int tempreadcount = 0;
byte second, minute, hour, day, month, year;
void dumpdata();
void setdate();
void printdate();
void zeroram();
void setup() {
Wire.begin();
Serial.begin(9600);
// Make sure the clock has valid data
Wire.beginTransmission(RTCI2C);
Wire.send(0x00);
Wire.endTransmission();
Wire.requestFrom(RTCI2C, 1);
byte runningflag = Wire.receive();
// Make sure that at least the clock didn't lose power
// but checking the CH (Clock Halt) flag
if (runningflag & (1<<7)) {
Serial.println("ERROR: RTC DEAD");
tempreadcount = 0xFFFF;
} else {
// Extract the read count from the clock's SRAM
Wire.beginTransmission(RTCI2C);
Wire.send(0x08);
Wire.endTransmission();
Wire.requestFrom(RTCI2C, 2);
tempreadcount = Wire.receive() << 8; // MSB
tempreadcount += Wire.receive(); // LSB
}
}
void loop() {
int funccode=0;
if (Serial.available()) {
funccode = Serial.read();
switch(funccode) {
case 'D': // Dump EEPROM data
dumpdata();
break;
case 'T': // Set the time
setdate();
case 't': // Print the time
printdate();
break;
case 'Z': // Zero temp read count
zeroram();
break;
}
}
}
void dumpdata() {
int i;
byte temp[2];
// Clear serial buffer
while (Serial.available()) {
Serial.read();
}
for (i=0; i<tempreadcount; i++) {
long wordaddr = ((long)i) * 2;
// AT24C1024B adds the 17th addr bit to I2C addr
byte eei2caddr = EEPROMI2C | (wordaddr>>16);
// Read tempurature from EEPROM
Wire.beginTransmission(eei2caddr);
Wire.send((byte)(wordaddr>>8) & 0xFF);
Wire.send((byte)(wordaddr) & 0xFF);
Wire.endTransmission();
Wire.requestFrom((int)eei2caddr, (int)0x2);
temp[0] = Wire.receive();
temp[1] = Wire.receive();
// Tab seperated for Excel
Serial.print(i, DEC);
Serial.print("\t");
Serial.print(temp[0], DEC);
Serial.print("\t");
Serial.println(temp[1], DEC);
//delay(1);
// Break on any key press
if (Serial.available()) {
return;
}
}
}
void setdate() {
year = (byte) ((Serial.read()-'0')*10 + (Serial.read()-'0'));
month = (byte) ((Serial.read()-'0')*10 + (Serial.read()-'0'));
day = (byte) ((Serial.read()-'0')*10 + (Serial.read()-'0'));
hour = (byte) ((Serial.read()-'0')*10 + (Serial.read()-'0'));
minute = (byte) ((Serial.read()-'0')*10 + (Serial.read()-'0'));
second = (byte) ((Serial.read()-'0')*10 + (Serial.read()-'0'));
Wire.beginTransmission(RTCI2C);
Wire.send(0x00);
Wire.send(DECTOBCD(second));
Wire.send(DECTOBCD(minute));
Wire.send(DECTOBCD(hour));
Wire.send(0x1); // ignore day of week (1-7)
Wire.send(DECTOBCD(day));
Wire.send(DECTOBCD(month));
Wire.send(DECTOBCD(year));
Wire.endTransmission();
}
void printdate() {
Wire.beginTransmission(RTCI2C);
Wire.send(0x00);
Wire.endTransmission();
Wire.requestFrom(RTCI2C, 7);
second = BCDTODEC(Wire.receive() & 0x7F);
minute = BCDTODEC(Wire.receive());
hour = BCDTODEC(Wire.receive() & 0x3F);
Wire.receive(); // ignore day of week (1-7)
day = BCDTODEC(Wire.receive());
month = BCDTODEC(Wire.receive());
year = BCDTODEC(Wire.receive());
Serial.print(hour, DEC);
Serial.print(":");
Serial.print(minute, DEC);
Serial.print(":");
Serial.print(second, DEC);
Serial.print(" ");
Serial.print(month, DEC);
Serial.print("/");
Serial.print(day, DEC);
Serial.print("/");
Serial.println(year, DEC);
}
void zeroram() {
Serial.println("ZEROING TEMP READ COUNT IN RTC RAM");
Wire.beginTransmission(RTCI2C);
Wire.send(0x08);
Wire.send(0x00);
Wire.send(0x00);
Wire.endTransmission();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment