我对LUA相当陌生,经验不足。
我在nodemcu esp8266上使用网络服务器,该服务器正在控制正在旋转云台的步进电机。为此,我找到了一个工作正常的步进器模块。有一个用于像这样旋转电动机的命令:turn(mno,direction,pan_speed,no_steps) 这很好。 我现在想让电动机转动,直到来自网络服务器的另一个命令停止为止。 在这里我需要一个建议。我可以使用执行模块中命令的循环从Web服务器内部启动电动机。这也可以,但是我无法停止电机,因为只要循环正在转动电机,Web服务器就不会收到停止命令。我尝试使用计时器,但是我仍然没有完全理解LUA中的事件处理。
任何建议都非常欢迎
德里克
这是主程序。在我尝试的过程中,只有使云台向左旋转的部分才有意义。程序向左转时,它无法接受第二条命令再次向左转,这将停止云台。
重要的是Web服务器中的常平架支架向左转,然后在步进器模块中“转向”功能。
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
答案 0 :(得分:0)
我自己走得更远。主要问题是(我认为)转动电动机的调用函数在一个模块中。我现在将其全部放在一个程序中。我正在使用计时器产生一些延迟,以使电动机减速。现在它可以工作约3次电动机启动和停止。此后,电动机保持转动大约半分钟,只有在那之后,该功能才会对Web服务器的输入做出反应。这似乎是时间问题。
致谢
德里克