Hello all,
I need a bit of technical guidance for my project. I am measuring the water consumption in a hotel. For each two rooms I have 4 flowmeters connected to one JeeNodehttp://jeelabs.net/projects/hardware/wiki/JeeNode, each measuring hot and cold. I send this data to a central node via a RFM12b. The central node is an Arduino UNO with the 'official' Ethernet Shield and a RFM12b. This is where I need guidance.
I have done range tests and the reception is phenomenal. There is a blindspot when the reception attempts to go though the structural core of the hotel with the elevators and such, but this is expected, and not too bad for a very low-cost, low power RF! Mostly everything works, until I try to use Ethernet to send data to Pachube. The whole thing works very well for about 10 minutes (have seen up to 25minutes), then it seems the RFM12b can no longer receive, and Ethernet sends nothing out because I do not reach the code where I process the Ethernet sending.
To note, I am using the RF12 library http://jeelabs.net/projects/cafe/wiki/RF12 from JeeLabs which allows me to use Pin 9 on the Arduino UNO as the chip select pin for the RFM12b.
I have read many posts on issues regarding the Ethernet Shield and other SPI devices. This one in particular from the old forum, seemed to shed some light: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1287657487.
It seems that by editing the W5100.cpp functions to disable/enable interrupts 'freakylabs' was able to get things working. I did attempt the edits, but I am still getting 10-25 minutes of sending and then I can no longer receive on the RFM12b.
I would very much appreciate if someone could guide me in how I can troubleshoot such a situation. Its driving me nuts, and I will not accept that the hardware cannot work together if it works for some amount of time, but then fails. Is there something I can insert in the code to check if things are going well? I am now trying this for two weeks without getting any further with stability. I am attaching the receiving code. This code, without Ethernet functions, can receive for days and days at a time (never had an error after many days of stability). Your help would be greatly appreciated.
Receiving Code:
#include <SPI.h>
#include <Ethernet.h>
#include "ERxPachube.h"
#include <Ports.h>
#include <RF12.h>
#include <Wire.h>
#include <RTClib.h>
unsigned long time=0;
RTC_Millis RTC;
/////////////NETWORK DATA////////////////////////////////
byte mac[] = {
0x90, 0xA2, 0xDA, 0x00, 0x4E, 0xBE }; // make sure this is unique on your network
byte ip[] = {
192, 168, 0, 177 }; // no DHCP so we set our own IP address
//byte ip[] = { 10,0,1,199 };
#define PACHUBE_API_KEY "PACHUBE API HERE" // fill in your API key PACHUBE_API_KEY
#define PACHUBE_FEED_ID 28839 // fill in your feed id
ERxPachubeDataOut dataout(PACHUBE_API_KEY, PACHUBE_FEED_ID);
void PrintDataStream(const ERxPachube& pachube);
void PrintString(const String& message) ;
/////////////////////////////////////////////////////////
//analogous data structure for incoming data
typedef struct {
int cnt;
unsigned long time; //ellapsed time since last reading
byte bat;
int p1, p2, p3, p4; //pulses
}
Payload;
Payload inData;
//////////define class for flowmeter calculations
typedef struct {
int p[3]; //current pulses
int tp[3]; //total pulses
float fr[3]; //flow rate
float t[3]; //total liters
}
FlowNode;
FlowNode fn1, fn2, fn3, fn4;
void setup () {
Serial.begin(57600);
Serial.println("Started Setup...");
RTC.begin(DateTime(__DATE__, __TIME__));
rf12_config();
Ethernet.begin(mac, ip);
/////////////NETWORK DATA////////////////////////////////
dataout.addData(0); //Node 2 pulses
dataout.addData(1); //Node 2 total pulses
dataout.addData(2); //Node 2 flow rate
dataout.addData(3); //Node 2 total consumption
delay(1000);
Serial.println("Ended Setup...");
}
static void consumeInData () {
DateTime now = RTC.now();
Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
Serial.print(' ');
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();
inData = *(Payload*) rf12_data;
Serial.println("+++++++++++++++++++++++++++++++++++++++");
Serial.print("id: ");
Serial.print(rf12_hdr, DEC); //print node id
Serial.print(" msg:");
Serial.print(inData.cnt); //print the message number
Serial.print(" time:");
Serial.print(inData.time); //print the amount of time the remote node measured water flow
Serial.print(" bat:");
Serial.print(inData.bat, DEC); //alert if battery low
Serial.println();
switch (rf12_hdr) {
case 1:
//process current pulses
fn1.p[0] = inData.p1;
fn1.p[1] = inData.p2;
fn1.p[2] = inData.p3;
fn1.p[3] = inData.p4;
//process total pulses
fn1.tp[0] += inData.p1;
fn1.tp[1] += inData.p2;
fn1.tp[2] += inData.p3;
fn1.tp[3] += inData.p4;
//process flow rate
fn1.fr[0] = processRate(inData.p1, inData.time);
fn1.fr[1] = processRate(inData.p2, inData.time);
fn1.fr[2] = processRate(inData.p3, inData.time);
fn1.fr[3] = processRate(inData.p4, inData.time);
//process total liters
fn1.t[0] += processTotal(fn1.fr[0], inData.time);
fn1.t[1] += processTotal(fn1.fr[1], inData.time);
fn1.t[2] += processTotal(fn1.fr[2], inData.time);
fn1.t[3] += processTotal(fn1.fr[3], inData.time);
dataout.updateData(0, fn1.p[1]);
dataout.updateData(1, fn1.tp[1]);
dataout.updateData(2, fn1.fr[1]);
dataout.updateData(3, fn1.t[1]);
break;
case 2:
//process current pulses
fn2.p[0] = inData.p1;
fn2.p[1] = inData.p2;
fn2.p[2] = inData.p3;
fn2.p[3] = inData.p4;
//process total pulses
fn2.tp[0] += inData.p1;
fn2.tp[1] += inData.p2;
fn2.tp[2] += inData.p3;
fn2.tp[3] += inData.p4;
//process flow rate
fn2.fr[0] = processRate(inData.p1, inData.time);
fn2.fr[1] = processRate(inData.p2, inData.time);
fn2.fr[2] = processRate(inData.p3, inData.time);
fn2.fr[3] = processRate(inData.p4, inData.time);
//process total liters
fn2.t[0] += processTotal(fn2.fr[0], inData.time);
fn2.t[1] += processTotal(fn2.fr[1], inData.time);
fn2.t[2] += processTotal(fn2.fr[2], inData.time);
fn2.t[3] += processTotal(fn2.fr[3], inData.time);
dataout.updateData(0, fn2.p[1]);
dataout.updateData(1, fn2.tp[1]);
dataout.updateData(2, fn2.fr[1]);
dataout.updateData(3, fn2.t[1]);
break;
}
cli();//is this necessary?
int status = dataout.updatePachube();
Serial.print("sync status code <OK == 200> => ");
Serial.println(status);
sei();//is this necessary?
Serial.println(" ");
}
void loop () {
if (rf12_recvDone() && rf12_crc == 0 && rf12_len == sizeof inData) {
memcpy(&inData, (byte*) rf12_data, sizeof inData);
// optional: rf12_recvDone(); // re-enable reception right away
consumeInData();
time = millis();
}
else{
if((millis()-time)>10000){
Serial.println("something wrong...");
}
}
}
float processRate(int p, unsigned long time){
// Pulse frequency (Hz) in Horizontal Test= 7.5Q, Q is flow rate in L/min. (Results in +/- 3% range)
//since we are receiving from the nodes every 5000 milliseconds,
//we divide 5000/1000 to get 5 seconds...
return (p/(time/1000)) / 7.5;
}
float processTotal(float fr, unsigned long time){
//first get the flow rate per second,
//second multiply by the number of seconds which have ellapsed
return (fr/60) *(time/1000);
}