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