Created
October 14, 2017 11:30
-
-
Save padcom/f30820535438fe4e5b3a607f00e3c060 to your computer and use it in GitHub Desktop.
NodeMCU RF receiver and decoder
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local BUFFER_SIZE = 512 | |
local timings = { } | |
local write = 0 | |
local read = 0 | |
local max = 0 | |
local function count(pos) | |
if pos == read then | |
return 0 | |
elseif pos > read then | |
return pos - read | |
else | |
return BUFFER_SIZE + pos - read; | |
end | |
end | |
local prev_ts = 0 | |
local function capture(level, ts) | |
local len = math.abs(prev_ts - ts) | |
prev_ts = ts | |
if count(write) < BUFFER_SIZE - 2 then | |
write = (write + 1) % BUFFER_SIZE | |
timings[write] = len | |
end | |
end | |
local STATE_PREAMBLE = 0 | |
local STATE_BIT_HIGH = 1 | |
local STATE_BIT_LOW = 2 | |
local state = 0 | |
local preamb = 0 | |
local long = 0 | |
local short = 0 | |
local bits = 24 | |
local nibble = 0 | |
local bit = 0 | |
local code = 0 | |
local callback = function(code, bits, preamble, short, long) end | |
local function process() | |
repeat | |
local pos = write | |
while count(pos) > 0 do | |
read = (read + 1) % BUFFER_SIZE | |
if state == STATE_PREAMBLE then | |
if timings[read] > 6000 then | |
preamble = timings[read] | |
long = (preamble * 3) / 31 | |
short = (preamble * 1) / 31 | |
bit = 0 | |
code = 0 | |
state = STATE_BIT_HIGH | |
end | |
elseif state == STATE_BIT_HIGH then | |
if math.abs(timings[read] - long) < (long * 10) / 25 then | |
nibble = 30 | |
state = STATE_BIT_LOW | |
elseif math.abs(timings[read] - short) < (short * 10) / 15 then | |
nibble = 10 | |
state = STATE_BIT_LOW | |
else | |
state = STATE_PREAMBLE | |
end | |
elseif state == STATE_BIT_LOW then | |
if math.abs(timings[read] - long) < (long * 10) / 25 then | |
nibble = nibble + 3 | |
state = STATE_BIT_HIGH | |
elseif math.abs(timings[read] - short) < (short * 10) / 15 then | |
nibble = nibble + 1 | |
state = STATE_BIT_HIGH | |
else | |
state = STATE_PREAMBLE | |
end | |
if state == STATE_BIT_HIGH then | |
if nibble == 13 then | |
code = code * 2 | |
bit = bit + 1 | |
elseif nibble == 31 then | |
code = code * 2 + 1 | |
bit = bit + 1 | |
else | |
state = STATE_PREAMBLE | |
end | |
end | |
if state == STATE_BIT_HIGH and bit == bits then | |
callback(code, bits, preamble, short, long) | |
state = STATE_PREAMBLE | |
end | |
else | |
state = STATE_PREAMBLE | |
end | |
end | |
until read == write | |
end | |
local function init(pin, led, cb) | |
for i = 0, BUFFER_SIZE - 1 do | |
timings[i] = 0 | |
end | |
callback = cb | |
gpio.mode(pin, gpio.INT, gpio.PULLUP) | |
gpio.trig(pin, "both", capture) | |
tmr.alarm(5, 100, tmr.ALARM_AUTO, process) | |
gpio.mode(led, gpio.OUTPUT) | |
gpio.write(led, 0) | |
end | |
rfrecv = { | |
init = init | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment