【问题标题】:NodeMcu Lua receive information from app in a serverNodeMcu Lua 从服务器中的应用程序接收信息
【发布时间】:2018-01-29 19:03:59
【问题描述】:

我在 MIT APP Inventor 中开发了一个简单的应用程序,用于控制热泵热水器。

应用程序会为每个按下的按钮发送不同的字符串,NodeMcu 会验证按下的是哪个按钮,如下面的代码所示。

srv=net.createServer(net.TCP)
srv:listen(80,function(conn)

conn:on("receive", function(client,request)
    local buf = ""
    local _, _, method, path, vars = string.find(request, "([A-Z]+) (.+)?(.+) HTTP")
    if(method == nil)then 
        _, _, method, path = string.find(request, "([A-Z]+) (.+) HTTP")
    end
    local _GET = {}
    if (vars ~= nil)then
        for k, v in string.gmatch(vars, "(%w+)=(%w+)&*") do
            _GET[k] = v
        end
    end
    local _on,_off = "",""

    if(_GET.pin == "ip")then
        local ip=wifi.sta.getip()
        local ler_ip=string.sub(ip,1,13)
        dofile("novolcd.lua").cls()
        dofile("novolcd.lua").lcdprint("IP="..ler_ip)
     elseif(_GET.pin == "05a60")then
        sp_temperaturas[5]=60

     elseif(_GET.pin == "06a60")then
        sp_temperaturas[6]=60

     elseif(_GET.pin == "Ferias")then
        dofile("novolcd.lua").cls()
        dofile("novolcd.lua").lcdprint("  Modo ferias   ")
        modo_ferias()

     elseif(_GET.pin == "Parar2")then
       dofile("novolcd.lua").cls()
        dofile("novolcd.lua").lcdprint("  Parar")
     end

end)
conn:on("sent", function (c) c:close() end)
  end)

当按下“Ferias”按钮时,系统通过调用函数 modo_ferias() 开始加热过程。

     function aquecer()

        local kp=100/10
        local ki=5
        local kd=5
        local tempo_on=0
        local tempo_off=0
        i=0
        local duty=0            
        erro=sp_temp-t_atual
        soma_erro = soma_erro + erro/5;
        dif_erro = (erro - erro_ant)/5;
        erro_ant = erro;
        print(erro.."          "..soma_erro.."    "..dif_erro)
        duty= kp * erro + soma_erro / ki + dif_erro * kd 
        print(duty)

        tempo_on= duty *50   
        if (tempo_on > 5000) then
            tempo_on = 5000
        end

        tempo_off = 5000 - tempo_on

        repeat
            i = i + 1
            tmr.delay(1000)
        until (i >= tempo_off)               

        gpio.write(8, gpio.HIGH)

        repeat
            i = i + 1      
            tmr.delay(1000)       
        until (i == 5000)

        gpio.mode(8, gpio.INPUT)

    end

    function modo_ferias()

        repeat            
            sair_ferias=0
            pressao()
            if (pressao_psi <=3)
                sair_ferias=1
            end 
            t_atual=ler_temperatura()
            local int = string.format("%d", t_atual )    -- parte inteira
            local dec = string.format("%.1d", t_atual % 10000)  -- parte decimal com uma casa
            t_display = int .. "." .. dec
            rtc()
            dofile("novolcd.lua").cls()
            dofile("novolcd.lua").lcdprint("Temp="..t_display.."  ST="..sp_temp..data_horas)
            sp_temp=40
           local horas_ferias=hour
           if(horas_ferias==0 or horas_ferias==1 or horas_ferias==2 or horas_ferias==3 or horas_ferias==4 or horas_ferias==5 or horas_ferias==6) then
             sp_temp=70
           end 
            if (sp_temp>t_atual) then
                aquecer()

            end  
        until (sair_ferias==1)    
    end

这就是我的问题出现的地方。如果我在按下“Ferias”按钮后按下应用程序中的按钮,NodeMcu 将不知道它,因为程序处于加热功能并且不验证应用程序是否发送任何指令。

有什么方法可以同时监听应用命令和加热过程?

【问题讨论】:

  • 问题是你的函数aquecer() 永远不会放弃控制。 tmr.delay() 是一个繁忙的循环,没有其他东西可以同时运行(比如你的 TCP 服务器)。您需要重写代码以使用只有一个主循环的事件。例如,让您的 TCP 处理程序设置一个全局标志以指示按下了按钮。该全局标志由您的 main 函数在执行主循环时读取。

标签: timer lua parallel-processing nodemcu interruption


【解决方案1】:

有几件事

全局状态

因为程序在加热功能中,并没有验证应用是否发送任何指令

如果通过按下各个按钮触发的命令不能彼此独立运行,那么您需要某种形式的全局状态来确保它们不会相互干扰。

忙循环

repeat
    i = i + 1
    tmr.delay(1000)
until (i == 5000)

This is a no-go 与 NodeMCU,因为它本质上是一个停止世界的繁忙循环。此外,tmr.delayscheduled to be removed,因为它经常被滥用。

任务发布

node.task.post 是一种可能的解决方案,用于安排“在不久的将来”执行的任务。您可以使用它从接收回调中发布任务,而不是同步执行它们。

【讨论】:

  • 首先感谢您的帮助。老实说,我试图理解 noed.task.post 解决方案,但没有退出。我不明白如何将服务器定义为高优先级,以及如何将监听部分和加热部分关联起来。不能在循环 i = i + 1 tmr.delay(1000) until (i == 5000) 上听,例如把浣熊放在这里吗?我也尝试使用 tmr.alarm() 来解决问题,但出现了最初的问题。没有办法使用计时器返回服务器大约 4 秒,然后返回加热?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-08-18
  • 1970-01-01
  • 1970-01-01
  • 2012-12-03
  • 2019-07-26
  • 2012-05-05
  • 1970-01-01
相关资源
最近更新 更多