I successfully migrated my electric meter monitor from Pi/Uno to Pi/Tiny85 today. I had been putting it off for months. Always some excuse not to work on it. It was surprisingly easy. It almost just worked out of the box. My biggest hang up was calibrating the clock. Serialdebug was being totally stupid. My first tries at tinytune yesterday got me nowhere, I was hooking one of the serial lines to the wrong pin. Using pin number not port number. Oops. After tinytune loaded up my script and it worked. I had to adjust oscal by hand, but still had intermittent corrupt characters. Upped serial to 38400 and they went away. Switched power from 5 to 3.3, no problem. Hooked into serial interface on Pi gpio header, and it worked. Moved power from uno to pi. Couldn't believe that almost everything worked the first try. Now I get my Uno back for playtime.
Using PI with btsync, apache, samba, and nodejs. Wired ethernet, passive usb hub, and thumb drive. Attiny 85 with photo-transistor and DS18B20+ sensors.
A while back the Pi crashed and corrupted the sdcard--probably power. So I lost my good scripts I was using for the web interface, have not spent anytime putting it back together. Just running the basics.
Attiny85 code
//1Wire
#include <OneWire.h>
#include <DallasTemperature.h>
// Data wire is plugged into port 3 on the Arduino
#define ONE_WIRE_BUS 4
#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 outSide={0x28,0x4E,0x57,0x3F,0x03,0x0,0x0,0x8A};
//DeviceAddress inSide={0x28,0x95,0x5E,0x3F,0x03,0x00,0x00,0x45};
//boolean oneWirePresent=false;
unsigned long oldTime, newTime, lastTemp;
boolean pulse=false;
int deviceCount;
#define IR_SENSOR 2
void setup(){
OSCCAL = 0x52;
//Initialize serial port at 115200 baud
Serial.begin(38400);
//Init 1Wire
sensors.begin();
//Make sure there are 2 sensors
// if(sensors.getDeviceCount()==2){
// oneWirePresent=true;
// sensors.setResolution(outSide,TEMPERATURE_PRECISION);
// sensors.setResolution(inSide,TEMPERATURE_PRECISION);
deviceCount = sensors.getDeviceCount();
// }
//Enable external interrupt of digital I/O pin 2
pinMode(IR_SENSOR,INPUT);
//Turn on internal pull-up
digitalWrite(IR_SENSOR,HIGH);
attachInterrupt(0,timePulse,FALLING);
lastTemp=millis();
}
void timePulse(){
newTime=millis();
pulse=true;
}
void loop() {
if (pulse){
unsigned int currentW=7200000/(newTime-oldTime);
Serial.print("W:");
Serial.println(currentW);
oldTime=newTime;
pulse=false;
}
if (millis()-lastTemp > 30000){
lastTemp=millis();
sensors.requestTemperatures();
for (int val=0; val < deviceCount; val++) {
DeviceAddress addr;
sensors.getAddress(addr, val);
printAddress(addr);
Serial.print(":");
Serial.println(sensors.getTempFByIndex(val));
}
// Serial.print("Out:");
// Serial.println(sensors.getTempF(outSide),1);
// Serial.print("In:");
// Serial.println(sensors.getTempF(inSide),1);
}
}
void printAddress(DeviceAddress deviceAddress)
{
for (uint8_t i = 0; i < 8; i++)
{
// zero pad the address if necessary
if (deviceAddress[i] < 16) Serial.print("0");
Serial.print(deviceAddress[i], HEX);
}
}
Nodejs on the pi
var serialport = require("serialport");
var serialPort = serialport.SerialPort;
var sp = new serialPort("/dev/ttyAMA0",{
baudrate: 38400,
parser: serialport.parsers.readline("\r\n")
});
var events = require('events');
var eventEmitter = new events.EventEmitter();
sp.on("data", function(data){
var split = data.split(":");
eventEmitter.emit(split[0],split[1]);
// console.log(split);
});
eventEmitter.on('W',function(data){
var exec = require('child_process').exec;
var child = exec('rrdtool update ' + __dirname + '/watt.rrd N:' + data);
});
eventEmitter.on('28955E3F03000045',function(data){
var exec = require('child_process').exec;
var child = exec('rrdtool update ' + __dirname + '/in.rrd N:' + data);
});
eventEmitter.on('284E573F0300008A',function(data){
var exec = require('child_process').exec;
var child = exec('rrdtool update ' + __dirname + '/out.rrd N:' + data);
});
var static = require('node-static');
var file = new(static.Server)(__dirname + '/public');
var httpserv = require('http').createServer(function (request, response) {
// request.addListener('end', function () {
file.serve(request, response);
// });
}).listen(8008);
var sqlite3 = require('sqlite3');
var db = new sqlite3.Database(__dirname + '/hem.db');
eventEmitter.on('W',function(data){
db.run('update hem set value=value+2 where key=0');
});
setInterval(function(){
var exec = require('child_process').exec;
var watt = exec("rrdtool graph " + __dirname + "/public/watt2.png -s now-4hour -e now -o -w 910 -h 190 --units=si DEF:watts=" + __dirname + "/watt.rrd:watt:AVERAGE LINE1:watts#000000:'Watt'");
var inside = exec("rrdtool graph " + __dirname + "/public/temp2.png -s now-4hour -e now -w 910 -h 190 DEF:in=" + __dirname + "/in.rrd:in:AVERAGE LINE1:in#cc0000:'In' DEF:out=" + __dirname + "/out.rrd:out:AVERAGE LINE1:out#0000cc:'Out'");
setTimeout(function(){
eventEmitter.emit('graph');
},5000);
},60000);
setInterval(function(){
var exec = require('child_process').exec;
var watt = exec("rrdtool graph " + __dirname + "/public/watt24.png -s now-48hour -e now -o -w 910 -h 190 --units=si DEF:watts=" + __dirname + "/watt.rrd:watt:AVERAGE LINE1:watts#000000:'Watt'");
var inside = exec("rrdtool graph " + __dirname + "/public/temp24.png -s now-48hour -e now -w 910 -h 190 DEF:in=" + __dirname + "/in.rrd:in:AVERAGE LINE1:in#cc0000:'In' DEF:out=" + __dirname + "/out.rrd:out:AVERAGE LINE1:out#0000cc:'Out'");
setTimeout(function(){
eventEmitter.emit('graph');
},5000);
},300000);
var socketio = require('socket.io');
socketio.listen(httpserv, { log: false }).on('connection', function (socket) {
eventEmitter.on('W',function(data){
socket.broadcast.emit('W',data);
db.each('select value from hem where key=0',function(err,row){
var kWh = row.value/1000;
var cost = (((kWh * 0.1)+19)*1.07);
socket.broadcast.emit('kWh',{'kWh' : kWh.toFixed(3), 'cost' : cost.toFixed(2)});
});
});
eventEmitter.on('28955E3F03000045',function(data){
socket.broadcast.emit('In',data);
});
eventEmitter.on('284E573F0300008A',function(data){
socket.broadcast.emit('Out',data);
});
eventEmitter.on('graph',function(data){
socket.broadcast.emit('graph','');
});
});
setInterval(function(){
var time = new Date();
if (time.getDate()===7 && time.getHours()===0 && time.getMinutes()===0) {
console.log(time);
db.run('update hem set value=0 where key=0');
}
},60000);
Nothing fancy. I wanted to give a little something back for everything I have borrowwed. Hopefully it helps someone else out.