DESKTOP-B25GA9E\W35
1 year ago
15 changed files with 685 additions and 1 deletions
@ -0,0 +1,10 @@ |
|||||||
|
{ |
||||||
|
"Lua.diagnostics.globals": [ |
||||||
|
"wifi", |
||||||
|
"net", |
||||||
|
"u8g2", |
||||||
|
"i2c", |
||||||
|
"gpio", |
||||||
|
"enduser_setup" |
||||||
|
] |
||||||
|
} |
After Width: | Height: | Size: 70 KiB |
After Width: | Height: | Size: 33 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 32 KiB |
Binary file not shown.
Binary file not shown.
@ -0,0 +1,27 @@ |
|||||||
|
--Init GPIO params |
||||||
|
function InitGPIO() |
||||||
|
gpio.mode(0,gpio.OUTPUT); |
||||||
|
gpio.mode(1,gpio.OUTPUT); |
||||||
|
gpio.mode(2,gpio.OUTPUT); |
||||||
|
gpio.mode(3,gpio.OUTPUT); |
||||||
|
gpio.mode(4,gpio.OUTPUT); |
||||||
|
gpio.write(0,gpio.LOW); |
||||||
|
gpio.write(1,gpio.LOW); |
||||||
|
gpio.write(2,gpio.LOW); |
||||||
|
gpio.write(3,gpio.LOW); |
||||||
|
gpio.write(4,gpio.LOW); |
||||||
|
end |
||||||
|
--Push gpio to high |
||||||
|
function GPIOOn(gpioId) |
||||||
|
if gpioId>=0 and gpioId<=4 then |
||||||
|
gpio.write(gpioId,gpio.HIGH) |
||||||
|
end |
||||||
|
end |
||||||
|
--Push gpio to low |
||||||
|
function GPIOOff(gpioId) |
||||||
|
if gpioId>=0 and gpioId<=4 then |
||||||
|
gpio.write(gpioId,gpio.LOW) |
||||||
|
end |
||||||
|
end |
||||||
|
InitGPIO(); |
||||||
|
print("gpio1-5 init over,turn all gpio to output,low") |
@ -0,0 +1,81 @@ |
|||||||
|
Id = 0 |
||||||
|
Sda = 5 -- GPIO14 |
||||||
|
Scl = 6 -- GPIO12 |
||||||
|
Sla = 0x3c |
||||||
|
i2c.setup(Id, Sda, Scl, i2c.SLOW) |
||||||
|
Disp = u8g2.ssd1306_i2c_128x64_noname(Id, Sla) |
||||||
|
print("Oled Init Success!"); |
||||||
|
|
||||||
|
Screen_WIFINAME = ""; |
||||||
|
Screen_IPADDRESS = ""; |
||||||
|
Screen_VERSION = ""; |
||||||
|
--tips to user link-AP |
||||||
|
function PageAPNet() |
||||||
|
Disp:clearBuffer() |
||||||
|
--Disp:setFont(u8g2.font_unifont_t_symbols); |
||||||
|
Disp:setFont(u8g2.font_unifont_t_symbols); |
||||||
|
Disp:drawStr(0,10,"AP-LinkMode"); |
||||||
|
Disp:setFont(u8g2.font_6x10_tf); |
||||||
|
Disp:drawStr(0,26,"Please use your"); |
||||||
|
Disp:drawStr(0,36,"mobile phone search"); |
||||||
|
Disp:drawStr(0,46,"and link ap-point"); |
||||||
|
Disp:drawStr(0,56,"DY-Light-Controller"); |
||||||
|
Disp:updateDisplay(); |
||||||
|
end |
||||||
|
|
||||||
|
--progress:1-100,tips loading and update from server |
||||||
|
function PageLoading(progress) |
||||||
|
Disp:clearBuffer(); |
||||||
|
--Disp:setFont(u8g2.font_unifont_t_symbols); |
||||||
|
Disp:setFont(u8g2.font_unifont_t_symbols); |
||||||
|
Disp:drawStr(40,10,"DYTech"); |
||||||
|
Disp:setFont(u8g2.font_6x10_tf); |
||||||
|
Disp:drawStr(16,32,"Check for update"); |
||||||
|
Disp:drawFrame(12,42,104,10); |
||||||
|
Disp:drawBox(14,44,progress,6); |
||||||
|
Disp:updateDisplay(); |
||||||
|
end |
||||||
|
|
||||||
|
-- |
||||||
|
function PageMainScene(wifiName,ipAddress,version) |
||||||
|
Disp:clearBuffer(); |
||||||
|
DrawMainScene(wifiName,ipAddress,version) |
||||||
|
Disp:updateDisplay(); |
||||||
|
Screen_WIFINAME = wifiName; |
||||||
|
Screen_IPADDRESS = ipAddress; |
||||||
|
Screen_VERSION = version; |
||||||
|
--Disp:sendBuffer(); |
||||||
|
end |
||||||
|
|
||||||
|
function DrawMainScene(wifiName,ipAddress,version) |
||||||
|
--Disp:setFont(u8g2.font_unifont_t_symbols); |
||||||
|
Disp:setFont(u8g2.font_unifont_t_symbols); |
||||||
|
Disp:drawStr(40,10,"DYTech"); |
||||||
|
Disp:setFont(u8g2.font_6x10_tf); |
||||||
|
Disp:drawStr(0,26,"Wifi:"..wifiName); |
||||||
|
Disp:drawStr(0,36,"Light Ctrl-UDP"..version); |
||||||
|
Disp:drawStr(0,46,"S:"..ipAddress..":5000"); |
||||||
|
end |
||||||
|
|
||||||
|
function PageLight(lightArr) |
||||||
|
Disp:clearBuffer(); |
||||||
|
DrawMainScene(Screen_WIFINAME,Screen_IPADDRESS,Screen_VERSION); |
||||||
|
Disp:drawCircle(16,56,4,u8g2.U8G2_DRAW_ALL); |
||||||
|
Disp:drawCircle(32,56,4,u8g2.U8G2_DRAW_ALL); |
||||||
|
Disp:drawCircle(48,56,4,u8g2.U8G2_DRAW_ALL); |
||||||
|
Disp:drawCircle(64,56,4,u8g2.U8G2_DRAW_ALL); |
||||||
|
for index, value in ipairs(lightArr) do |
||||||
|
if value then |
||||||
|
Disp:drawDisc(16*index,56,4,u8g2.U8G2_DRAW_ALL); |
||||||
|
end |
||||||
|
end |
||||||
|
Disp:sendBuffer(); |
||||||
|
--Disp:updateDisplayArea(0,0,64,64); |
||||||
|
end |
||||||
|
|
||||||
|
--PageMainScene("DF2","192.168.1.111","V1.0") |
||||||
|
--LightArr = {[1]=true,[2]=false,[3]=true,[4]=true} |
||||||
|
--PageLight(LightArr) |
||||||
|
--LightArr[1] = false; |
||||||
|
--PageLight(LightArr) |
||||||
|
PageAPNet() |
@ -1,3 +1,78 @@ |
|||||||
# WiFiLightController |
# WiFiLightController |
||||||
|
|
||||||
|
--- |
||||||
|
|
||||||
基于NodeMcu开发的ESP8266物联网LED灯控制设备,接入SSD1306作为配网以及服务显示功能,后续会增加更多功能 |
基于NodeMcu开发的ESP8266物联网LED灯控制设备,接入SSD1306作为配网以及服务显示功能,后续会增加更多功能 |
||||||
|
|
||||||
|
## 1.准备工作🧐 |
||||||
|
|
||||||
|
#### 1.1设备清单 |
||||||
|
|
||||||
|
`数据线等烧录用不在此列` |
||||||
|
|
||||||
|
| 设备名称 | 数量 | 设备型号 | |
||||||
|
| ----------- | ------ | --------------------- | |
||||||
|
| ESP8266 | 1 | ESP-12F,其他ESP8266可用型号 | |
||||||
|
| led灯珠 | 4-5个 | 3v3最低耐压 | |
||||||
|
| 电线 | 12-16条 | 常用杜邦线或者其他相似参数 | |
||||||
|
| I2C协议OLED屏幕 | 1 | SSD1306_12864_noname | |
||||||
|
| USB供电(可选) | 1 | 3.3v引脚供电&5VUSB供电 | |
||||||
|
|
||||||
|
#### 1.2固件烧录 |
||||||
|
|
||||||
|
先从该连接,下载 Flash下载工具(flash_download_tool_3.9.5_0.zip),如果有新版本可能名称会有所不同。 |
||||||
|
|
||||||
|
[工具 | 乐鑫科技 ](https://www.espressif.com.cn/zh-hans/support/download/other-tools) |
||||||
|
|
||||||
|
下载完之后,将工程下的flash_download_tool_3.9.5.exe打开 |
||||||
|
![](DocRes\1_1.jpg) |
||||||
|
|
||||||
|
选择ESP8266 |
||||||
|
|
||||||
|
![](DocRes\1_2.jpg) |
||||||
|
|
||||||
|
进入如下界面,点击第一项,选择工程下 Firmware里对应的固件文件,由于程序使用的固件版本为float,但未曾写过使用float类型的程序。int没有测试过,保险起见可以选择float版本,右边填0。选择如下所示,串口检测到后点击对应的串口进行烧录即可。 |
||||||
|
|
||||||
|
![](DocRes/1_0.jpg) |
||||||
|
|
||||||
|
烧录的波特率默认为115200,运行以及开发用的波特率同理。 |
||||||
|
|
||||||
|
#### 1.3程序烧录 |
||||||
|
|
||||||
|
首先去github上下载ESPlorer,右侧release可以下载最新的发布版本,可能需要翻墙。 |
||||||
|
|
||||||
|
[ESPlorer](https://github.com/4refr0nt/ESPlorer) |
||||||
|
|
||||||
|
下载完成后运行ESPlorer.bat,即可打开该开发工具,然后打开工程的所有lua文件并保存到ESP8266中。目前还处于手动配置网络的阶段,后续会继续优化该配网功能。 |
||||||
|
|
||||||
|
## 2.接线说明🔌 |
||||||
|
|
||||||
|
NodeMCU开发板引脚图 |
||||||
|
|
||||||
|
![](DocRes/NodeMcu_Pinout.webp) |
||||||
|
|
||||||
|
#### 2.1GPIO-LED接线说明 |
||||||
|
|
||||||
|
GPIO控制D0-D4,一共五路GPIO供电开关。 |
||||||
|
|
||||||
|
| 接线方式 | LED引脚 | ESP8266引脚 | |
||||||
|
| ---- | ----- | --------- | |
||||||
|
| 直连 | 负极 | GND | |
||||||
|
| 直连 | 正极 | D0 | |
||||||
|
| 直连 | 正极 | D1 | |
||||||
|
| 直连 | 正极 | D2 | |
||||||
|
| 直连 | 正极 | D3 | |
||||||
|
| 直连 | 正极 | D4 | |
||||||
|
|
||||||
|
#### 2.2SSD1306-12864-I2C接线说明 |
||||||
|
|
||||||
|
oled显示屏用于显示配网参数以及连接状态,指示灯状态等信息,方便更快找到设备故障原因。 |
||||||
|
|
||||||
|
| 接线方式 | SSD1306-12864-I2C引脚 | ESP8266引脚 | |
||||||
|
| ---- | ------------------- | --------- | |
||||||
|
| 直连 | GND | GND | |
||||||
|
| 直连 | VCC | 3v3 | |
||||||
|
| 直连 | SCL | D6 | |
||||||
|
| 直连 | SDA | D5 | |
||||||
|
|
||||||
|
`如有其他设备需要接线后续补充` |
@ -0,0 +1,23 @@ |
|||||||
|
-- |
||||||
|
-- json.lua |
||||||
|
-- |
||||||
|
-- Copyright (c) 2020 rxi |
||||||
|
-- |
||||||
|
-- Permission is hereby granted, free of charge, to any person obtaining a copy of |
||||||
|
-- this software and associated documentation files (the "Software"), to deal in |
||||||
|
-- the Software without restriction, including without limitation the rights to |
||||||
|
-- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies |
||||||
|
-- of the Software, and to permit persons to whom the Software is furnished to do |
||||||
|
-- so, subject to the following conditions: |
||||||
|
-- |
||||||
|
-- The above copyright notice and this permission notice shall be included in all |
||||||
|
-- copies or substantial portions of the Software. |
||||||
|
-- |
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||||
|
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||||
|
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||||
|
-- SOFTWARE. |
||||||
|
-- |
@ -0,0 +1,364 @@ |
|||||||
|
local json = { _version = "0.1.2" } |
||||||
|
|
||||||
|
------------------------------------------------------------------------------- |
||||||
|
-- Encode |
||||||
|
------------------------------------------------------------------------------- |
||||||
|
|
||||||
|
local encode |
||||||
|
|
||||||
|
local escape_char_map = { |
||||||
|
[ "\\" ] = "\\", |
||||||
|
[ "\"" ] = "\"", |
||||||
|
[ "\b" ] = "b", |
||||||
|
[ "\f" ] = "f", |
||||||
|
[ "\n" ] = "n", |
||||||
|
[ "\r" ] = "r", |
||||||
|
[ "\t" ] = "t", |
||||||
|
} |
||||||
|
|
||||||
|
local escape_char_map_inv = { [ "/" ] = "/" } |
||||||
|
for k, v in pairs(escape_char_map) do |
||||||
|
escape_char_map_inv[v] = k |
||||||
|
end |
||||||
|
|
||||||
|
|
||||||
|
local function escape_char(c) |
||||||
|
return "\\" .. (escape_char_map[c] or string.format("u%04x", c:byte())) |
||||||
|
end |
||||||
|
|
||||||
|
|
||||||
|
local function encode_nil(val) |
||||||
|
return "null" |
||||||
|
end |
||||||
|
|
||||||
|
|
||||||
|
local function encode_table(val, stack) |
||||||
|
local res = {} |
||||||
|
stack = stack or {} |
||||||
|
|
||||||
|
-- Circular reference? |
||||||
|
if stack[val] then error("circular reference") end |
||||||
|
|
||||||
|
stack[val] = true |
||||||
|
|
||||||
|
if rawget(val, 1) ~= nil or next(val) == nil then |
||||||
|
-- Treat as array -- check keys are valid and it is not sparse |
||||||
|
local n = 0 |
||||||
|
for k in pairs(val) do |
||||||
|
if type(k) ~= "number" then |
||||||
|
error("invalid table: mixed or invalid key types") |
||||||
|
end |
||||||
|
n = n + 1 |
||||||
|
end |
||||||
|
if n ~= #val then |
||||||
|
error("invalid table: sparse array") |
||||||
|
end |
||||||
|
-- Encode |
||||||
|
for i, v in ipairs(val) do |
||||||
|
table.insert(res, encode(v, stack)) |
||||||
|
end |
||||||
|
stack[val] = nil |
||||||
|
return "[" .. table.concat(res, ",") .. "]" |
||||||
|
|
||||||
|
else |
||||||
|
-- Treat as an object |
||||||
|
for k, v in pairs(val) do |
||||||
|
if type(k) ~= "string" then |
||||||
|
error("invalid table: mixed or invalid key types") |
||||||
|
end |
||||||
|
table.insert(res, encode(k, stack) .. ":" .. encode(v, stack)) |
||||||
|
end |
||||||
|
stack[val] = nil |
||||||
|
return "{" .. table.concat(res, ",") .. "}" |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
|
||||||
|
local function encode_string(val) |
||||||
|
return '"' .. val:gsub('[%z\1-\31\\"]', escape_char) .. '"' |
||||||
|
end |
||||||
|
|
||||||
|
|
||||||
|
local function encode_number(val) |
||||||
|
-- Check for NaN, -inf and inf |
||||||
|
if val ~= val or val <= -math.huge or val >= math.huge then |
||||||
|
error("unexpected number value '" .. tostring(val) .. "'") |
||||||
|
end |
||||||
|
return string.format("%.14g", val) |
||||||
|
end |
||||||
|
|
||||||
|
|
||||||
|
local type_func_map = { |
||||||
|
[ "nil" ] = encode_nil, |
||||||
|
[ "table" ] = encode_table, |
||||||
|
[ "string" ] = encode_string, |
||||||
|
[ "number" ] = encode_number, |
||||||
|
[ "boolean" ] = tostring, |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
encode = function(val, stack) |
||||||
|
local t = type(val) |
||||||
|
local f = type_func_map[t] |
||||||
|
if f then |
||||||
|
return f(val, stack) |
||||||
|
end |
||||||
|
error("unexpected type '" .. t .. "'") |
||||||
|
end |
||||||
|
|
||||||
|
|
||||||
|
function json.encode(val) |
||||||
|
return ( encode(val) ) |
||||||
|
end |
||||||
|
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------- |
||||||
|
-- Decode |
||||||
|
------------------------------------------------------------------------------- |
||||||
|
|
||||||
|
local parse |
||||||
|
|
||||||
|
local function create_set(...) |
||||||
|
local res = {} |
||||||
|
for i = 1, select("#", ...) do |
||||||
|
res[ select(i, ...) ] = true |
||||||
|
end |
||||||
|
return res |
||||||
|
end |
||||||
|
|
||||||
|
local space_chars = create_set(" ", "\t", "\r", "\n") |
||||||
|
local delim_chars = create_set(" ", "\t", "\r", "\n", "]", "}", ",") |
||||||
|
local escape_chars = create_set("\\", "/", '"', "b", "f", "n", "r", "t", "u") |
||||||
|
local literals = create_set("true", "false", "null") |
||||||
|
|
||||||
|
local literal_map = { |
||||||
|
[ "true" ] = true, |
||||||
|
[ "false" ] = false, |
||||||
|
[ "null" ] = nil, |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
local function next_char(str, idx, set, negate) |
||||||
|
for i = idx, #str do |
||||||
|
if set[str:sub(i, i)] ~= negate then |
||||||
|
return i |
||||||
|
end |
||||||
|
end |
||||||
|
return #str + 1 |
||||||
|
end |
||||||
|
|
||||||
|
|
||||||
|
local function decode_error(str, idx, msg) |
||||||
|
local line_count = 1 |
||||||
|
local col_count = 1 |
||||||
|
for i = 1, idx - 1 do |
||||||
|
col_count = col_count + 1 |
||||||
|
if str:sub(i, i) == "\n" then |
||||||
|
line_count = line_count + 1 |
||||||
|
col_count = 1 |
||||||
|
end |
||||||
|
end |
||||||
|
error( string.format("%s at line %d col %d", msg, line_count, col_count) ) |
||||||
|
end |
||||||
|
|
||||||
|
|
||||||
|
local function codepoint_to_utf8(n) |
||||||
|
-- http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=iws-appendixa |
||||||
|
local f = math.floor |
||||||
|
if n <= 0x7f then |
||||||
|
return string.char(n) |
||||||
|
elseif n <= 0x7ff then |
||||||
|
return string.char(f(n / 64) + 192, n % 64 + 128) |
||||||
|
elseif n <= 0xffff then |
||||||
|
return string.char(f(n / 4096) + 224, f(n % 4096 / 64) + 128, n % 64 + 128) |
||||||
|
elseif n <= 0x10ffff then |
||||||
|
return string.char(f(n / 262144) + 240, f(n % 262144 / 4096) + 128, |
||||||
|
f(n % 4096 / 64) + 128, n % 64 + 128) |
||||||
|
end |
||||||
|
error( string.format("invalid unicode codepoint '%x'", n) ) |
||||||
|
end |
||||||
|
|
||||||
|
|
||||||
|
local function parse_unicode_escape(s) |
||||||
|
local n1 = tonumber( s:sub(1, 4), 16 ) |
||||||
|
local n2 = tonumber( s:sub(7, 10), 16 ) |
||||||
|
-- Surrogate pair? |
||||||
|
if n2 then |
||||||
|
return codepoint_to_utf8((n1 - 0xd800) * 0x400 + (n2 - 0xdc00) + 0x10000) |
||||||
|
else |
||||||
|
return codepoint_to_utf8(n1) |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
|
||||||
|
local function parse_string(str, i) |
||||||
|
local res = "" |
||||||
|
local j = i + 1 |
||||||
|
local k = j |
||||||
|
|
||||||
|
while j <= #str do |
||||||
|
local x = str:byte(j) |
||||||
|
|
||||||
|
if x < 32 then |
||||||
|
decode_error(str, j, "control character in string") |
||||||
|
|
||||||
|
elseif x == 92 then -- `\`: Escape |
||||||
|
res = res .. str:sub(k, j - 1) |
||||||
|
j = j + 1 |
||||||
|
local c = str:sub(j, j) |
||||||
|
if c == "u" then |
||||||
|
local hex = str:match("^[dD][89aAbB]%x%x\\u%x%x%x%x", j + 1) |
||||||
|
or str:match("^%x%x%x%x", j + 1) |
||||||
|
or decode_error(str, j - 1, "invalid unicode escape in string") |
||||||
|
res = res .. parse_unicode_escape(hex) |
||||||
|
j = j + #hex |
||||||
|
else |
||||||
|
if not escape_chars[c] then |
||||||
|
decode_error(str, j - 1, "invalid escape char '" .. c .. "' in string") |
||||||
|
end |
||||||
|
res = res .. escape_char_map_inv[c] |
||||||
|
end |
||||||
|
k = j + 1 |
||||||
|
|
||||||
|
elseif x == 34 then -- `"`: End of string |
||||||
|
res = res .. str:sub(k, j - 1) |
||||||
|
return res, j + 1 |
||||||
|
end |
||||||
|
|
||||||
|
j = j + 1 |
||||||
|
end |
||||||
|
|
||||||
|
decode_error(str, i, "expected closing quote for string") |
||||||
|
end |
||||||
|
|
||||||
|
|
||||||
|
local function parse_number(str, i) |
||||||
|
local x = next_char(str, i, delim_chars) |
||||||
|
local s = str:sub(i, x - 1) |
||||||
|
local n = tonumber(s) |
||||||
|
if not n then |
||||||
|
decode_error(str, i, "invalid number '" .. s .. "'") |
||||||
|
end |
||||||
|
return n, x |
||||||
|
end |
||||||
|
|
||||||
|
|
||||||
|
local function parse_literal(str, i) |
||||||
|
local x = next_char(str, i, delim_chars) |
||||||
|
local word = str:sub(i, x - 1) |
||||||
|
if not literals[word] then |
||||||
|
decode_error(str, i, "invalid literal '" .. word .. "'") |
||||||
|
end |
||||||
|
return literal_map[word], x |
||||||
|
end |
||||||
|
|
||||||
|
|
||||||
|
local function parse_array(str, i) |
||||||
|
local res = {} |
||||||
|
local n = 1 |
||||||
|
i = i + 1 |
||||||
|
while 1 do |
||||||
|
local x |
||||||
|
i = next_char(str, i, space_chars, true) |
||||||
|
-- Empty / end of array? |
||||||
|
if str:sub(i, i) == "]" then |
||||||
|
i = i + 1 |
||||||
|
break |
||||||
|
end |
||||||
|
-- Read token |
||||||
|
x, i = parse(str, i) |
||||||
|
res[n] = x |
||||||
|
n = n + 1 |
||||||
|
-- Next token |
||||||
|
i = next_char(str, i, space_chars, true) |
||||||
|
local chr = str:sub(i, i) |
||||||
|
i = i + 1 |
||||||
|
if chr == "]" then break end |
||||||
|
if chr ~= "," then decode_error(str, i, "expected ']' or ','") end |
||||||
|
end |
||||||
|
return res, i |
||||||
|
end |
||||||
|
|
||||||
|
|
||||||
|
local function parse_object(str, i) |
||||||
|
local res = {} |
||||||
|
i = i + 1 |
||||||
|
while 1 do |
||||||
|
local key, val |
||||||
|
i = next_char(str, i, space_chars, true) |
||||||
|
-- Empty / end of object? |
||||||
|
if str:sub(i, i) == "}" then |
||||||
|
i = i + 1 |
||||||
|
break |
||||||
|
end |
||||||
|
-- Read key |
||||||
|
if str:sub(i, i) ~= '"' then |
||||||
|
decode_error(str, i, "expected string for key") |
||||||
|
end |
||||||
|
key, i = parse(str, i) |
||||||
|
-- Read ':' delimiter |
||||||
|
i = next_char(str, i, space_chars, true) |
||||||
|
if str:sub(i, i) ~= ":" then |
||||||
|
decode_error(str, i, "expected ':' after key") |
||||||
|
end |
||||||
|
i = next_char(str, i + 1, space_chars, true) |
||||||
|
-- Read value |
||||||
|
val, i = parse(str, i) |
||||||
|
-- Set |
||||||
|
res[key] = val |
||||||
|
-- Next token |
||||||
|
i = next_char(str, i, space_chars, true) |
||||||
|
local chr = str:sub(i, i) |
||||||
|
i = i + 1 |
||||||
|
if chr == "}" then break end |
||||||
|
if chr ~= "," then decode_error(str, i, "expected '}' or ','") end |
||||||
|
end |
||||||
|
return res, i |
||||||
|
end |
||||||
|
|
||||||
|
|
||||||
|
local char_func_map = { |
||||||
|
[ '"' ] = parse_string, |
||||||
|
[ "0" ] = parse_number, |
||||||
|
[ "1" ] = parse_number, |
||||||
|
[ "2" ] = parse_number, |
||||||
|
[ "3" ] = parse_number, |
||||||
|
[ "4" ] = parse_number, |
||||||
|
[ "5" ] = parse_number, |
||||||
|
[ "6" ] = parse_number, |
||||||
|
[ "7" ] = parse_number, |
||||||
|
[ "8" ] = parse_number, |
||||||
|
[ "9" ] = parse_number, |
||||||
|
[ "-" ] = parse_number, |
||||||
|
[ "t" ] = parse_literal, |
||||||
|
[ "f" ] = parse_literal, |
||||||
|
[ "n" ] = parse_literal, |
||||||
|
[ "[" ] = parse_array, |
||||||
|
[ "{" ] = parse_object, |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
parse = function(str, idx) |
||||||
|
local chr = str:sub(idx, idx) |
||||||
|
local f = char_func_map[chr] |
||||||
|
if f then |
||||||
|
return f(str, idx) |
||||||
|
end |
||||||
|
decode_error(str, idx, "unexpected character '" .. chr .. "'") |
||||||
|
end |
||||||
|
|
||||||
|
|
||||||
|
function json.decode(str) |
||||||
|
if type(str) ~= "string" then |
||||||
|
error("expected argument of type string, got " .. type(str)) |
||||||
|
end |
||||||
|
local res, idx = parse(str, next_char(str, 1, space_chars, true)) |
||||||
|
idx = next_char(str, idx, space_chars, true) |
||||||
|
if idx <= #str then |
||||||
|
decode_error(str, idx, "trailing garbage") |
||||||
|
end |
||||||
|
return res |
||||||
|
end |
||||||
|
|
||||||
|
|
||||||
|
return json |
@ -0,0 +1,46 @@ |
|||||||
|
-- UDPSocket = nil; |
||||||
|
-- UDPIP = nil; |
||||||
|
-- UDPPort = nil; |
||||||
|
require("GPIO"); |
||||||
|
function StartUDPService() |
||||||
|
if UDPSocket == nil then |
||||||
|
UDPSocket = net.createUDPSocket(); |
||||||
|
UDPSocket:listen(5000); |
||||||
|
UDPSocket:on("receive", UDPService); |
||||||
|
UDPPort, UDPIP = UDPSocket:getaddr(); |
||||||
|
else |
||||||
|
UDPSocket:listen(5000); |
||||||
|
UDPSocket:on("receive", UDPService); |
||||||
|
UDPPort, UDPIP = UDPSocket:getaddr(); |
||||||
|
end |
||||||
|
--print(string.format("local UDP socket address / port: %s:%d", UDPIP, UDPPort)) |
||||||
|
end |
||||||
|
|
||||||
|
function UDPService(s, data, port, ip) |
||||||
|
local commandSet = {}; |
||||||
|
for word in string.gmatch(data, "[^-]+") do |
||||||
|
table.insert(commandSet,word); |
||||||
|
end |
||||||
|
print("get data count" .. #commandSet); |
||||||
|
if string.match(data,"^Light") then |
||||||
|
if #commandSet==3 then |
||||||
|
print(tonumber(commandSet[2]).."-"..commandSet[3]) |
||||||
|
if commandSet[3]=="On" and tonumber(commandSet[2])~=nil then |
||||||
|
GPIOOn(tonumber(commandSet[2])); |
||||||
|
s:send(port, ip, "Light "..commandSet[2].." "..commandSet[3]); |
||||||
|
elseif commandSet[3]=="Off" and tonumber(commandSet[2])~=nil then |
||||||
|
GPIOOff(tonumber(commandSet[2])); |
||||||
|
s:send(port, ip, "Light "..commandSet[2].." "..commandSet[3]); |
||||||
|
else |
||||||
|
s:send(port, ip, "CommandFaild"); |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
function StopUDPService() |
||||||
|
if UDPSocket ~= nil then |
||||||
|
UDPSocket:close(); |
||||||
|
end |
||||||
|
end |
||||||
|
--StartUDPService(); |
@ -0,0 +1,46 @@ |
|||||||
|
StationCfg = {} |
||||||
|
IpCfg = {} |
||||||
|
|
||||||
|
function AutoLink() |
||||||
|
wifi.setmode(wifi.STATION) |
||||||
|
StationCfg.ssid="DF2" |
||||||
|
StationCfg.pwd="wodepasstne?" |
||||||
|
StationCfg.save=true |
||||||
|
wifi.sta.config(StationCfg) |
||||||
|
wifi.sta.connect() |
||||||
|
end |
||||||
|
|
||||||
|
--mobile setting ap and passwd |
||||||
|
function AutoLinkByMobile() |
||||||
|
wifi.setmode(wifi.STATIONAP) |
||||||
|
wifi.ap.config({ssid="MyPersonalSSID", auth=wifi.OPEN}) |
||||||
|
enduser_setup.manual(true) |
||||||
|
enduser_setup.start( |
||||||
|
function() |
||||||
|
print("Connected to WiFi as:" .. wifi.sta.getip()) |
||||||
|
end, |
||||||
|
function(err, str) |
||||||
|
print("enduser_setup: Err #" .. err .. ": " .. str) |
||||||
|
end |
||||||
|
) |
||||||
|
print("init endUserServer") |
||||||
|
end |
||||||
|
|
||||||
|
|
||||||
|
--GetAPList |
||||||
|
-- function Listap(t) |
||||||
|
-- for k,v in pairs(t) do |
||||||
|
-- print(k.." : "..v) |
||||||
|
-- end |
||||||
|
-- end |
||||||
|
-- wifi.sta.getap(Listap) |
||||||
|
|
||||||
|
function SetIP(ipAddress,netmask,gateway) |
||||||
|
IpCfg = { |
||||||
|
ip = ipAddress, |
||||||
|
netmask = netmask, |
||||||
|
gateway = gateway |
||||||
|
} |
||||||
|
wifi.sta.setip(IpCfg) |
||||||
|
end |
||||||
|
--SetIP("192.168.1.115","255.255.255.0","192.168.1.1") |
Loading…
Reference in new issue