Application note aims to help you with implementation of pulse pattern recognition and sending a custom message depending on 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 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(at)acrios.com. For further technical details, please contact Mr. Novak at novak(at)acrios.com.
ACR-CV-101L-I2-EAC(D) can be also used to detect the pulse patterns. I4 and I2 in the code stands for 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 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.