I'm looking for a little feed back on this sketch. Basically I'm using an IR photo-transistor to listen for the test pulses my electric smart meter sends out every 2 W hr. Time between pulses is sent out the serial interface to a Visual Basic program, that passes the data onto RRDtool. Since the Arduino wasn't very busy I added on a RTC, SDcard, and some DS18B20's.
Overall everything works Ok. I do have some memory problems. The queuearray library that I'm using to buffer the pulse timing, was hogging memory anytime it had to resize it's array. I've fixed it by increasing the default size in the library.
The RTC and DS18B20 libraries annoyed me. It seems they all had some kind of compromise. I really wanted the TIME library for it's unix timestamp function, but I couldn't get it to set the clock properly. Kept coming up several hours off. The ds1307new library is okay, but it looks like it is doing alot of extra work than I really need.
I still need to write function to set RTC time. Need some kind of rolling log file on the sdcard, takes a really long time to dump at 115200 bps. Need to be able to dump data from a given time period. My goal is for the Arduino to be self-sufficient. Dump data for processing when asked. Right now I have to keep my desktop running, which goes against the whole motivation of the project--saving energy. Need to figure out a clean way of dropping the first 2 IR samples. The first sample is always inaccurate.
Looking for tips and pointers. Not really a C++ guy. Any different strategies or techniques I should consider. I haven't had this Arduino less than a month. Really amazed at it's flexibility, and how easy it is. Thanx.
//1Wire
#include <OneWire.h>
#include <DallasTemperature.h>
// Data wire is plugged into port 3 on the Arduino
#define ONE_WIRE_BUS 3
#define TEMPERATURE_PRECISION 9
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
// arrays to hold device addresses
DeviceAddress waterHeater={0x28,0x4E,0x57,0x3F,0x03,0x0,0x0,0x8A};
DeviceAddress room={0x28,0x95,0x5E,0x3F,0x03,0x00,0x00,0x45};
boolean oneWirePresent=false;
//Real Time Clock
#include <Wire.h>
#include <DS1307new.h>
boolean rtcPresent=false;
//SD Card
#include <SD.h>
const int chipSelect=10;
boolean sdCardPresent=false;
//FIFO Queue
#include <QueueArray.h>
QueueArray <unsigned int> queue;
boolean serialOut=true;
const int irSensor=2;
void setup(){
//Initialize serial port at 9600 baud
Serial.begin(115200);
//Init SD
pinMode(chipSelect,OUTPUT);
if(SD.begin(chipSelect)){
sdCardPresent=true;
}
//Init RTC -- Set SQW pin to 1 Hz to flash LED
if(RTC.isPresent()){
RTC.ctrl=0x10;
RTC.setCTRL();
rtcPresent=true;
}
//Init 1Wire
sensors.begin();
//Make sure there are 2 sensors
if(sensors.getDeviceCount()==2){
oneWirePresent=true;
sensors.setResolution(waterHeater,TEMPERATURE_PRECISION);
sensors.setResolution(room,TEMPERATURE_PRECISION);
sensors.setWaitForConversion(true);
}
//Enable external interrupt of digital I/O pin 2
pinMode(irSensor,INPUT);
//Turn on internal pull-up
digitalWrite(irSensor,HIGH);
attachInterrupt(0,timePulse,FALLING);
}
void timePulse(){
//Push current millis to queue
queue.push(millis());
}
void loop() {
if(queue.count()>1){
//Calculate instant power.
unsigned int oldTime=queue.pop();
unsigned int newTime=queue.peek();
float currentW=(float)7200000/(newTime-oldTime);
//Send out serial with 1 digit 00.0
if(serialOut){
Serial.print("W:");
Serial.println(currentW,1);
}
// If the SD card is available, log the current wattage
if(sdCardPresent){
File dataFile=SD.open("watt.txt",FILE_WRITE);
if(dataFile){
if(rtcPresent){
RTC.getTime();
dataFile.print(RTC.time2000);
dataFile.print(":");
}
dataFile.println(currentW);
dataFile.close();
}
}
}
}
//Handle incoming serial
void serialEvent(){
while (Serial.available()){
//Incoming commands begin with !
if(Serial.read()=='!'){
//Delay, otherwise missing the next character, why!?!?
delay(1);
switch(Serial.read()){
case 's':
serialOut = false;
break;
case 'S':
serialOut = true;
break;
case 'd':{
//Dump log file
File dataFile=SD.open("watt.txt",FILE_READ);
if(dataFile){
while(dataFile.available()){
Serial.write(dataFile.read());
}
dataFile.close();
}
break;
}
case 't':
//Print current time
RTC.getTime();
Serial.println(RTC.time2000);
Serial.print(RTC.month);
Serial.print("-");
Serial.print(RTC.day);
Serial.print("-");
Serial.print(RTC.year);
Serial.print(" ");
Serial.print(RTC.hour);
Serial.print(":");
Serial.print(RTC.minute);
Serial.print(":");
Serial.println(RTC.second);
break;
case 'T':
//Set RTC time
break;
case 'w':
if(oneWirePresent){
sensors.requestTemperatures();
float tempC=sensors.getTempC(waterHeater);
Serial.print("WH:");
Serial.println(DallasTemperature::toFahrenheit(tempC));
}
break;
case 'r':
if(oneWirePresent){
sensors.requestTemperatures(); //request by addr not working for some reason
float tempC=sensors.getTempC(room);
Serial.print("R:");
Serial.println(DallasTemperature::toFahrenheit(tempC));
}
break;
}
}
}
}
Moderator edit: added
tags