Getting places with gas meters, reed switches and ESP2866/NodeMCU/Lua

I've had a free weekend, so I finally decided to sit down and properly hammer out measuring pulses from my gas meter.

Originally I was going to build a 433mhz transmitter - either one of Nathan Chantrell's tinyTXs, or one of Martin Harizanov's FunkyV2s..These would connect to my Pi and use NodeRED to spit the data toward emoncms. 

A couple of months back the internet was awash with stories of these super cheap ESP2866 wifi enabled chips.. You could plug them into your Arduino projects, send them AT commands and do all kinds of amazing things.. Someone clever figured out how to flash a Lua interpreter onto these chips, so it seemed reasonable to try doing away with the Pi 433mhz middleman and connect directly to emoncms over wifi.

If anyone is interested in playing with these chips theres an awesome getting started guide written by Peter Jennings on Benlo.com.

So, connected to a breadboard I have a couple of resistors, a long wire that goes out to the reed switch near the meter and the ESP2866.

The following code is pretty hacky for now. But pretty bullit-proof. It counts pulses connected to GPO2, saves this count to flash - saving I discovered was important because NodeMCU has a tendency to crash and restart randomly. On each pulse the properly formatted URL is sent to emoncms... My gas in measured in 0.01 increments, but NodeMCU's Lua implementation isn't that good at rounding floating point numbers (the type "float" didn't exist at all in this implementation till around a month ago), so I chose to count in integers and covert to a string with a decimal point before sending it to emoncms. Finally it also runs a little webserver so you can connect to it, see the current gas meter count and change it without having to reconnect the ESP2866 to your PC and edit the source's "count" variable.

count = 0
delay = 0
tempstr = ''
convertedfloat = ''

gpio.mode(4,gpio.INT,gpio.PULLUP)

srv=net.createServer(net.TCP)
 
srv:listen(80,function(conn)
    conn:on("receive",function(conn,payload)
    
    if string.find(payload,"newgascount=") ~= nil then
        if string.find(payload,"send") ~= nil then    
            file.open("counter.lua", "w+")
            file.writeline(string.sub(payload, 13, 19))
            file.close()
        end
    end

    file.open("counter.lua", "r")
    count = file.readline()
    file.close()
    conn:send('<html>Enter gas meter reading and press "send" to reset the counter<br>'(format XXXXXXX - no decimal)'
        ..'<form method="POST" name="gas_meter" >'
        ..'<p><input name="newgascount" value="" maxlength="7" size="7"></p>'
        ..'<p><input type="submit" name="lo" value="send" /></p>'
        ..'Current Meter Value: '..count..'</form></body>')
    collectgarbage()
end)

conn:on("sent",function(conn) conn:close() 
end)

end)

function counter(level)
    conn = nil
    conn = net.createConnection(net.TCP, 0)
    x = tmr.now()
    if x > delay then
        delay = tmr.now()+250000

        file.open("counter.lua", "r")
        count = file.readline()
        file.close()        

        count = count + 1
        tempstr = tostring(count)
        convertedfloat = string.sub(tempstr, 1, 5)..'.'..string.sub(tempstr, 6, 7)
        
        file.open("counter.lua", "w+")
        file.writeline(count)
        file.close()

        conn:on("receive", function(conn, payload) 
        end)

        conn:on("connection", function(conn, payload) 
            conn:send("GET /input/post.json?json={gas:"..convertedfloat.."}&apikey=XXXXXXXXXXXXXXXXXXXXXXXXXXX "
            .." HTTP/1.1\r\n" 
            .."Host: emoncms.org\r\n"
            .."Connection: close\r\n"
            .."Accept: */*\r\n" 
            .."User-Agent: Mozilla/4.0 (compatible; esp8266 Lua; Windows NT 5.1)\r\n" 
            .."\r\n")
            print("http://emoncms.org/input/post.json?json={gas:"..convertedfloat.."}&apikey=XXXXXXXXXXXXXXXXXXX")
        end) 

        conn:on("disconnection", function(conn, payload) 
        end)

        conn:connect(80,'80.243.190.58')
    end
end

gpio.trig(4, "down",counter)

So there you have it, it's do-able! Any suggestions to getting the best data out of my counter? Is sending an actual pulse-count the best way to go?

Thanks!

 

zhivko's picture

Re: Getting places with gas meters, reed switches and ESP2866/NodeMCU/Lua

Are you really using NodeMCU?

Is reset pin connected to 3.3V via 10k resistor? I also have found that resets are usual if reset is left floating.

mrgreedy's picture

Re: Getting places with gas meters, reed switches and ESP2866/NodeMCU/Lua

I'm really trying to use NodeMCU yes. I say "try". Because it's buggy as hell. That was the initial reason for saving the count to a file every pulse - and having a webserver to change the count.

I've not really had a chance to play with this over the last couple of weeks. I was getting weird resetting behaviour, so I flashed the chip to the latest firmware - that broke its webserving abilities - so I naturally lost interest.

I've finally found a version of NodeMCU that seems pretty stable so I'll put the thing all back together at try it for a day in situ when I can.

I've not got the reset pin connected to anything, actually. I'll try this too.

I'd ordered an ESP07 from China ages ago, and that finally arrived, so I've been soldering legs on that - it's got more exposed GPIOs (which is helpful because on the ESP01 connecting GPIOs to ground at boot time puts the chip into reflash mode).

So I've got:

VCC -> 3.3v

CH_PD -> 3.3v

GND -> gnd

GPIO15 -> 10k resistor on one side and my reed switch which is connected to 3.3v on the other

The ESP07 needs GPIO15 to be connect to ground at boot for the LUA interepter to start. So this works well for me.

I'lll deffo try the reset pin thing. And post my findings (and slightly better code) later.

Thanks!

zhivko's picture

Re: Getting places with gas meters, reed switches and ESP2866/NodeMCU/Lua

Definetely try to connect reset pin to VCC, I remember some guys reported that they were able to reset esp8266, just by moving hand over rst pin. I haven't experienced any resets -  I have esp07 module bought from banggood - and reset is connected to VCC.

socket's picture

Re: Getting places with gas meters, reed switches and ESP2866/NodeMCU/Lua

Hello,

I launched the code on my ESP but I am getting an error. The server works fine and I am able to update the counter value but when getting new pulses the error below appears:

-------------------------------------------------

Config done, IP is 192.168.1.193
PANIC: unprotected error in call to Lua API (serv.lua:48: attempt to perform arithmetic on global 'count' (a string value))
PANIC: unprotected error in call to Lua API (attempt to call a nil value)

----------------------------------------------

The line 48 is around the function couner:

 

----------------------------------------------------------------

function counter(level)
    conn = nil
    conn = net.createConnection(net.TCP, 0)
    x = tmr.now()
    if x > delay then
        delay = tmr.now()+250000

        file.open("counter.lua", "r")
        count = file.readline()
        file.close()        

        count = count + 1
        tempstr = tostring(count)
        convertedfloat = string.sub(tempstr, 1, 5)..'.'..string.sub(tempstr, 6, 7)

---------------------------------------------------------------------------------------------------------------

I searched for the error message in google but nothing helps. Do you know what could be wrong with this?

Thank you !

Regards

Tom

 

socket's picture

Re: Getting places with gas meters, reed switches and ESP2866/NodeMCU/Lua

Finally I have found the root cause of this issue. When uploading the value of the counter from the website it has been saved with the "&" string on the end of the value. That is why when performing arithmetic operation I am getting error "attempt to perform arithmetic on global 'count' (a string value))".

juanpintom's picture

Re: Getting places with gas meters, reed switches and ESP2866/NodeMCU/Lua

Hi all!, Im tryin to integrate emonlib on ESP wifi module and load it directly with this modified Arduino IDE:

https://github.com/esp8266/Arduino

It's a hard work but this could be useful to make easy wifi nodes, and this can be integrated on Souliss too to see the data etc... Any help and ideas are appreciated. I'll work on it and let you know.

Regards!

Bill Thomson's picture

Re: Getting places with gas meters, reed switches and ESP2866/NodeMCU/Lua

Socket,

Have you tried using the tonumber function on your convertedfloat variable to change it back to a numeric value?

reference: www.lua.org/manual/5.1/manual.html#pdf-tonumber

additional info here: http://stackoverflow.com/questions/20543450/how-to-convert-a-lua-string-to-float

Regards,

Bill

 

DGee's picture

Re: Getting places with gas meters, reed switches and ESP2866/NodeMCU/Lua

Picking up the meter pulses

Is there now a "standard" approach for this?

The options, in the absence of an electrical connection, seem to be based on the rotating magnet inside the gas meter or on the mirrored zero on the right-most digit of the mechanical meter display or on the meter-pulse-flashing LED.

The flashing LED, if there is one, should be fairly simple – use any available photocell to react to its light.

The silver zero is similar except that an illuminating light source is needed. It also seems that some of the packaged photoreflective devices on offer may not work because they need to be mounted very close to the reflector. Is there a recommended device, or a recipe for cannibalising an optical mouse perhaps?

The magnetic approach depends on a pick-up coil, a Hall-effect device or on a reed relay, in each case sensitive enough to respond to the changing magnetic field. Are there recommended devices/circuits? A reed looks to be the cheapest option - 10p for a reed and 2-wire connection.

I note that my gas meter gives my magnetic compass a snappy tug via the magnet – has anyone thought it worth fitting a compass needle with a photoreflective sensor?

ricard0g0mes's picture

Re: Getting places with gas meters, reed switches and ESP2866/NodeMCU/Lua

Any news about this?

I would love to see this working.

I use emoncms to measure my energy with an W5100 and Arduino Nano.

I have to have ethernet cable and would love to get rid of it :D

juanpintom's picture

Re: Getting places with gas meters, reed switches and ESP2866/NodeMCU/Lua

Hi, you can get this working using an Arduino to read the data and the ESP act like a W5100.

On Souliss we've made an example to use both devices on this way connected via UART. Here is an example:

https://github.com/souliss/souliss/wiki/ESP8266%20to%20RS485

Regards

PD. I think it's possible to read a CT sensor with the A0 of the ESP, If someone accomplish this please let me know.

 

ricard0g0mes's picture

Re: Getting places with gas meters, reed switches and ESP2866/NodeMCU/Lua

Yes, with the arduino+esp i know but i wanted to use only one device. ;)

 

solrac76's picture

Re: Getting places with gas meters, reed switches and ESP2866/NodeMCU/Lua

Hello Ricardo 

I have done this in Lua, and is working very well :-) , i am counting pulses with my esp8266 , after 15 minutes it sends the total pulses to emoncms , the esp do a sync with an ntp server to syncronise the own time , so it is sending every 00 , 15, 30,45 minutes , if you need the project i can give it to you.

 

Bramco's picture

Re: Getting places with gas meters, reed switches and ESP2866/NodeMCU/Lua

Solrac,

Why don't you share your code anyway. I'm sure you have reused loads of sections of your code from other people's code.

I would be interested to see how you did the NTP bit for example.

Thanks.

solrac76's picture

Re: Getting places with gas meters, reed switches and ESP2866/NodeMCU/Lua

Hello Bramco, sure i have take take pieces of code from everywhere and have build this for my needs, can you tell me how i can upload this project?, i have 4 lua files.

Init.lua: looks if the esp has a config file where the info is about your router (ssid and password) if yes the program will start , if not it will start a wifi config

wifi config: the Esp will start as Ap you can connect with the esp8266 and call the webserver (IP 192.168.0.1), there you can put your wifi ssid and password, and you can put a node number and api key for your emoncms, after this wificonfig will create a config file, and restart the esp.

run_program: counts the pulses and sends to a emoncms server after every 15 minutes, every hour makes a sync with a ntp server, every second will call a file (berechn.lua) there will convert the unix time in a human time :-) , i am only using the minutes.

Nodemcu has a firmware with an Api for the sntp you can look here https://github.com/nodemcu/nodemcu-firmware/wiki/nodemcu_api_en

I hope maybe we can work together an make it better :-) 

 

Bramco's picture

Re: Getting places with gas meters, reed switches and ESP2866/NodeMCU/Lua

I think you can simply attach the files to a reply to this thread.

solrac76's picture

Re: Getting places with gas meters, reed switches and ESP2866/NodeMCU/Lua

Here are the files, you need a node mcu Firmware with this api modules: node,file,gpio,wifi,net,tmr,uart,ow,dht,rtctime,sntp

 

fluppie007's picture

Re: Getting places with gas meters, reed switches and ESP2866/NodeMCU/Lua

http://www.esp8266.nu/index.php/PulsCounter

https://github.com/ESP8266nu/ESPEasy​

Don't know if it's reliable enough.

 

solrac76's picture

Re: Getting places with gas meters, reed switches and ESP2866/NodeMCU/Lua

Thanks fluppie , you haved make a nice work , but i think we are here talking about Esp8266 with Lua , sending data to Emoncms.

Comment viewing options

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