init
This commit is contained in:
parent
b07f1d53e9
commit
a7a2dcbc7a
209
DS1820.lua
Normal file
209
DS1820.lua
Normal file
@ -0,0 +1,209 @@
|
||||
--------------------------------------------------------------------------------
|
||||
-- DS18B20 one wire module for NODEMCU
|
||||
-- NODEMCU TEAM
|
||||
-- LICENCE: http://opensource.org/licenses/MIT
|
||||
-- @voborsky, @devsaurus, TerryE 26 Mar 2017
|
||||
--------------------------------------------------------------------------------
|
||||
local modname = ...
|
||||
|
||||
-- Used modules and functions
|
||||
local type, tostring, pcall, ipairs =
|
||||
type, tostring, pcall, ipairs
|
||||
-- Local functions
|
||||
local ow_setup, ow_search, ow_select, ow_read, ow_read_bytes, ow_write, ow_crc8,
|
||||
ow_reset, ow_reset_search, ow_skip, ow_depower =
|
||||
ow.setup, ow.search, ow.select, ow.read, ow.read_bytes, ow.write, ow.crc8,
|
||||
ow.reset, ow.reset_search, ow.skip, ow.depower
|
||||
|
||||
local node_task_post, node_task_LOW_PRIORITY = node.task.post, node.task.LOW_PRIORITY
|
||||
local string_char, string_dump = string.char, string.dump
|
||||
local now, tmr_create, tmr_ALARM_SINGLE = tmr.now, tmr.create, tmr.ALARM_SINGLE
|
||||
local table_sort, table_concat = table.sort, table.concat
|
||||
local file_open = file.open
|
||||
local conversion
|
||||
|
||||
local DS18B20FAMILY = 0x28
|
||||
local DS1920FAMILY = 0x10 -- and DS18S20 series
|
||||
local CONVERT_T = 0x44
|
||||
local READ_SCRATCHPAD = 0xBE
|
||||
local READ_POWERSUPPLY= 0xB4
|
||||
local MODE = 1
|
||||
|
||||
local pin, cb, unit = 3
|
||||
local status = {}
|
||||
|
||||
local debugPrint = function() return end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Implementation
|
||||
--------------------------------------------------------------------------------
|
||||
local function enable_debug()
|
||||
debugPrint = function (...) print(now(),' ', ...) end
|
||||
end
|
||||
|
||||
local function to_string(addr, esc)
|
||||
if type(addr) == 'string' and #addr == 8 then
|
||||
return ( esc == true and
|
||||
'"\\%u\\%u\\%u\\%u\\%u\\%u\\%u\\%u"' or
|
||||
'%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X '):format(addr:byte(1,8))
|
||||
else
|
||||
return tostring(addr)
|
||||
end
|
||||
end
|
||||
|
||||
local function readout(self)
|
||||
local next = false
|
||||
local sens = self.sens
|
||||
local temp = self.temp
|
||||
for i, s in ipairs(sens) do
|
||||
if status[i] == 1 then
|
||||
ow_reset(pin)
|
||||
local addr = s:sub(1,8)
|
||||
ow_select(pin, addr) -- select the sensor
|
||||
ow_write(pin, READ_SCRATCHPAD, MODE)
|
||||
local data = ow_read_bytes(pin, 9)
|
||||
|
||||
local t=(data:byte(1)+data:byte(2)*256)
|
||||
-- t is actually signed so process the sign bit and adjust for fractional bits
|
||||
-- the DS18B20 family has 4 fractional bits and the DS18S20s, 1 fractional bit
|
||||
t = ((t <= 32767) and t or t - 65536) *
|
||||
((addr:byte(1) == DS18B20FAMILY) and 625 or 5000)
|
||||
local crc, b9 = ow_crc8(string.sub(data,1,8)), data:byte(9)
|
||||
|
||||
if unit == 'F' then
|
||||
t = (t * 18)/10 + 320000
|
||||
elseif unit == 'K' then
|
||||
t = t + 2731500
|
||||
end
|
||||
local sgn = t<0 and -1 or 1
|
||||
local tA = sgn*t
|
||||
local tH=tA/10000
|
||||
local tL=(tA%10000)/1000 + ((tA%1000)/100 >= 5 and 1 or 0)
|
||||
|
||||
if tH and (t~=850000) then
|
||||
debugPrint(to_string(addr),(sgn<0 and "-" or "")..tH.."."..tL, crc, b9)
|
||||
if crc==b9 then temp[addr]=t end
|
||||
status[i] = 2
|
||||
end
|
||||
end
|
||||
next = next or status[i] == 0
|
||||
end
|
||||
if next then
|
||||
node_task_post(node_task_LOW_PRIORITY, function() return conversion(self) end)
|
||||
else
|
||||
--sens = {}
|
||||
if cb then
|
||||
node_task_post(node_task_LOW_PRIORITY, function() return cb(temp) end)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
conversion = (function (self)
|
||||
local sens = self.sens
|
||||
local powered_only = true
|
||||
for _, s in ipairs(sens) do powered_only = powered_only and s:byte(9) ~= 1 end
|
||||
if powered_only then
|
||||
debugPrint("starting conversion: all sensors")
|
||||
ow_reset(pin)
|
||||
ow_skip(pin) -- skip ROM selection, talk to all sensors
|
||||
ow_write(pin, CONVERT_T, MODE) -- and start conversion
|
||||
for i, _ in ipairs(sens) do status[i] = 1 end
|
||||
else
|
||||
local started = false
|
||||
for i, s in ipairs(sens) do
|
||||
if status[i] == 0 then
|
||||
local addr, parasite = s:sub(1,8), s:byte(9) == 1
|
||||
if parasite and started then break end -- do not start concurrent conversion of powered and parasite
|
||||
debugPrint("starting conversion:", to_string(addr), parasite and "parasite" or "")
|
||||
ow_reset(pin)
|
||||
ow_select(pin, addr) -- select the sensor
|
||||
ow_write(pin, CONVERT_T, MODE) -- and start conversion
|
||||
status[i] = 1
|
||||
if parasite then break end -- parasite sensor blocks bus during conversion
|
||||
started = true
|
||||
end
|
||||
end
|
||||
end
|
||||
tmr_create():alarm(750, tmr_ALARM_SINGLE, function() return readout(self) end)
|
||||
end)
|
||||
|
||||
local function _search(self, lcb, lpin, search, save)
|
||||
self.temp = {}
|
||||
if search then self.sens = {}; status = {} end
|
||||
local sens = self.sens
|
||||
pin = lpin or pin
|
||||
|
||||
local addr
|
||||
if not search and #sens == 0 then
|
||||
-- load addreses if available
|
||||
debugPrint ("geting addreses from flash")
|
||||
local s,check,a = pcall(dofile, "ds18b20_save.lc")
|
||||
if s and check == "ds18b20" then
|
||||
for i = 1, #a do sens[i] = a[i] end
|
||||
end
|
||||
debugPrint (#sens, "addreses found")
|
||||
end
|
||||
|
||||
ow_setup(pin)
|
||||
if search or #sens == 0 then
|
||||
ow_reset_search(pin)
|
||||
-- ow_target_search(pin,0x28)
|
||||
-- search the first device
|
||||
addr = ow_search(pin)
|
||||
else
|
||||
for i, _ in ipairs(sens) do status[i] = 0 end
|
||||
end
|
||||
local function cycle()
|
||||
if addr then
|
||||
local crc=ow_crc8(addr:sub(1,7))
|
||||
if (crc==addr:byte(8)) and ((addr:byte(1)==DS1920FAMILY) or (addr:byte(1)==DS18B20FAMILY)) then
|
||||
ow_reset(pin)
|
||||
ow_select(pin, addr)
|
||||
ow_write(pin, READ_POWERSUPPLY, MODE)
|
||||
local parasite = (ow_read(pin)==0 and 1 or 0)
|
||||
sens[#sens+1]= addr..string_char(parasite)
|
||||
status[#sens] = 0
|
||||
debugPrint("contact: ", to_string(addr), parasite == 1 and "parasite" or "")
|
||||
end
|
||||
addr = ow_search(pin)
|
||||
node_task_post(node_task_LOW_PRIORITY, cycle)
|
||||
else
|
||||
ow_depower(pin)
|
||||
-- place powered sensors first
|
||||
table_sort(sens, function(a, b) return a:byte(9)<b:byte(9) end) -- parasite
|
||||
-- save sensor addreses
|
||||
if save then
|
||||
debugPrint ("saving addreses to flash")
|
||||
|
||||
local addr_list = {}
|
||||
for i =1, #sens do
|
||||
local s = sens[i]
|
||||
addr_list[i] = to_string(s:sub(1,8), true)..('.."\\%u"'):format(s:byte(9))
|
||||
end
|
||||
local save_statement = 'return "ds18b20", {' .. table_concat(addr_list, ',') .. '}'
|
||||
debugPrint (save_statement)
|
||||
local save_file = file_open("ds18b20_save.lc","w")
|
||||
save_file:write(string_dump(loadstring(save_statement)))
|
||||
save_file:close()
|
||||
end
|
||||
-- end save sensor addreses
|
||||
if lcb then node_task_post(node_task_LOW_PRIORITY, lcb) end
|
||||
end
|
||||
end
|
||||
cycle()
|
||||
end
|
||||
|
||||
local function read_temp(self, lcb, lpin, lunit, force_search, save_search)
|
||||
cb, unit = lcb, lunit or unit
|
||||
_search(self, function() return conversion(self) end, lpin, force_search, save_search)
|
||||
end
|
||||
|
||||
-- Set module name as parameter of require and return module table
|
||||
local M = {
|
||||
sens = {},
|
||||
temp = {},
|
||||
C = 'C', F = 'F', K = 'K',
|
||||
read_temp = read_temp, enable_debug = enable_debug
|
||||
}
|
||||
_G[modname or 'ds18b20'] = M
|
||||
return M
|
||||
Binary file not shown.
1
Ground/.~lock.датчики.ods#
Normal file
1
Ground/.~lock.датчики.ods#
Normal file
@ -0,0 +1 @@
|
||||
,zoviet,libreboot,30.03.2025 23:32,file:///home/zoviet/.config/libreoffice/4;
|
||||
209
Ground/DS1820.lua
Normal file
209
Ground/DS1820.lua
Normal file
@ -0,0 +1,209 @@
|
||||
--------------------------------------------------------------------------------
|
||||
-- DS18B20 one wire module for NODEMCU
|
||||
-- NODEMCU TEAM
|
||||
-- LICENCE: http://opensource.org/licenses/MIT
|
||||
-- @voborsky, @devsaurus, TerryE 26 Mar 2017
|
||||
--------------------------------------------------------------------------------
|
||||
local modname = ...
|
||||
|
||||
-- Used modules and functions
|
||||
local type, tostring, pcall, ipairs =
|
||||
type, tostring, pcall, ipairs
|
||||
-- Local functions
|
||||
local ow_setup, ow_search, ow_select, ow_read, ow_read_bytes, ow_write, ow_crc8,
|
||||
ow_reset, ow_reset_search, ow_skip, ow_depower =
|
||||
ow.setup, ow.search, ow.select, ow.read, ow.read_bytes, ow.write, ow.crc8,
|
||||
ow.reset, ow.reset_search, ow.skip, ow.depower
|
||||
|
||||
local node_task_post, node_task_LOW_PRIORITY = node.task.post, node.task.LOW_PRIORITY
|
||||
local string_char, string_dump = string.char, string.dump
|
||||
local now, tmr_create, tmr_ALARM_SINGLE = tmr.now, tmr.create, tmr.ALARM_SINGLE
|
||||
local table_sort, table_concat = table.sort, table.concat
|
||||
local file_open = file.open
|
||||
local conversion
|
||||
|
||||
local DS18B20FAMILY = 0x28
|
||||
local DS1920FAMILY = 0x10 -- and DS18S20 series
|
||||
local CONVERT_T = 0x44
|
||||
local READ_SCRATCHPAD = 0xBE
|
||||
local READ_POWERSUPPLY= 0xB4
|
||||
local MODE = 1
|
||||
|
||||
local pin, cb, unit = 3
|
||||
local status = {}
|
||||
|
||||
local debugPrint = function() return end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Implementation
|
||||
--------------------------------------------------------------------------------
|
||||
local function enable_debug()
|
||||
debugPrint = function (...) print(now(),' ', ...) end
|
||||
end
|
||||
|
||||
local function to_string(addr, esc)
|
||||
if type(addr) == 'string' and #addr == 8 then
|
||||
return ( esc == true and
|
||||
'"\\%u\\%u\\%u\\%u\\%u\\%u\\%u\\%u"' or
|
||||
'%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X '):format(addr:byte(1,8))
|
||||
else
|
||||
return tostring(addr)
|
||||
end
|
||||
end
|
||||
|
||||
local function readout(self)
|
||||
local next = false
|
||||
local sens = self.sens
|
||||
local temp = self.temp
|
||||
for i, s in ipairs(sens) do
|
||||
if status[i] == 1 then
|
||||
ow_reset(pin)
|
||||
local addr = s:sub(1,8)
|
||||
ow_select(pin, addr) -- select the sensor
|
||||
ow_write(pin, READ_SCRATCHPAD, MODE)
|
||||
local data = ow_read_bytes(pin, 9)
|
||||
|
||||
local t=(data:byte(1)+data:byte(2)*256)
|
||||
-- t is actually signed so process the sign bit and adjust for fractional bits
|
||||
-- the DS18B20 family has 4 fractional bits and the DS18S20s, 1 fractional bit
|
||||
t = ((t <= 32767) and t or t - 65536) *
|
||||
((addr:byte(1) == DS18B20FAMILY) and 625 or 5000)
|
||||
local crc, b9 = ow_crc8(string.sub(data,1,8)), data:byte(9)
|
||||
|
||||
if unit == 'F' then
|
||||
t = (t * 18)/10 + 320000
|
||||
elseif unit == 'K' then
|
||||
t = t + 2731500
|
||||
end
|
||||
local sgn = t<0 and -1 or 1
|
||||
local tA = sgn*t
|
||||
local tH=tA/10000
|
||||
local tL=(tA%10000)/1000 + ((tA%1000)/100 >= 5 and 1 or 0)
|
||||
|
||||
if tH and (t~=850000) then
|
||||
debugPrint(to_string(addr),(sgn<0 and "-" or "")..tH.."."..tL, crc, b9)
|
||||
if crc==b9 then temp[addr]=t end
|
||||
status[i] = 2
|
||||
end
|
||||
end
|
||||
next = next or status[i] == 0
|
||||
end
|
||||
if next then
|
||||
node_task_post(node_task_LOW_PRIORITY, function() return conversion(self) end)
|
||||
else
|
||||
--sens = {}
|
||||
if cb then
|
||||
node_task_post(node_task_LOW_PRIORITY, function() return cb(temp) end)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
conversion = (function (self)
|
||||
local sens = self.sens
|
||||
local powered_only = true
|
||||
for _, s in ipairs(sens) do powered_only = powered_only and s:byte(9) ~= 1 end
|
||||
if powered_only then
|
||||
debugPrint("starting conversion: all sensors")
|
||||
ow_reset(pin)
|
||||
ow_skip(pin) -- skip ROM selection, talk to all sensors
|
||||
ow_write(pin, CONVERT_T, MODE) -- and start conversion
|
||||
for i, _ in ipairs(sens) do status[i] = 1 end
|
||||
else
|
||||
local started = false
|
||||
for i, s in ipairs(sens) do
|
||||
if status[i] == 0 then
|
||||
local addr, parasite = s:sub(1,8), s:byte(9) == 1
|
||||
if parasite and started then break end -- do not start concurrent conversion of powered and parasite
|
||||
debugPrint("starting conversion:", to_string(addr), parasite and "parasite" or "")
|
||||
ow_reset(pin)
|
||||
ow_select(pin, addr) -- select the sensor
|
||||
ow_write(pin, CONVERT_T, MODE) -- and start conversion
|
||||
status[i] = 1
|
||||
if parasite then break end -- parasite sensor blocks bus during conversion
|
||||
started = true
|
||||
end
|
||||
end
|
||||
end
|
||||
tmr_create():alarm(750, tmr_ALARM_SINGLE, function() return readout(self) end)
|
||||
end)
|
||||
|
||||
local function _search(self, lcb, lpin, search, save)
|
||||
self.temp = {}
|
||||
if search then self.sens = {}; status = {} end
|
||||
local sens = self.sens
|
||||
pin = lpin or pin
|
||||
|
||||
local addr
|
||||
if not search and #sens == 0 then
|
||||
-- load addreses if available
|
||||
debugPrint ("geting addreses from flash")
|
||||
local s,check,a = pcall(dofile, "ds18b20_save.lc")
|
||||
if s and check == "ds18b20" then
|
||||
for i = 1, #a do sens[i] = a[i] end
|
||||
end
|
||||
debugPrint (#sens, "addreses found")
|
||||
end
|
||||
|
||||
ow_setup(pin)
|
||||
if search or #sens == 0 then
|
||||
ow_reset_search(pin)
|
||||
-- ow_target_search(pin,0x28)
|
||||
-- search the first device
|
||||
addr = ow_search(pin)
|
||||
else
|
||||
for i, _ in ipairs(sens) do status[i] = 0 end
|
||||
end
|
||||
local function cycle()
|
||||
if addr then
|
||||
local crc=ow_crc8(addr:sub(1,7))
|
||||
if (crc==addr:byte(8)) and ((addr:byte(1)==DS1920FAMILY) or (addr:byte(1)==DS18B20FAMILY)) then
|
||||
ow_reset(pin)
|
||||
ow_select(pin, addr)
|
||||
ow_write(pin, READ_POWERSUPPLY, MODE)
|
||||
local parasite = (ow_read(pin)==0 and 1 or 0)
|
||||
sens[#sens+1]= addr..string_char(parasite)
|
||||
status[#sens] = 0
|
||||
debugPrint("contact: ", to_string(addr), parasite == 1 and "parasite" or "")
|
||||
end
|
||||
addr = ow_search(pin)
|
||||
node_task_post(node_task_LOW_PRIORITY, cycle)
|
||||
else
|
||||
ow_depower(pin)
|
||||
-- place powered sensors first
|
||||
table_sort(sens, function(a, b) return a:byte(9)<b:byte(9) end) -- parasite
|
||||
-- save sensor addreses
|
||||
if save then
|
||||
debugPrint ("saving addreses to flash")
|
||||
|
||||
local addr_list = {}
|
||||
for i =1, #sens do
|
||||
local s = sens[i]
|
||||
addr_list[i] = to_string(s:sub(1,8), true)..('.."\\%u"'):format(s:byte(9))
|
||||
end
|
||||
local save_statement = 'return "ds18b20", {' .. table_concat(addr_list, ',') .. '}'
|
||||
debugPrint (save_statement)
|
||||
local save_file = file_open("ds18b20_save.lc","w")
|
||||
save_file:write(string_dump(loadstring(save_statement)))
|
||||
save_file:close()
|
||||
end
|
||||
-- end save sensor addreses
|
||||
if lcb then node_task_post(node_task_LOW_PRIORITY, lcb) end
|
||||
end
|
||||
end
|
||||
cycle()
|
||||
end
|
||||
|
||||
local function read_temp(self, lcb, lpin, lunit, force_search, save_search)
|
||||
cb, unit = lcb, lunit or unit
|
||||
_search(self, function() return conversion(self) end, lpin, force_search, save_search)
|
||||
end
|
||||
|
||||
-- Set module name as parameter of require and return module table
|
||||
local M = {
|
||||
sens = {},
|
||||
temp = {},
|
||||
C = 'C', F = 'F', K = 'K',
|
||||
read_temp = read_temp, enable_debug = enable_debug
|
||||
}
|
||||
_G[modname or 'ds18b20'] = M
|
||||
return M
|
||||
2
Ground/flash.sh
Normal file
2
Ground/flash.sh
Normal file
@ -0,0 +1,2 @@
|
||||
python3 -m esptool --port /dev/ttyUSB0 erase_flash
|
||||
python3 -m esptool --port /dev/ttyUSB0 write_flash -fm dio 0x00000 nodemcu-release-9-modules-2024-09-15-16-23-23-integer.bin
|
||||
43
Ground/init.lua
Normal file
43
Ground/init.lua
Normal file
@ -0,0 +1,43 @@
|
||||
local t = require("DS1820")
|
||||
local pin = 1
|
||||
|
||||
function adc_read()
|
||||
local ao = adc.read(0)
|
||||
print(ao)
|
||||
end
|
||||
|
||||
local function readout(temp)
|
||||
if t.sens then
|
||||
print("Total number of DS18B20 sensors: ".. #t.sens)
|
||||
for i, s in ipairs(t.sens) do
|
||||
print(string.format(" sensor #%d address: %s%s", i, ('%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X'):format(s:byte(1,8)), s:byte(9) == 1 and " (parasite)" or ""))
|
||||
end
|
||||
end
|
||||
for addr, temp in pairs(temp) do
|
||||
--if tonumber(temp) < 20000 then
|
||||
print(string.format("Sensor %s: %s °C", ('%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X'):format(addr:byte(1,8)), temp))
|
||||
--end
|
||||
end
|
||||
|
||||
-- Module can be released when it is no longer needed
|
||||
--t = nil
|
||||
--package.loaded["ds18b20"] = nil
|
||||
end
|
||||
|
||||
local function read()
|
||||
t:read_temp(readout, pin, t.C)
|
||||
end
|
||||
|
||||
if adc.force_init_mode(adc.INIT_ADC)
|
||||
then
|
||||
node.restart()
|
||||
return -- don't bother continuing, the restart is scheduled
|
||||
end
|
||||
|
||||
timer = tmr.create()
|
||||
timer:register(7000, tmr.ALARM_AUTO,read)
|
||||
timer:start()
|
||||
|
||||
sensorstimer = tmr.create()
|
||||
sensorstimer:register(5000, tmr.ALARM_AUTO, adc_read)
|
||||
sensorstimer:start()
|
||||
BIN
Ground/nodemcu-release-9-modules-2024-09-15-16-23-23-integer.bin
Normal file
BIN
Ground/nodemcu-release-9-modules-2024-09-15-16-23-23-integer.bin
Normal file
Binary file not shown.
BIN
Ground/датчики.ods
Normal file
BIN
Ground/датчики.ods
Normal file
Binary file not shown.
76
README.md
76
README.md
@ -1,2 +1,76 @@
|
||||
# braga_firmware
|
||||
# Бродильная камера на ESP 8266
|
||||
|
||||
## Необходимые детали
|
||||
|
||||
1. Wemos D1 Mini
|
||||
|
||||
2. Датчик интенсивности ультрафиолета GUVA-S12SD
|
||||
|
||||
3. Датчик температуры и влажности DHT-11
|
||||
|
||||
4. Датчик давления и температуры BMP280
|
||||
|
||||
|
||||
## Схема подключения
|
||||
|
||||
DHT 11:
|
||||
|
||||
"-" - GND
|
||||
|
||||
S - D1
|
||||
|
||||
V - 3.3
|
||||
|
||||
BME280:
|
||||
|
||||
SDA - D3
|
||||
|
||||
SCL - D4
|
||||
|
||||
G - G
|
||||
|
||||
V - 3.3
|
||||
|
||||
GUVA-S12SD:
|
||||
|
||||
SIO - AO
|
||||
|
||||
GND - G
|
||||
|
||||
VCC - 3.3
|
||||
|
||||
## Прошивка
|
||||
|
||||
Понадобятся:
|
||||
|
||||
1. esptool - https://docs.espressif.com/projects/esptool/en/latest/esp32/
|
||||
|
||||
2. git
|
||||
|
||||
3. python2 и python3
|
||||
|
||||
По желанию ESPlorer - https://esp8266.ru/forum/threads/esplorer.34/
|
||||
|
||||
Загрузка прошивки с необходимыми модулями:
|
||||
|
||||
```
|
||||
git clone https://github.com/Zoviet/meteo
|
||||
cd meteo
|
||||
bash flash.sh
|
||||
|
||||
```
|
||||
После загрузки прошивки устройство сразу готово к работе.
|
||||
|
||||
## Подключение к Wi-Fi
|
||||
|
||||
При подключении к новой сети устройство поднимает веб-сервер. В списке доступных Wi-Fi сетей появится сеть meteo, к которой следует подключиться. В запросе авторизации появится форма для выбора сети, к которой планируется подключить устройство, и форма ввода пароля от нее.
|
||||
|
||||
## Проверка работособности
|
||||
|
||||
При включении и/или перезагрузке устройство, даже не подключенное к Интернету, отдает в виртуальный COM-порт данные датчиков. Прочитать из можно с помощью ESPlorer либо любой программы для чтения COM-порта.
|
||||
|
||||
## Протокол обмена с сервером
|
||||
|
||||
TCP, порт 4999, ожидаемый формат - json, закодированный в Base64.
|
||||
|
||||
|
||||
|
||||
BIN
Schematic/schematic.fzz
Normal file
BIN
Schematic/schematic.fzz
Normal file
Binary file not shown.
BIN
Schematic/schematic_МП.png
Normal file
BIN
Schematic/schematic_МП.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 141 KiB |
BIN
Schematic/schematic_схема.png
Normal file
BIN
Schematic/schematic_схема.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 38 KiB |
3
firmware.sh
Normal file
3
firmware.sh
Normal file
@ -0,0 +1,3 @@
|
||||
dmesg | grep tty
|
||||
python3 -m esptool --port /dev/ttyUSB0 erase_flash
|
||||
python3 -m esptool --port /dev/ttyUSB0 write_flash -fm dio 0x00000 nodemcu-release-17-modules-2025-01-01-15-13-22-float.bin
|
||||
66
flash.sh
Executable file
66
flash.sh
Executable file
@ -0,0 +1,66 @@
|
||||
#!/bin/bash
|
||||
|
||||
if read -p "Подключите плату к USB и нажмите ENTER: " start; then
|
||||
line=$(dmesg | grep 'ttyUSB' | tail -1)
|
||||
if [[ $line == *"attached"* ]]; then
|
||||
port=`echo "$line" | sed 's/.*ttyUSB\(.\)$/\1/'`
|
||||
else
|
||||
printf '\033[91mУстройство не найдено!\033[0m\n'
|
||||
exit 0
|
||||
fi
|
||||
printf '\033[92mУстройство найдено на порту: '$port'\033[0m\n'
|
||||
fi
|
||||
|
||||
if read -p "Для начала прошивки нажмите ENTER: " start; then
|
||||
cd Firmware
|
||||
firmware=($(find -name '*.bin'))
|
||||
if [[ $firmware == *"nodemcu"* ]]; then
|
||||
printf '\033[92mНайдена прошивка: '$firmware'\033[0m\n\n'
|
||||
printf '\n\033[92mСтираем существующую прошивку:\033[0m\n\n'
|
||||
python3 -m esptool --port /dev/ttyUSB$port erase_flash
|
||||
if [ $? -ne 0 ]; then
|
||||
printf '\033[91mОшибка устройства!\033[0m\n'
|
||||
exit 0
|
||||
fi
|
||||
printf '\n\033[92mЗаливаем прошивку nodemcu для Lua:\033[0m\n\n'
|
||||
python3 -m esptool --port /dev/ttyUSB$port write_flash -fm dio 0x00000 $firmware
|
||||
if [ $? -ne 0 ]; then
|
||||
printf '\033[91mОшибка устройства!\033[0m\n'
|
||||
exit 0
|
||||
fi
|
||||
else
|
||||
printf '\033[91mПрошивка не найдена!\033[0m\n'
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
cd ../
|
||||
|
||||
if read -p "Для начала заливки скетча нажмите ENTER: " start; then
|
||||
echo 'Заливаем Lua скетч:'
|
||||
python2 luatool.py --port /dev/ttyUSB$port --src init.lua --dest init.lua --verbose --restart --baud 115200
|
||||
if [ $? -ne 0 ]; then
|
||||
printf '\033[91mОшибка заливки скетча!\033[0m\n'
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
printf '\n\033[92mЖдем перезагрузки устройства:\033[0m\n\n'
|
||||
sleep 5
|
||||
mac=$(python3 -m esptool --port /dev/ttyUSB$port read_mac)
|
||||
if [ $? -ne 0 ]; then
|
||||
printf '\033[91mОшибка чтения из устройства!\033[0m\n'
|
||||
exit 0
|
||||
fi
|
||||
guid=`echo "$mac" | grep -m 1 MAC | sed 's/\://g' | sed 's/MAC //g'`
|
||||
echo 'GUID устройства: '$guid
|
||||
first_byte=${guid:0:2}
|
||||
new_byte=$((16#$first_byte + 2 | bc))
|
||||
new_first_byte=`echo "ibase=10; obase=16; ${new_byte}" | bc | sed 's/[A-Z]/\L&/g'`
|
||||
if (( ${#new_first_byte} == 1 )); then
|
||||
new_first_byte='0'$new_first_byte
|
||||
fi
|
||||
guid=`echo "$guid" | sed 's/^'$first_byte'/'$new_first_byte'/'`
|
||||
printf '\033[92mОпределен guid устройства: '$guid' \033[0m\n'
|
||||
|
||||
printf '\033[92mУстановка успешно завершена, ID устройства: \033[0m'$guid'\n'
|
||||
129
init.lua
Normal file
129
init.lua
Normal file
@ -0,0 +1,129 @@
|
||||
timing = 5000 -- Sending timer
|
||||
srv = nil -- TCP client
|
||||
uid = '' -- MAC UID
|
||||
dhtpin = 1 -- DHT11 pin
|
||||
sda, scl = 3, 4 -- BME280 pins
|
||||
alt = 320 -- altitude of the measurement place
|
||||
|
||||
-- Weather vars
|
||||
|
||||
T = - 300 -- BME temp
|
||||
P = - 300 -- BME pressure
|
||||
curAlt = - 300 -- BME altitude
|
||||
TB = - 300 -- DHT temp
|
||||
TH = - 300 -- DHT humidity
|
||||
UF = 0 -- UF index
|
||||
|
||||
-- Read the solar sensor
|
||||
|
||||
function adc_read()
|
||||
UF = adc.read(0)
|
||||
print('UF index: '..UF)
|
||||
end
|
||||
|
||||
-- Read the BME280 sensor
|
||||
|
||||
function bme_read()
|
||||
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))
|
||||
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))
|
||||
end
|
||||
|
||||
-- Read the DHT11 sensor
|
||||
|
||||
function dht_read()
|
||||
status, temp, humi, temp_dec, humi_dec = dht.read(dhtpin)
|
||||
if status == dht.OK then
|
||||
TB = temp
|
||||
TH = humi
|
||||
print("DHT Temperature:"..temp..";".."Humidity:"..humi)
|
||||
elseif status == dht.ERROR_CHECKSUM then
|
||||
print( "DHT Checksum error." )
|
||||
elseif status == dht.ERROR_TIMEOUT then
|
||||
print( "DHT timed out." )
|
||||
end
|
||||
end
|
||||
|
||||
-- Prepare data for TCP server
|
||||
|
||||
function data_out()
|
||||
local pack = {}
|
||||
pack['id'] = uid
|
||||
pack['bme'] = {['temp'] = T,['press'] = P,['alt'] = curAlt}
|
||||
pack['dht'] = {['temp'] = TB,['humi'] = TH}
|
||||
pack['uf'] = UF
|
||||
return encoder.toBase64(sjson.encode(pack))
|
||||
end
|
||||
|
||||
-- Exchange data with server
|
||||
|
||||
function tcp()
|
||||
srv:connect(4999,"braga.ulgrad.ru")
|
||||
srv:on("connection", function(sck, c)
|
||||
print('connection')
|
||||
sck:send(data_out().."\r\n")
|
||||
end)
|
||||
srv:on("disconnection", function(sck,c)
|
||||
print('disconnection')
|
||||
end)
|
||||
end
|
||||
|
||||
-- On Internet connect
|
||||
|
||||
function on_connect()
|
||||
-- Generate UID from MAC address
|
||||
uid = string.gsub(wifi.ap.getmac(),':','')
|
||||
print("Connected to wifi as: " .. wifi.sta.getip())
|
||||
ssid,password,bssid_set,bssid = wifi.sta.getconfig()
|
||||
sensor_start()
|
||||
print(
|
||||
"\nCurrent Station configuration:"
|
||||
.."\nSSID : "..ssid
|
||||
.."\nPassword : "..password
|
||||
.."\nBSSID_set : "..bssid_set
|
||||
.."\nBSSID: "..bssid
|
||||
.."\nUID:"..uid
|
||||
.."\nClient IP:"..wifi.sta.getip().."\n"
|
||||
)
|
||||
srv = net.createConnection(net.TCP, 0)
|
||||
if srv then
|
||||
print('TCP Connection start')
|
||||
tcptimer:start()
|
||||
else
|
||||
print('Error connect to TCP')
|
||||
end
|
||||
end
|
||||
|
||||
-- Setup ADC
|
||||
|
||||
if adc.force_init_mode(adc.INIT_ADC)
|
||||
then
|
||||
node.restart()
|
||||
return -- don't bother continuing, the restart is scheduled
|
||||
end
|
||||
|
||||
-- Setup sensors
|
||||
|
||||
i2c.setup(0, sda, scl, i2c.SLOW) -- call i2c.setup() only once
|
||||
bme280.setup()
|
||||
|
||||
-- Setup timers
|
||||
|
||||
tcptimer = tmr.create()
|
||||
tcptimer:register(12000, tmr.ALARM_AUTO,tcp)
|
||||
|
||||
inittimer = tmr.create()
|
||||
inittimer:register(5000, tmr.ALARM_SINGLE, function()
|
||||
adc_read()
|
||||
bme_read()
|
||||
dht_read()
|
||||
enduser_setup.start('meteo',on_connect)
|
||||
end)
|
||||
|
||||
inittimer:start()
|
||||
358
luatool.py
Executable file
358
luatool.py
Executable file
@ -0,0 +1,358 @@
|
||||
#!/usr/bin/env python2
|
||||
#
|
||||
# ESP8266 luatool
|
||||
# Author e-mail: 4ref0nt@gmail.com
|
||||
# Site: http://esp8266.ru
|
||||
# Contributions from: https://github.com/sej7278
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it under
|
||||
# the terms of the GNU General Public License as published by the Free Software
|
||||
# Foundation; either version 2 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
|
||||
# Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
import sys
|
||||
import serial
|
||||
from time import sleep
|
||||
import socket
|
||||
import argparse
|
||||
from os.path import basename
|
||||
|
||||
|
||||
tqdm_installed = True
|
||||
try:
|
||||
from tqdm import tqdm
|
||||
except ImportError, e:
|
||||
if e.message == 'No module named tqdm':
|
||||
tqdm_installed = False
|
||||
else:
|
||||
raise
|
||||
|
||||
version = "0.6.4"
|
||||
|
||||
|
||||
class TransportError(Exception):
|
||||
"""Custom exception to represent errors with a transport
|
||||
"""
|
||||
def __init__(self, message):
|
||||
self.message = message
|
||||
|
||||
def __str__(self):
|
||||
return self.message
|
||||
|
||||
class AbstractTransport:
|
||||
def __init__(self):
|
||||
raise NotImplementedError('abstract transports cannot be instantiated.')
|
||||
|
||||
def close(self):
|
||||
raise NotImplementedError('Function not implemented')
|
||||
|
||||
def read(self, length):
|
||||
raise NotImplementedError('Function not implemented')
|
||||
|
||||
def writeln(self, data, check=1):
|
||||
raise NotImplementedError('Function not implemented')
|
||||
|
||||
def writer(self, data):
|
||||
self.writeln("file.writeline([==[" + data + "]==])\r")
|
||||
|
||||
def performcheck(self, expected):
|
||||
line = ''
|
||||
char = ''
|
||||
i = -1
|
||||
while char != chr(62): # '>'
|
||||
char = self.read(1)
|
||||
if char == '':
|
||||
raise Exception('No proper answer from MCU')
|
||||
if char == chr(13) or char == chr(10): # LF or CR
|
||||
if line != '':
|
||||
line = line.strip()
|
||||
if line+'\r' == expected and not args.bar:
|
||||
sys.stdout.write(" -> ok")
|
||||
elif line+'\r' != expected:
|
||||
if line[:4] == "lua:":
|
||||
sys.stdout.write("\r\n\r\nLua ERROR: %s" % line)
|
||||
raise Exception('ERROR from Lua interpreter\r\n\r\n')
|
||||
else:
|
||||
expected = expected.split("\r")[0]
|
||||
sys.stdout.write("\r\n\r\nERROR")
|
||||
sys.stdout.write("\r\n send string : '%s'" % expected)
|
||||
sys.stdout.write("\r\n expected echo : '%s'" % expected)
|
||||
sys.stdout.write("\r\n but got answer : '%s'" % line)
|
||||
sys.stdout.write("\r\n\r\n")
|
||||
raise Exception('Error sending data to MCU\r\n\r\n')
|
||||
line = ''
|
||||
else:
|
||||
line += char
|
||||
if char == chr(62) and expected[i] == char:
|
||||
char = ''
|
||||
i += 1
|
||||
|
||||
|
||||
class SerialTransport(AbstractTransport):
|
||||
def __init__(self, port, baud, delay):
|
||||
self.port = port
|
||||
self.baud = baud
|
||||
self.serial = None
|
||||
self.delay = delay
|
||||
|
||||
try:
|
||||
self.serial = serial.Serial(port, baud)
|
||||
except serial.SerialException as e:
|
||||
raise TransportError(e.strerror)
|
||||
|
||||
self.serial.timeout = 3
|
||||
self.serial.interCharTimeout = 3
|
||||
|
||||
def writeln(self, data, check=1):
|
||||
if self.serial.inWaiting() > 0:
|
||||
self.serial.flushInput()
|
||||
if len(data) > 0 and not args.bar:
|
||||
sys.stdout.write("\r\n->")
|
||||
sys.stdout.write(data.split("\r")[0])
|
||||
self.serial.write(data)
|
||||
sleep(self.delay)
|
||||
if check > 0:
|
||||
self.performcheck(data)
|
||||
elif not args.bar:
|
||||
sys.stdout.write(" -> send without check")
|
||||
|
||||
def read(self, length):
|
||||
return self.serial.read(length)
|
||||
|
||||
def close(self):
|
||||
self.serial.flush()
|
||||
self.serial.close()
|
||||
|
||||
|
||||
class TcpSocketTransport(AbstractTransport):
|
||||
def __init__(self, host, port):
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.socket = None
|
||||
|
||||
try:
|
||||
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
except socket.error as e:
|
||||
raise TransportError(e.strerror)
|
||||
|
||||
try:
|
||||
self.socket.connect((host, port))
|
||||
except socket.error as e:
|
||||
raise TransportError(e.strerror)
|
||||
# read intro from telnet server (see telnet_srv.lua)
|
||||
self.socket.recv(50)
|
||||
|
||||
def writeln(self, data, check=1):
|
||||
if len(data) > 0 and not args.bar:
|
||||
sys.stdout.write("\r\n->")
|
||||
sys.stdout.write(data.split("\r")[0])
|
||||
self.socket.sendall(data)
|
||||
if check > 0:
|
||||
self.performcheck(data)
|
||||
elif not args.bar:
|
||||
sys.stdout.write(" -> send without check")
|
||||
|
||||
def read(self, length):
|
||||
return self.socket.recv(length)
|
||||
|
||||
def close(self):
|
||||
self.socket.close()
|
||||
|
||||
|
||||
def decidetransport(cliargs):
|
||||
if cliargs.ip:
|
||||
data = cliargs.ip.split(':')
|
||||
host = data[0]
|
||||
if len(data) == 2:
|
||||
port = int(data[1])
|
||||
else:
|
||||
port = 23
|
||||
return TcpSocketTransport(host, port)
|
||||
else:
|
||||
return SerialTransport(cliargs.port, cliargs.baud, cliargs.delay)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# parse arguments or use defaults
|
||||
parser = argparse.ArgumentParser(description='ESP8266 Lua script uploader.')
|
||||
parser.add_argument('-p', '--port', default='/dev/ttyUSB0', help='Device name, default /dev/ttyUSB0')
|
||||
parser.add_argument('-b', '--baud', default=9600, help='Baudrate, default 9600')
|
||||
parser.add_argument('-f', '--src', default='main.lua', help='Source file on computer, default main.lua')
|
||||
parser.add_argument('-t', '--dest', default=None, help='Destination file on MCU, default to source file name')
|
||||
parser.add_argument('-c', '--compile', action='store_true', help='Compile lua to lc after upload')
|
||||
parser.add_argument('-r', '--restart', action='store_true', help='Restart MCU after upload')
|
||||
parser.add_argument('-d', '--dofile', action='store_true', help='Run the Lua script after upload')
|
||||
parser.add_argument('-v', '--verbose', action='store_true', help="Show progress messages.")
|
||||
parser.add_argument('-a', '--append', action='store_true', help='Append source file to destination file.')
|
||||
parser.add_argument('-l', '--list', action='store_true', help='List files on device')
|
||||
parser.add_argument('-w', '--wipe', action='store_true', help='Delete all lua/lc files on device.')
|
||||
parser.add_argument('-i', '--id', action='store_true', help='Query the modules chip id.')
|
||||
parser.add_argument('-e', '--echo', action='store_true', help='Echo output of MCU until script is terminated.')
|
||||
parser.add_argument('--bar', action='store_true', help='Show a progress bar for uploads instead of printing each line')
|
||||
parser.add_argument('--delay', default=0.3, help='Delay in seconds between each write.', type=float)
|
||||
parser.add_argument('--delete', default=None, help='Delete a lua/lc file from device.')
|
||||
parser.add_argument('--ip', default=None, help='Connect to a telnet server on the device (--ip IP[:port])')
|
||||
args = parser.parse_args()
|
||||
|
||||
transport = decidetransport(args)
|
||||
|
||||
if args.bar and not tqdm_installed:
|
||||
sys.stdout.write("You must install the tqdm library to use the bar feature\n")
|
||||
sys.stdout.write("To install, at the prompt type: \"pip install tqdm\"\n")
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
if args.list:
|
||||
transport.writeln("local l = file.list();for k,v in pairs(l) do print('name:'..k..', size:'..v)end\r", 0)
|
||||
while True:
|
||||
char = transport.read(1)
|
||||
if char == '' or char == chr(62):
|
||||
break
|
||||
sys.stdout.write(char)
|
||||
sys.exit(0)
|
||||
|
||||
if args.id:
|
||||
transport.writeln("=node.chipid()\r", 0)
|
||||
id=""
|
||||
while True:
|
||||
char = transport.read(1)
|
||||
if char == '' or char == chr(62):
|
||||
break
|
||||
if char.isdigit():
|
||||
id += char
|
||||
print("\n"+id)
|
||||
sys.exit(0)
|
||||
|
||||
if args.wipe:
|
||||
transport.writeln("local l = file.list();for k,v in pairs(l) do print(k)end\r", 0)
|
||||
file_list = []
|
||||
fn = ""
|
||||
while True:
|
||||
char = transport.read(1)
|
||||
if char == '' or char == chr(62):
|
||||
break
|
||||
if char not in ['\r', '\n']:
|
||||
fn += char
|
||||
else:
|
||||
if fn:
|
||||
file_list.append(fn.strip())
|
||||
fn = ''
|
||||
for fn in file_list[1:]: # first line is the list command sent to device
|
||||
if args.verbose:
|
||||
sys.stderr.write("Delete file {} from device.\r\n".format(fn))
|
||||
transport.writeln("file.remove(\"" + fn + "\")\r")
|
||||
sys.exit(0)
|
||||
|
||||
if args.delete:
|
||||
transport.writeln("file.remove(\"" + args.delete + "\")\r")
|
||||
sys.exit(0)
|
||||
|
||||
if args.dest is None:
|
||||
args.dest = basename(args.src)
|
||||
|
||||
# open source file for reading
|
||||
try:
|
||||
try:
|
||||
f = open(args.src, "rt")
|
||||
except:
|
||||
import os
|
||||
base_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
f = open(os.path.join(base_dir, args.src), "rt")
|
||||
os.chdir(base_dir)
|
||||
except:
|
||||
sys.stderr.write("Could not open input file \"%s\"\n" % args.src)
|
||||
sys.exit(1)
|
||||
|
||||
# Verify the selected file will not exceed the size of the serial buffer.
|
||||
# The size of the buffer is 256. This script does not accept files with
|
||||
# lines longer than 230 characters to have some room for command overhead.
|
||||
num_lines = 0
|
||||
for ln in f:
|
||||
if len(ln) > 230:
|
||||
sys.stderr.write("File \"%s\" contains a line with more than 240 "
|
||||
"characters. This exceeds the size of the serial buffer.\n"
|
||||
% args.src)
|
||||
f.close()
|
||||
sys.exit(1)
|
||||
num_lines += 1
|
||||
|
||||
# Go back to the beginning of the file after verifying it has the correct
|
||||
# line length
|
||||
f.seek(0)
|
||||
|
||||
# set serial timeout
|
||||
if args.verbose:
|
||||
sys.stderr.write("Upload starting\r\n")
|
||||
|
||||
# remove existing file on device
|
||||
if args.append==False:
|
||||
if args.verbose:
|
||||
sys.stderr.write("Stage 1. Deleting old file from flash memory")
|
||||
transport.writeln("file.open(\"" + args.dest + "\", \"w\")\r")
|
||||
transport.writeln("file.close()\r")
|
||||
transport.writeln("file.remove(\"" + args.dest + "\")\r")
|
||||
else:
|
||||
if args.verbose:
|
||||
sys.stderr.write("[SKIPPED] Stage 1. Deleting old file from flash memory [SKIPPED]")
|
||||
|
||||
|
||||
# read source file line by line and write to device
|
||||
if args.verbose:
|
||||
sys.stderr.write("\r\nStage 2. Creating file in flash memory and write first line")
|
||||
if args.append:
|
||||
transport.writeln("file.open(\"" + args.dest + "\", \"a+\")\r")
|
||||
else:
|
||||
transport.writeln("file.open(\"" + args.dest + "\", \"w+\")\r")
|
||||
line = f.readline()
|
||||
if args.verbose:
|
||||
sys.stderr.write("\r\nStage 3. Start writing data to flash memory...")
|
||||
if args.bar:
|
||||
for i in tqdm(range(0, num_lines)):
|
||||
transport.writer(line.strip())
|
||||
line = f.readline()
|
||||
else:
|
||||
while line != '':
|
||||
transport.writer(line.strip())
|
||||
line = f.readline()
|
||||
|
||||
# close both files
|
||||
f.close()
|
||||
if args.verbose:
|
||||
sys.stderr.write("\r\nStage 4. Flush data and closing file")
|
||||
transport.writeln("file.flush()\r")
|
||||
transport.writeln("file.close()\r")
|
||||
|
||||
# compile?
|
||||
if args.compile:
|
||||
if args.verbose:
|
||||
sys.stderr.write("\r\nStage 5. Compiling")
|
||||
transport.writeln("node.compile(\"" + args.dest + "\")\r")
|
||||
transport.writeln("file.remove(\"" + args.dest + "\")\r")
|
||||
|
||||
# restart or dofile
|
||||
if args.restart:
|
||||
transport.writeln("node.restart()\r")
|
||||
if args.dofile: # never exec if restart=1
|
||||
transport.writeln("dofile(\"" + args.dest + "\")\r", 0)
|
||||
|
||||
if args.echo:
|
||||
if args.verbose:
|
||||
sys.stderr.write("\r\nEchoing MCU output, press Ctrl-C to exit")
|
||||
while True:
|
||||
sys.stdout.write(transport.read(1))
|
||||
|
||||
# close serial port
|
||||
transport.close()
|
||||
|
||||
# flush screen
|
||||
sys.stdout.flush()
|
||||
sys.stderr.flush()
|
||||
if not args.bar:
|
||||
sys.stderr.write("\r\n--->>> All done <<<---\r\n")
|
||||
15
tests/client.lua
Normal file
15
tests/client.lua
Normal file
@ -0,0 +1,15 @@
|
||||
local host, port = "meteo.ulgrad.ru", 4999
|
||||
local socket = require("socket")
|
||||
local tcp = assert(socket.tcp())
|
||||
|
||||
tcp:connect(host, port);
|
||||
--note the newline below
|
||||
tcp:send("thunder!");
|
||||
|
||||
while true do
|
||||
local s, status, partial = tcp:receive()
|
||||
print(s or partial)
|
||||
print(status)
|
||||
if status == "closed" then break end
|
||||
end
|
||||
tcp:close()
|
||||
2
tests/tcp.test
Normal file
2
tests/tcp.test
Normal file
@ -0,0 +1,2 @@
|
||||
nc meteo.ulgrad.ru 4999
|
||||
nc 5.187.7.142 4999
|
||||
Loading…
x
Reference in New Issue
Block a user