• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Нужна помощь ESP8266 CH340 NodeMcu V3 Lua+MH-Z19B подключение по PWM.

nikolz

Well-known member
Код:
local pin, h, l, co2, TRIGGER_ON, tt = 1, 0, 0, 0, "both", 0
local function mh19Begin(level)
local tt = tmr.now()/1000;
if level == 1 then
      co2 = 5000 * (l-h- 2) / (tt-h - 4); h=tt;
      print("co2", co2)
else
      l = tt;
      print("tt", tt)
      print("h", h)
      print("l", l)
      print("h+l", h+l) 
end
end
   gpio.mode(pin,gpio.INT)
   gpio.trig(pin, TRIGGER_ON, mh19Begin)
Посмотреть вложение 6963
печать надо поставить перед расчетом СО2
и выведите в печать l-h и tt-h
 

SSS_Viva

Member
печать надо поставить перед расчетом СО2
и выведите в печать l-h и tt-h
upload_2018-12-21_13-47-50.png

Код:
local pin, h, l, co2, TRIGGER_ON = 1, 0, 0, 0, "both"
local function mh19Begin(level)
local tt = tmr.now()/1000;
if level == 1 then
      print("tt", tt)
      print("h", h)
      print("l", l)
      print("h+l", h+l)
      print("l-h", l-h)
      print("tt-h", tt-h)
      co2 = 5000 * (l-h- 2) / (tt-h - 4); h=tt;
      print("co2", co2)
else
      l = tt;
    
end
end
   gpio.mode(pin,gpio.INT)
   gpio.trig(pin, TRIGGER_ON, mh19Begin)
 

nikolz

Well-known member
Посмотреть вложение 6965

Код:
local pin, h, l, co2, TRIGGER_ON = 1, 0, 0, 0, "both"
local function mh19Begin(level)
local tt = tmr.now()/1000;
if level == 1 then
      print("tt", tt)
      print("h", h)
      print("l", l)
      print("h+l", h+l)
      print("l-h", l-h)
      print("tt-h", tt-h)
      co2 = 5000 * (l-h- 2) / (tt-h - 4); h=tt;
      print("co2", co2)
else
      l = tt;
 
end
end
   gpio.mode(pin,gpio.INT)
   gpio.trig(pin, TRIGGER_ON, mh19Begin)
все правильно, но точность не повысилась. Сравните с вариантом расчета при Low
еще замечу, что интервал должен быть равен 1000 а получается 998 Полагаю что вместо -4 надо написать +2.
----------------------
надо калибровать датчик
 
Последнее редактирование:

SSS_Viva

Member
все правильно, но точность не повысилась. Сравните с вариантом расчета при Low
еще замечу, что интервал должен быть равен 1000 а получается 998 Полагаю что вместо -4 надо написать +2.
----------------------
надо калибровать датчик
По мне так тоже не правильно, если я все правильно понимаю, то tt это аптайм esp, по даташиту на датчик, у него с начало на выходе 0(что в принципе логично), потом 1, и если считать как ниже, то h будет равно аптайму до перехода с 0 в 1, а это начало импульса., а h это время от перехода с 0 в 1( начало) до перехода с 1 в 0 конец. Если смотреть переход в 0, то первый раз h в себя будет включать период стартового 0+ период первого имульса, что тоже будет не верно.
Прикольно что +2, а tt-h так и остался 998.

Код:
local pin, h, l, co2, TRIGGER_ON = 1, 0, 0, 0, "both"
local function mh19Begin(level)
local tt = tmr.now()/1000;
if level == 1 then
      print("tt", tt)
      print("h", h)
      print("l", l)
      print("h+l", h+l)
      print("l-h", l-h)
      print("tt-h", tt-h)
      co2 = 5000 * (l-h- 2) / (tt-h + 2); h=tt;
      print("co2", co2)
else
      l = tt;
  
end
end
   gpio.mode(pin,gpio.INT)
   gpio.trig(pin, TRIGGER_ON, mh19Begin)
upload_2018-12-21_21-27-6.png
 
Последнее редактирование:

SSS_Viva

Member
Попробовал в лоб описать то, что написал выше, в принципе глобально ничего не поменяло в показаниях, ну и с точки зрения программеров наверное смешной код, но все же выложу. И так как Tl+Th все теже 998, в формуле подсчета CO2 попробовал учесть эти две еденички. Ну и Китайцы такие Китайцы, в даташите про эти 2мс на переключение написано что это теоретическая величина -).
Код:
local pin, h, l, co2, TRIGGER_ON, Th, Tl = 1, 0, 0, 0, "both", 0, 0


local function ThTl(level)
  local tt = tmr.now()/1000;
  if level == 1 then
     h=tt;
     Tl = tt - l;
     print("tt", tt)
     print("l", l)
     print("Tl", Tl)
     print("Tl+Th", Tl + Th)
     print("CO2", 5000 * (Th - 1) / (Tl + Th - 2))
  else
     Th = tt - h;
     print("tt", tt)
     print("h", h)
     print("Th", Th)
     l=tt;
  end
  end
     
gpio.mode(pin,gpio.INT)
gpio.trig(pin, TRIGGER_ON, ThTl)
Вот что на выходе.

upload_2018-12-21_23-26-57.png


Специально заскриншотил момент после включения, когда по истечении какого-то времени показания резко изменяются, в данном случае с 413 на 2005, исходя из даташита, если и делать ручную калибровку, то нужно поместить датчик в среду с 400ppm и запустить калибровку, то можно предположить что в начале передавая 413, датчик пытается передать 0, тогда от 2005 можно смело отнимать 413, и показания будут более менее. Так же есть в даташите инфа про автоматическую каллибровку, которая происходит по какой то там логике, по истечению 24 часов, не удивлюсь, если логика такая, смотрим показания 24 часа, берем наименьшее оно и ноль ). При таком варианте датчик надо на 24 выкидывать на удицу, и пусть автоматически откалибруется, так как сделать показания ниже чем на улице будет довольно тяжело, а вот момент когда надо проветрить будет понятен. Короче вывод один с этим датчиком много НО. Ну и интересно было бы взять какой нить поверенный показментор на прокат и сравнить показания, и на основании сравнения внести корректировку ).
 

Вложения

Последнее редактирование:

mihail_do

New member
может кому пригодится. у меня стабильно работает вот так:

Код:
lcd = require("lcd")()
local i=1
local tm1=0
local tm2=0
local tm3=0
local tm4=0
local ppm=0
local th=0
local tl=0
local cycle=0
local tm=tmr.now()
gpio.mode(5,gpio.INT,gpio.PULLUP)
gpio.trig(5, "both",function(level, tm)

if i==1 and gpio.read(5) == 1 then
    tm1=tm
    i=i+1
    elseif i==2 then
        tm2=tm
        i=i+1
    elseif i==3 then
        tm3=tm
        i=i+1
    elseif i==4 then
        cycle=(tm3-tm1)/1000
        if cycle>950 and cycle<1055   --по даташиту цикл скачет +-5%
            then
                th=(tm2-tm1)/1000
                tl=(tm3-tm2)/1000
                ppm=5000*(th-2)/(th+tl-4)
            end
        i=1
end
lcd.setText(2,  string.format("CO2 %.4f", ppm),false)
end)
значения вывожу на lcd, поэтому такая команда в конце вместо print
на датчике наклейка 0-5000ppm, решил тоже умножать на 5000. вроде как значения соответствуют ожидаемым.
я не настоящий сварщик, пишу как могу)) главное - работает
 
Сверху Снизу