0

我在 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 将不知道它,因为程序处于加热功能中并且不验证应用程序是否发送任何指令。

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

4

1 回答 1

0

有几件事

全局状态

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

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

忙循环

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

对 NodeMCU 来说是不行的,因为它本质上是一个停止世界的繁忙循环。此外,由于经常被滥用,因此tmr.delay计划将其删除。

任务发布

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

于 2017-08-22T05:12:43.417 回答