Pulse Decoding


Closed Thread
Results 1 to 13 of 13

Thread: Pulse Decoding

Hybrid View

  1. #1
    Join Date
    May 2008
    Posts
    46


    Did you find this post helpful? Yes | No

    Default

    Thanks for the information Bruce.

    My input signal appears to be high and fairly noisy with pulses low - I really need a real scope

    If I read the code you provided correctly, it shouldn't reach GOTO GET_ADD without receiving a full pulse (or at least a full initial pulse)

    Mine's running all the way through without thinking about it, even with a resistor to gnd and no actual signal.

    I don't have a uart hooked up to this board at the moment so I'm just storing the values in eeprom - they're all showing up as 0's

    - Edit

    Oh dear, spoze if it wasn't 3 am and I'd had some coffee I would have done some thinking

    1) 4 mhz clock (getting 20 mhz crystals tomorrow, ran out)
    2) This is probably a one off - so at the very least I can look for 4 high pulses at the start, if not look specifically for more components of the bitstream

    I'll go to bed now and resume banging head on desk tomorrow.
    Last edited by Freman; - 31st May 2008 at 18:20. Reason: More info

  2. #2
    Join Date
    May 2008
    Posts
    46


    Did you find this post helpful? Yes | No

    Default

    Ok, so further testing - this time using Audacity to record the waveforms as it gives me more freedom to scroll back and forth - has resulted in the following 3 waveforms: http://img527.imageshack.us/my.php?i...8222006dl4.png

    I'm going to opt to completely ignore the first transmission sequence as the start of it is a little messed up and target the second transmission sequence (I pushed the button as fast as I could, I always got 2 or more sequences).

    So the following code is what I've got (haven't run it yet).

    Does it look right?

    I was playing around with it before as '1's instead of '0's in pulsin but it was picking up the block of 0's not the block of 1's. (If that makes any sense)

    I've decided to chop the data comming up as
    ADDRESS-DATA-S
    1111000100110101-11000000-0
    1111000100110101-00110000-0
    1111000100110101-00000011-0

    Following the encoder's specs this is actually
    110F01FF1000S
    110F01FF0100S
    110F01FF0001S
    F = Floating
    S = Sync

    Further reading of the specs - there'll be 4 sequences. Seeing as the first of the sequence is trashed, I just need to record and compare the other 3

    Code:
    ' Configure the FUSE options for the compiler
    @     device pic16F628A, hs_osc, wdt_off, pwrt_on, lvp_off, protect_off, bod_on, cpd_off, pwrt_off, mclr_off
    
    ' Running a 4Mhz clock
    DEFINE OSC 20
    DEFINE PULSIN_MAX 3000
    
    ' Setup the USART
    DEFINE HSER_RCSTA 90h      ' Receive register to receiver enabled
    DEFINE HSER_TXSTA 20h      ' Transmit register to transmitter enabled
    DEFINE HSER_BAUD 9600      ' Set baud rate
    
    CMCON  = 7
    ALL_DIGITAL
    
    RFIN VAR PORTB.7
    
    INPUT RFIN
    
    PBITS   VAR BYTE[17] ' The bits we've read
    RAW     VAR BYTE     ' The raw pulsin value
    ADDRESS VAR WORD     ' Storage for the address
    DBYTE   VAR BYTE     ' Storage for the data
    X       VAR BYTE
    Y       VAR BYTE
    
    
    GET_ADD:
        ADDRESS = 0 : RAW = 0 : DBYTE = 0
    
    GET_PULSE:
        ' Count 4 long pulses.
        FOR x = 0 TO 3
            PULSIN RFIN, 0, RAW
            if RAW < 220 OR RAW > 230 THEN GET_PULSE
        NEXT X    
    
        ' Count 3 short pulse.
        FOR X = 0 to 2
            PULSIN RFIN, 0, RAW
            IF RAW < 70 OR RAW > 80 THEN GET_PULSE
        NEXT X
    
        ' Read 9 address bits and 8 data bits    
        FOR X = 0 TO 16
            PULSIN RFIN, 0, RAW
            PBITS[x] = NCD RAW
        NEXT X
    
        ' Read a sync bit    
        PULSIN RFIN, 0, RAW
        IF RAW < 70 OR RAW > 80 THEN GET_PULSE
        
        
        ADDRESS = 511 ' Maxmimum known ID
        FOR X = 0 to 8
            IF PBITS[x] > 7 THEN ADDRESS.0[X] = 0
        NEXT X
        
        DBYTE = 255 ' Maximum known data value
        Y=0
        FOR X = 9 TO 16
            IF PBITS[X] > 7 THEN DBYTE.0[Y] = 0
            Y = Y + 1
        NEXT X
        
        
        IF ADDRESS > 0 THEN
            WRITE 1, ADDRESS.LowByte
            WRITE 2, ADDRESS.HighByte
            Write 3, DBYTE
            HSEROUT ["ADD = ",IBIN9 ADDRESS," : ",IDEC ADDRESS,13,10]
            HSEROUT ["DAT = ",IBIN8 DBYTE," : ",IDEC DBYTE,13,10]
        ENDIF
        GOTO GET_ADD
    END
    Last edited by Freman; - 1st June 2008 at 14:04.

  3. #3
    Join Date
    Dec 2005
    Posts
    1,073


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Freman View Post
    I'm going to opt to completely ignore the first transmission sequence as the start of it is a little messed up and target the second transmission sequence (I pushed the button as fast as I could, I always got 2 or more sequences).
    You will always need 2 or more copies of the code as the first (and sometimes the second, third and...) will always be messed up. This is because the receiver's AGC/ATC circuitry has not yet adapted to the signal strength. How many are messed up depends on the strength of the signal. This is why I never recommend using 10101010 type sequences as a start of frame marker. In this case, Bruce uses the long silence that follows each copy of the code as a start of frame marker for the next. All you can do is test each bit and abort if the pulse or space width exceeds a maximum. I define MAX PULSE for this.
    I was playing around with it before as '1's instead of '0's in pulsin but it was picking up the block of 0's not the block of 1's. (If that makes any sense)
    With this particular protocol, the bit period is constant and the pulses and spaces are complementary (i.e wide pulse & narrow space and vice versa) so it really doesn't matter whether you use 1 or 0 with PulsIn.

  4. #4
    Join Date
    May 2008
    Posts
    46


    Did you find this post helpful? Yes | No

    Default

    Yes I've slept on it, so I'll be aiming for the long low pulse as my 'start of sequence' then working on the bits. It annoys me that I have to go to work for 8 hours before I can test this

    Edit

    Ok, so the long pulse is 4.6 ms long - so I should increase DEFINE PULSIN_MAX 3000 to say DEFINE PULSIN_MAX 5000 yes?

    Or is that calculated the same was as the actual pulsein is calculated...

    ie: DURATION / CLOCKSPEED

    In which case... 3000 is just perfect
    Last edited by Freman; - 2nd June 2008 at 03:07.

  5. #5
    Join Date
    May 2008
    Posts
    46


    Did you find this post helpful? Yes | No

    Default

    Well here we go, and it even works - well there's no false positives, but some times it doesn't activate, but better then it was.

    Code:
    ' Configure the FUSE options for the compiler
    @     device pic16F628A, hs_osc, wdt_off, pwrt_on, lvp_off, protect_off, bod_on, cpd_off, pwrt_off, mclr_off
    
    ' Running a 4Mhz clock
    DEFINE OSC 20
    DEFINE PULSIN_MAX 3000
    
    CMCON  = 7
    ALL_DIGITAL
    
    ' Setup the USART
    DEFINE HSER_RCSTA 90h      ' Receive register to receiver enabled
    DEFINE HSER_TXSTA 20h      ' Transmit register to transmitter enabled
    DEFINE HSER_BAUD 9600      ' Set baud rate
    
    RFIN VAR PORTB.7
    
    INPUT RFIN
    
    PBITS   VAR BYTE[24] ' The bits we've read
    RAW     VAR WORD     ' The raw pulsin value
    ADDRESS VAR WORD     ' Storage for the address
    DBYTE   VAR BYTE     ' Storage for the data
    LOOPDBYTE VAR BYTE
    LOOPADDRESS VAR WORD
    X       VAR BYTE
    Y       VAR BYTE
    
    GET_ADD:
        ADDRESS = 0 : RAW = 0 : DBYTE = 0
    
    GET_PULSE:
        ' Look for one huge low pulse
        PULSIN RFIN, 0, RAW
        ' 2350 is about mean average
        IF RAW < 2330 OR RAW > 2370 THEN GET_PULSE
    
        ' Read 16 address bits and 8 data bits    
        FOR X = 0 TO 23
            PULSIN RFIN, 0, RAW
            PBITS[x] = NCD RAW
        NEXT X
        
        ADDRESS = 65535 ' Maxmimum known ID
        FOR X = 0 to 15
            IF PBITS[x] > 7 THEN ADDRESS.0[X] = 0
        NEXT X
        
        DBYTE = 255 ' Maximum known data value
        Y=0
        FOR X = 16 TO 23
            IF PBITS[X] > 7 THEN DBYTE.0[Y] = 0
            Y = Y + 1
        NEXT X
    
        ' If we've done a loop...
        IF ADDRESS == LOOPADDRESS AND DBYTE == LOOPDBYTE THEN
            SELECT CASE DBYTE
                CASE 3
                    GOSUB subUp
                CASE 12
                    GOSUB subStop
                CASE 192
                    GOSUB subDown
            END SELECT
            LOOPDBYTE = 0
            LOOPADDRESS = 0
        ELSE
            ' Start a loop
            LOOPDBYTE = DBYTE
            LOOPADDRESS = ADDRESS
        ENDIF
    
        GOTO GET_ADD
    END
    
    subUp:
        HSEROUT ["UP",10,13]
        RETURN
        
    subStop:
        HSEROUT ["STOP", 10, 13]
        RETURN
    
    subDown:
        HSEROUT ["DOWN",10,13]
        RETURN
    Any suggestible improvements? (btw, thanks for all the help so far

  6. #6
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Increase your pulsin_max until it kicks out a false positive, then back up a bit.

  7. #7
    Join Date
    Dec 2005
    Posts
    1,073


    Did you find this post helpful? Yes | No

    Default

    When looking for a long-0 pulse, DEFINE MAX PULSE really doesn't do anything. It's only useful when looking for a long 1-pulse.

    I suggest testing each bit as received and aborting if it is shorter than the shortest normal 0-pulse. With a weak signal, noise pulses will appear during the silences (i.e.. 0-pulses), shortening the measured PulsIn value but they will just be superimposed on a 1-pulse. In some cases there may be insufficient time to do this test but I think it will work here. Take a look at...to see what I mean.

Similar Threads

  1. Pulse Capture and byte building
    By boroko in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 21st July 2009, 01:59
  2. Single digit 7 Seg LED clock - PIC16F88
    By thirsty in forum Code Examples
    Replies: 4
    Last Post: - 17th July 2009, 08:42
  3. Replies: 3
    Last Post: - 13th September 2008, 17:40
  4. Decoding an incoming infrared signal: need advice
    By xnihilo in forum mel PIC BASIC Pro
    Replies: 10
    Last Post: - 9th May 2008, 16:28
  5. Pulse Frequency Multiplication
    By jamie_s in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 21st August 2005, 10:39

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts