Application note aims to help you with the implementation of pulse pattern recognition and sending a custom message depending on the recognized pattern.
For this task, the custom LUA script needs to be created and loaded into the device. In our case, we will be scanning for 4 different patterns that can occur. Each signal has its own signal waveform. After the signal is detected, a message will be sent including the information on which pattern was detected. The following 4 patterns can occur:
1. Pattern 1: 1Hz frequency (about 500ms »on« and 500ms »off«)
2. Pattern 2: 0,5Hz frequency (about 500ms »off« and 1500ms »on«)
3. Pattern 3: 0,5 Hz frequency (about 500ms »on« and 1500ms »off«)
4. Pattern 4: 20Hz frequency (about 25ms »off« and about 25ms »on«)
This application can be implemented using ACR-CV-101L-I4-EAC(D). For orders, please contact Mr. Smetana at smetana@acrios.com. For further technical details, please contact Mr. Novak at novak@acrios.com.
ACR-CV-101L-I2-EAC(D) can be also used to detect the pulse patterns. I4 and I2 in the code stand for a number of inputs where I4 supports the 4 inputs and I2 supports the 2 inputs. One input is being used for one pulse generating device with pulse patterns as above (or similar).
The analog filter is being used and limits the minimum duration of the pulse. The other option is to read the digital signal input and send a message when change occurs.
function onWake ()
end
function onThreshold ()
end
function onInputChanged ()
end
SIG_1HZ = 1 -- 1. 1Hz, 500ms ON, 500ms OFF
SIG_0_5HZ_POS = 2 -- 2. 0.5Hz 500ms OFF, 1500ms ON
SIG_0_5HZ_NEG = 3 -- 3. 0.5Hz 500ms ON, 1500ms OFF
SIG_20HZ = 4 -- 4. 20Hz 25ms ON, 25ms OFF
SIG_UNKNOWN = 5
SIG_1HZ_SEQ = {{400, 600, 1}, {400, 600, 0}, {400, 600, 1}, {400, 600, 0}, {400, 600, 1}, {400, 600, 0}, {400, 600, 1}, {400, 600, 0}}
SIG_0_5HZ_POS_SEQ = {{400, 600, 1}, {1300, 1800, 0},{400, 600, 1}, {1300, 1800, 0},{400, 600, 1}, {1300, 1800, 0},{400, 600, 1}, {1300, 1800, 0}}
SIG_0_5HZ_NEG_SEQ = {{400, 600, 0}, {1300, 1800, 1},{400, 600, 0}, {1300, 1800, 1},{400, 600, 0}, {1300, 1800, 1},{400, 600, 0}, {1300, 1800, 1}}
SIG_20HZ_SEQ = {{2, 80, 1}, {2, 80, 0},{2, 80, 1}, {2, 80, 0},{2, 80, 1}, {2, 80, 0},{2, 80, 1}, {2, 80, 0}}
SIG_TO_DETECT = {SIG_1HZ_SEQ, SIG_0_5HZ_POS_SEQ, SIG_0_5HZ_NEG_SEQ, SIG_20HZ_SEQ}
DetectedSignals = {SIG_UNKNOWN,SIG_UNKNOWN,SIG_UNKNOWN,SIG_UNKNOWN}
LastPinDetectedPulses = {{{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}}, {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}}, {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}}, {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}}}
function dumpDetected(pin)
local x = LastPinDetectedPulses[pin]
print("dump "..tostring(pin))
for i = 1,8 do
print(tostring(x[i][1])..", "..tostring(x[i][2]))
end
end
function addToDetectionArray(pin, newdiff, newval)
for i = 8,2,-1 do
LastPinDetectedPulses[pin][i] = LastPinDetectedPulses[pin][i-1]
end
--print(tostring(pin).." : {" .. tostring(newdiff) .. ", " .. tostring(newval) .. "}")
LastPinDetectedPulses[pin][1] = {newdiff, newval}
end
function detectNew(pin)
retval = false
for i = 1,4 do
test = 1
for j = 1,8 do
lpdp = LastPinDetectedPulses[pin][j]
diff = lpdp[1]
val = lpdp[2]
s2d = SIG_TO_DETECT[i][j]
diffmin = s2d[1]
diffmax = s2d[2]
reqval = s2d[3]
if val ~= reqval then
test = 0
break
end
if diff < diffmin then
test = 0
break
end
if diff > diffmax then
test = 0
break
end
end
if test == 1 then
print(tostring(pin) .. " => " .. tostring(i))
if DetectedSignals[pin] ~= i then
print("PIN "..tostring(pin)..": "..tostring(i))
DetectedSignals[pin] = i
retval = true
end
end
end
return retval
end
function onStartup()
print("onStartup(), 0.5Hz pos/neg, 1Hz and 20Hz signal detection")
api.setVerbosity(0)
startTs = api.getTick()
LastChangeTs = {startTs, startTs, startTs, startTs}
LastLogicState = {api.DIOreadPin(1), api.DIOreadPin(2), api.DIOreadPin(3), api.DIOreadPin(4)}
while true do
for pin = 1,4 do
val = api.DIOreadPin(pin)
if val ~= LastLogicState[pin] then
ts = api.getTick()
diff = ts - LastChangeTs[pin]
-- filter out too short
if diff < 1 then
print("x")
break
end
LastChangeTs[pin] = ts
LastLogicState[pin] = val
addToDetectionArray(pin, diff, val)
hasNew = detectNew(pin)
if hasNew then
-- message format: [ CH1, CH2, CH3, CH4 ]
buf = string.char(DetectedSignals[1])
buf = buf .. string.char(DetectedSignals[2])
buf = buf .. string.char(DetectedSignals[3])
buf = buf .. string.char(DetectedSignals[4])
api.loraSend(1,5000,buf)
end
end
end
end
end
The payload format is [ CH1, CH2, CH3, CH4 ], where the signal is defined as:
SIG_1HZ = 1 — 1. 1Hz, 500ms ON, 500ms OFF
SIG_0_5HZ_POS = 2 — 2. 0.5Hz 500ms OFF, 1500ms ON
SIG_0_5HZ_NEG = 3 — 3. 0.5Hz 500ms ON, 1500ms OFF
SIG_20HZ = 4 — 4. 20Hz 25ms ON, 25ms OFF
SIG_UNKNOWN = 5
which is being sent in payload message in the format:
buf = string.char(DetectedSignals[1])
buf = buf .. string.char(DetectedSignals[2])
buf = buf .. string.char(DetectedSignals[3])
buf = buf .. string.char(DetectedSignals[4])\\
The payload: 05 01 03 04
means, that on CH1 is an unknown pulse pattern (nr. 5), on CH2 is the first pulse pattern, on CH3 is the third pulse pattern and on the CH4 is the fourth pulse pattern.