Wi-Fi измеритель CO2 на ESP8266 + K-30

d313f722711840339e388037165370ba.pngВ данной статье мы продолжим эксперименты с Wi-Fi модулем ESP8266 и попробуем реализовать опрос датчика CO2 K-30 через MODBUS.В первой части мы прошили в ESP8266 NodeMCU, подключили DS18b20 и научились отправлять данные о температуре в облако. Попробуем добавить опрос датчика CO2.Самое интересное реализовать весь функционал в ESP8266 не подключая внешний контроллерHardware и подключениеДобавляем к конфигу из предыдущей статьи датчик K-30.Соединяем UART RX, UART TX и GND у датчика K-30 и ESP8266. Питание у них будет разное.Сложность заключается в том, что UART у ESP8266 всего один, так что либо консоль и отладка, либо K-30Внимание! Питание у K-30 5–14В, у ESP8266 — 3.3В.Я решил данную проблему применив преобразователь 5→3.3Вbaf1aa7e24474325bda320e250f268c8.webp

Программная часть

1) init.lua — практически не изменился

--init.lua print («Setting up WIFI…») wifi.setmode (wifi.STATION) --modify according your wireless router settings wifi.sta.config («YOUR_SSID», «YOUR_PASSWD») wifi.sta.connect () tmr.alarm (1, 1000, 1, function () if wifi.sta.getip ()== nil then print («IP unavaiable, Waiting…») else tmr.stop (1) print («Config done, IP is »…wifi.sta.getip ()) dofile («all.lua») end end) 2) all.lua — код опроса датчиков и отправки данных на сервер

pin = 6 t = 0

function read (addr, unit) ow.setup (pin) result = nil flag = false if (addr == nil) then ow.reset_search (pin) count = 0 repeat count = count + 1 addr = ow.search (pin) tmr.wdclr () until ((addr ~= nil) or (count > 100)) ow.reset_search (pin) end if (addr == nil) then return result end crc = ow.crc8(string.sub (addr,1,7)) if (crc == addr: byte (8)) then if ((addr: byte (1) == 0×10) or (addr: byte (1) == 0×28)) then ow.reset (pin) ow.select (pin, addr) ow.write (pin, 0×44, 1) present = ow.reset (pin) ow.select (pin, addr) ow.write (pin,0xBE,1) data = nil data = string.char (ow.read (pin)) for i = 1, 8 do data = data … string.char (ow.read (pin)) end crc = ow.crc8(string.sub (data,1,8)) if (crc == data: byte (9)) then

t = (data: byte (1) + data: byte (2) * 256) * 625

t = t / 10000 return t end tmr.wdclr () else end else end return result end

function sendt (t, co, key) print («Temp:»…t…» C\n») conn=net.createConnection (net.TCP, 0) conn: on («receive», function (conn, payload) print (payload) end) conn: connect (80,'184.106.153.149') conn: send («GET /update? key=»…key…»&field1=»…t…»&field2=»…co…» HTTP/1.1\r\n») conn: send («Host: api.thingspeak.com\r\n») conn: send («Accept: */*\r\n») conn: send («User-Agent: Mozilla/4.0 (compatible; esp8266 Lua; Windows NT 5.1)\r\n») conn: send (»\r\n»)

conn: on («sent», function (conn) print («Closing connection») conn: close () end) conn: on («disconnection», function (conn) print («Got disconnection…») end) end

uart.setup (0,9600,8,0,1,0) uart.on («data», 0, function (data) --print («receive from uart:», data) if string.len (data) == 7 then result = string.byte (data,4)*256 + string.byte (data,5) print (result) sendt (t, result, «YOUR_KEY») end end, 0)

function sendData () t = read () uart.write (0,0xFE,0×04,0×00,0×03,0×00,0×01,0xD5,0xC5) end

tmr.alarm (0, 60000, 1, function () sendData () end) Алгоритм работы:

Инициализируем UART на 9600 Устанавливаем callback на получение данных из UART. В случае получения пакета из 7 байт (ответ K-30 по MODBUS) отправляем данные на thingspeak.com Каждую минуту опрашиваем датчик температуры DS18b20 и отправляем в UART запрос данных по CO2. Запрос найден в даташите Раскидать по отдельным файлам не получилось, не хватало памяти, поэтому реализовал как смог. Lua для меня до сих пор тёмный лес.Результаты9e17b4196f6142a1a5c7b3b629885d56.png

Получилось очень интересное устройство. Питание сделал от USB, соответственно можно брать куда угодно. PowerBank сегодня есть почти у каждого. По поводу Wi-Fi — поднимаем точку на телефоне и наш датчик снова в сети.

По ощущениям — действительно появляется дискомфорт при превышении CO2 уровня в 800–1000 ppm.

© Habrahabr.ru