2017-08-21 2 views
0

J'ai développé une application simple dans MIT APP Inventor qui contrôle un chauffe-eau pompe à chaleur.NodeMcu Lua recevoir des informations de l'application dans un serveur

L'application envoie une chaîne différente pour chaque bouton enfoncé et le NodeMcu vérifie quel bouton a été enfoncé, comme vous pouvez le voir dans le code ci-dessous.

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) 

Et quand le bouton « Ferias » est appuyé sur le système démarre le processus de chauffage en appelant la fonction 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 

Et voici où mon problème apparaît. Si j'appuie sur un bouton de l'application après avoir appuyé sur le bouton "Ferias", le NodeMcu ne le connaîtra pas car le programme est dans les fonctions de chauffage et ne vérifie pas si l'application a envoyé une instruction quelconque.

Y at-il un moyen d'écouter les commandes de l'application et de faire le processus de chauffage en même temps?

+0

Le problème est que votre fonction 'aquecer()' ne renonce jamais au contrôle. 'tmr.delay()' est une boucle occupée, rien d'autre ne peut être exécuté simultanément (comme votre serveur TCP). Vous devez réécrire votre code pour travailler en utilisant des événements avec une seule boucle principale. Par exemple, demandez à votre gestionnaire TCP de définir un indicateur global pour indiquer qu'un bouton a été enfoncé. Ce drapeau global est lu par votre fonction principale lors de l'exécution de la boucle principale. – ktb

Répondre

0

Il y a quelques choses

d'état global

parce que le programme est dans les fonctions de chauffage et de ne pas vérifier si l'application sended toute instruction

Si les commandes déclenchées en appuyant sur les différents boutons peuvent pas fonctionner indépendamment les uns des autres alors vous avez besoin d'une forme d'état global t o Assurez-vous qu'ils n'interfèrent pas.

boucle Occupé

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

This is a no-go avec NodeMCU comme il est essentiellement un arrêt du monde boucle occupée. En outre, tmr.delay est scheduled to be removed parce qu'il est abusé si souvent.

affichage Tâche

node.task.post est une solution possible à la planification des tâches d'exécution "dans un avenir proche". Vous pouvez l'utiliser pour publier une tâche à partir du rappel sur réception plutôt que de l'exécuter de manière synchrone.

+0

Tout d'abord, merci de votre aide. Pour être sincère j'ai essayé de comprendre la solution noed.task.post mais sans sortie. Je ne comprends pas comment je peux définir le serveur comme une priorité élevée et comment pourrais-je corréler à la fois la partie d'écoute et la partie de chauffage. could't ça marche à l'écoute pendant la boucle i = i + 1 tmr.delay (1000) jusqu'à ce que (i == 5000) Par exemple mis ici le coon? J'ai également essayé d'utiliser le tmr.alarm() pour résoudre le problème, mais le problème initial se produit. Il n'est pas possible d'utiliser une minuterie pour revenir au serveur pendant 4 secondes, puis revenir au chauffage? –