[OpenTRV-dev] OT: need help with reading my heat meter
Bo Herrmannsen
EMAIL ADDRESS HIDDEN
Wed May 29 20:14:46 BST 2013
Hi.. moved the pi out to my utility closet and now trying to read it via
IR.... when i reverse rx and tx it will not output anything... and if i
reverse again it just returns 0.00
could it be the code that is wrong?
#include <SoftwareSerial.h>
// Kamstrup Multical 601
word const kregnums[] = {
0x003C,0x0050,0x0056,0x0057,0x0059,0x004a,0x0044,0x0045 };
char* kregstrings[] = { "Energy","Current Power","Temperature
t1","Temperature t2","Temperature diff", "Flow", "Volumen 1", "Volumen 2" };
#define NUMREGS 8
#define KAMBAUD 1200
// Units
char* units[65] = {"","Wh","kWh","MWh","GWh","j","kj","Mj",
"Gj","Cal","kCal","Mcal","Gcal","varh","kvarh","Mvarh","Gvarh",
"VAh","kVAh","MVAh","GVAh","kW","kW","MW","GW","kvar","kvar","Mvar",
"Gvar","VA","kVA","MVA","GVA","V","A","kV","kA","C","K","l","m3",
"l/h","m3/h","m3xC","ton","ton/h","h","hh:mm:ss","yy:mm:dd","yyyy:mm:dd",
"mm:dd","","bar","RTC","ASCII","m3 x 10","ton x 10","GJ x
10","minutes","Bitfield",
"s","ms","days","RTC-Q","Datetime"};
// Pin definitions
#define PIN_KAMSER_RX 6 // Kamstrup IR interface RX Port 3 DIO
#define PIN_KAMSER_TX 7 // Kamstrup IR interface TX Port 4 DIO
// Kamstrup optical IR serial
#define KAMTIMEOUT 2000 // Kamstrup timeout after transmit
#define POLLINTERVAL 5000 // Polling interval
SoftwareSerial kamSer(PIN_KAMSER_RX, PIN_KAMSER_TX, true); // Initialize
serial
// last poll variable
long lastpoll;
void setup() {
// setup pins
pinMode(PIN_KAMSER_RX,INPUT);
pinMode(PIN_KAMSER_TX,OUTPUT);
// initialize kamstrup serial interface
kamSer.begin(KAMBAUD);
// initialize serial interface (connected to linksys router)
Serial.begin(9600);
// initialize lastpoll value
lastpoll = 0;
}
void loop() {
// check if it is time to do a poll
if(millis() - lastpoll > POLLINTERVAL or lastpoll == 0) {
// get Kamstrup data from meter
for (int kreg = 0; kreg < NUMREGS; kreg++) {
kamReadReg(kreg);
delay(100);
}
// send a newline to have linksys process the data
Serial.println("");
// update lastpoll
lastpoll = millis();
}
// loop delay
delay(500);
};
// kamReadReg - read a Kamstrup register
void kamReadReg(unsigned short kreg) {
byte recvmsg[30]; // buffer of bytes to hold the received data
float rval; // this will hold the final value
// prepare message to send and send it
byte sendmsg[] = { 0x3f, 0x10, 0x01, (kregnums[kreg] >> 8),
(kregnums[kreg] & 0xff) };
kamSend(sendmsg, 5);
// listen if we get an answer
unsigned short rxnum = kamReceive(recvmsg);
// check if number of received bytes > 0
if(rxnum != 0){
// decode the received message
rval = kamDecode(kreg,recvmsg);
// print out received value to terminal
if (rval != false) {
Serial.print(rval);
}
}
Serial.print(rval);
Serial.print(",");
}
// kamSend - send data to Kamstrup meter
void kamSend(byte const *msg, int msgsize) {
// append checksum bytes to message
byte newmsg[msgsize+2];
for (int i = 0; i < msgsize; i++) { newmsg[i] = msg[i]; }
newmsg[msgsize++] = 0x00;
newmsg[msgsize++] = 0x00;
int c = crc_1021(newmsg, msgsize);
newmsg[msgsize-2] = (c >> 8);
newmsg[msgsize-1] = c & 0xff;
// build final transmit message - escape various bytes
byte txmsg[20] = { 0x80 }; // prefix
int txsize = 1;
for (int i = 0; i < msgsize; i++) {
if (newmsg[i] == 0x06 or newmsg[i] == 0x0d or newmsg[i] == 0x1b or
newmsg[i] == 0x40 or newmsg[i] == 0x80) {
txmsg[txsize++] = 0x1b;
txmsg[txsize++] = newmsg[i] ^ 0xff;
} else {
txmsg[txsize++] = newmsg[i];
}
}
txmsg[txsize++] = 0x0d; // EOF
// send to serial interface
for (int x = 0; x < txsize; x++) {
kamSer.write(txmsg[x]);
}
}
// kamReceive - receive bytes from Kamstrup meter
unsigned short kamReceive(byte recvmsg[]) {
byte rxdata[50]; // buffer to hold received data
unsigned long rxindex = 0;
unsigned long starttime = millis();
kamSer.flush(); // flush serial buffer - might contain noise
byte r;
// loop until EOL received or timeout
while(r != 0x0d){
// handle rx timeout
if(millis()-starttime > KAMTIMEOUT) {
return 0;
}
// handle incoming data
if (kamSer.available()) {
// receive byte
r = kamSer.read();
if(r != 0x40) { // don't append if we see the start marker
// append data
rxdata[rxindex] = r;
rxindex++;
}
}
}
// remove escape markers from received data
unsigned short j = 0;
for (unsigned short i = 0; i < rxindex -1; i++) {
if (rxdata[i] == 0x1b) {
byte v = rxdata[i+1] ^ 0xff;
if (v != 0x06 and v != 0x0d and v != 0x1b and v != 0x40 and v !=
0x80){
Serial.print("Missing escape ");
Serial.println(v,HEX);
}
recvmsg[j] = v;
i++; // skip
} else {
recvmsg[j] = rxdata[i];
}
j++;
}
// check CRC
if (crc_1021(recvmsg,j)) {
Serial.println("CRC error: ");
return 0;
}
return j;
}
// kamDecode - decodes received data
float kamDecode(unsigned short const kreg, byte const *msg) {
// skip if message is not valid
if (msg[0] != 0x3f or msg[1] != 0x10) {
return false;
}
if (msg[2] != (kregnums[kreg] >> 8) or msg[3] != (kregnums[kreg] & 0xff))
{
return false;
}
// decode the mantissa
long x = 0;
for (int i = 0; i < msg[5]; i++) {
x <<= 8;
x |= msg[i + 7];
}
// decode the exponent
int i = msg[6] & 0x3f;
if (msg[6] & 0x40) {
i = -i;
};
float ifl = pow(10,i);
if (msg[6] & 0x80) {
ifl = -ifl;
}
// return final value
return (float )(x * ifl);
}
// crc_1021 - calculate crc16
long crc_1021(byte const *inmsg, unsigned int len){
long creg = 0x0000;
for(unsigned int i = 0; i < len; i++) {
int mask = 0x80;
while(mask > 0) {
creg <<= 1;
if (inmsg[i] & mask){
creg |= 1;
}
mask>>=1;
if (creg & 0x10000) {
creg &= 0xffff;
creg ^= 0x1021;
}
}
}
return creg;
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.opentrv.org.uk/pipermail/opentrv-dev/attachments/20130529/69ba0bd5/attachment.html>
More information about the OpenTRV-dev
mailing list