模块中的功能忙时网络服务器未接收

Posted

技术标签:

【中文标题】模块中的功能忙时网络服务器未接收【英文标题】:webserver not receiving while function in a module is busy 【发布时间】:2019-07-10 18:14:57 【问题描述】:

我对 LUA 比较陌生,没有太多经验。

我在 nodemcu esp8266 上使用网络服务器,它控制正在转动万向节的步进电机。为此,我找到了一个工作正常的步进模块。有一个像这样转动电机的命令:turn(mno,direction,pan_speed,no_steps) 这工作正常。 我现在想让电机转动,直到来自网络服务器的另一个命令停止它。 在这里我需要一个建议。我可以使用在模块中执行命令的循环从网络服务器中启动电机。这也有效,但我无法停止电机,因为只要循环正在转动电机,网络服务器就不会收到停止命令。我尝试过使用计时器,但我仍然没有完全理解 LUA 中的事件处理。

非常欢迎任何建议

德里克

这是主程序。正如我正在尝试的那样,不同的事情只有将云台向左转动的部分是相关的。当程序左转时,它不能接受再次左转的第二个命令,这应该停止云台。

重要的是网络服务器中云台左转的部分,然后是步进模块中的“转”功能。

    motors  = require ('stepper')

    pan_speed = 1
    tilt_speed = pan_speed

    pan_steps=50
    tilt_steps=pan_steps

    steps = 50
    mno=1

    gol=1
    gor=0

    stop=1

    -- a simple http server
    if srv ~= nil then
      --srv:close()
    end

    srv=net.createServer(net.TCP,180) 
    srv:listen(80,function(conn) 
        conn:on("receive",function(conn,request) 
            -- print(node.heap())
            buf = ""
            local buf = "";
                buf = buf.."HTTP/1.1 200 OK\n\n"
            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


            if(_GET.direction or _GET.speed) or _GET.distance then

                if(_GET.direction) == "left"  then
                    print("pressed left")
                    dir = -1
                    if stop==0 then stop=1 elseif stop == 1 then stop=0 end
                    print("stop = ",stop)
                    buf = "OK" 
                    mno=1  
                    while stop == 0 do
                        turn(mno,dir,pan_speed,1)   
                    end
                 end

                if(_GET.direction) == "right" then
                    if stop==0 then stop=1 elseif stop == 1 then stop=0 end
                    buf = "OK"
                    mno=1 
                    while stop == 0  do 
                    print("gimbal dreht rechts")
                    --turn(mno,1,1,1)
                    end
                end

                if(_GET.direction) == "up" then
                    buf = "OK"
                    mno=2
                    --turn(mno,1,tilt_speed,tilt_steps)
                end

                if(_GET.direction) == "down" then
                    buf = "OK"
                    mno=2
                    --turn(mno,-1,tilt_speed,tilt_steps)
                    --collectgarbage()
                end

                if(_GET.speed) then
                    buf = "OK"
                    pan_speed = _GET.speed
                    tilt_speed = pan_speed
                    collectgarbage()
                end

                if(_GET.distance) then
                    buf = "OK"
                    pan_steps = tonumber(_GET.distance)
                    tilt_steps = pan_steps
                    collectgarbage()
                end
                --write_config() 
                collectgarbage()
            end

            conn:send(buf)
            -- srv:close()
            collectgarbage()




            print("stop 3 = ",stop)
        end) 
        print("stop 2 = ",stop)

end)

这是步进模块:

stepper = 
do

    local mot =  1,2,3,4,5,6,7,8

    -- direction = 1
    steps = 50
    speed = 4
    del = 1000 * speed
    print("Modul del = ",del)
    mno = 1
    pan_pos = 0

    gpio.mode(12, gpio.INPUT)
    gpio.write(12, gpio.HIGH)
    print("GPIO-0 = ",gpio.read(12))

    r_stop = 0
    l_stop = 0
    u_stop = 0
    d_stop = 0

    max_left = 1425
    max_right = 0
    pan_pos = 0

    stop=0

    for i = 1, 8,1 do
        gpio.mode(mot[i], gpio.OUTPUT)  --  define output
    end

    function say_stop(s)
        if s == 1 then stop = 1 end
        if s == 0 then stop = 0 end
    end

    function ask_stop()
        return stop
    end

    function set_stop(l_s,r_s,u_s,d_s)
        l_stop = l_s r_stop = r_s u_stop = u_s d_stop = d_s
    end

    function get_stop(l_stop, r_stop, u_stop, d_stop)
        return l_stop, r_stop, u_stop, d_stop
    end

    function write_config()
        cf = file.open("config_data.cfg", "w+")
        if cf then
            cf.writeline(max_left)
            cf.writeline(max_right)
            cf.writeline(pan_pos)
            cf:close()
        end
    end
    -- write_config()  

    function load_config()
        cf = file.open("config_data.cfg", "r")
        if cf then
            max_left = tonumber(cf.readline())
            max_right = tonumber(cf.readline())
            pan_pos = tonumber(cf.readline())
            print("Werte geladen")
            print("max_left = ",max_left)
            print("max_right = ",max_right)
            print("pan_pos = ",pan_pos)
            cf:close()
        end
    end

    load_config()


    function sequence_l(a, b, c, d,mno)--gimbal dreht links

        if mno == 1 then       
            gpio.write(mot[1], a)
            gpio.write(mot[2], b)
            gpio.write(mot[3], c)
            gpio.write(mot[4], d) 
            tmr.delay(del)
        end
        if gpio.read(12) == 0 then l_stop = pan_pos end 

        if mno == 2 and stop == 0  then
            gpio.write(mot[5], a)
            gpio.write(mot[6], b)
            gpio.write(mot[7], c)
            gpio.write(mot[8], d)
            tmr.delay(del)              
        end
    end

    function sequence_r(a, b, c, d,mno)--gimbal dreht rechts

        if mno == 1 then
            gpio.write(mot[1], a)
            gpio.write(mot[2], b)
            gpio.write(mot[3], c)
            gpio.write(mot[4], d)
            tmr.delay(del)                       
        end
        if gpio.read(12) == 0 then r_stop = pan_pos end  

        if mno == 2 then
            gpio.write(mot[5], a)
            gpio.write(mot[6], b)
            gpio.write(mot[7], c)
            gpio.write(mot[8], d)
            tmr.delay(del)                    
        end
    end


    function turn(mno,direction,speed,steps)
        del = 100 * speed  -- bestimmt Geschwindigkeit

        if direction == 1 then  -- Gimbal turning right                 
            while pan_pos > max_right do --Rotation in one direction
                    if stop == 1 then break end
                    pan_pos = pan_pos -1
                    tmr.alarm(3, del, 0, function() sequence_r(gpio.HIGH, gpio.LOW, gpio.LOW, gpio.LOW,mno) print("timer 3 = ",stop)
                    end)
            tmr.unregister(3)                   
                    --sequence_r(gpio.HIGH, gpio.LOW, gpio.LOW, gpio.LOW,mno)
                    sequence_r(gpio.HIGH, gpio.HIGH, gpio.LOW, gpio.LOW,mno)
                    sequence_r(gpio.LOW, gpio.HIGH, gpio.LOW, gpio.LOW,mno)
                    sequence_r(gpio.LOW, gpio.HIGH, gpio.HIGH, gpio.LOW,mno)
                    sequence_r(gpio.LOW, gpio.LOW, gpio.HIGH, gpio.LOW,mno)
                    sequence_r(gpio.LOW, gpio.LOW, gpio.HIGH, gpio.HIGH,mno)
                    sequence_r(gpio.LOW, gpio.LOW, gpio.LOW, gpio.HIGH,mno)
                    sequence_r(gpio.HIGH, gpio.LOW, gpio.LOW, gpio.HIGH,mno)
            end
            sequence_r(gpio.HIGH, gpio.LOW, gpio.LOW, gpio.LOW,mno)

        elseif direction == -1 then  -- Gimbal turning left
                while pan_pos <max_left do 
                print("turning left")
                if stop == 1 then break end
                pan_pos = pan_pos +1
                sequence_l(gpio.LOW, gpio.LOW, gpio.LOW, gpio.HIGH,mno)
                sequence_l(gpio.LOW, gpio.LOW, gpio.HIGH, gpio.HIGH,mno)
                sequence_l(gpio.LOW, gpio.LOW, gpio.HIGH, gpio.LOW,mno)
                sequence_l(gpio.LOW, gpio.HIGH, gpio.HIGH, gpio.LOW,mno)
                sequence_l(gpio.LOW, gpio.HIGH, gpio.LOW, gpio.LOW,mno)
                sequence_l(gpio.HIGH, gpio.HIGH, gpio.LOW, gpio.LOW,mno)
                sequence_l(gpio.HIGH, gpio.LOW, gpio.LOW, gpio.LOW,mno)
                sequence_l(gpio.HIGH, gpio.LOW, gpio.LOW, gpio.HIGH,mno)
            end
            sequence_l(gpio.LOW, gpio.LOW, gpio.LOW, gpio.HIGH,mno)
        end

        print("-----------------------------------")
        print ("pan_pos=",pan_pos)
        print("Modul steps = ",steps)
        print("r_stop",r_stop)
        print("l_stop",l_stop)
        print("u_stop",u_stop)
        print("d_stop",d_stop)
        print("stop",stop)
        collectgarbage()
    end 
end

return stepper

【问题讨论】:

请出示您的代码。 【参考方案1】:

我自己走得更远了。主要问题是(我认为)转动电机的被调用函数位于模块中。我现在在一个程序中拥有这一切。我正在使用计时器来产生一些延迟以减慢电机速度。它现在可以工作大约 3 次电机启动和停止。之后,电机继续转动大约半分钟,并且只有在此时间之后,该功能才会对来自网络服务器的输入做出反应。这似乎是一个时间问题。

问候

德里克

【讨论】:

以上是关于模块中的功能忙时网络服务器未接收的主要内容,如果未能解决你的问题,请参考以下文章

在事件中心接收消息时未触发 ASE 中的 Azure 函数

网络基础:socket模块

Web Socket 消息未全部接收

Python------网络编程3

SocketServer模块中的几种类

NFV到底是什么?