PPM decoding using 12F508 problem


Closed Thread
Results 1 to 3 of 3
  1. #1
    Join Date
    Jan 2014
    Posts
    84

    Default PPM decoding using 12F508 problem

    I decoded a PPM signal from a old RC receiver with a shift register(HC595) with succes, but short noises cause random output on all channels , so was not a good ideea.
    Also I tried to decode a PPM signal with my own code, but after a some work weeks I saw that is a disaster.

    Finally I found a asm file made by BRUCE, work very stable but I need to make some changes .
    Actually , the program have a fail safe, when input detect a bad pulses , each output go to initial start values. When input detect a bad pulses , I want to have 1,5 ms on each output.

    Can somebody help me to modify the asm file , please? In asm I understant nothing ..(:

    Here is BRUCE link : http://www.bhabbott.net.nz/decoder.html

    Thx in advance!

    Code:
    ;***************************************************************************
    ;   rxdecode.asm      Pulse Position Modulation Decoder for 4 Channel Rx
    ;***************************************************************************
    ;            Bruce Abbott   [email protected] 
    ;
    ;        for Microchip PIC 12C508, 12C509, 12F629 or 12F675.
    ;
    ;============================= Description =================================
    ;
    ; PPM DECODER:
    ;
    ; Each frame consists of 4 to 8 channels (5 to 9 pulses), followed by a sync 
    ; gap. We only decode the first 4 channels. 
    ;
    ; The width of each channel is 1 to 2mS (1.5mS when sticks centered). The 
    ; sync gap is at least 2.5mS long, and frame length is approximately 20mS.
    ;
    ; The input signal should look something like this:- 
    ;
    ;            |<------------------ 1 frame (~20mS) -------------------->|
    ;            |< 1~2mS >|                                 
    ;             _            _        _        _        _                    _
    ; ___________| |_______| |______| |______| |______| |__ // ____________| |____
    ;   sync gap     ch1       ch2      ch3      ch4       etc.  sync gap      ch1
    ;
    ; NOTE: This waveform shows positive 'shift'. If your Rx outputs negative 
    ;       'shift', the waveform is inverted.  
    ;
    ; There is just enough time to generate four decoded outputs after receiving 
    ; channel 4, and before the end of the sync gap. 
    ;
    ; GLITCH FILTER:
    ;
    ; Each channel is averaged with the value from the previous frame, reducing
    ; servo jitter on weak signals. If any channel in a frame is corrupted, the 
    ; whole frame is discarded and the last good frame is used instead.  
    ;
    ; FAILSAFE:
    ;
    ; On receiving a sufficient number of good frames we save it for failsafe. 
    ; Then, if the signal is corrupted for too long, we output the failsafe frame
    ; instead of the last good frame.  
    ;
    ; THROTTLE ARMING:
    ;
    ; When entering failsafe the throttle is cut, and it will not be restarted 
    ; until a good signal is detected AND the throttle is manually reset. This 
    ; should prevent the situation where motor-induced RF interference causes 
    ; the decoder to cycle in and out of failsafe repeatedly.  
    ;
    ; For this feature to work the throttle channel has to be determined. Futaba 
    ; and Hitec tranmitters assign the throttle to channel 3. JR, Airtronics and 
    ; GWS use channel 1. 
    ;
    ; Some ESC's need to have the throttle set to maximum at startup, perhaps to 
    ; disable the brake or to enter programming mode. Therefore, channel 1 is 
    ; designated as throttle if it measures less than 1.3mS or more than 1.7mS at 
    ; startup, otherwise channel 3 is assumed. 
    ;
    ; The throttle channel is forced to 1.05mS during failsafe, rather than set
    ; to its failsafe value, in case that value was full throttle! 
    ;
    ; =============================================================================
    ;                             Summary of Changes
    ;
    ; 2003/12/2  V0.5 - Initial release 
    ;
    ; 2003/12/27 V0.6 - ASM Error if 'addwf PCL' not in page 0.
    ;                 - Select processor via MPLab's Device Select menu. 
    ; 2004/1/7   V0.7 - No output until failsafe frame captured. Should now be
    ;                   compatible with JR/GWS transmitters (throttle on CH1). 
    ;                    
    ; 2004/1/9   V0.8 - Increased range to 0.75~2.28mS, now accepts >125% throws.
    ;                   Resolution is slightly reduced (from 5uS to 6uS).                 
    ;                 - Failsafe and Hold frames now use averaged output values.
    ;                 - Ignore missing 4th channel (for 3 channel TX) NOT TESTED!
    ;
    ; 2004/2/15  V0.9 - Fixed bug:- OSCCAL not initialized in 12F675 code! 
    ;                 - Detect throttle channel. The throttle is held OFF after
    ;                   failsafe, until re-armed manually. This prevents cyling
    ;                   into and out of failsafe due to electrical noise coming
    ;                   from the motor.
    ;
    ; 2004/6/20  V1.0 - Using TMR0 to detect loss of signal. This prevents lockup
    ;                   during a clean signal loss (no noise) which may occur if
    ;                   used in a receiver which has muting.
    ;                 - TMR0 is also used to set frame repeat time in failsafe.
    ;          - Fixed bug:- Initial channel output values were wrong.
    ;
    ; 2004/10/24 V1.1 - Positive and Negative shift versions.
    ;          - Ignore short glitches on signal transitions. 
    ;          - Ensure throttle is low in failsafe, even if it was maxiumum 
    ;                   at startup (possible requirement for ESC programming). 
    ;
    ; 2004/12/12 V1.2 - Fixed bug: JR throttle arming was disabled due to a typo!
    ; 
    ; 2005/1/20  V1.3 - Now accepts pulse widths from 180uS to 700uS. 
    ;
    ; -----------------------------------------------------------------------------
    
    #DEFINE version  "1.3"
    
    #DEFINE ARM_THROTTLE    ; enable if throttle arming control wanted.      
    #DEFINE    DETECT_JR    ; enable for JR/Airtronics/GWS throttle detection.
    
    ;#DEFINE Negative_Shift  ; enable for Futaba/Hitec on 72MHz 
    
    
    ; Make sure that PROCESSOR and <include> file are compatible with your CPU!
    ; 12C508(A) and 12C509(A) can use 12C508 definitions. 12F629 can use 12F675 
    ; definitions (just don't try to use the A/D module...)
    
    ;#DEFINE __12C508    ; enable if processor not specified elsewhere 
    ;#DEFINE __12F675    ; (MPLAB:- use menu <Configure/Select_Device>) 
    
    ;#DEFINE NO_OSCCAL     ; enable if OSCCAL value was erased!
    
    
        ifdef      __12C508
        PROCESSOR PIC12C508
            INCLUDE   <P12C508.inc>
        __CONFIG  _MCLRE_OFF&_CP_OFF&_WDT_ON&_IntRC_OSC    
        else
            PROCESSOR PIC12F675
            INCLUDE   <P12F675.inc>
        __CONFIG  _MCLRE_OFF&_CP_OFF&_WDT_ON&_BODEN_ON&_INTRC_OSC_NOCLKOUT
        endif
    
            radix     dec
    
        errorlevel 0,-305,-302
    
    
    ; Bit definitions for the GPIO register and the TRIS register
    
    #DEFINE CH_1     0    ; pin 7   Channel 1 output
    #DEFINE CH_2     1    ; pin 6   Channel 2 output
    #DEFINE CH_3     2    ; pin 5   Channel 3 output
    #DEFINE PPM_in     3    ; pin 4   input pulse stream
    #DEFINE CH_4     4    ; pin 3   Channel 4 Output
    #DEFINE LED     5    ; pin 2   Signal Indicator LED
    
    #DEFINE TrisBits H'FF'&~((1<<CH_1)|(1<<CH_2)|(1<<CH_3)|(1<<CH_4)|(1<<LED))
    
    
    ; Bits to be set with the OPTION instruction
    ;   No wake up
    ;   No weak pullups
    ;   Timer 0 source internal
    ;   Prescaler to Timer 0, divide by 256.
    ;
    #DEFINE OptionBits B'11000111'
    
    ; =========================================================================
    ; Macro for generating short time delays
    ;
    NO_OP           MACRO   count
    NO_OP_COUNT     SET     count
                    WHILE   NO_OP_COUNT>1
            goto    $+1        ; 2 clocks
    NO_OP_COUNT     SET     NO_OP_COUNT-2
                    ENDW
            IF    NO_OP_COUNT
            nop            ; 1 clock
            ENDIF
                    ENDM
    
    ;===========================================================================
    ; Macro to create offsets for variables in RAM
    ;
            ifdef    __12C508
    ByteAddr    SET    7
            else
    ByteAddr    SET    32        ; user RAM starts here
            endif
    
    BYTE            MACRO     ByteName
    ByteName        EQU       ByteAddr
    ByteAddr    SET       ByteAddr+1
                    ENDM
    
    ; ==========================================================================
    ;                 RAM Variable Definitions  
    ;
            BYTE    Flags        ; various boolean flags            
    
            BYTE    PPMcount    ; pulse length. 1~255 = 0.75~2.28mS  
    
            BYTE    PPM_1        ; channel 1 in        
            BYTE    PPM_2        ; channel 2 in
        BYTE    PPM_3        ; channel 3 in
        BYTE    PPM_4        ; channel 4 in
    
        BYTE    PWM_1        ; channel 1 out
        BYTE    PWM_2        ; channel 2 out
        BYTE    PWM_3        ; channel 3 out
        BYTE    PWM_4        ; channel 4 out
    
        BYTE    PMM_1        ; channel 1 memory
        BYTE    PMM_2        ; channel 2 memory
        BYTE    PMM_3        ; channel 3 memory
        BYTE    PMM_4        ; channel 4 memory
    
        BYTE    FLS_1        ; channel 1 failsafe
        BYTE    FLS_2        ; channel 2 failsafe            
        BYTE    FLS_3        ; channel 3 failsafe            
        BYTE    FLS_4        ; channel 4 failsafe            
    
        BYTE    GoodFrames    ; No. of good frames to go before
                    ; accepting failsafe frame.
     
        BYTE    HoldFrames    ; No. of bad frames to go before going
                    ; to failsafe
    
        BYTE    ArmFrames    ; No. of low throttle frames to go
                    ; before arming throttle.
        BYTE    Temp1
        BYTE    Temp2
    
    
    
    ; flag values
    ;
    #DEFINE WATCH    0        ; Watchdog timeout
    #DEFINE GOT_FS    1        ; have captured failsafe frame
    #DEFINE    GOT_4    2        ; 4 channels found in current frame
    #DEFINE DET_4    3        ; 4 channel TX detected
    #DEFINE JR    4        ; JR throttle detected
    #DEFINE    ARMED    5        ; throttle armed
    
    ; number of consecutive good frames required at startup.
    
    #DEFINE GOODCOUNT 10
    
    ; number of consecutive bad frames accepted without going to failsafe.
    
    #DEFINE HOLDCOUNT 25 
    
    ; number of consecutive low throttle frames required before arming.
    
    #DEFINE    ARMCOUNT 10
    
    
    ; macros for working with negative or positive shift
    
    skip_PPM_high  MACRO
        ifdef    Negative_Shift
        btfsc    GPIO,PPM_in
        else
        btfss    GPIO,PPM_in
        endif
        ENDM
    
    skip_PPM_low   MACRO
        ifdef    Negative_Shift
        btfss    GPIO,PPM_in
        else
        btfsc    GPIO,PPM_in
        endif
        ENDM
    
    ;****************************************************************************
    ;                                Code
    ;
        ORG    0
        goto    ColdStart
    
    ;-------------------------- version string ----------------------------------
    
        org    8        
        ifdef    __12C508
        dt    "RXDEC508"
        endif
        ifdef    __12F629    
        dt    "RXDEC629"
        endif
        ifdef    __12F675    
        dt    "RXDEC675"
        endif
        dt    "--V"
        dt    version
        dt    "--"
        ifdef    ARM_THROTTLE
        dt    "ARMTHROT"
        endif
        ifdef    DETECT_JR
        dt    "DETECTJR"
        endif
        ifdef    Negative_Shift
        dt    "NEG_SHFT"
        endif    
    
    ;============================================================================
    
    ColdStart:        
        bcf    Flags,WATCH
        btfss    STATUS,NOT_TO        ; copy Watchdog timeout flag
        bsf    Flags,WATCH
    
    ; get oscillator calibration value and use it to fine-tune clock frequency.
    ; 12C508/9 has value in W at startup, 12F629/75 gets it from RETLW at 0x3ff.
    
        ifdef    __12C508
        ifdef    NO_OSCCAL        
        movlw    0x90            ; replace with value for your PIC!
        endif
        movwf    OSCCAL            ; set oscillator calibration 
        else 
        bsf    STATUS,RP0        ; register bank 1 (12F629/75) 
        call    0x3ff            ; get OSCCAL value
        movwf    OSCCAL            ; set oscillator calibration 
            bcf    STATUS, RP0        ; register bank 0 
            endif
                          
        ifdef    __12C508
            clrwdt                    
            movlw    OptionBits  
            OPTION                        
        else
            clrwdt                    
        bsf    STATUS,RP0    ; register bank 1 (12F629/75)
            movlw    OptionBits
            movwf    OPTION_REG
        bcf    STATUS,RP0    ; register bank 0
            clrwdt
        endif
    
    
    ; initialise I/O registers 
    
        ifdef    __12C508
            clrf    GPIO            ; all outputs low
            movlw    TrisBits
            TRIS    GPIO            ; set I/O pin directions
        else
            clrf    GPIO            ; all outputs low
        bsf    STATUS,RP0        ; register bank 1 (12F629/75)
            movlw    TrisBits
            movwf    TRISIO            ; set I/O pin directions
        ifdef    ANSEL
        clrf    ANSEL            ; disable analog inputs (12F675)
        endif
        bcf    STATUS,RP0        ; register bank 0
        movlw    b'00000111'              
            movwf    CMCON            ; Comparator off
        endif
    
    ; CPU specific stuff done, now we can start the main program!
    
            goto    Main        
                                                               
    ;----------------------------------------------------------------------------
    ; GetPPM:             Get time to next PPM pulse    
    ;---------------------------------------------------------------------------- 
    ;
    ; input:    PPM signal has just gone high. 
    ; output:    PPMcount = Pulse Width * 6uS, next pulse has started
    ; error:    PPMcount = XX and error code in W.
    ;
    ; Error Codes
    ;        0 = good channel
    ;        1 = pulse too short, too long, or next pulse too soon 
    ;        2 = no next pulse (ie. no channel)
    
    PRECHARGE = ((750-15)/6)        ; = 0.75mS
    
    GetPPM:    
            movlw    PRECHARGE    ; preset count for signal high length
            movwf    PPMcount
    
            movlw    (30/6)
            movwf    Temp1
    high_delay:    NO_OP    2
            decf    PPMcount    ; wait 30uS to skip short glitches
            decfsz    Temp1
            goto    high_delay        
    hiloop:    
            skip_PPM_high        ; signal gone low ?
            goto    pulselo
            nop            ; 6uS per loop
            decfsz    PPMcount    ; count down
            goto    hiloop
            retlw    1        ; timed out, signal high
    pulselo:
            movlw    PRECHARGE-(180/6)    
            subwf    PPMcount,W    
            skpnc            ; less than minimum pulse width ?
            retlw    1
            movlw   PRECHARGE-(700/6)
            subwf   PPMcount,W
            skpc            ; greater than maximum pulse width ?
            retlw    1
    
            movlw    (30/6)
            movwf    Temp1
    low_delay:    NO_OP    2
            decf    PPMcount    ; wait 30uS to skip short glitches
            decfsz    Temp1
            goto    low_delay    
    to750uS:    
            skip_PPM_low        ; signal should stay low until 0.75mS
            retlw    1
            nop            ; 6uS per loop
            decfsz  PPMcount    ; count down to zero @ 0.75mS
            goto    to750uS
            incf    PPMcount    ; count up, start at 1
    to2280uS:
            skip_PPM_low        ; start of next channel pulse ?
            retlw    0        ; return OK
            nop            ; 6uS per loop
            incfsz  PPMcount    ; count up to 256 @ 2.28mS
            goto    to2280uS
            retlw    2        ; return timeout error @ 2.28mS        
        
    
    
    ;------------------------------------------------------------------------------
    ;                   Output PPM widths to channels 1-4
    ;------------------------------------------------------------------------------
    Output:        
            movf    PWM_1,W        ; get pulse length
            bsf    GPIO,CH_1    ; start pulse
            call    Servo_Delay    ; delay 6uS*len
            bcf    GPIO,CH_1    ; finish pulse
            movf    PWM_2,W
            bsf    GPIO,CH_2
            call    Servo_Delay
            bcf    GPIO,CH_2
            movf    PWM_3,W
            bsf    GPIO,CH_3
            call    Servo_Delay
            bcf    GPIO,CH_3
            movf    PWM_4,W
            bsf    GPIO,CH_4
            call    Servo_Delay
            bcf    GPIO,CH_4
            retlw    0
    
    
    ;------------------------------------------------------------------------------
    ;                     Delay Timer for Output Pulse
    ;------------------------------------------------------------------------------
    ;
    ; input: W=delay count, 1 to 255 = 0.75 to 2.28mS
    ;
    
    Servo_Delay:    
            movwf    Temp2
            movlw    (750-6)/6    
            movwf    Temp1
    _ds1:        nop
            clrwdt
            nop
            decfsz    Temp1        ; wait 750uS  
            goto    _ds1
    _ds2:        nop
            clrwdt
            nop
            decfsz    Temp2        ; wait 0~1.53mS, total = 0.75~2.28mS
            goto    _ds2        
            retlw    0
    
    ;-------------------------------------------------------------------------------
    ;                    Millisecond Delay Timer 
    ;-------------------------------------------------------------------------------
    ; Input: W = number of milliseconds to wait (max 256mS)
    ;
    
    dx1k:        movwf    Temp1
    _dx1k1:        movlw    (1000-5)/5
            movwf    Temp2
    _dx1k2:        clrwdt            ; avoid watchdog timeout
            nop
            decfsz    Temp2        ; wait 1mS
            goto    _dx1k2
            decfsz    Temp1        
            goto    _dx1k1
            retlw    0
    
    
    ;*******************************************************************************
    ;                   Main
    ;*******************************************************************************        
    
    
    Main:        btfsc    Flags,WATCH    ; did the watchdog timeout ?
                goto    Failsafe    ; oops! try to keep going ...
    
            clrf    Flags        ; clear all flags
    
            movlw    250        ; wait 500mS for Rx to stabilise 
            call    dx1k        ; (signal LED is on)
            movlw    250
            call    dx1k
    
    Start:        bsf    GPIO,LED    ; signal LED off
            movlw    (1500-750)/6            
            movwf    PMM_1        
            movwf    PMM_2        ; all channel outputs at midpoint        
            movwf    PMM_3        
            movwf    PMM_4                   
    
            movwf    PPM_4        ; init channel 4 (for 3 channel TX)
    
            movlw    GOODCOUNT    ; set number of good frames required
            movwf    GoodFrames    ; before saving failsafe values.
    
            movlw    HOLDCOUNT    ; set number of bad frames allowed
            movwf    HoldFrames    ; before going to failsafe.
    
            movlw    ARMCOUNT    ; set number of low throttle frames
            movwf    ArmFrames    ; before arming throttle
    
            goto    no_signal    
    
    
    Failsafe:    movlw    1
            movwf    HoldFrames    ; stay in failsafe until signal returns        
    
            btfss    Flags,GOT_FS    ; do we have good failsafe values?
            goto    no_signal    
    
            movf    FLS_1,W
            movwf    PWM_1        
            movf    FLS_2,W        ; get failsafe values
            movwf    PWM_2           
            movf    FLS_3,W
            movwf    PWM_3        
            movf    FLS_4,W
            movwf    PWM_4
    
            call    Output        ; output failsafe frame
    
            bcf    Flags,ARMED    ; keep throttle OFF
            movlw    ARMCOUNT
            movwf    ArmFrames    ; reset throttle arming delay    
    
    no_signal:    bsf    GPIO,LED    ; signal LED off
            
    wait_sync:    clrwdt            ; we're still sane, no reset please!
    
            clrf    Temp1
            movlw    9        ; set 'gap detect' timeout to 23mS
            movwf    Temp2
            
    wait_gap:    skip_PPM_high        ; wait for a gap    ]
            goto    time_gap    ;             ]
            nop            ;            ]
            clrwdt            ;            ]
            nop            ;            ] 10uS per loop
            decf    Temp1        ;            ]
            skpnz            ;            ]
            decfsz    Temp2        ; timed out ?        ]
            goto    wait_gap    ;            ] 
            goto    badframe    ; can't find sync gap!             
        
    time_gap:    clrf    PPMcount    ; reset gap timer     
    
    in_gap:        decf    Temp1        ;            }
            skpnz            ;            }
            decf    Temp2        ; timed out ?        }
            skpnz            ;            } 
            goto    badframe    ; can't find sync gap!    } 10uS per loop
            skip_PPM_low        ; still in gap ?    }
            goto    wait_gap    ;             }
            incfsz    PPMcount    ; gap > 2.56mS ?    }
            goto    in_gap        ; no, continue timing    }
    
    Get_Frame:    movlw    128-(23000/256)    ; set frame timeout to 23mS
            movwf    TMR0
    wait_1st:    clrwdt
            btfsc    TMR0,7        ; timer reached 23mS ?
            goto    badframe    
            skip_PPM_high        ; wait for start of first channel
            goto    wait_1st
            bcf     Flags,GOT_4    ; channel 4 not received yet
            NO_OP    3
            call    GetPPM        ; get first channel
            andlw    255
            skpz            ; process return code
            goto    badframe
            movf    PPMcount,W
            movwf    PPM_1
            call    GetPPM        ; get 2nd channel
            andlw    255
            skpz           
            goto    badframe
            movf    PPMcount,W
            movwf    PPM_2
            call    GetPPM        ; get 3rd channel
            andlw    255
            skpz           
            goto    badframe
            movf    PPMcount,W
            movwf    PPM_3
            call    GetPPM        ; get 4th channel
            andlw    255
            skpz           
            goto    error4
            movf    PPMcount,W
            movwf    PPM_4
            bsf    Flags,GOT_4
            goto    update
            
    error4:        xorlw    2
            skpz            ; channel 4 missing ?
            goto    badframe    
            btfss    Flags,GOT_FS    ; got failsafe frame yet ?
            goto    update        ; no, ignore missing channel 4        
            btfss    Flags,DET_4    ; 4 channels detected ?
            goto    update        ; no, ignore missing channel 4
        
    badframe:    clrwdt
            movlw    128-((23000-9000)/256); timer reached 9mS ?
            subwf    TMR0,w
            skpc            ; wait 9mS to skip other channels
            goto    badframe
            movlw    ARMCOUNT    ; reset throttle arming delay
            movwf    ArmFrames
            decfsz    HoldFrames    ; too many bad frames ?
            goto    hold
            goto    Failsafe
    
    hold:        btfsc    Flags,GOT_FS    ; good frame available for hold ?
            call    Output        ; yes, output last good frame
            goto    no_signal    ; no, just stay silent
    
    ;
    ; Got a good frame. Output the averaged pulse widths of this frame 
    ; and the last frame. 
    ;
    update:        movf    PPM_1,W
            addwf    PMM_1        ; PWM out = average(this+last)   
            rrf    PMM_1,w
            movwf    PWM_1        
            movf    PPM_2,W
            addwf    PMM_2
            rrf    PMM_2,w
            movwf    PWM_2
            movf    PPM_3,W
            addwf    PMM_3
            rrf    PMM_3,w
            movwf    PWM_3
            movf    PPM_4,W
            addwf    PMM_4
            rrf    PMM_4,w
            movwf    PWM_4
    
            btfss    Flags,GOT_FS    ; no output until failsafe captured
            goto    output_done
    
            ifdef    ARM_THROTTLE
    
            btfsc    Flags,ARMED    ; throttle armed ?
            goto    do_output    ; yes
    
            movlw    (1300-750)/6      
            btfsc    Flags,JR    
            subwf    PWM_1,w        ; throttle < 1.3mS ?
            btfss    Flags,JR
            subwf    PWM_3,w
            skpc    
            goto    low_throttle    ; yes    
            movlw    ARMCOUNT
            movwf    ArmFrames    ; no, reset arming delay
            goto    disarm
    
    low_throttle:    decfsz    ArmFrames    ; got enough arming frames ?    
            goto    disarm
            bsf    Flags,ARMED    ; yes, arm throttle now
            goto    do_output
    disarm:
            movf    FLS_3,w
            btfss    Flags,JR
            movwf    PWM_3        ; set throttle to failsafe value
            movf    FLS_1,w
            btfsc    Flags,JR
            movwf    PWM_1        
    
            endif    ; ARM_THROTTLE
    
    do_output:    call    Output        ; output good frame
    
    output_done:    movf    PPM_1,W        
            movwf    PMM_1
            movf    PPM_2,W        ; remember this frame 
            movwf    PMM_2
            movf    PPM_3,W
            movwf    PMM_3
            movf    PPM_4,W
            movwf    PMM_4
    
            movlw    HOLDCOUNT    ; reset failsafe timeout
            movwf    HoldFrames
    
            bcf    GPIO,LED    ; signal LED on 
    
            btfsc    Flags,GOT_FS    ; already got failsafe frame ?
            goto    frame_done    ; yes
    
            clrwdt
    
            decfsz    GoodFrames    ; got enough good frames ?
            goto    frame_done    ; no
    
    ; Got enough good frames, now get failsafe values
    
            btfsc    Flags,GOT_4    ; channel 4 detected ?
            bsf    Flags,DET_4    
    
            movf    PWM_1,W
            movwf    FLS_1        
            movf    PWM_2,W
            movwf    FLS_2           
            movf    PWM_3,W        ; copy good output to failsafe     
            movwf    FLS_3        
            movf    PWM_4,W
            movwf    FLS_4
    
            bsf    Flags,GOT_FS    ; failsafe frame captured    
    
            ifdef    ARM_THROTTLE
    
            ifdef    DETECT_JR
            movlw    (1300-750)/6
            subwf    FLS_1,w        ; channel 1 < 1.3mS ?
            skpc
            goto    jr_detected
            movlw    (1700-750)/6
            subwf    FLS_1,w        ; channel 1 >= 1.7mS ?
            skpc
            goto    futaba
            movlw    (1100-750)/6    ; failsafe low throttle!
            movwf    FLS_1
    jr_detected:    bsf    Flags,JR    ; JR throttle detected
            goto    arm
            endif    ; DETECT_JR
    
    futaba:        movlw    (1700-750)/6
            subwf    FLS_3,w        ; channel 3 >= 1.7mS ?
            skpc
            goto    arm
            movlw    (1100-750)/6    ; failsafe low throttle!
            movwf    FLS_3
    
    arm:        bsf    Flags,ARMED    ; arm throttle now
    
            endif    ; ARM_THROTTLE
    
    frame_done:    goto    wait_sync    ; wait for next frame
    
    
    ;---------- Oscillator Calibration Subroutine (12F629/75 only) --------------
    
            ifdef    __12F675
            org    0x3ff
            retlw    0x90    ; replace with oscal value for your PIC!
            endif
    
            END

  2. #2
    Join Date
    Aug 2003
    Posts
    985


    Did you find this post helpful? Yes | No

    Default Re: PPM decoding using 12F508 problem

    I think this will work.

    changed last label to Failsafeb
    Code:
    badframe:    clrwdt
            movlw    128-((23000-9000)/256); timer reached 9mS ?
            subwf    TMR0,w
            skpc            ; wait 9mS to skip other channels
            goto    badframe
            movlw    ARMCOUNT    ; reset throttle arming delay
            movwf    ArmFrames
            decfsz    HoldFrames    ; too many bad frames ?
            goto    hold
            goto    Failsafeb

    then try this directly above the routine Failsafe
    Code:
    Failsafeb:  
        	bsf    GPIO,CH_1
    	bsf    GPIO,CH_2
    	bsf    GPIO,CH_3
    	bsf    GPIO,CH_4
    
            movlw 	1	;total 1.5ms
    	call	Servo_Delay
    	movlw 	1
    	call	Servo_Delay
    
    	;goto	Failsafe ; not needed because execution will continue to Failsafe
    I can’t guess if you want to turn throttle off before or after the 1.5ms,
    or when you want to reset throttle arming delay which was done in Failsafe.
    That turns all outputs on 1 instruction apart.

    If you meant cycle them all with 1.5 ms delay each, then ignore all of the above,
    and simply write your own delay constants in the original routine instead of copying
    from the variables.

    This flows onto the next label int he program so must be left in place.
    Code:
    Failsafe:    movlw    1
            movwf    HoldFrames    ; stay in failsafe until signal returns        
    
            btfss    Flags,GOT_FS    ; do we have good failsafe values?
            goto    no_signal    
    
            movlw    110		; only guessing approx value for 1.5ms here
            movwf    PWM_1        
            movlw    110
            movwf    PWM_2           
            movlw    110
            movwf    PWM_3        
            movlw    110
            movwf    PWM_4
    
            call    Output        ; output failsafe frame
    
            bcf    Flags,ARMED    ; keep throttle OFF
            movlw    ARMCOUNT
            movwf    ArmFrames    ; reset throttle arming delay
    Last edited by Art; - 9th August 2016 at 17:10.

  3. #3
    Join Date
    Jan 2014
    Posts
    84


    Did you find this post helpful? Yes | No

    Default Re: PPM decoding using 12F508 problem

    Thank you very much Art ! All its ok, now is working perfectly.

    I adjusted the value, now the pulse on all chanells have 1,5mS

    Code:
     movlw    125		;  value for 1.5ms here
            movwf    PWM_1        
            movlw    125
            movwf    PWM_2           
            movlw    125
            movwf    PWM_3        
            movlw    125
            movwf    PWM_4
    Last edited by midali; - 9th August 2016 at 17:33.

Similar Threads

  1. 12F508 OPTION Register
    By sayzer in forum mel PIC BASIC Pro
    Replies: 7
    Last Post: - 13th January 2013, 00:00
  2. 12F508 and Dallas 1820 not working
    By Picprogman in forum mel PIC BASIC Pro
    Replies: 13
    Last Post: - 10th February 2012, 17:13
  3. 12F508 strange timing
    By pk7639 in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 23rd April 2007, 00:25
  4. calibration clock 12f508
    By volcane in forum mel PIC BASIC Pro
    Replies: 13
    Last Post: - 5th December 2006, 10:33
  5. 12F508 question...
    By muddy0409 in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 22nd August 2005, 09:32

Members who have read this thread : 1

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