advice for monitoring water meters? [Closed]

Hi

excuse me if this has been asked before, but have anybody done monitoring water usage?

I saw some examples on a sketch for 3 phase electricity... but would it be hard to both monitor the 3 individual phases and also calculate the combined use of electricity?

I had an idea... use both CT an optical sensor to in some way try to predict what the meter says and if it varies then manuel input the meter reading... would that be possible and if so would it be hard to do?

i have asked the facotry of the water meter if its possible to attach a read switch or something and it seems so on their webpage (http://www.elstermetering.com/en/693.html look at page 2 in the meters pdf)

The electricity meter is a self reporting meter so i could look up the usage on the internet but even thou the meter reports for every hour, its sometimes several hours to do updates if not a day or 2... i want to see the effect of my behaviour right away

for the water meter i have to fill in a report card once a year... far to long, it want to have hourly reporting here also..

The heat meter is selfreporting, thou it only updates once every 3 months... dont know if i could but a hall effect to the flow counter and how accurate i could get temp readings... but the meter allows me to read the temps and maybe i could use that to account for the fall in temp there will be when mounting a sensor outside on the tube... will have to check in to that..

 

hope for some input and ideas

 

/bo

Robert Wall's picture

Re: advice for monitoring water meters? [Closed]

have anybody done monitoring water usage?
I have not seen that reported here, but if you can have a pulse output from your meter, then the emonTx pulse input can be used.

3 phase electricity... but would it be hard to both monitor the 3 individual phases
No, it has been done http://openenergymonitor.org/emon/node/1170

and also calculate the combined use of electricity?
Add the power / energy for each of the phases together to obtain the total.

The electricity meter is a self reporting meter 
Does your meter also have an infra-red output? If it has, it might be possible to read that. And the same for your heat meter.
 

 

StuntMonkeh's picture

Re: advice for monitoring water meters? [Closed]

Most water meters use a reed switch.  Take a look at your water meter and find the datasheet for it.

Its possible to buy pulse modules to clip on the top of the water meter that have a flying lead attached so you can count the pulses.

Heat meters often have pulse outputs for kWh or a comms bus which uses a protocol i.e. M-Bus.  Again, find the datasheet for your heat meter and you will be able to see what it offers.  Unfortunately its usually one or the other.

In short its trivial to count pulses but bus protocols are going to be more difficult.

boelle's picture

Re: advice for monitoring water meters? [Closed]

Back again... strange enough i did not get any emails for the 2 replys

For my heat meter i know it has an infra output and i just have to build an rs-232 interface for it.. i also got a list of the different ID it spits out.. the only thing left is to figure on how to pas the relavant data on. Not that sharp in programming :-(

The water meter do need the clip on read switch... i have seen people use an  hall effect sensor, an interesting idea is found here where the res. can be as good as 15ml.(tablesppon): http://www.edcheung.com/automa/water.htm

The manufacture has not responded to my mails even thou they sell a clip on thing

The electricity meter do only have an blink output, 10000 pulses for every kwh

3 phase electricity... i looked at the link and the only thing i could not figure is why there was 2 jacks on the side of each board... since each phase only need 1 CS clamp i would figure only one jack is needed?? the thread did not give me any clues

 

boelle's picture

Re: advice for monitoring water meters? [Closed]

So i checked up on the water meter... the factory do have an reed disc option its even showed on the data sheet: http://www.elstermetering.com/downloads/M100_D_0101e_1012.pdf

Also i mailed them to hear if i could get a disc (i'm a bit lazy)

if not would a reed switch or hall effect give the best results?

 

next if to check the heat meter.. an Kamstrup Multical 601... on this link the register id's can be found, page 90 : http://kamstrup.com/media/11976/file.pdf

boelle's picture

Re: advice for monitoring water meters? [Closed]

lucky me... a nice arduino geek send me this arduino code that is made for my meter...

#include <SoftwareSerial.h>
#include <OneWire.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_1WIRE      4  // 1-Wire bus
#define PIN_KAMSER_RX  6  // Kamstrup IR interface RX
#define PIN_KAMSER_TX  7  // Kamstrup IR interface TX
#define PIN_DIAG_LED   13 // Diag LED to blink with for fun

// Kamstrup optical IR serial
#define KAMTIMEOUT 2000      // Kamstrup timeout after transmit
#define POLLINTERVAL 300000  // Polling interval
SoftwareSerial kamSer(PIN_KAMSER_RX, PIN_KAMSER_TX, true);  // Initialize serial

// 1-wire
byte ts_t[]  = {0x28,0x14,0xA9,0xAA,0x03,0x00,0x00,0x0F};  // Indoor temperature
OneWire ds(PIN_1WIRE);  // Initialize 1-Wire

// last poll variable
long lastpoll;

void setup() {
  // setup pins
  pinMode(PIN_DIAG_LED,OUTPUT);
  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);
    }

    // get 1-wire temps
    String t = gettemp_ds18b20(ts_t);
    Serial.print(t);

    // send a newline to have linksys process the data
    Serial.println("");   

    // update lastpoll
    lastpoll = millis();
  }

  // toggle LED to show we are alive
  togglePin(PIN_DIAG_LED);
 
  // loop delay
  delay(500);
 
};

// Toggle pin
void togglePin(int pinNum) {
  digitalWrite(pinNum, !digitalRead(pinNum));
}

// get temperature reading from 1wire sensor
String gettemp_ds18b20(byte addr[8]) {
  byte i;
  byte present = 0;
  byte data[12];
  int HighByte, LowByte, TReading, SignBit, Tc_100, Whole, Fract;
  String value = "";
  ds.reset();
  ds.select(addr);
  ds.write(0x44,1);
  delay(1000);
  present = ds.reset();
  ds.select(addr);   
  ds.write(0xBE);         // Read Scratchpad
  for ( i = 0; i < 2; i++) {           // we need 2 bytes
    data[i] = ds.read();
  }
  // Convert to degrees celsius
  LowByte = data[0];
  HighByte = data[1];
  TReading = (HighByte << 8) + LowByte;
  SignBit = TReading & 0x8000;  // test most sig bit
  if (SignBit) // negative
  {
    TReading = (TReading ^ 0xffff) + 1; // 2's comp
  }
  Tc_100 = (6 * TReading) + TReading / 4;    // multiply by (100 * 0.0625) or 6.25
  Whole = Tc_100 / 100;  // separate off the whole and fractional portions
  Fract = Tc_100 % 100;
  if (SignBit) // If its negative
  {
    value = "-";
  }
  value += Whole;
  value += ".";
  if (Fract < 10)
  {
    value += "0";
  }
  value += Fract;
  return value;
}

// 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(",");

}

// 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;
}
 

boelle's picture

Re: advice for monitoring water meters? [Closed]

phew... i guess that one saves a lot of trouble... now how do i send data to the emon cms system?

StuntMonkeh's picture

Re: advice for monitoring water meters? [Closed]

If you can find an Elster distributor they should be able to give you a price although I suggest making it as easy as possible for them by giving them a part number.  Don't give up though, they will often say they will get back to you so you will need to keep hassling them.

You could possibly use something else but I doubt it would be worth the hassle.  The problem with water meters are they often tend to be located in a hole outside.  If you get their module it will clip straight on and will be suitably rated against water ingress.

I assume the Kamstrup meter is being read from an IR receiver.  You will need to merge your code with some from the emonTX sketch to bundle the data in the standard format you want to send to your emonBase.

boelle's picture

Re: advice for monitoring water meters? [Closed]

The water meter is inside my flat...

In fact the water meter, heat meter and fuse box are inside the same closet... so 1 emontx can handle both the electricity (3 cs clamps) and water meter (elster disc or hall effect...

think i will spend the evening figureing out how to merge codes... any help with that is more than welcome..

on the hardware side... how would i fit an ir interface to the imontx if its possible?

boelle's picture

Re: advice for monitoring water meters? [Closed]

btw... the code for the emontx... i looked and there are a lot of examples...

is there not a "standard" code that comes with the assembled units sold in the store or do i have to hack something together?

boelle's picture

Re: advice for monitoring water meters? [Closed]

boelle's picture

Re: advice for monitoring water meters? [Closed]

so far i have managed to build this sketch that should do electricity and water.. only thing is that there is only 1 input for 9V AC... is there a way to hack in 2 more?

 

#include "EmonLib.h"                   // Include Emon Library

//------------------------Electricity Start---------------------------
EnergyMonitor ct1;                     // Create an instance Phase 1
EnergyMonitor ct2;                     // Create an instance Phase 2
EnergyMonitor ct3;                     // Create an instance Phase 3
//------------------------Electricity End-----------------------------
//------------------------Water Start---------------------------------
long pulseCount = 0;
unsigned long pulseTime,lastTime;      // Used to measure time between pulses
double power;
int ppltr = 1;                         // pulses per liter
//------------------------Water End-----------------------------------

void setup()
{  
  Serial.begin(9600);
//------------------------Electricity Start---------------------------
ct1.voltageTX(238.5, 1.7);             // Calibration, phase_shift
ct1.currentTX(1, 115.6);               // CT channel, calibration.
ct2.voltageTX(238.5, 1.7);             // Calibration, phase_shift
ct2.currentTX(1, 115.6);               // CT channel, calibration.
ct3.voltageTX(238.5, 1.7);             // Calibration, phase_shift
ct3.currentTX(1, 115.6);               // CT channel, calibration.
//------------------------Electricity End-----------------------------
//------------------------Water Start---------------------------------
// pulse detection interrupt (emontx pulse channel - IRQ0 D3)
attachInterrupt(1, onPulse, FALLING);
//------------------------Water End-----------------------------------
}

void loop()
{
//------------------------Electricity Start---------------------------
ct1.calcVI(20,2000);                   // Calculate all. No.of wavelengths, time-out
ct1.serialprint();                     // Print out all variables
ct2.calcVI(20,2000);                   // Calculate all. No.of wavelengths, time-out
ct2.serialprint();                     // Print out all variables
ct3.calcVI(20,2000);                   // Calculate all. No.of wavelengths, time-out
ct3.serialprint();                     // Print out all variables
delay(1000);
//------------------------Electricity End-----------------------------
//------------------------Water Start---------------------------------
Serial.print(Water);
Serial.print(' ');
Serial.print(Liter);
Serial.println(pulseCount * ppltr);    // Liters used
delay(1000);
//------------------------Water End-----------------------------------
}
//------------------------Water Start--------------------------------- 
//The interrupt routine – runs each time a falling edge of a pulse is detected
void onPulse()                  
{
lastTime = pulseTime;
pulseTime = micros();
pulseCount++;                          // count pulse               
power = int((3600000000.0 / (pulseTime - lastTime))/ppltr);  // calculate water
}
//------------------------Water End-----------------------------------

 

boelle's picture

Re: advice for monitoring water meters? [Closed]

now with transmit in the code - only need to figure how to read from heat meter:

 

#include <JeeLib.h>
#include "EmonLib.h"                   // Include Emon Library
//------------------------Transmit Start-------------------------
// this is added as we're using the watchdog for low-power waiting
ISR(WDT_vect) { Sleepy::watchdogEvent(); }

// create structure – a neat way of packaging data for RF comms
typedef struct { int power; } PayloadTX;                                
PayloadTX emontx;
//------------------------Transmit End---------------------------

//------------------------Electricity Start----------------------
EnergyMonitor ct1;                     // Create an instance Phase 1
EnergyMonitor ct2;                     // Create an instance Phase 2
EnergyMonitor ct3;                     // Create an instance Phase 3
//------------------------Electricity End------------------------
//------------------------Water Start----------------------------
long pulseCount = 0;
unsigned long pulseTime,lastTime;      // Used to measure time between pulses
double power;
int ppltr = 1;                         // pulses per liter
//------------------------Water End------------------------------

void setup()
{  
  Serial.begin(9600);
//------------------------Electricity Start----------------------
ct1.voltageTX(238.5, 1.7);             // Calibration, phase_shift
ct1.currentTX(1, 115.6);               // CT channel, calibration.
ct2.voltageTX(238.5, 1.7);             // Calibration, phase_shift
ct2.currentTX(1, 115.6);               // CT channel, calibration.
ct3.voltageTX(238.5, 1.7);             // Calibration, phase_shift
ct3.currentTX(1, 115.6);               // CT channel, calibration.
//------------------------Electricity End------------------------
//------------------------Transmit Start-------------------------
// initialize RFM12B (node id, frequency, group)
rf12_initialize(10, RF12_433MHZ, 210);      
rf12_sleep(RF12_SLEEP);
//------------------------Transmit End---------------------------
//------------------------Water Start----------------------------
// pulse detection interrupt (emontx pulse channel - IRQ0 D3)
attachInterrupt(1, onPulse, FALLING);
//------------------------Water End------------------------------
}

void loop()
{
//------------------------Transmit Start-------------------------
emontx.power = ct1.calcIrms(1480) * 240.0;
//------------------------Transmit End---------------------------
//------------------------Electricity Start----------------------
ct1.calcVI(20,2000);                   // Calculate all. No.of wavelengths, time-out
ct1.serialprint();                     // Print out all variables
ct2.calcVI(20,2000);                   // Calculate all. No.of wavelengths, time-out
ct2.serialprint();                     // Print out all variables
ct3.calcVI(20,2000);                   // Calculate all. No.of wavelengths, time-out
ct3.serialprint();                     // Print out all variables
//------------------------Transmit Start-------------------------
rf12_sleep(RF12_WAKEUP);

int i = 0; while (!rf12_canSend() && i<10) {rf12_recvDone(); i++;}

rf12_sendStart(0, &emontx, sizeof emontx);
// set the sync mode to 2 if the fuses are still the Arduino default
// mode 3 (full powerdown) can only be used with 258 CK startup fuses
rf12_sendWait(2);

rf12_sleep(RF12_SLEEP);
Sleepy::loseSomeTime(5000);
//------------------------Transmit End---------------------------
delay(1000);
//------------------------Electricity End------------------------
//------------------------Water Start----------------------------
Serial.print(Water);
Serial.print(' ');
Serial.print(Liter);
Serial.println(pulseCount * ppltr);    // Liters used
delay(1000);
//------------------------Water End------------------------------
}
//------------------------Water Start---------------------------- 
//The interrupt routine – runs each time a falling edge of a pulse is detected
void onPulse()                  
{
lastTime = pulseTime;
pulseTime = micros();
pulseCount++;                          // count pulse               
power = int((3600000000.0 / (pulseTime - lastTime))/ppltr);  // calculate water
}
//------------------------Water End------------------------------

 

boelle's picture

Re: advice for monitoring water meters? [Closed]

boelle's picture

Re: advice for monitoring water meters? [Closed]

trying to integrate this thread... http://openenergymonitor.org/emon/node/1170

still have to figure why 2  jacks are pluged in to each....

boelle's picture

Re: advice for monitoring water meters? [Closed]

so far i got this for the master module... a bit worried about counting pulses for water meter is done right:

 

Version:1.0 StartHTML:0000000167 EndHTML:0000012001 StartFragment:0000000454 EndFragment:0000011985

#define FVCAL 237 // default is 234.26

#define FICAL 111.5 // default 111.1

#define FPHASE 1 // default 1.7

 

#define FILTERSETTLETIME 5000 // Time (ms) to allow the filters to settle before sending data

 

//CT 1 is always enabled

const int CT2 = 1; // Set to 1 to enable CT channel 2

const int CT3 = 0; // Set to 1 to enable CT channel 3

 

#define freq RF12_433MHZ // Frequency of RF12B module can be RF12_433MHZ, RF12_868MHZ or RF12_915MHZ. You should use the one matching the module you have.433MHZ, RF12_868MHZ or RF12_915MHZ. You should use the one matching the module you have.

 

const int nodeID = 10; // emonTx RFM12B node ID

 

const int networkGroup = 210; // emonTx RFM12B wireless network group - needs to be same as emonBase and emonGLCD needs to be same as emonBase and emonGLCD

 

const int UNO = 1; // Set to 0 if your not using the UNO bootloader (i.e using Duemilanove) - All Atmega's shipped from OpenEnergyMonitor come with Arduino Uno bootloader

 

#include <avr/wdt.h> // the UNO bootloader

 

#include <JeeLib.h> // Download JeeLib: http://github.com/jcw/jeelib

 

ISR(WDT_vect) { Sleepy::watchdogEvent(); }

 

#include "EmonLib.h"

 

EnergyMonitor ct1,ct2,ct3; // Create instances for each CT channel

 

#include <Wire.h>

 

typedef struct { int power1, power2, power3, Vrms; } PayloadTX; // neat way of packaging data for RF comms

 

PayloadTX emontx[3];

 

const int LEDpin = 9; // On-board emonTx LED

 

boolean settled = false;

 

//------------------------Water Start----------------------------

long pulseCount = 0;

unsigned long pulseTime,lastTime; // Used to measure time between pulses

double power;

int ppltr = 1; // pulses per liter

//------------------------Water End------------------------------

 

Void setup()

{

Serial.begin(9600);

Serial.println("emonTX CT123 Voltage example");

Serial.println("OpenEnergyMonitor.org");

Serial.print("Node: ");

Serial.print(nodeID);

Serial.print(" Freq: ");

if (freq == RF12_433MHZ) Serial.print("433Mhz");

if (freq == RF12_868MHZ) Serial.print("868Mhz");

if (freq == RF12_915MHZ) Serial.print("915Mhz");

Serial.print(" Network: ");

Serial.println(networkGroup);

 

ct1.voltageTX(FVCAL, FPHASE); // ct.voltageTX(calibration, phase_shift) - make sure to select correct calibration for AC-AC adapter http://openenergymonitor.org/emon/modules/

emontx/firmware/calibration

 

ct1.currentTX(1, FICAL);1 // Setup emonTX CT channel (channel (1,2 or 3), calibration)

// CT Calibration factor = CT ratio / burden resistance

ct2.voltageTX(FVCAL, FPHASE); // CT Calibration factor = (100A / 0.05A) x 18 Ohms

ct2.currentTX(2, FICAL);

 

ct3.voltageTX(FVCAL, FPHASE);

ct3.currentTX(3, FICAL);

 

rf12_initialize(nodeID, freq, networkGroup); // initialize RF

//rf12_control(0xc657);

// approx. 3.918kps, i.e. 10000/29(1+0x57) kps

rf12_sleep(RF12_SLEEP);

 

Wire.begin(); // join i2c bus (address optional for master)

 

pinMode(LEDpin, OUTPUT); // Setup indicator LED

 

digitalWrite(LEDpin, HIGH);

 

if (UNO) wdt_enable(WDTO_8S); // Enable anti crash (restart) watchdog if UNO bootloader is selected. Watchdog does not work with duemilanove

 

bootloader // Restarts emonTx if sketch hangs for more than 8s

 

//------------------------Water Start----------------------------

// pulse detection interrupt (emontx pulse channel - IRQ0 D3)

attachInterrupt(1, onPulse, FALLING);

//------------------------Water End------------------------------

}

void loop()

{

pokeSlave(2); // start slave on phase 2

pokeSlave(3); // start slave on phase 3

 

ct1.calcVI(20,2000); // Calculate all. No.of crossings, time-out

emontx[0].power1 = ct1.realPower;

Serial.print(emontx[0].power1);

 

emontx[0].Vrms = ct1.Vrms*100; // AC Mains rms voltage

 

if (CT2)

{

ct2.calcVI(20,2000); //ct.calcVI(number of crossings to sample, time out (ms) if no waveform is detected)

emontx[0].power2 = ct2.realPower;

Serial.print("\t"); Serial.print(emontx[0].power2);

//Serial.print("\t"); Serial.print(ct2.Irms);

//Serial.print("\t"); Serial.print(ct2.powerFactor);

}

 

if (CT3)

{

ct3.calcVI(20,2000);

emontx[0].power3 = ct3.realPower;

Serial.print("\t"); Serial.print(emontx[0].power3);

}

 

Serial.print("\t"); Serial.print(ct1.Vrms);

Serial.println(); delay(100);

 

// because millis() returns to zero after 50 days !

 

if (!settled && millis() > FILTERSETTLETIME) settled = true;

 

if (settled) // send data only after filters have settled

{

readSlave(2); // get data for phase 2

readSlave(3); // get data for phase 3

delay(100); // send_rf_data corrupts any pending Serial.prints so wait until they finish - need to find out why

 

send_rf_data(); // *SEND RF DATA* - see emontx_lib

 

digitalWrite(LEDpin, HIGH); delay(2); digitalWrite(LEDpin, LOW); // flash LED

 

emontx_sleep(5); // sleep or delay in seconds - see emontx_lib

}

else if (UNO) wdt_reset();

 

//------------------------Water Start----------------------------

Serial.print(Water);

Serial.print(' ');

Serial.print(Liter);

Serial.println(pulseCount * ppltr); // Liters used

delay(1000);

//------------------------Water End------------------------------

 

}

 

//------------------------Water Start----------------------------

 

//The interrupt routine – runs each time a falling edge of a pulse is detected

 

void onPulse()

{

lastTime = pulseTime;

pulseTime = micros();

pulseCount++; // count pulse

 

power = int((3600000000.0 / (pulseTime - lastTime))/ppltr); // calculate water

}

//------------------------Water End------------------------------

 

 

boelle's picture

Re: advice for monitoring water meters? [Closed]

final cosmetic changes, still need to figure where to find emontx_lib.ino:

 

/*

EmonTx CT123 + Voltage example

 

An example sketch for the emontx module for CT only electricity monitoring.

 

Part of the openenergymonitor.org project

Licence: GNU GPL V3

 

Authors: Glyn Hudson, Trystan Lea

Builds upon JeeLabs RF12 library and Arduino

 

emonTx documentation: http://openenergymonitor.org/emon/modules/emontx/

emonTx firmware code explination: http://openenergymonitor.org/emon/modules/emontx/firmware

emonTx calibration instructions: http://openenergymonitor.org/emon/modules/emontx/firmware/calibration

 

THIS SKETCH REQUIRES:

 

Libraries in the standard arduino libraries folder:

- JeeLib https://github.com/jcw/jeelib

- EmonLib https://github.com/openenergymonitor/EmonLib.git

 

Other files in project directory (should appear in the arduino tabs above)

- emontx_lib.ino

 

Slave control for 3-phase added by Martin Roberts 14/10/12

 

Pulse counter for Elster m100 Artist water meter by Bo Herrmannsen 16/02/13

 

*/

 

 

#define FVCAL 237 // default is 234.26

#define FICAL 111.5 // default 111.1

#define FPHASE 1 // default 1.7

 

#define FILTERSETTLETIME 5000 // Time (ms) to allow the filters to settle before sending data

 

//CT 1 is always enabled

const int CT2 = 1; // Set to 1 to enable CT channel 2

const int CT3 = 0; // Set to 1 to enable CT channel 3

 

#define freq RF12_433MHZ // Frequency of RF12B module can be RF12_433MHZ, RF12_868MHZ or RF12_915MHZ. You should use the one matching the module you have.433MHZ, RF12_868MHZ or RF12_915MHZ. You should use the one matching the module you have.

 

const int nodeID = 10; // emonTx RFM12B node ID

 

const int networkGroup = 210; // emonTx RFM12B wireless network group - needs to be same as emonBase and emonGLCD needs to be same as emonBase and emonGLCD

 

const int UNO = 1; // Set to 0 if your not using the UNO bootloader (i.e using Duemilanove) - All Atmega's shipped from OpenEnergyMonitor come with Arduino Uno bootloader

 

#include <avr/wdt.h> // the UNO bootloader

 

#include <JeeLib.h> // Download JeeLib: http://github.com/jcw/jeelib

 

ISR(WDT_vect) { Sleepy::watchdogEvent(); }

 

#include "EmonLib.h"

 

EnergyMonitor ct1,ct2,ct3; // Create instances for each CT channel

 

#include <Wire.h>

 

typedef struct { int power1, power2, power3, Vrms; } PayloadTX; // neat way of packaging data for RF comms

 

PayloadTX emontx[3];

 

const int LEDpin = 9; // On-board emonTx LED

 

boolean settled = false;

 

//------------------------Water Start----------------------------

long pulseCount = 0;

unsigned long pulseTime,lastTime; // Used to measure time between pulses

double power;

int ppltr = 1; // Pulses per liter

//------------------------Water End------------------------------

 

Void setup()

{

Serial.begin(9600);

Serial.println("emonTX CT123 Voltage example");

Serial.println("OpenEnergyMonitor.org");

Serial.print("Node: ");

Serial.print(nodeID);

Serial.print(" Freq: ");

if (freq == RF12_433MHZ) Serial.print("433Mhz");

if (freq == RF12_868MHZ) Serial.print("868Mhz");

if (freq == RF12_915MHZ) Serial.print("915Mhz");

Serial.print(" Network: ");

Serial.println(networkGroup);

 

ct1.voltageTX(FVCAL, FPHASE); // ct.voltageTX(calibration, phase_shift) - make sure to select correct calibration for AC-AC adapter http://openenergymonitor.org/emon/modules/

emontx/firmware/calibration

 

ct1.currentTX(1, FICAL);1 // Setup emonTX CT channel (channel (1,2 or 3), calibration)

// CT Calibration factor = CT ratio / burden resistance

ct2.voltageTX(FVCAL, FPHASE); // CT Calibration factor = (100A / 0.05A) x 18 Ohms

ct2.currentTX(2, FICAL);

 

ct3.voltageTX(FVCAL, FPHASE);

ct3.currentTX(3, FICAL);

 

rf12_initialize(nodeID, freq, networkGroup); // initialize RF

//rf12_control(0xc657);

// approx. 3.918kps, i.e. 10000/29(1+0x57) kps

rf12_sleep(RF12_SLEEP);

 

Wire.begin(); // join i2c bus (address optional for master)

 

pinMode(LEDpin, OUTPUT); // Setup indicator LED

 

digitalWrite(LEDpin, HIGH);

 

if (UNO) wdt_enable(WDTO_8S); // Enable anti crash (restart) watchdog if UNO bootloader is selected. Watchdog does not work with duemilanove

 

bootloader // Restarts emonTx if sketch hangs for more than 8s

 

//------------------------Water Start----------------------------

// pulse detection interrupt (emontx pulse channel - IRQ0 D3)

attachInterrupt(1, onPulse, FALLING);

//------------------------Water End------------------------------

}

void loop()

{

pokeSlave(2); // start slave on phase 2

pokeSlave(3); // start slave on phase 3

 

ct1.calcVI(20,2000); // Calculate all. No.of crossings, time-out

emontx[0].power1 = ct1.realPower;

Serial.print(emontx[0].power1);

 

emontx[0].Vrms = ct1.Vrms*100; // AC Mains rms voltage

 

if (CT2)

{

ct2.calcVI(20,2000); //ct.calcVI(number of crossings to sample, time out (ms) if no waveform is detected)

emontx[0].power2 = ct2.realPower;

Serial.print("\t"); Serial.print(emontx[0].power2);

//Serial.print("\t"); Serial.print(ct2.Irms);

//Serial.print("\t"); Serial.print(ct2.powerFactor);

}

 

if (CT3)

{

ct3.calcVI(20,2000);

emontx[0].power3 = ct3.realPower;

Serial.print("\t"); Serial.print(emontx[0].power3);

}

 

Serial.print("\t"); Serial.print(ct1.Vrms);

Serial.println(); delay(100);

 

// because millis() returns to zero after 50 days !

 

if (!settled && millis() > FILTERSETTLETIME) settled = true;

 

if (settled) // send data only after filters have settled

{

readSlave(2); // get data for phase 2

readSlave(3); // get data for phase 3

delay(100); // send_rf_data corrupts any pending Serial.prints so wait until they finish - need to find out why

 

send_rf_data(); // *SEND RF DATA* - see emontx_lib

 

digitalWrite(LEDpin, HIGH); delay(2); digitalWrite(LEDpin, LOW); // flash LED

 

emontx_sleep(5); // sleep or delay in seconds - see emontx_lib

}

else if (UNO) wdt_reset();

 

//------------------------Water Start----------------------------

Serial.print(Water);

Serial.print(' ');

Serial.print(Liter);

Serial.println(pulseCount * ppltr); // Liters used

delay(1000);

//------------------------Water End------------------------------

 

}

 

//------------------------Water Start----------------------------

 

//The interrupt routine – runs each time a falling edge of a pulse is detected

 

void onPulse()

{

lastTime = pulseTime;

pulseTime = micros();

pulseCount++; // count pulse

 

power = int((3600000000.0 / (pulseTime - lastTime))/ppltr); // calculate water

}

//------------------------Water End------------------------------

 

void pokeSlave(byte phase)

{

//Serial.print("Poking slave ");

//Serial.println(phase,DEC);

Wire.beginTransmission(phase); // transmit to device slave

Wire.write(0x5a); // send any data

Wire.endTransmission(); // stop transmitting

}

 

void readSlave(byte phase)

{

byte *p;

int i;

 

if((phase<2)||(phase>3)) return;

p=(byte *)(&emontx[phase-1]);

 

//Serial.print("Reading from slave ");

//Serial.println(phase,DEC);

Wire.requestFrom(phase, sizeof emontx[0]); // request data from slave device

 

i=0;

while(Wire.available()) // slave may send less than requested

{

p[i++] = Wire.read();

}

}

boelle's picture

Re: advice for monitoring water meters? [Closed]

when compiling i got these errors.. i guess its very simple:

 

In file included from sketch_feb16b.cpp:58:
/Applications/Arduino101.app/Contents/Resources/Java/libraries/JeeLib/JeeLib.h:9: error: stray '\302' in program
/Applications/Arduino101.app/Contents/Resources/Java/libraries/JeeLib/JeeLib.h:9: error: stray '\267' in program
/Applications/Arduino101.app/Contents/Resources/Java/libraries/JeeLib/JeeLib.h:9: error: stray '\302' in program
/Applications/Arduino101.app/Contents/Resources/Java/libraries/JeeLib/JeeLib.h:9: error: stray '\267' in program
In file included from sketch_feb16b.cpp:58:
/Applications/Arduino101.app/Contents/Resources/Java/libraries/JeeLib/JeeLib.h:252:46: error: invalid suffix "dc3202e9bd6dee29fbfadea040f592d" on integer constant
/Applications/Arduino101.app/Contents/Resources/Java/libraries/JeeLib/JeeLib.h:253:62: error: invalid suffix "dc3202e9bd6dee29fbfadea040f592d" on integer constant
/Applications/Arduino101.app/Contents/Resources/Java/libraries/JeeLib/JeeLib.h:442: error: stray '#' in program
In file included from sketch_feb16b.cpp:62:
/Applications/Arduino101.app/Contents/Resources/Java/libraries/EmonLib/EmonLib.h:9: error: stray '\302' in program
/Applications/Arduino101.app/Contents/Resources/Java/libraries/EmonLib/EmonLib.h:9: error: stray '\267' in program
/Applications/Arduino101.app/Contents/Resources/Java/libraries/EmonLib/EmonLib.h:9: error: stray '\302' in program
/Applications/Arduino101.app/Contents/Resources/Java/libraries/EmonLib/EmonLib.h:9: error: stray '\267' in program
In file included from sketch_feb16b.cpp:62:
/Applications/Arduino101.app/Contents/Resources/Java/libraries/EmonLib/EmonLib.h:248:46: error: invalid suffix "c7fa71f1de8d7c8a35f1c2056c669ff" on integer constant
/Applications/Arduino101.app/Contents/Resources/Java/libraries/EmonLib/EmonLib.h:249:62: error: invalid suffix "c7fa71f1de8d7c8a35f1c2056c669ff" on integer constant
/Applications/Arduino101.app/Contents/Resources/Java/libraries/EmonLib/EmonLib.h:270: error: stray '\342' in program
/Applications/Arduino101.app/Contents/Resources/Java/libraries/EmonLib/EmonLib.h:270: error: stray '\200' in program
/Applications/Arduino101.app/Contents/Resources/Java/libraries/EmonLib/EmonLib.h:270: error: stray '\246' in program
/Applications/Arduino101.app/Contents/Resources/Java/libraries/EmonLib/EmonLib.h:391: error: stray '#' in program
/Applications/Arduino101.app/Contents/Resources/Java/libraries/EmonLib/EmonLib.h:391: error: stray '#' in program
/Applications/Arduino101.app/Contents/Resources/Java/libraries/EmonLib/EmonLib.h:391: error: stray '#' in program
/Applications/Arduino101.app/Contents/Resources/Java/libraries/EmonLib/EmonLib.h:391: error: stray '#' in program
/Applications/Arduino101.app/Contents/Resources/Java/libraries/EmonLib/EmonLib.h:391: error: stray '#' in program
/Applications/Arduino101.app/Contents/Resources/Java/libraries/EmonLib/EmonLib.h:391: error: stray '#' in program
/Applications/Arduino101.app/Contents/Resources/Java/libraries/EmonLib/EmonLib.h:391: error: stray '#' in program
/Applications/Arduino101.app/Contents/Resources/Java/libraries/EmonLib/EmonLib.h:489: error: stray '#' in program
sketch_feb16b:33: error: 'Void' does not name a type
In file included from sketch_feb16b.cpp:58:
/Applications/Arduino101.app/Contents/Resources/Java/libraries/JeeLib/JeeLib.h:4: error: expected unqualified-id before '<' token
/Applications/Arduino101.app/Contents/Resources/Java/libraries/JeeLib/JeeLib.h:389: error: expected constructor, destructor, or type conversion before '<' token
/Applications/Arduino101.app/Contents/Resources/Java/libraries/JeeLib/JeeLib.h:421: error: expected constructor, destructor, or type conversion before '<' token
/Applications/Arduino101.app/Contents/Resources/Java/libraries/JeeLib/JeeLib.h:423: error: expected constructor, destructor, or type conversion before '<' token
/Applications/Arduino101.app/Contents/Resources/Java/libraries/JeeLib/JeeLib.h:430: error: expected unqualified-id before numeric constant
sketch_feb16b.cpp: In function 'void __vector_12()':
sketch_feb16b:53: error: 'Sleepy' has not been declared
In file included from sketch_feb16b.cpp:62:
/Applications/Arduino101.app/Contents/Resources/Java/libraries/EmonLib/EmonLib.h: At global scope:
/Applications/Arduino101.app/Contents/Resources/Java/libraries/EmonLib/EmonLib.h:4: error: expected unqualified-id before '<' token
/Applications/Arduino101.app/Contents/Resources/Java/libraries/EmonLib/EmonLib.h:391: error: expected constructor, destructor, or type conversion before ';' token
/Applications/Arduino101.app/Contents/Resources/Java/libraries/EmonLib/EmonLib.h:391: error: expected unqualified-id before numeric constant
/Applications/Arduino101.app/Contents/Resources/Java/libraries/EmonLib/EmonLib.h:391: error: expected unqualified-id before '=' token
/Applications/Arduino101.app/Contents/Resources/Java/libraries/EmonLib/EmonLib.h:391: error: expected constructor, destructor, or type conversion before '.' token
/Applications/Arduino101.app/Contents/Resources/Java/libraries/EmonLib/EmonLib.h:391: error: expected unqualified-id before '<' token
/Applications/Arduino101.app/Contents/Resources/Java/libraries/EmonLib/EmonLib.h:391: error: expected constructor, destructor, or type conversion before '.' token
/Applications/Arduino101.app/Contents/Resources/Java/libraries/EmonLib/EmonLib.h:391: error: expected unqualified-id before '<' token

boelle's picture

Re: advice for monitoring water meters? [Closed]

sorry for the crossposting....

 

i got a heads up on the errors and will add the missing .cpp

 

and will check if water messurement is done right... but heads up on that are welcome

boelle's picture

Re: advice for monitoring water meters? [Closed]

i thank Robert Wall for the heads up...

My errors are now down to this little:

sketch_feb16b.cpp: In function 'void setup()':
sketch_feb16b:113: error: 'bootloader' was not declared in this scope
sketch_feb16b.cpp: In function 'void loop()':
sketch_feb16b:160: error: 'send_rf_data' was not declared in this scope
sketch_feb16b:164: error: 'emontx_sleep' was not declared in this scope

i assume its because i have yet to figure which emontx_lib.ino to use (found a lot of them)

Other files in project directory (should appear in the arduino tabs above)
        - emontx_lib.ino

The org sketch comes from here: http://openenergymonitor.org/emon/node/1170 and the only link was to the sketch itself

boelle's picture

Re: advice for monitoring water meters? [Closed]

found the file... just there are 6 copies in the firmware zip... each seems a bit different...

EDIT: 2 of them are the same, so 5 different versions... the 2 first files are excatly the same, the rest are just subversion so to speak.. some lines are commented out in one version and in the others other lines are commented out.  still i dont know which one the author intended to use

boelle's picture

Re: advice for monitoring water meters? [Closed]

thinking about adding a infrared serial port to read my heat meter...

have looked at the schematics and to me it seems that there are no free pins on the chip... or have i missed something?

if i have not what would be the most wise to do? i was thinking about using the pin for temp prope since i do not plan to use it anyway and maybe one of the CT jack ports

since i intend to copy the full 3 phase system i only use 1 CT probe and the pulse input on the master

if its total undoable i do have an mega on the shelf that could be used to read the heat meter and send to the emonbase

boelle's picture

Re: advice for monitoring water meters? [Closed]

all problems sorted for so far... except one:

sketch_feb16b.cpp: In function 'void setup()':
sketch_feb16b:113: error: 'bootloader' was not declared in this scope

but with this little my head have moved forward... is it possible with simple small hacks to add a serial port?

sketch attached, if any erros please let me know

Robert Wall's picture

Re: advice for monitoring water meters? [Closed]

That error is telling me that the compiler thinks there is a variable (or a function) called "bootloader" that has not been declared or defined.  I do not think there is a such a thing. ":113" means that at line 113, the compiler knew there was an error. The error might be that line or somewhere before that. What does line 113, or the line or lines that come immediately before it, look like?  Do they look correct? Is something obviously wrong?

How did you obtain the file? I did warn you not to copy off the screen, but to download a "Raw" file or a "Zip" file from Github. If you must copy off the screen, you must make sure you do not create new lines where the screen image wraps around.

(I can see what your problem is, I am trying to teach you how to find it for yourself, and how to avoid the problem next time).

Look at the Community section http://openenergymonitor.org/emon/node/626 for information about reading serial data from a meter.

boelle's picture

Re: advice for monitoring water meters? [Closed]

dooh... i got the code from here: http://openenergymonitor.org/emon/sites/default/files/emonTx_CT123_Volta...

then i added the sections from the pulse count examples (modded to count water instead)

of course in the first link the bootloader statement is not even there and should not be even if i add pulse count... (in fact its not even in the pulse count example found here: http://openenergymonitor.org/emon/emontx/firmware/writing-code-for-the-e...

So now the big mystery is just where i found the bootloader line

 

 

boelle's picture

Re: advice for monitoring water meters? [Closed]

i read the post at http://openenergymonitor.org/emon/node/626

only thing is that i does not descripe how to connect the ir sender and ir photo transistor

i allready have a arduino code spec for my meter and how to connect IR stuff... i only miss how to hook up the IR stuff to the imontx... i assume that it requires that there are free pins or that there are unused jacks.. in my case i know that i will only use one CT jack

MartinR's picture

Re: advice for monitoring water meters? [Closed]

So now the big mystery is just where i found the bootloader line

It's not that big a mystery, Robert gave you a very big hint above. Try searching for "bootloader" in the original code and you should see where it came from. You must have added the semicolon your self so that should have given you a clue.

It seems to me that you are well out of your depth here and are trying to do something quite difficult before you have mastered the basics. It's always best to take small steps when you aren't sure exactly how things work. e.g. get the original code to compile before you try to modify it.

 

boelle's picture

Re: advice for monitoring water meters? [Closed]

oh yeah... forgot about my meter... compared to the elster meter mine does not transmit anything before it has gotten a request... hence there is a need for 2 pins.. one for tx and one for rx.

i have attached the sketch (not made by me) for my heat meter... it was org written to just output the data and a set interval. It will need to be reduced in what data is sent, i only need total energy since you can always calc what has been consumed each poll.

boelle's picture

Re: advice for monitoring water meters? [Closed]

well it might seems that i stand in water to my nose... programming has never been my strong side, but i have made an arduino base gsm remote to control my pre-heater in the car.. only problem there is that the gsm shield sometimes loose connection to the gsm network... but i just need to figure some code that can check the blink freq and reset the gsm module it the reception LED blinks to fast.

so in other words i can hack together code... even thou sometimes i need a lot of help...

boelle's picture

Re: advice for monitoring water meters? [Closed]

*see's the light*

now i got it... indeed i have put in a semicolon the wrong place... but yes, i agree... start with the org code as is before start modding it...

i was just a bit to fast... like the idea of the project so much that i dont take time to sit back and understand first (a weakness of mine)

boelle's picture

Re: advice for monitoring water meters? [Closed]

think i got most of the sketch done...

as i have a mega on the shelf i wanted to use that as a play-a-round platform... but how do i change pin mapping... i guess in the emontx_lib.cpp but the only thing i could find there is:

//--------------------------------------------------------------------------------------
// Sets the pins to be used for voltage and current sensors based on emontx pin map
//--------------------------------------------------------------------------------------

since i plan to use 3 phase i will need the emontx in the end but wanted to fault check my sketch first.

boelle's picture

Re: advice for monitoring water meters? [Closed]

hmm... have been thinking about this since my last post

since i got a mega could i use 3 shields (one with rf) and stack them all on top of each other?

boelle's picture

Re: advice for monitoring water meters? [Closed]

been comparing the schematics for the emontx and the arduino mega 2560.. i can compare all the pin names on the atmega chips so i guess i don't need to change the library's but just connectt the right places...

the only thing i cant figure is how i change the library so it can work with 3 ac inputs at the same time... (so i get each phase more accurate)

 

EDIT: of course this all means i have to make a shield myself... unless i can use the emontx shield and just stack them..

boelle's picture

Re: advice for monitoring water meters? [Closed]

hmm.. building a shield is not that hard....

 

but where do i find port maps etc? i would need that to change the pins from what's used on an uno to what an mega has

boelle's picture

Re: advice for monitoring water meters? [Closed]

Almost ready with the schematic... just need to figure what pins on an mega board i will have to connect the imputs to so that i can use the library's without having to change them much

 

about the lib's.. i know i can messure current with one CT and one 9V AC... but how do i go about 3 CT's and 9V AC for each CT but on same board sketch?

can i just match the pin names on an uno with the pin names on a mega or is there more to it than that?

boelle's picture

Re: advice for monitoring water meters? [Closed]

Attached is a draft for an EmonTX Shield for the Arduino Mega.

The end goal / Idea is to have a shield that has full 3 Phase input (not just 1 9VAC input), Input for Water Meter (Pulse) and Infra Red Port for Meters that do coms that way...

Suggestions Ideas are more than welcome

Only thing that could have been done wrong is what pin each input is connected to. I have done my best to match pin names from the emontx chip to what i can read on a schematic for the mega

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.