当前位置: 首页 > 工具软件 > Espruino > 使用案例 >

ESP8266用网页控制电灯--从micropython移植到espruino第2集

林炫明
2023-12-01

人生苦短,能省一秒是一秒,但是我不但没省出来,反而越来越离谱。上次说了micropython的wifi经常断,这次改espruino后两天就发现问题了,而且我仍然解决不了问题,就是socket用几个小时或一两天就连不上了,复位后正常。查源代码,espruino里边根本没有超时一项,c代码我也没时间研究,反正搜索根本没有timeout一说。

espruino http服务器模块复位后测试,process.memory()查询内存使用了79个内存块,用10个http请求同时连接服务器,有两个马上返回断开。内存使用279个内存块。剩余8个连接只连接不发送数据,12分钟左右后自动超时断开,内存还是占用279个内存块。如果再次发起连接,会全部立即返回断开,不重启永久连不上了。

espruino socket服务器最多支持9个连接,如果有9个外部连接同时持续连接到80端口,内置的telnet就连不上了,其他连接断开后telnet就恢复正常。连接socket不发数据(发数据没有测试)内存占用增加。12分钟左右超时自动断开。断开后内存占用减少,重新连接仍然正常。

电脑同时发十个连接到espruino socket服务器,然后服务器设置10秒超时关闭连接,反复同时连接,服务器socket号涨到80几就连接不上了。电脑单独发一个连接到espruino socket服务器,每隔一秒发一次,然后电脑马上关闭连接,服务器socket号涨到100多就连接不上了,也就是只能连接100多次。如果由espruino socket服务器关闭连接则正常,socket号涨到500多了还能正常连接。

手机浏览器经常休眠,后台运行,网络信号丢失,可能会经常发生错误,所以可能espruino服务器不能长时间正常工作。

无奈之下,只能又改方案了,nodemcu用lua,想少浪费点生命真的不行,又学了学lua语言,倒是不太复杂。

nodemcu的ide试了试esplorer,linux版没法用,点俩下就出错误,于是用minicom,modemcu的终端跟espruino和micropython的repl比起来太简陋,太难用。而且没有网络传输脚本功能。lua跟电脑版有些差别。micropython和espruino虽然优点很多,但是网络不稳定就没法用,这个虽然难用,目前测试网络稳定,并且网络数据包里有一个极少见的保活选项。我希望这是最后一集,不要逼我最后选择Arduino。

下面是移植到lua的代码,定时和温度功能暂时不可用:

wifi.setmode(wifi.STATION)
wifi.sta.config({
    ssid = "OpenWrt",
    pwd = "xxx"
})
-- wifi.sta.setip({ip="192.168.123.33",netmask="255.255.255.0",gateway="192.168.123.1"})

local zhuangtai = {
    deng1 = false,
    deng2 = false,
    dianruzi = 0,
    dangwei = 0
}
local Deng1 = 2
local Deng2 = 1
local Dianruzi = 5
gpio.mode(Deng1, gpio.OUTPUT)
gpio.mode(Deng2, gpio.OUTPUT)
gpio.mode(Dianruzi, gpio.OUTPUT)

local baduan = 8;
function dangwei()
    baduan = baduan - 1
    if (baduan == 0) then
        baduan = 8;
        gpio.write(Dianruzi, gpio.LOW)
    end
    if baduan == zhuangtai.dianruzi then
        gpio.write(Dianruzi, gpio.HIGH)
    end
end

local mytimer = tmr.create()
mytimer:alarm(10000, tmr.ALARM_AUTO, dangwei)

srv = net.createServer(net.TCP, 10)
srv:listen(80, function(conn)
    print("lianjie")
    conn:on("receive", function(conn, payload)
        local e = payload:find("\r\n", 1, true)
        if not e then
            conn:close()
            return
        end
        local line = payload:sub(1, e - 1)
        local _
        _, _, method, url = line:find("^([A-Z]+) (.-) HTTP/1.1$")
        postparse = {url:find("mcu_do=")}
        if url == "/" then
            local htmlen = #htm
            local n = 1
            local fini = 0
            conn:send("HTTP/1.1 200 OK\r\nTransfer-Encoding:chunked\nContent-Type:text/html\r\n\r\n"..("%X\r\n"):format(#htm))
            conn:on("sent", function(conn)
                if fini == 1 then
                    conn:close()
                    return
                end
                if htmlen - n < 256 then
                    conn:send(htm:sub(n).."\r\n".."0\r\n\r\n")
                    fini = 1
                    return
                end
                conn:send(htm:sub(n, n + 255))
                n = n + 256
            end)
        elseif postparse[2] ~= nil then
            mcu_do = string.sub(url, postparse[2] + 1)            
            if mcu_do == "1on" then
                gpio.write(Deng1, gpio.HIGH)
                zhuangtai.deng1 = true
            elseif mcu_do == "1of" then
                gpio.write(Deng1, gpio.LOW)
                zhuangtai.deng1 = false
            elseif mcu_do == "2on" then
                gpio.write(Deng2, gpio.HIGH)
                zhuangtai.deng2 = true
            elseif mcu_do == "2of" then
                gpio.write(Deng2, gpio.LOW)
                zhuangtai.deng2 = false
            elseif mcu_do == "0da" then
                zhuangtai.dangwei = 0
            elseif mcu_do == "1da" then
                zhuangtai.dangwei = 1
            elseif mcu_do == "2da" then
                zhuangtai.dangwei = 2
            elseif mcu_do == "3da" then
                zhuangtai.dangwei = 3
            elseif mcu_do == "4da" then
                zhuangtai.dangwei = 4
            end

            if zhuangtai.dangwei == 0 then
                zhuangtai.dianruzi = 0
            else
                zhuangtai.dianruzi = (2^(4 - zhuangtai.dangwei))
            end
            local fini = 0
            conn:on("sent", function(conn)
                if fini == 1 then
                    conn:close()
                    return
                end
                local shuju='{"deng1":' .. tostring(zhuangtai.deng1) .. ',"deng2":' .. tostring(zhuangtai.deng2) ..',"dianruzi":' .. zhuangtai.dangwei .. "}"
                conn:send(("%X\r\n"):format(#shuju)..shuju.."\r\n".."0\r\n\r\n")
                fini = 1
            end)
            conn:send("HTTP/1.1 200 OK\r\nTransfer-Encoding:chunked\nContent-Type:text/html\r\n\r\n")
        else
            conn:on("sent", function(conn)
                conn:close()
            end)
            conn:send("HTTP/1.1 404 Not Found\r\n\r\n")
        end

    end)
end)
htm = [[<!DOCTYPE html><html><head>
<meta  http-equiv="Content-Type"  content="text/html; charset=utf-8" />
<meta name="viewport"content="width=device-width, initial-scale=1.0, minimum-scale=0.5, maximum-scale=2.0, user-scalable=yes"/>
<style>
input[type="button"]{margin:10px;width:40px;height:40px;border-radius: 10px;}
</style>
</head>
<script >
function dianji(val)
{
    var request = new XMLHttpRequest();
    request.open('GET', "?mcu_do="+val,true);
    request.onload = function() {
    zhuangtai=JSON.parse(this.response)
    deng1.style.color=zhuangtai.deng1?"red":"black"
    deng2.style.color=zhuangtai.deng2?"red":"black"    
    if( zhuangtai.dianruzi>0){dianruzi.style.color="red";
    dang.innerText= ":"+zhuangtai.dianruzi+"档"}
    else {dianruzi.style.color="black" 
    dang.innerText= ""}
    }
    request.send();
}


function xiugaidingshi(){
var request = new XMLHttpRequest();
request.open('GET',"?mcu_do=xgd"+(shi.value-0+100)+(fen.value-0+100)+(shi2.value-0+100)+(fen2.value-0+100),true)
request.onload = function(){chenggong.innerHTML="<p>成功</p>"}
request.send();
}


function shuaxin()
{
dianji("shx")
var request = new XMLHttpRequest();
request.open('GET', "?mcu_do=dqd",true);
request.onload = function(){
aa=this.response.split("#")
shijianxianshi.innerText=aa[1]
a=aa[0].split(",")
shi.value=a[0]
fen.value=a[1]
shi2.value=a[2]
fen2.value=a[3]
}
request.send();
}
document.onload=dianji("shx")
</script>
<body  style="text-align:center">
    <h1 id=deng1 style="color:black">屋里电灯</h1>
    <input  type="button" onclick="dianji('1on');" value="开" /><span  style="margin:20px;"></span>
    <input  type="button" onclick="dianji('1of');" value="关" />
    <h1 id=deng2 style="color:black" >院里电灯</h1>
    <input  type="button" onclick="dianji('2on');" value="开" /><span  style="margin:20px;"></span>
    <input  type="button" onclick="dianji('2of');" value="关" />
    <h1 id=dianruzi style="color:black" >电褥子<span id="dang"></span></h1>
    <input  type="button" onclick="dianji('1da');" value="一档" />
    <input  type="button" onclick="dianji('2da');" value="二档" />
    <input  type="button" onclick="dianji('3da');" value="三档" />
    <input  type="button" onclick="dianji('4da');" value="四档" />
    <br><br>
    <input  type="button" onclick="dianji('0da');" value="关" />        
    <br><br><div id="shijianxianshi"></div>
    <br>开<input type="number"  style="width:60px"  value="0" id="shi" />时<input type="number"  style="width:60px"  value="0" id="fen"  />分
<br><br>关<input type="number"  style="width:60px"  value="0" id="shi2" />时<input type="number"  style="width:60px"  value="0" id="fen2"  />分
<br><br><input type="button"  style="width:80px"  onclick="xiugaidingshi()" value="修改定时"/>
<br><div id="chenggong"></div><br>
<input  type="button" onclick="dianji('wen');" value="温湿度" style="width:60px" />
    <br>    
    <p id="huixian"></p>
</body>
</html>]]

 类似资料: