Here you go, this receives from an Arduino that interrogates the gas boiler. The boiler sends out 64byte replies which have to be split into 3 for transmission over VW. I'm afraid the output lines are very long and I've had to truncate them to post, They're probably incomprehensible in a small code window anyway. They work though.
The other sketch is simpler, it just receives gas meter monitoring, but includes loads of debug info so I don't have to spend too much time in the cellar.
/************* Streaming *************/
template<class T> inline Print &operator <<(Print &obj, T arg) {
obj.print(arg);
return obj;
}
/*************** VW ************/
#include <VirtualWire.h>
#include "SD.h"
byte reply[66];
byte sum = 0;
byte csbyte;
byte cs = 0;
int w=0; // various status conditions
int a=0; // length of FAAF
int b=0; // length of FBBF
int c=0; // length of FCCF
int x=0;
long lastTime;
/*************** SD ************/
boolean sdOK = 0; // SD operational
boolean datalogenable = 1; // normally on
char name[] = "Log00.CSV";
long oldFileSize=0;
void setup()
{
// *** initialise VirtualWire
vw_set_rx_pin(7);
vw_set_ptt_inverted(true);
vw_setup(2000);
vw_rx_start();
// *** initialise Serial
Serial.begin(115200);
Serial << freeRam() << "\nBoiler Monitor Rx start\n" ;
// *** initialise SD
pinMode(4, OUTPUT);
sdOK = SD.begin(4);
if(sdOK == 1){
Serial << datalogenable << " SD GOOD";
}
if(sdOK == 0){
Serial << datalogenable << " SD BAD";
datalogenable = 0;
}
if(datalogenable == 1 && sdOK == 1){
Serial << "\nLogging to: " << (name) ;
File dataFile = SD.open(name, FILE_WRITE);
dataFile << "\n************** Log start *************" ;
dataFile.close();
}
}
void loop()
{
/***********************************************Receive******************************************/
uint8_t vBuf[VW_MAX_MESSAGE_LEN];
uint8_t vBuflen = VW_MAX_MESSAGE_LEN;
if (vw_get_message(vBuf, &vBuflen))
{
/************************ debug raw reception*****************************
Serial << "\nvBuf\t\t" ;
for (int i = 0; i < vBuflen; i++) {
Serial.print(vBuf[i], HEX);
}
Serial << "\t:" << vBuflen << "\n" ;
/************************************** Assemble ***********************************************/
for ( int i=0 ; i<=65 ; i++ ) {
if ((vBuf[0]==0xFA) && (vBuf[1]==0xAF) && (vBuf[2]==0x2) && (vBuf[3]==0x41)) {
a = vBuflen-2;
if (i >= 0 && i <= vBuflen-3) {
reply[i] = vBuf[i+2];
w = 1;
}
}
else {
if ((vBuf[0]==0xFA) && (vBuf[1]==0xAF)) {
Serial << "\nFailed A ";
}
}
if ( (vBuf[0]==0xFB) && (vBuf[1]==0xBF)) {
b = vBuflen-2;
w = 2;
if (i >= 0 && i <= vBuflen-3) {
reply[i+a]=vBuf[i+2];
}
}
if ( (vBuf[0]==0xFC) && (vBuf[1]==0xCF) && vBuf[23]==0x3 ) {
c = vBuflen-2;
w = 3;
if (i >= 0 && i <= vBuflen-2) {
reply[i+a+b]=vBuf[i+2];
}
x=1;
}
else {
if ((vBuf[0]==0xFC) && (vBuf[1]==0xCF)) {
Serial << "\nFailed C ";
}
}
} // for
if ( w==3 && x==1) {
/***************************************** Checksum*****************************************/
sum=0;
for (int i = 0; i <= 63; i++) {
sum += reply[i];
}
csbyte = reply[65]; // incoming checksum from Tx
cs= csbyte - sum;
if (cs != 0) {
Serial << "\nBad Checksum";
File dataFile = SD.open(name, FILE_WRITE);
dataFile << "\nBad Checksum";
dataFile.close();
debug2();
}
else {
// Serial << "\nChecksum good ";
// debug2();
}
x = 0;
} // if w & x
/******************************************** Output *******************************************/
if (w == 3 && cs == 0 && datalogenable == 1 && sdOK == 1) {
char value[250];
float result;
/************************** HEX output ***************************************
File dataFile = SD.open(name, FILE_WRITE);
dataFile << "\n";
for ( int i=0 ; i<66 ; i++ ) {
Serial.print(reply[i], HEX);
dataFile.print(reply[i], HEX);
dataFile << ",";
Serial << " " ;
}
Serial << "\t:" << sizeof(reply);
/**************************** SD Write ***************************************/
dataFile << "\nBoiler," << reply[66-2] << ",date" << ",time," << reply[46] << "," << reply[47] << "," << reply[48] << ",";
dataFile << (reply[6]) + (reply[7] << 8) << "," << (reply[8]) + (reply[9] << 8) << ",," << (reply[14]) + (reply[15] << 8) << "," << (reply[12]) + (reply[13] << 8) << "," << (reply[33]) + (reply[34] << 8) << "," << (reply[22]) + (reply[23] << 8) << "," << (reply[24]) + (reply[25] << 8) << "," << (reply[20]) + (reply[21] << 8) << "," << (reply[26]) + (reply[27] << 8) << "," << (reply[18]) + (reply[19] << 8) << "," ;
Serial << "\nSD written: " << dataFile.size() - oldFileSize;
oldFileSize = dataFile.size();
dataFile << "\nlooptime," << millis() - lastTime ;
dataFile.close();
/**************************** Print ***************************************/
Serial << "\tlooptime: " << millis() - lastTime << "\t";
lastTime = millis();
Serial << "same as the datalog, truncated for posting";
//******************************************** end Output **************************************************/
w = 0;
} // if w & cs
} // ifvBuf
} //loop
/**************************************************************************************************/
/* Free ram
/**************************************************************************************************/
int freeRam () {
extern int __heap_start, *__brkval;
int v;
return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}
/**************************************************************************************************/
/* printhexbyte
/**************************************************************************************************/
void printhexbyte(byte x)
{
Serial << "0x";
if (x < 16) {
Serial << '0';
}
Serial.print(x, HEX);
}
/**************************************************************************************************
* debug1
**************************************************************************************************/
void debug1(int w)
{
Serial << "\nReceived " ;
if (w != 9) {
Serial << w ;
}
Serial << ":\t" ;
for ( int i=0 ; i<66 ; i++ ) {
Serial.print(reply[i], HEX);
Serial << " ";
}
Serial << "\t:" << sizeof(reply);
}
/**************************************************************************************************
* debug2
**************************************************************************************************/
void debug2()
{
Serial << "\nReceived checksum byte = " << csbyte << "\nCalculated checksum = " << sum << "\nerror = " << cs << "\n" ;
}
/**************************************************************************************************
* debug3
**************************************************************************************************
void debug3()
{
Serial.print(F("\nconfidence w x: ")) ;
Serial.print(w) ;
Serial.print(x) ;
Serial.print(F("\nlength 1:\t"));
Serial.print(a+2);
Serial.print(F("\nlength 2:\t"));
Serial.print(b+2);
Serial.print(F("\nlength 3:\t"));
Serial.print(c+2);
Serial.print(F("\nlength full:\t"));
Serial.print(sizeof(reply));
Serial.print("\nChecksum:\t");
printhexbyte(sum);
}