RC Groups

RC Groups
    DIY Electronics
        Build Log Yet another Evo9 2.4GHz conversion

#1 mmormota Nov 13, 2007 09:42 PM

Yet another Evo9 2.4GHz conversion
 
9 Attachment(s)
I converted my Evo9 to FASST spreaded spectrum radio, using a T6EXA rf pcb and a PIC12F683 uC. Let the pictures tell the story... ;)

The failsafe mode and the range check mode is controlled by the Evo, programmable in the usual way.


"I am not recommending this modification to anybody. I am only reporting what I did and how."

It is working for me, but there are possible errors in the code or the method itself. A malfuction may cause the loss of control, injury etc.

#2 mmormota Nov 13, 2007 09:48 PM

The source code:
Code:

;
;        -------------------------------------------------------------------
;        |                                                                                                                                        |
;        |                Interface program for using the Futaba T6EX radio's                        |
;        |                FASST Rf pcb in the Multiplex Royal Evo9 radio                                |
;        |                                                                                                                                        |
;        -------------------------------------------------------------------
;
; The Futaba FASST pcb needs a special 8 channel ppm input. The length of the 1st positive
; pulse determines if the module transmits on normal or reduced power level.
; 1st pulse:
;                420 usec: normal power
;                440 usec: reduced power, range check mode
; 2nd to 9th pulse:
;                400 usec
; The value of the 8th channel determinies the fail-safe value and mode.
; The failsafe mode means that in case of connection break the 3rd channel output gets the last
; value of the 8th channel.
; If the 8th channel value is 0,9 ms = -110% (on a -100% to +100% scale) then fail-safe is off, the 3rd channel just keeps the
; last valid value. 
;
; This firmware made for a PIC12F683 uC. It receives the ppm signal from the Evo9 on GP2 pin5, and sends
; out the the modified pulses on GP0 pin7. (Vdd: pin1 Gnd:pin8 all other pins NC)
; The delay on receiving the pulses and sending them out is negligible, a few usecs only.
;   
; The interface has 2 basic modes.
; Mode 1:
;        the Evo9 must be in 8 channel mode (8th channel assigned to a function, the 9th is not)
;  the interface sends out the pulses to choose the "normal power" mode.
; Mode 2:
;        The mode is programmable in the usual way using the 9th. channel. As the range check mode is critical, never
;        program it to a normal switch. Use a pushbutton to avoid unwanted reduced power mode during normal flight.
;        the Evo9 must be in 9 channel mode (the 9th channels assigned to a function)
;        the 9th channel tells to the interface the necessary power mode
;                range check mode:  set ch9 to 2000 usec or 90% (on a -100% to +100% scale)
;                normal power mode: set ch9 to 1000 usec or -90% (on a -100% to +100% scale)       
;        the interface just receives ch9, but not sends out the 10th pulse, as the FASST pcb needs 8ch ppm

; A possible way to program the modes in the Evo9:
; In the setup menu, assign the H pushbutton to the AUX1 menu.
; In the servo menu, assign ch8 to AUX1. The is the servo/calibrate menu, turn all points to the same value (getting a horizontal line),
; this value is the fail-safe for the 3rd channel. Turn all points to -110% for fail-safe mode off.
; For range check, assign ch9 to AUX1. Turn the end points to -80% and +80%. Push and keep pushed the H button to get range-check mode.
; (the red led blinks to indicate the reduced power mode)
;
        list        p=12f683
        #include P12F683.INC
        __CONFIG  _MCLRE_OFF&_CP_OFF&_WDT_OFF&_INTRC_OSC_NOCLKOUT

; Bit definitions for the GPIO register and the TRIS register

#DEFINE        no_pulse                0                        ; no output pulse on irq
#DEFINE        norm_power                D'420'                ; 420 usec, normal power                 
#DEFINE        range_check                D'440'                ; 440 usec, reduced power
#DEFINE        normal_pulse        D'400'                ; 400 usec, normal 3...9th pulse
#DEFINE        ch9_range_min        D'1900'                ; if 1900 < 9th_channel <2000 it's range check
#DEFINE        ch9_range_max        D'2050'                ; if no 9th channel or the pulse is out of the above range it's normal power mode

;===========================================================================
; Macro to create offsets for variables in RAM
;
ByteAddr        SET        32                ; user RAM starts here

BYTE                MACRO    ByteName
ByteName        EQU      ByteAddr
ByteAddr        SET      ByteAddr+1
                        ENDM

; ==========================================================================
;                RAM Variable Definitions 
;
        BYTE        mode                        ; bit7: the irq sends a message to the main program by clearing the bit
                                                        ;  it means, that an input pwm pulse received
    BYTE        counter                        ; time counter, 12usec / step
        BYTE        pulse_length        ; the main program sets it, and the irq creates a pulse according to this value
        BYTE        first_pulse                ; the length of the first pulse according to mode
        BYTE        startup_counter        ; it counts the frames sat startup
        BYTE        delay_counter
   


;        -------------------------------------------------------------------
;        |                                                                                                                                        |
;        |                        Code start                                                                                                |
;        |                                                                                                                                        |
;        -------------------------------------------------------------------

        org 0x000

          goto        Start                        ; Start application beyond vector area
        org                04h
        goto        interrupt

;        -------------------------------------------------------------------
;        |                                                                                                                                        |
;        |                        Main program start                                                                                |
;        |                                                                                                                                        |
;        -------------------------------------------------------------------

        org 8h
Start:
        nop
        nop
        nop
        nop
        BCF        STATUS,RP0                ;Bank 0
        CLRF        GPIO                        ;Init GPIO
        MOVLW        07h                        ;Set GP<2:0> to
        MOVWF        CMCON0                        ;digital I/O
        BSF        STATUS,RP0                ;Bank 1
        CLRF        ANSEL                        ;digital I/O
        MOVLW        04h                        ;Set GP2 as input
        MOVWF        TRISIO                        ;and set GP<5,4,3,1,0> as outputs
        bsf                OSCCON,4                ;switch to 8MHz, default on startup is 4MHz
        BCF        STATUS,RP0                ;Bank 0
        bsf                INTCON,INTE
       

        bsf                GPIO,0                                ; 220 msec high on startup

        bsf                mode,7
        movlw        no_pulse
        movwf        pulse_length
        bcf                INTCON,INTF
        bsf                INTCON,GIE

        movlw        D'72'                                ; waits for several pulses before start
        movwf        startup_counter

wait_pulses:
        bsf                mode,7
wait_0:
        btfsc        mode,7
        goto        wait_0

        decfsz        startup_counter
        goto        wait_pulses

        bcf                GPIO,0                                ; startup pulse end


default_pulses:
        movlw        norm_power/4                ; default mode setting: normal power
        movwf        first_pulse

wait_frame_gap:
        bsf                mode,7       
        call        time_counter

        addlw        0ffh                                ; if the time_counter reaches 3ms, it comes back with 1
        bnz                wait_frame_gap                ; jumps to wait_frame_gap, if the counter comes back before 3ms               

        movf        first_pulse,w
        movwf        pulse_length
        bsf                mode,7
wait_1:
        btfsc        mode,7
        goto        wait_1

        movf        normal_pulse/4
        movwf        pulse_length
        bsf                mode,7
wait_2:       
        btfsc        mode,7
        goto        wait_2

        movlw        normal_pulse/4
        movwf        pulse_length
        bsf                mode,7
wait_3:
        btfsc        mode,7
        goto        wait_3

        movlw        normal_pulse/4
        movwf        pulse_length
        bsf                mode,7
wait_4:
        btfsc        mode,7
        goto        wait_4

        movlw        normal_pulse/4
        movwf        pulse_length
        bsf                mode,7
wait_5:
        btfsc        mode,7
        goto        wait_5

        movlw        normal_pulse/4
        movwf        pulse_length
        bsf                mode,7
wait_6:
        btfsc        mode,7
        goto        wait_6

        movlw        normal_pulse/4
        movwf        pulse_length
        bsf                mode,7
wait_7:
        btfsc        mode,7
        goto        wait_7

        movlw        normal_pulse/4
        movwf        pulse_length
        bsf                mode,7
wait_8:
        btfsc        mode,7
        goto        wait_8

        movlw        normal_pulse/4
        movwf        pulse_length
        bsf                mode,7
wait_9:
        btfsc        mode,7
        goto        wait_9

wait_10:
        movlw        no_pulse/4
        movwf        pulse_length
        bsf                mode,7
        call        time_counter

        addlw        0ffh
        bz                default_pulses                ; if no 9th channel (10th pulse) then use the default settings

        movlw        D'400'/D'12'
        addwf        counter,f                        ; because the counter starts at the end of the pulse
        movf        counter,w                        ; 1 counter step means 12 usec
        addlw        D'256'-ch9_range_min/D'12'
        bnc                default_pulses                ; if the 9th channel is too short then use the default setting       

        movf        counter,w                        ; 1 counter step means 12 usec
        addlw        D'256'-ch9_range_max/D'12'
        bc                default_pulses                ; if the 9th channel is too long, then use the default pulse setting

        movlw        range_check/4                ; settings for reduced power (range check) and failsafe on
        movwf        first_pulse

        goto        wait_frame_gap                ; if the 9th channel is in the proper range,
                                                                ;  then use the above pulse settings
;
;        -------------------------------------------------------------------
;        |                                                                                                                                        |
;        |                        Interrupt                                                                                                |
;        |                                                                                                                                        |
;        -------------------------------------------------------------------
;
; Interrupt starts on positive edge of the irq input, GP2.
; The routine sends out a pulse_length long positive pulse on GP0. One step gives 4 usec.
; If pulse_length = 0 no pulse generated.
; The routine clears the mode.7 bit, it tells to the main program that irq occoured.
;
interrupt:
        movf        pulse_length,w
        addlw        0
        bz                nopulse

        bsf                GPIO,0                ; output pulse start
irq1:
        nop
        nop
        nop
        nop
        nop
        decfsz        pulse_length
        goto        irq1

        bcf                GPIO,0                ; output pulse end
nopulse:
        bcf                mode,7
        bcf                INTCON,INTF
        retfie

;        -------------------------------------------------------------------
;        |                                                                                                                                        |
;        |                        Time counter                                                                                        |
;        |                                                                                                                                        |
;        -------------------------------------------------------------------
;
; It's a 3 ms delay loop, if no input pulse received. In this case it returns with 1.
; If a pulse received, irq starts and clears the mode.7 bit. Then the routine returns with 0.
;  In this case the run time is stored in counter, 1 step means 12 usec.
 
time_counter:
        clrf        counter
tc1:
        btfss        mode,7
        retlw        0                        ; 0 means that it returns because of irq occoured
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        incfsz        counter
        goto        tc1
        retlw        1                        ; 1 means it counted up to 3ms                       

;        -------------------------------------------------------------------
;        |                                                                                                                                        |
;        |                        delay counter                                                                                        |
;        |                                                                                                                                        |
;        -------------------------------------------------------------------
;
; It's delay loop. delay = delay_counter * 10 usec.
       
delay_loop:
        goto        dl2
dl1:
        nop
        nop
        nop
        nop
        nop
        nop
dl2:
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        decfsz        delay_counter
        goto        dl1
        return
       



        end

The hex code:
Code:

:020000040000FA
:020000000828CE
:020008006D2861
:1000100000000000000000008312850107309900F5
:1000200083169F01043085000F1683120B160514EA
:10003000B2170030B4008B108B174830B600B217DF
:10004000B21B2028B60B1F2805106930B500B21767
:100050007D20FF3E031D27283508B400B217B21BD0
:100060002F28E408B400B217B21B34286430B4005F
:10007000B217B21B39286430B400B217B21B3E2845
:100080006430B400B217B21B43286430B400B21716
:10009000B21B48286430B400B217B21B4D2864303C
:1000A000B400B217B21B52286430B400B217B21BAE
:1000B00057280030B400B2177D20FF3E03192528D1
:1000C0002130B3073308623E031C25283308563E0F
:1000D000031825286E30B50027283408003E031980
:1000E0007A28051400000000000000000000B40B96
:1000F00072280510B2138B100900B301B21F00342F
:1001000000000000000000000000000000000000EF
:1001100000000000000000000000000000000000DF
:10012000000000000000B30F7E2801349D2800006D
:1001300000000000000000000000000000000000BF
:1001400000000000000000000000000000000000AF
:06015000B70B9728080020
:02400E00D43F9D
:00000001FF


#3 pegase Nov 21, 2007 08:35 AM

Hi mmormota,

I'am studying your source code to make something like for my FX18 radio.

Your modul seems to need positive input pulses and generate positive output pulses.

Is it exact ? I suppose it is.

I scope input signal of radio board : 3.3V peak to peak, positive pulses.

So as I only have PPM with negative pulses available I have to change input polarity of firmware. I'll try by patching bin.

Thanks mmormota to give us source and bin. This will be a great help for me.

Pegase

#4 coro Dec 24, 2007 04:13 AM

Thank You very much for the great idea and sharing the code.
I have EVO9, and also I like Futaba FASST system much more than any other available.
Subscribed and really thank You.
Next step, I have to purchase RF module (is it usable with any Futaba FASST module?) and PIC, or perhaps I will rewrite Your code for some ATTiny mcu.
Merry Christmas!

#5 cp1 Jan 04, 2008 06:29 PM

GCC code for an ATtiny25 is available on www.drivecalc.de. I made it for my son's MPX Cockpit SX. The adapter swaps channels 3 and 4 and adds a 0% signal on channel 8 for failsafe.

Christian

#6 mmormota Jan 07, 2008 01:26 PM

1 Attachment(s)
Another version built with unmodified Evo9 , the external FASST box connected via trainer port. The radio is working with the internal 35MHz synth module too.

The firmware and the shamatics is the same, just the ppm input is limited to 3V using a series 47kOhm and a parallel white Led.

Range check and fail-safe function is working.

#7 coro Jan 07, 2008 09:53 PM

Thank You very much for writing and sharing GCC source code, it saves a lot of time.
External module using trainer port is excellent idea.

#8 cp1 Jan 08, 2008 06:18 AM

Hi coro,

you're welcome. Are you going to use a Cockpit SX? Otherwise, if there is no need to swap channels, you could use much simpler code. PM me your address, if you want to receive that simpler version.

Christian

#9 cp1 Jan 08, 2008 05:13 PM

I have posted a new software version today, featuring true 16 bit resolution.

#10 coro Jan 17, 2008 04:52 PM

Dear Christian, no, than You, I have no FASST module yet. I am using and I will be upgrading MPX Royal Evo 9. Not right now..
I have stopped thinking about new transmitter purchase, and I am glad that I found this sollution. I will look into Your code, as well as mmormota code, further, once I get ready.
And thank You for 16-bit version as well.

#11 cp1 Jan 17, 2008 06:50 PM

Hi Coro,

for the Evo 9 you could use the code I have made for my Evo 12. Just PM me if want to receive it.

Christian

#12 mmormota Jan 19, 2008 06:56 AM

Warning

The additional box version becames ZEROID.
It's possible reason, that sometimes the FASST panel didn't boot up properly (I mean the LED's keep blinking). The owner in order to test it, many times switched on and off the radio. It happened before the ZEROID issue surfaced in this forum.

-------------------------

The built-in pcb works without issues, and boot up properly without a single exception. The same the situation, if the additional box version is switched on with RF tilt (pushing the wrench button...).

The cause of the boot up issue is that the radio communicates first with the internal synth module. It takes some time, and during this time no proper ppm signal is generated for the FASST pcb input. The late start of the ppm signal causes that sometimes that the FASST panel just keeps blinking.

#13 cp1 Jan 19, 2008 01:11 PM

At this time there are 4 external moduls in our club, all driven by my ATtiny code, and we have checked them for the zero ID issue, of course. So far, there is no evidence.

mmormota, how do you identify a zero ID transmitter modul? You cannot read the ID, can you? The only way that I know of is by trying to connect to someone else's RX. If that person also has a zero ID TX, you will be able to take over the control. If you have a zero ID module, how can you be sure it had an ID when you purchased it?

By the way, I still have to see the boot up issue you are talking about. Ever since I am using code that produces accurate timing, the LEDs never kept blinking.

#14 mmormota Jan 19, 2008 01:46 PM

Quote:

Originally Posted by cp1
At this time there are 4 external moduls in our club, all driven by my ATtiny code, and we have checked them for the zero ID issue, of course. So far, there is no evidence.

Most probally the reason was the test, not the modification. During the test, the radio was many times rapidly switched on/off to check if it starts properly. That time the ZGUID problem was not surfaced, so we didn§t know that this is dangerous.

Quote:

mmormota, how do you identify a zero ID transmitter modul? You cannot read the ID, can you?
A brand new receiver is working with the radio without binding.

#15 cp1 Jan 29, 2008 01:31 PM

Today I have posted another software version for transmitters that do not need channel swapping, like the MPX Evo. It features latency free transmission, since without swapping there is no need to record and replay the signals. Nevertheless it also adds the motor off signal on channel 8 for the failsafe function, and in case the PPM stream carries less than 7 channels, it amends the missing channels on neutral servo positions.

Christian


All times are GMT -5. The time now is 05:25 AM.