On a ESP8266 with nodemcu and LUA 5.1 I need to use an upvalue to process a turn event for a rotary encoder. However this variable is always NIL. As I understand the principle of upvalues, the variable sv should be passed the the callback of the 'turn' function, but it is not. What I miss by understanding of upvalues?
local turn = function(type, pos, when)
print(type, pos, when, sv.value)
if type == rotary.TURN then
local move = sv.last - pos
sv.last = pos
sv.x = sv.value + move
local tm
if tm == nil then
tm = tmr.create()
tm:register(500, tmr.ALARM_SINGLE, function()
setTo(sv)
end)
end
tm:start()
end
end
local setupRotary = function(sv)
local ch, a, b, sw = sv.rotary_ch, sv.rotary_a, sv.rotary_b, sv.rotary_sw
print(ch, a, b, sw)
rot.init(ch, a, b, 1, sw)
sv.last = 0
rot.on(ch, rot.TURN, turn)
end
By the way, "rot" is also a lua module. When I rotate the encoder, I get "attempt to index global 'sv' (a nil value)" at the first line of th "turn" function.
The manual describes upvalue as follows:
A local variable used by an inner function is called an upvalue, or external local variable, inside the inner function.
turn
is not an inner function of setupRotary
, so sv
will not be passed.
You can fix this problem by moving the function inside:
local turn
local setupRotary = function(sv)
turn = function(type, pos, when)
-- here sv is visible
end
end