User Tools

Site Tools


public:application:pulse_pattern_recognition_using_acr-cv

Pulse patter recoginition using ACR-CV - Universal S0 converter





Introduction

Application note aims to help you with implementation of pulse pattern recognition and sending a custom message depending on recognized pattern.


Task

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«)


Hardware

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.


Custom LUA script

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

Payload

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])\\ 

Example

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.

public/application/pulse_pattern_recognition_using_acr-cv.txt · Last modified: 2020/10/05 06:55 by Acrios Admin