![](https://habrastorage.org/files/d31/3f7/227/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В
![](https://habrastorage.org/files/baf/1aa/7e2/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) == 0x10) or (addr:byte(1) == 0x28)) then
ow.reset(pin)
ow.select(pin, addr)
ow.write(pin, 0x44, 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,0x04,0x00,0x03,0x00,0x01,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 для меня до сих пор тёмный лес.
Результаты
![](https://habrastorage.org/files/9e1/7b4/196/9e17b4196f6142a1a5c7b3b629885d56.png)
Получилось очень интересное устройство. Питание сделал от USB, соответственно можно брать куда угодно. PowerBank сегодня есть почти у каждого. По поводу Wi-Fi — поднимаем точку на телефоне и наш датчик снова в сети.
По ощущениям — действительно появляется дискомфорт при превышении CO2 уровня в 800-1000 ppm.