I thought I might post my first working cut. It creates an 8ch PPM frame. The first two channels step in opposition to each other. The device allows me to run tests on manufacturers transmitter modules without using a real RC transmitter or operator.
I enhanced it after this for different speeds and button control
Code:
'****************************************************************
'* Name : 8ch PPM generator.BAS
'* Author : Martin S (mr.sneezy)
'* Notice : Copyright (c) 2008 [select VIEW...EDITOR OPTIONS]
'* : All Rights Reserved
'* Date : 22/11/2008
'* Version : 1.0
'* Notes : Code for PIC12F683, logic direction suits Futaba compatible TX modules
'* :
'****************************************************************
Define Osc 4
' Software Defines
' ----------------
Temp_Var2 var word
Servo_dir var byte ' Store the servo going left or right direction flag 0 or 1
Run_flag var byte 'Loop flag for triggering a PPM frame
PPM1_value var Word 'variable for the value ch1 servo position pulse
PPM2_value var Word 'variable for the value ch2 servo position pulse
PPM_Out Var GPIO.0 'PPM drive for TX module is on this port pin
LED1 Var GPIO.1 'Indicator LED is on this port pin
' Initialise Processor - check for each PIC type
' --------------------
VRCON.7 = %0 'Comparator voltage reference OFF
CMCON0 = %111 'Comparator inputs to OFF, all pins normal I/O
ANSEL = 0 'Turn off all AD's
' Set GPIO port pins as Input or Output
TRISIO.0 = 0 'Input(0 = output, 1 = Input)
TRISIO.1 = 0 '
TRISIO.2 = 0 '
TRISIO.3 = 1 '
TRISIO.5 = 1 '
TRISIO.6 = 1 '
INCLUDE "DT_INTS-14.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, _my_handler, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
T1CON = $1 ; TMR1ON
@ INT_ENABLE TMR1_INT ; enable Timer 1 interrupts
Low LED1
Low PPM_out
PPM1_value = 500 'seed the center value of the servos
PPM2_value = 500 'seed the center value of the servos
Servo_dir = 0 'Set initial servo direction
Main:
While Run_flag = 0 'loop looking for trigger
goto Main
Wend
Gosub Start_pulse 'start of a channel (or sync pulse)
Gosub Channel_1 'channel 1 PPM period
Gosub Start_pulse 'start of a channel
Gosub Channel_2 'channel 2 PPM period
Gosub Unused_ch 'a complete PPM channel pulse set, servo centered (1500uS)
Gosub Unused_ch '
Gosub Unused_ch '
Gosub Unused_ch '
Gosub Unused_ch '
Gosub Unused_ch '
Gosub Start_pulse 'start of sync pulse
If Servo_dir = 0 then 'do math while waiting for interrupt, plenty of time
PPM1_value = PPM1_value + 5 'count upwards ch1 servo goes clockwise
Else
PPM1_value = PPM1_value - 5 'count downwards ch1 servo goes anti-clockwise
Endif
If PPM1_value = 1000 then 'detect servo limit CW
Servo_dir = 1
Endif
If PPM1_value = 0 then 'detect servo limit CCW
Servo_dir = 0
Endif
PPM2_value = 1000 - PPM1_value 'Ch2 servo moves opposite direction to servo Ch1
Run_flag = 0 'clear the interrupt handlers trigger flag
GOTO Main
Start_pulse:
high PPM_out
Pauseus 400 'channel start high period
Low PPM_out
return
Unused_ch:
high PPM_out
Pauseus 400 'channel start high period
Low PPM_out
Pauseus 1100 'Unused channel low period
return
Channel_1:
Pauseus PPM1_value 'just leave channel low for X time
Pauseus 600 'make up the minimum pulse to 1000uS
return
Channel_2:
Pauseus PPM2_value 'just leave channel low for X time
Pauseus 600 'make up the minimum pulse to 1000uS (start pluse + possition + this)
return
'---[TMR1 - interrupt handler]--------------------------------------------------
my_handler:
T1CON = %0 'Stop timer 1
TMR1L = $23 'Load for 22.5mS interrupts
TMR1H = $A8
T1CON = %1 'Start timer1
TOGGLE LED1
Run_flag = 1
@ INT_RETURN
Bookmarks