Closed ameeuw closed 7 years ago
Not sure whether you're suggesting this be a bug as you also posted on Stack Overflow at http://stackoverflow.com/q/39095456/131929. Potentially related to #1012.
Not sure whether its a bug or a feature. I would expect a function to explicitly read out the UART buffer when a certain amount of bytes are available, not just after \r\n has been received.
Problem solved: uart.on takes an additional parameter whether to only process input after \r or \n, or to listen the amount of bytes. Thank you Marcel.
Great you got it solved but I don't understand. Your initial code already does use the number-of-characters variant (uart.on('data', 9,
) rather than the stop-char variant (uart.on('data', '\r',
or so).
Hi, everyboday!
Now I am facing a very hard problem, even make the whole day confusion on my mind, as folllows:
I want to read CO2 and PM2.5 value from sensors which are connected with UART. But I found that the received data were sometimes right and sometimes wrong, e.g. PM2.5 received data: 22 17 11 0 0 2 245 0 0 2 249 0 0 2 240 2 0 0 3 229 In my code, I just judged the existing "22" in the received data, then the pm2.5 could be calculated using the formulation. However, the data absolutely were wrong, PM2.5 = 757. The correct data were: received data: 22 17 11 0 0 0 28 0 0 0 28 0 0 0 25 0 0 0 3 122, the reasonable value is PM2.5 = 28. The bold numbers above made a big difference in some time, especially I downloaded the code into me device with plugging off the USB, making it operation under the battery.
Maybe some guys could help me to find my code where I made a big mistake to make it happen.
`function measure(num, switch)
local tem = switch uart.on("data", num, function(data) switch = 0 uart.on("data") uart.alt(0) uart.setup(0, 115200, 8, uart.PARITY_NONE, uart.STOPBITS_1, 1)
print("receive from uart:", data)
print("received data:", string.byte(data, 1, num))
print("tem", tem)
if num == 20 then
pm25_i = 1
while(pm25_i < num)
do
pm25_a = string.byte(data, pm25_i)
if pm25_a == tonumber('16', 16) then
pm25_b = tonumber(string.byte(data, pm25_i - 1 + 7), '10') --+ string.byte(data,5) * math.pow(2,8) + string.byte(data,4) * * math.pow(2,16) + string.byte(data,5) * * math.pow(2,24)
pm25_c = tonumber(string.byte(data, pm25_i - 1 + 6), '10')
pm25_e = tonumber(string.byte(data, pm25_i - 1 + 5), '10')
pm25_f = tonumber(string.byte(data, pm25_i - 1 + 4), '10')
qiaqia_pm25 = pm25_b + bit.lshift(pm25_c, 8) + bit.lshift(pm25_e, 16) + bit.lshift(pm25_f, 24)
m:valuechange("4", qiaqia_pm25)
print(qiaqia_pm25)
break
end
pm25_i = pm25_i + 1
end
end
if num == 9 then
co2_i = 1
while(co2_i < num)
do
co2_a = string.byte(data, co2_i)
co2_b = string.byte(data, co2_i + 1)
if co2_a == tonumber('ff', 16) and co2_b == tonumber('86', 16) then
co2_c = tonumber(string.byte(data, co2_i + 2), '10')
co2_d = tonumber(string.byte(data, co2_i + 1), '10')
qiaqia_co2 = bit.lshift(co2_c, 8) + co2_d
m:valuechange("3", qiaqia_co2)
print(qiaqia_co2)
break
end
co2_i = co2_i + 1
end
end
end, 0)
if switch == 1 then
uart.alt(1)
uart.setup(0, 9600, 8, uart.PARITY_NONE, uart.STOPBITS_1, 0)
pin = 10
gpio.mode(pin,gpio.OUTPUT)
gpio.write(pin,gpio.LOW)
uart.write(0, 0xff, 0x01, 0x86, 0, 0, 0, 0, 0, 0x79)
end
if switch == 2 then
uart.alt(1)
uart.setup(0, 9600, 8, uart.PARITY_NONE, uart.STOPBITS_1, 0)
pin = 10
gpio.mode(pin,gpio.OUTPUT)
gpio.write(pin,gpio.HIGH)
uart.write(0, 0x11, 0x02, 0x0B, 0x01, 0xE1)
end
end
awp = 1
tmr.alarm(1, 2000, 1, function()
if awp == 1 then
measure(9, 1)
awp = 0
elseif awp == 0 then
measure(20, 2)
awp = 1
end
end)`
Thanks so much!
Intro
I am currently writing drivers for indoor air quality sensors (CO2 and particulate matter) in lua for the NodeMCU firmware.
The sensors are connected via the alternative UART pins GPIO13/15. On issuing a measure command, the ESP switches uart.alt(1) and registers a uart.on("data", 9, ...) function for firing after nine bytes are received. I have tested this with two ch340 connected to native and alternative UART pins. The reading of the values is fine if i manually enter the data and add \r\n (0d 0a).
However my used sensors do not have \r\n at the end of their replies - how can I change my code to read out the UART buffer after 9 bytes received?
Expected behavior
uart.on('data', 9, function(data) print(data) end) firing after 9 bytes of received UART data.
Actual behavior
uart.on('data', 9, function(data) print(data) end) only fires after 9 bytes + \r\n
Test code
Here is the particular part of my code:
NodeMCU version
1.5.1
Hardware
ESP12F Witty Boards & MH-Z19 CO2 sensor