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;