-3

我有一个电动卷帘项目。我正在关注这个指导:https ://www.instructables.com/id/Motorized-WiFi-IKEA-Roller-Blind/ 。

我正在使用instructable中的代码,但我怀疑错误出现在以下代码之一中:

配置文件

-- file : config.lua
local module = {}
module.SSID = {}
module.SSID["ssid"] = "password"

-- example for local MQTT
--module.MQHOST = "ohab.local"
--module.MQPORT = 1883
--module.MQID = node.chipid()
--module.MQUSR = ""
--module.MQPW = ""

-- example for cloud MQTT
module.MQHOST = "192.***.*.*"
module.MQPORT = 1883
module.MQID = node.chipid()
module.MQUSR = "username"
module.MQPW = "password"
module.MQTLS = 1 -- 0 = unsecured, 1 = TLS/SSL
module.ENDPOINT = "/house/masterbedroom/rollerblind/"
module.ID = "0"

--module.SUB = "set"
module.SUB = {[module.ENDPOINT .. module.ID .. "/set"]=0,[module.ENDPOINT .. "all"]=0}
module.POST = module.ENDPOINT .. module.ID .. "/status"
return module

wifi_setup

-- file: setup.lua
local module = {}
local function wifi_wait_ip()
    if wifi.sta.getip()== nil then
        print("IP unavailable, Waiting...")
    else
        tmr.stop(1)
        gpio.write(pin_led,1) --off
        print("\n================== ==================")
        print("ESP8266 mode is: " .. wifi.getmode())
        print("MAC address is: " .. wifi.ap.getmac())
        print("IP is "..wifi.sta.getip())
        print("====================================")
        mq.start()
    end
end

local function wifi_start(list_aps)
    if list_aps then
        gpio.write(pin_led,0) --on
        for key,value in pairs(list_aps) do
            if config.SSID and config.SSID[key] then
                wifi.setmode(wifi.STATION);
                wifi.sta.config(key,config.SSID[key])
                wifi.sta.connect()
                print("Connecting to " .. key .. " ...")
                --config.SSID = nil  -- can save memory
                tmr.alarm(1, 2500, 1, wifi_wait_ip)
            end
        end
    else
        print("Error getting AP list")
    end
end

function module.start()
  print("Configuring Wifi ...")
  wifi.setmode(wifi.STATION);
  wifi.sta.getap(wifi_start)
end
return module

可悲的是,我无法超越第 4 步。尝试将代码下载到 ESP8266 后,我只收到此错误:

PANIC:调用 Lua API 时出现未受保护的错误(wifi_setup.lua:25:'config' 的参数 #1 错误(未找到配置表!))

ESPlorer 程序的错误截图

我只改变了教练告诉我要改变的东西,我自己也试着寻找错误,但我找不到任何问题……这是我第一次使用 Lua,所以这对我来说是全新的。

希望这里有人可以提供一些帮助。卡在这上面好几天了...

这部分问题已解决。检查解决方案的评论


可悲的是,当一个问题解决了,一个新的问题就出现了……

该芯片现在已成功连接到 wifi 和 mqtt 服务,但是当我尝试通过输入命令“step_move(1000,FWD,2)”来进行空运行时,没有任何反应。电机应该转动...

此外,当我按下按钮时,我得到一个新的恐慌错误,如下所示:

PANIC:调用 Lua API 时出现不受保护的错误(button.lua:23:尝试对 upvalue '?'(一个 nil 值)执行算术运算)

按钮.lua

--file button4.lua

do
  -- use pin 1 as the input pulse width counter
  local pin=5
  local debounce = 150 --ms
  local longpress = 2000 --ms
  local pulse1, pulse2, du, now, trig = 1, 0, 0, tmr.now, gpio.trig
  local prev_int_time, int_time, up_time = 0
  local cal_steps = 100000
  local cal_steps_dn = 0
  local cal_steps_up = 0
  local cal_state = 0 -- 0 = not calibration, 1 = calibrating down, 2 = calibrating up
  state = 0 -- state: 0 = up, 1 = transition, 2 = down
  gpio.mode(pin,gpio.INT)

  local function pin4cb(level)
    int_time = now() / 1000
    if ((int_time - prev_int_time) > debounce) then
      if (level == 0) then
        up_time = int_time
      else
        if((int_time - up_time) > longpress) then
          print("calibrating")
          cal_state = 1
          --cur_step = 100000
          step_move(cal_steps,FWD,2)
        else -- short press
          print("short", cal_state)
          if (cal_state == 2) then -- calibrated up (done)
            print("calibration done")
            state = 0 -- up
            cur_step = 0
            tot_steps = cal_steps - step_stepsleft
            print("cal_steps: " .. cal_steps)
            print("step_stepsleft: " .. step_stepsleft)
            print("tot_steps: " .. tot_steps)
            step_stop()
            pins_disable()
            cal_state = 0
            if file.open("cfg_tot_steps.lua", "w+") then
              file.write("tot_steps=" .. tot_steps .. '\n')
              file.close()
            end
          elseif (cal_state == 1) then -- calibrated dn (switch direction)
            print("calibration low point")
             print(cal_steps - step_stepsleft) 
            step_stop()
            step_move(cal_steps,REV,2)
            cal_state = 2
          elseif (cal_state == 0) then
            if (state == 0 and step_stepsleft == 0) then -- i am up, go dowm
              rollerblind.down()
--              state = 2
            elseif (state == 1) then -- i am moving, do nothing
              -- do nothing
            elseif (state == 2 and step_stepsleft == 0) then -- i am down, go up
              rollerblind.up()
--              state = 0
            end
         end
       end
      end
      --print (level)
      prev_int_time = int_time
    end
  end
      gpio.trig(pin, "both", pin4cb)
 end

这是 stepper.lua 的代码:

    -- stepper.lua
-- code from: http://www.esp8266.com/viewtopic.php?f=19&t=2326
-- simple stepper driver for controlling a stepper motor with a
-- l293d driver
-- nodemcu pins:  0  5  6  7
stepper_pins = {1,3,2,4} -- (A-)blue, (A+)pink, (B-)yellow, (B+)orange
--stepper_pins = {1,2,3,4}
-- half or full stepping
step_states4 = {
 {1,0,0,1},
 {1,1,0,0},
 {0,1,1,0},
 {0,0,1,1}
}
step_states8 = {
 {1,0,0,0},
 {1,1,0,0},
 {0,1,0,0},
 {0,1,1,0},
 {0,0,1,0},
 {0,0,1,1},
 {0,0,0,1},
 {1,0,0,1},
}
step_states = step_states4 -- choose stepping mode
step_numstates = 4 -- change to match number of rows in step_states
step_delay = 10 -- choose speed
step_state = 0 -- updated by step_take-function
step_direction = 1 -- choose step direction -1, 1
step_stepsleft = 0 -- number of steps to move, will de decremented
step_timerid = 4 -- which timer to use for the steps
status_timerid = 2 -- timer id for posing of status messages
-- setup pins
function pins_enable()
  for i = 1, 4, 1 do
    gpio.mode(stepper_pins[i],gpio.OUTPUT)
  end
end

function pins_disable()
--  for i = 1, 4, 1 do -- no power, all pins
  for i = 2, 4, 1 do -- no power, all pins except one (to keep it in place)
    gpio.mode(stepper_pins[i],gpio.INPUT)
  end
end
-- turn off all pins to let motor rest
function step_stopstate() 
  for i = 1, 4, 1 do
    gpio.write(stepper_pins[i], 0)
  end
end

-- make stepper take one step
function step_take()
  -- jump to the next state in the direction, wrap
  step_state = step_state + step_direction
  cur_step = cur_step + step_direction * FWD
      if step_state > step_numstates then
    step_state = 1;
  elseif step_state < 1 then
    step_state = step_numstates
  end
  -- write the current state to the pins
  pins_enable()
  for i = 1, 4, 1 do
    gpio.write(stepper_pins[i], step_states[step_state][i])
  end
  -- might take another step after step_delay
  step_stepsleft = step_stepsleft-1
  if step_stepsleft > 0 then
--  if cur_step > 0 and cur_step < tot_steps and step_stepsleft > 0 then
    tmr.alarm(step_timerid, 10, 0, step_take )
    --tmr.alarm(step_timerid, 10, 0, step_take )
  else
    step_stopstate()
    step_stop()
    pins_disable()
    mq.post_status()
    if file.open("cfg_cur_step.lua", "w+") then
      file.write("cur_step=" .. cur_step .. '\n')
      file.close()
    end
  end
end

-- public method to start moving number of 'int steps' in 'int direction'    
function step_move(steps, direction, delay)
  tmr.stop(step_timerid)
  step_stepsleft = steps
  step_direction = direction
  step_delay = delay
  step_take()
end

function step_go_to(step, delay)
  if step >= cur_step then
    steps = step - cur_step
    step_move(steps, FWD, delay)
  end
  if step <= cur_step then
    steps = cur_step - step
    step_move(steps, REV, delay)
  end
end

function percent_go_to(percent, delay)
  if(percent >= 0 and percent <= 100) then
    step_stop()
    tmr.register(status_timerid, 1000, tmr.ALARM_AUTO, function () mq.post_status() end)
    tmr.start(status_timerid)
    step = percent * tot_steps / 100
    step_go_to(step, delay)
  end
end

-- public method to cancel moving
function step_stop()
  tmr.stop(step_timerid)
  tmr.stop(status_timerid)
  step_stepsleft = 0
  step_stopstate()
end
4

2 回答 2

2

我们来一一解析错误信息:

unprotected error in call to Lua API (wifi_setup.lua:25: bad argument #1 to 'config' (config table not found!))

未受保护的错误意味着您执行了正常的函数调用,而不是受保护的调用(aka pcall),这是一个函数调用,您希望在其中发生错误并希望提供处理它们的方法。由于您没有进行受保护的调用,Lua 不知道如何处理错误并立即终止(这不是一件坏事)。

wifi_setup.lua:25告诉您发生错误的文件和行。

bad argument #1 to 'config'意味着问题是由于第一个参数传递给名为config.

config table not found!是该函数的实现者提供的错误消息。

所以总而言之,函数调用存在问题,wifi.sta.config(key,config.SSID[key])因为它需要一个表作为第一个参数,而您提供了一些不同的东西(即带有 BSSID 的字符串)。确实检查NodeMCU 文档表明您需要将表传递给此函数:

wifi.sta.config()

设置 WiFi 站配置。[...]

句法

wifi.sta.config(station_config)

参数

station_config包含站配置数据的表

表格的预期布局也详细记录在该页面上。

于 2017-09-19T07:13:20.213 回答
1

ComicSansMS 提供了一个很好的答案,其本质是您需要替换

wifi.sta.config(key,config.SSID[key])

wifi.sta.config{ssid=key,pwd=config.SSID[key]}

因此,一个独立的例子可能是这样的:

--wifi.setmode(wifi.NULLMODE)

config = {}
config.SSID = {}
config.SSID["ssid"] = "password"

function wifi_wait_ip()
  if wifi.sta.getip() == nil then
    print("IP unavailable, Waiting...")
  else
    tmr.stop(1)
    print("\n====================================")
    print("ESP8266 mode is: " .. wifi.getmode())
    print("MAC address is: " .. wifi.ap.getmac())
    print("IP is " .. wifi.sta.getip())
    print("====================================")
  end
end

function wifi_start(list_aps)
  if list_aps then
    for key, value in pairs(list_aps) do
      if config.SSID and config.SSID[key] then
        wifi.setmode(wifi.STATION);
        wifi.sta.config{ssid=key, pwd=config.SSID[key]}
        -- wifi.sta.connect() not needed as config() uses auto-connect=true by default
        print("Connecting to " .. key .. " ...")
        tmr.alarm(1, 2500, 1, wifi_wait_ip)
      end
    end
  else
    print("Error getting AP list")
  end
end

function start()
  print("Configuring Wifi ...")
  wifi.setmode(wifi.STATION)
  wifi.sta.getap(wifi_start)
end

start()
于 2017-09-19T09:46:37.460 回答