nodemcu / nodemcu-firmware

Lua based interactive firmware for ESP8266, ESP8285 and ESP32
https://nodemcu.readthedocs.io
MIT License
7.67k stars 3.13k forks source link

bmp/bme280 first read #1994

Closed johndoe71rus closed 7 years ago

johndoe71rus commented 7 years ago

First read data bmp/bme280 get error

dofile("bmp280.lua") bmp280.lua:7: bad argument #2 to 'format' (number expected, got nil) stack traceback: [C]: in function 'format' bmp280.lua:7: in main chunk [C]: in function 'dofile' stdin:1: in main chunk

all next readings correct. I have bme280 and bmp280, check booth.

Code http://paste.ubuntu.com/24710875/ logs http://paste.ubuntu.com/24711075/

i can wait long time to start script. Problem only with the first reading. After power up

marcelstoer commented 7 years ago

I can confirm that. Just ran into this yesterday.

devsaurus commented 7 years ago

What is returned by init()? Should be nil in the error case.

marcelstoer commented 7 years ago

My test bed is really simple (snippet from our examples). Note that I'm on the 1.5.4 branch while the OP tests against https://github.com/nodemcu/nodemcu-firmware/tree/22e1adc4b06c931797539b986c85e229e5942a5f i.e. doesn't have your #1887 changes yet.

print(bme280.init(6, 7))

H, T = bme280.humi()
print(string.format("T=%d.%02d", T / 100, T % 100))
print(string.format("humidity=%d.%03d%%", H / 1000, H % 1000))

Run for the 1st time right after power up this yields

2 -- i.e. it's a BME280
stdin:1: attempt to perform arithmetic on global 'T' (a nil value)
...

NOT running bme280.init() again but only querying the sensor for humi after that works fine.

devsaurus commented 7 years ago

Maybe you hit the initial measurement phase with the read commands. Does it help anything to insert a ~100-200ms delay between init() and humi()?

marcelstoer commented 7 years ago

A delay of even 10ms fixes this for me:

print(bme280.init(6, 7))

tmr.create():alarm(10, tmr.ALARM_SINGLE, function()
    local H, T = bme280.humi()
    print(string.format("T=%d.%02d", T / 100, T % 100))
    print(string.format("humidity=%d.%03d%%", H / 1000, H % 1000))
end)

Is there a sensible way for the module to correct this internally or do we just need to document this behavior?

devsaurus commented 7 years ago

The delay depends on the selected oversampling rates (ref. chapter 9.1 in the BME280 datasheet) and varies between some tens to hundreds of milliseconds. I think the user script should at least get a chance to spend the time with something more meaningful than waiting. So I'd vote for the doc solution (and have consistent examples which poll after init until data is delivered).

eyaleb commented 7 years ago

I expect that the correct way to handle this is to check the status register (0xF3) for zero after a forced read or after a cold start.

johndoe71rus commented 7 years ago

So, "universal" code looks like this?


alt=217 -- altitude of the measurement place
mode = nil
mode = bme280.init(5, 4)
tmr.create():alarm(200, tmr.ALARM_SINGLE, function()
if mode == 1 then
    print("bmp280")
    T, P, H, QNH = bme280.read(alt)
    local Tsgn = (T < 0 and -1 or 1); T = Tsgn*T
    print(string.format("T=%s%d.%02d", Tsgn<0 and "-" or "", T/100, T%100))
    print(string.format("QFE=%d.%03d", P/1000, P%1000))
    print(string.format("QNH=%d.%03d", QNH/1000, QNH%1000))
    MHG = P / 133,3
    print(string.format("pressure = %d.%02d", MHG/10 , MHG%10))
    -- altimeter function - calculate altitude based on current sea level pressure (QNH) and measure pressure
    P = bme280.baro()
    curAlt = bme280.altitude(P, QNH)
    local curAltsgn = (curAlt < 0 and -1 or 1); curAlt = curAltsgn*curAlt
    print(string.format("altitude=%s%d.%02d", curAltsgn<0 and "-" or "", curAlt/100, curAlt%100))
elseif mode == 2 then
    print("bme280")
    T, P, H, QNH = bme280.read(alt)
    local Tsgn = (T < 0 and -1 or 1); T = Tsgn*T
    print(string.format("T=%s%d.%02d", Tsgn<0 and "-" or "", T/100, T%100))
    print(string.format("QFE=%d.%03d", P/1000, P%1000))
    print(string.format("QNH=%d.%03d", QNH/1000, QNH%1000))
    MHG = P / 133,3
    print(string.format("pressure = %d.%02d", MHG/10 , MHG%10))
    print(string.format("humidity=%d.%03d%%", H/1000, H%1000))
    D = bme280.dewpoint(H, T)
    local Dsgn = (D < 0 and -1 or 1); D = Dsgn*D
    print(string.format("dew_point=%s%d.%02d", Dsgn<0 and "-" or "", D/100, D%100))
    -- altimeter function - calculate altitude based on current sea level pressure (QNH) and measure pressure
    P = bme280.baro()
    curAlt = bme280.altitude(P, QNH)
    local curAltsgn = (curAlt < 0 and -1 or 1); curAlt = curAltsgn*curAlt
    print(string.format("altitude=%s%d.%02d", curAltsgn<0 and "-" or "", curAlt/100, curAlt%100))
else
    print("no device")  
end
end)
johndoe71rus commented 7 years ago

i don't know why panic happend paste.ubuntu.com/24891194

paste.ubuntu.com/24891211 sensors.lua first time it go to print("ok") but then panic because P is nil

johndoe71rus commented 7 years ago

I have to replace

bme280.init(bmeSdaPin, bmeSclPin) 

to

i2c.setup(0, sda, scl, i2c.SLOW) -- call i2c.setup() only once
bme280.setup()

?

this work in master or i need dev firmware?

marcelstoer commented 7 years ago

The documentation for the respective branch has the authoritative answers. So either https://nodemcu.readthedocs.io/en/master/en/modules/bme280/ or https://nodemcu.readthedocs.io/en/dev/en/modules/bme280/

-> bme280.init() is deprecated in both branches

johndoe71rus commented 7 years ago

the log http://pastebin.ubuntu.com/25376531/ sensors.lua http://pastebin.ubuntu.com/25376535/

i need new firmware?

marcelstoer commented 7 years ago

Yes, we only support current versions (atm 2.1).

build built on: 2017-04-14 07:36 powered by Lua 5.1.4 on SDK 2.0.0(656edbf)

You could use init instead of setup but since the former is deprecated I wouldn't recommend that.

johndoe71rus commented 7 years ago
NodeMCU custom build by frightanic.com
    branch: master
    commit: b62fae918b3627209fe434950cffb2506cee9a31
    SSL: false
    modules: bme280,file,gpio,i2c,net,node,ow,spi,tmr,uart,wifi
 build  built on: 2017-08-23 16:50
 powered by Lua 5.1.4 on SDK 2.1.0(116b762)
lua: cannot open init.lua
> dofile("initsens.lua")
> Status = 5 (Got IP)
I'm connected to my last network. Launching my real task.
PANIC: unprotected error in call to Lua API (error loading module 'sensors' from file 'sensors.lua':
    sensors.lua:37: malformed number near '0.01')

need help

sorry, wrong version. Need float but the same, first time read

> dofile("initsens.lua")
> Status = 5 (Got IP)
I'm connected to my last network. Launching my real task.
1
fail read alt
fail baro
PANIC: unprotected error in call to Lua API (sensors.lua:36: attempt to perform arithmetic on global 'P' (a nil value))
marcelstoer commented 7 years ago

We gotta stop this, GitHub ain't a support forum, see #1010

ccunarro commented 6 years ago

hi @johndoe71rus , I am getting the same nil response after calling bme.setup(), how did you fix it? Were you using the bme280 with 6 pins? In case so, can you tell me how did you hook it with the nodemcu? thanks.

johndoe71rus commented 6 years ago

@ccunarro now i use this code https://github.com/johndoe71rus/bme280_web/blob/master/files/bmX280.lua the first reading is still nil. But it does not result in a reboot of nodemcu. For 6 pins bme280 i connect only 4 VCC, Gnd, SDA, SCL all works for me