Gas meter

The gas meter was more of a challenge. Unfortunately our meter has no magnetic field and also no mirror on any of the digits… hmmm… a bigger challenge.

After some seaching on the net I didn’t find any answers to ‘solve’ my problem. Calling the gas company for a new meter wasn’t really an option seeing that there will be costs related to this.

I put my IR sensor (CNY 70) in front of the 2nd digit to see if I get a decent reading, but after some trial and error I came to conclusion that it wasn’t workable.

Next thought I had was to dril a small hole in the plastic cover and then using some superglue to glue some silver foil on 1 of the letters and then read it with the sensor. After a lot of though about this I ended up drilling the hole, but to my surprise there was another thin piece of plastic protecting the numbers of the dial. Hmm…. I thought it is too risky to cut or drill through this as well in case we get meter control and note that I drilled through it all.

But, having a hole in the cover plate did allow me to get the sensor much closer to the 2nd digit. After some testing here I did get some measurements which could be analysed with some code to determine when the digit turns. In the analysis of the numbers when the gas meter was on I noted that for every digit there was a short peak, but the static readings when waiting also varied due to the fact that the reflection on a 1 is different to an 8.

Again after some trial and error I ended up using an array to store the last 10 readings in. Within these 10 reading the peaks for a specific dial change are included. I then compare the minimum and maximum values in the array to determine if the dial is moving.

When the dial settles again the base reading will sending a different value, but by using an array with the last 10 readings and doing a check based on the difference between min & max I get about 95-98% accuracy. For me enough to get some good information for analisys.

The code is included underneath.

#include <Average.h>
#include <Ethernet.h>
#include <SPI.h>
 
EthernetClient client;
 
const int numReadings = 10;
byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0xB4, 0x23 };
char server[] = "yourweb.com"; 
 
String URLdata="";
 
unsigned long lastConnectionTime = 0;         
const unsigned long postingInterval = 600000;
 
int readings[numReadings];// the readings from the analog input
int tempreading[numReadings];
int index = 0;                  // the index of the current reading
int total = 0;
unsigned long standmeter = 3368553;  // stand 04-02-2013
unsigned long tellerinperiode = 0;
int pHigh = 0;
int pLow = 0;
int pDif =0;
boolean counted = false;
int inputPin = A1;
 
void setup()
{
  // initialize serial communication with computer:
  Serial.begin(9600);                   
  // initialize all the readings to 0: 
  for (int thisReading = 0; thisReading < numReadings; thisReading++)
    readings[thisReading] = 0;  
 
   // start the Ethernet connection:
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    for(;;)
      ;
    }
 
  Serial.println("Starting.....");
  delay(5000);  
}
 
void loop() {
  // subtract the last reading:
  total= total - readings[index];         
  // read from the sensor:  
  readings[index] = analogRead(inputPin); 
  Serial.print(readings[index]);
  // add the reading to the total:
  total= total + readings[index];       
  // advance to the next position in the array:  
  index = index + 1;                    
 
  // if we're at the end of the array... wrap to start
  if (index >= numReadings) index = 0;                           
 
  // extract the highest and lowest values from the array
  pHigh=maximum(readings,numReadings),DEC;
  pLow=minimum(readings,numReadings),DEC;
  pDif=pHigh - pLow;
  // send it to the computer as ASCII digits
  Serial.print("  " );   
  Serial.println(pDif);
  if (pDif >= 8 && !counted) {
        tellerinperiode+=1;
        counted=true;
        Serial.println(tellerinperiode+standmeter);
        Serial.print(readings[index-1]);   
        Serial.print("  " );   
        Serial.print(" Max: ");
        Serial.print(pHigh);   
        Serial.print("  " );   
        Serial.print(" Min: ");
        Serial.print(pLow);   
        Serial.print("  " ); 
        Serial.print(pHigh - pLow);   
        Serial.print("  " ); 
        Serial.print(millis()); 
        Serial.println("  " ); 
  }
  if (counted && pDif <= 3)
  {
    counted=false;
  }
  delay(300);   // delay in between reads for stability   
 
    // check to see if time has lapsed before recording
  if(millis() - lastConnectionTime > postingInterval){
    standmeter+=tellerinperiode;
     sendData();
  }
}

To implement I used the following;

  • breadboard
  • CNY 70 sensor
  • about 4 kohm resistors
  • some wires (4 from sensor to breadboard, 3 from breadboard to arduino

I played around with how many kohm I required to get decent data to read. I only had loose ones lying around, so that why picture shows 4 of them :).

Some pictures of the setup;

IMAG0468 IMAG0467 IMAG0466 IMAG0470

 (you also see some extra wires for the temp sensors which I process on this arduino)