Minor update. I have been playing around with the trying to have the Atom Pro trying to reliably intercepting the PWM signals from the Hitec receiver. My first attempt looked like:
[code]Variable declaration
PULSE_SLOP con 10 ; try to define some slop in pulse size so dont just flop back and forth
lPulse var long(6)
LPulseT var long
lPulsePrev var long(6)
bChannel var byte
bChannelMask var byte
pass var byte
PulseChanged var byte
TCNTStart var word(6)
…
;============================== Start of CODE ================================================
; Initialization code
gosub LCD_Init
;Interrupt init
ONINTERRUPT WKPINT_0,handle_intp0
ONINTERRUPT WKPINT_1,handle_intp1
ONINTERRUPT WKPINT_2,handle_intp2
ONINTERRUPT WKPINT_3,handle_intp3
ONINTERRUPT WKPINT_4,handle_intp4
ONINTERRUPT WKPINT_5,handle_intp5
PMR5.bit0 = 1 ;enables pin as WKP interrupt instead of normal I/O
PMR5.bit1 = 1 ;enables pin as WKP interrupt instead of normal I/O
PMR5.bit2 = 1 ;enables pin as WKP interrupt instead of normal I/O
PMR5.bit3 = 1 ;enables pin as WKP interrupt instead of normal I/O
PMR5.bit4 = 1 ;enables pin as WKP interrupt instead of normal I/O
PMR5.bit5 = 1 ;enables pin as WKP interrupt instead of normal I/O
IEGR2.bit0 = 0 ;0 = Pin will interrupt on a falling edge, 1 to interrupt on a rising edge.
IEGR2.bit1 = 0 ;0 = Pin will interrupt on a falling edge, 1 to interrupt on a rising edge.
IEGR2.bit2 = 0 ;0 = Pin will interrupt on a falling edge, 1 to interrupt on a rising edge.
IEGR2.bit3 = 0 ;0 = Pin will interrupt on a falling edge, 1 to interrupt on a rising edge.
IEGR2.bit4 = 0 ;0 = Pin will interrupt on a falling edge, 1 to interrupt on a rising edge.
IEGR2.bit5 = 0 ;0 = Pin will interrupt on a falling edge, 1 to interrupt on a rising edge.
; TimerW regs
TCRW.bit5 = 1 ;TIMERW counts on clk/8
TCRW.bit4 = 1 ;TIMERW counts on clk/8
TCRW.bit7 = 0 ;TCNT free running counter
TMRW.bit7 = 1 ;TCNT free running counter
pass = 0
PulseChanged = 0
ENABLE WKPINT_0
ENABLE WKPINT_1
ENABLE WKPINT_2
ENABLE WKPINT_3
ENABLE WKPINT_4
ENABLE WKPINT_5
LCD_String = “PWM Intercept”, 0
gosub LCD_Print[1, 0]
;================================ Main Loop =================================================
main_loop
; I wish I had some semaphores!
if PulseChanged then
DISABLE WKPINT_0
DISABLE WKPINT_1
DISABLE WKPINT_2
DISABLE WKPINT_3
DISABLE WKPINT_4
DISABLE WKPINT_5
gosub LCD_SetPos[0, 1]
for i = 0 to 5
if i = 3 then
gosub LCD_SetPos[0, 2]
endif
gosub LCDConvertNumToString[lPulse(i)]
gosub LCD_Print[0,0]
LCD_STRING = " ",0
gosub LCD_PRINT[0,0]
next
PulseChanged = 0
ENABLE WKPINT_0
ENABLE WKPINT_1
ENABLE WKPINT_2
ENABLE WKPINT_3
ENABLE WKPINT_4
ENABLE WKPINT_5
pause 500
endif
goto main_loop
'============================================================================================
’
’ Handle interrupts for each of the channels
handle_intp0
bChannel = 0
goto HandleChannel
handle_intp1
bChannel = 1
goto HandleChannel
handle_intp2
bChannel = 2
goto handleChannel
handle_intp3
bChannel = 3
goto handleChannel
handle_intp4
bChannel = 4
goto handleChannel
handle_intp5
bChannel = 5
goto handleChannel
HandleChannel
bChannelMask = 1 << bChannel
If (pass & bChannelMask) = 0 then
' Handle rare case of multiple channels active same time, by only resetting TCNT if we are the only channel...
if pass = 0 then
TCNT = 0
endif
TCNTStart(bChannel) = TCNT
IEGR2 = IEGR2 & ~bChannelMask ' interrupt on falling edge
pass = pass | bChannelMask
else
lPulseT = (TCNT - TCNTStart(bChannel))/2 ; divide by 2 to obtain us
if ((lpulseT + PULSE_SLOP) < lPulse(bChannel)) or ((lPulseT - PULSE_SLOP) > lPulse(bChannel)) then
lPulse(bChannel) = lpulseT
PulseChanged = 1
endif
IEGR2 = IEGR2 | bChannelMask 'interrupt on a rising edge
pass = pass & ~bChannelMask
endif
Resume
…[/code]
I do get the interrupts properly and calculate numbers. I believe that the first channel comes in accurately, but the others timings are off as I believe the ammount of time I spend processing the falling edge of one channel delays the processing of the raising edge of the next one and so the timing is to short. I looked at the 6 channels using the Parallax USB Oscilloscope and it looks like the 6 channels are each output sequentially, starting with CH1. It looks like CH2 might go high just before CH1 goes low, but could be same time. After CH6 goes low their is a delay until the cycle is repeated. (Each cycle is something like 20ms).
For my next attempt I will assume that channels are sequential and on rising edge of CH1 I will reset the TCNT to zero and then wait for the falling edge of all 6 channels and simply save away TCNT difference from one channel to the next. I may also have the code do most of its processing in the dead time after CH6.
Anyone have any other suggestions?