Introduction: Electricity, Water and Centralized Heating Meter Readout Using Arduino, WR703N Router and Linux Webcams

Files describe how to move towards smart home and make readout system  for energy and water meters.

- Optical sensor reading out Electricity meter disk. Works well. Live at

- Webcam picturing hot water meter. LCD screen contrast too low for OCR.

- Control of hot water supply valve using Arduino and servo motor.

- Webcam picturing  cold water meter. OCR or optical readout sensor will come.

Please have a look at  system live here:


goran.lundquist.96 made it! (author)2014-12-18

I have previously tried to read the water meter using a phototransistor and a IR diode, but have not managed to get it hundred percent stable.

Instead, I have now used a little more technically challenging solution but it works perfect.

I use a webcam and calculates one of the dialers position and movements.

The solution consist of:

- A webcam with USB connection.

- Two white LEDs. Used to have a constant uniform illumination of the meter.

- A Raspberry Pi with some image processing software.

I have adapted this opensource software to my camera and this specific application.

The Raspberry Pi is managing to read and process approx 10 frames per second. I have defined four zones in the image and keeps track of when these zones goes from light to dark when the dial passes. My dial makes one revolution per liter of water so it will be a resolution of 0.25 liters.

Attached is it a couple of pictures and a video that shows how it looks like in practice.

" frameborder="0" allowfullscreen>


Hello Goran!

You made a great comment and demonstration. It could become a popular instructable, if you publish it in Instructables.

Thanks for the image processing link. I will look at it closer how to use and compile it. And would be happy to get some help from you if get stuck.

I am presently experimenting with dust in air sensing using strong laser light that is scatered by dust and photographed by a webcam. Image recognition would be needed to count bright spots.

fxspaet (author)2013-03-30

Thank you for your instructable. My electricity meter readout system works pretty good now.

List of used parts:
+ IR reflection light sensor MRL601
+ transistor 2N2222
+ breadboard, some resistors, LED, clamps, wires, ...
+ mini WLAN router T-Link TL-MR3020
+ USB hub with integrated micro SD card reader
+ micro SD memory card

The CNY70 light sensor couldn't recognise the red mark on the wheel. Although expensive the MRL601 sensor does this very well if it is mounted in a certain angle. I copied the OpenWrt installation to the SD card (extroot) to have more available memory. My code is written in python. I dropped the debounce check which seems not to be necessary here. RRDtool rocks!

mahirsmart (author)fxspaet2013-09-03

hello mr fxspaet...your electricity meter readout system how its work can explain about it or if u can give a document ? what are the thinks need to do this system? please help me ....

janisalnis (author)fxspaet2013-03-30

Thanks for sharing info about what you use.

Python is a nice language but of course needs much space. I got a problem with SD card after some 3 months. Ca 150k write cycles. And now send data away (without writing to SD) to some real server with a HDD.
Writing in RAM is OK. and creating rrdtools plots in RAM is OK.

Unfortunately, I could not figure out how to save absolute meter readings. (Arduino counter values are lost after power reset). Arduino has EEPROM but it has limited write cycles. May be could save not every turn but once a full kW is used.

fxspaet (author)2013-04-19

I played around with RRDtool and found a solution to get absolute (or cumulative) meter readings saved and plotted. Let me sketch it here.

The Python script running on TL-MR3020 creates a second data base cumulative.rrd:

def midnight():
    ts = datetime(1970, 1, 1)
    t = datetime.utcnow()
    td = datetime(t.year, t.month, - ts
    return int(td.total_seconds())

def createCumulativeRrd():
    rrd = RRD('cumulative.rrd',
        # heartbeat: at 20 watt it takes 2400 seconds for 1 revolution
        #            75 rev/kWh * 0.02 kWh = 1.5 rev/h
        #            3600 sec/h / 1.5 rev/h = 2400 sec/rev
        #            2400 sec/rev * 1 rev/update = 2400 sec/update = 40 min/update
        ds = [DataSource(dsName = 'revolutions', dsType = 'GAUGE', heartbeat = 2400)],
        # steps: take 6 steps to calculate 1 new data point in archive
        #        600 sec/step * 6 step/point = 1 h/point
        # rows: store data points in archive for a maximum of 366 days
        #       1 h/point * 1 point/row * 8784 row/archive = 366 day/archive
        rra = [RRA(cf = 'LAST', xff = 0, steps = 6, rows = 8784)],
        start = midnight() - 10,
        # calculate a step every 10 minutes = 600 seconds
        step = 600)
    return rrd

Remaining Python code which cummunicates with Arduino board and filles in data bases is omitted here for brevity. It resets the counter at midnight which is useful for plotting later.

The following shell script plots the graph:


# first argument specifies the number of days in the past and is optional
if [ -z "${1}" ]
    # for today
    # for number of days in the past

# date formatted as YYYY-MM-DD
day=$(date -d "today0${offset}" +%F)

# delete old image
rm -f cumulative-daily-${day}.png

# calculate time range in whole days
start=$(date -d "today0${offset}" +%s)
end=$(date -d "today0+24hours-1secs" +%s)

# create new image from RRD file
# + scale image to 1600 x 800 px
# + put title on top
# + left scale is kWh (kilo Watt hour)
# + bottom line is always at 0
# + plot data between this time range
# + fetch data from RRD file and name it rev (revolutions)
# + create new data points kWh: 75 revolutions are 1 kWh
# + draw kWh using a 2 px thick line in red color
rrdtool graph cumulative-daily-${day}.png \
    --width 1600 --height 800 --full-size-mode \
    --title "Electricity Consumption - Cumulative For Each Day - Starting At ${day}" \
    --vertical-label "kWh" \
    --lower-limit 0 \
    --start=${start} --end=${end} \
    DEF:rev=cumulative.rrd:revolutions:MAX \
    CDEF:kWh=rev,75,/ \

# display image on desktop
feh cumulative-daily-${day}.png

Have fun! :)

janisalnis (author)fxspaet2013-04-20

Liked a lot your idea for cumulative representation of daily data. Then can immediately see which day used more current.

fxspaet (author)2013-04-02

Well, you're right. Python requires lots of RAM. However it is a powerful tool and apparently the TL-MR3020 box has enough RAM for running Python.

Thank you for the hint about the wear out of SD cards. Hence I reduced the writes to the SD card. Fortunately the PyRRD wrapper supports data buffering already. Now the Python script buffers the data for one kilowatt in RAM till it updates the RRD archive file in flash memory of the SD card.

(Sorry for answering here but the captcha in the Reply section didn't work...)

vturkovic (author)2012-07-11

Here are some info how to use tesseract to OCR only numbers:


vturkovic (author)2012-07-09

I took photos of my gas meter and then tested all ocr engines that I could find, after doing that I got to my conclusion.

vturkovic (author)2012-07-09

After doing some research I found out that best OCR engines on Linux are tesseract and gocr

vturkovic (author)2012-07-09

Can't wait for OCR part!

About This Instructable




Bio: I am a researcher working on development of optical atomic clocks. Electronics is my hobby since childhood when my uncle was bringing me old phones ... More »
More by janisalnis:Arduino Webservers Ethernet ENC28J60 with thermometer DS18B20, I2C LCD and Power Over Ethernet POE  for ZABBIX IOT data loggingMini-spectrometer From a DVD and Folded Paper1 single digit Nixie clock
Add instructable to: