First, its not an issue. An issue implies a bug. In this case it’s the way the commands function. Each pulsin command has to wait for the next pulse and then wait for the pulse to finish before the next command will be processed. The pulsin command is software(eg bitbanged). The pulses you are reading are very slow so your program is very slow. The only real solution would be to use the capture hardware. There are 4 pins(p9,p10,p11 and p12 also called FTIOA-FTIOD) which can be used to do hardware capture of pulses. Note even using the hardware this is no picnic and I’m not going to go into details unless you are actually going to use this feature.
This is just a guess as to your issue but are you polling the servo signals in the order they are decoded by the receiver or did you arbitrarily choose the order to poll them? Here is why it might matter. Conventional R/C radios, that is using receivers that are not computer based, have up to 9 channels serially encoded one after another, each channel being 2mS max duration and the 10th slot is not used so the receiver can use it to sync. When the signals are demultiplexed by the receiver into individual servo signals they are then skewed by 2mS each in time. With a computer based receiver this might not be the case. Anyway, when capturing the pulses from the R/C receiver you should determine in what order they arrive and poll them with the pulsin in that order. If you do not then the pulsin may have to wait an entire frame (20mS) plus a worst case of 2 channels of skew (as much as another 4mS) to capture a particular channel. If you poll them in order then you can measure all 4 channels every frame and have the remainder of the frame to process the sensors and then re-transmit the 4 channels. this implies you would have about 4 mS to do your processing. How well any of this applies to computer based receivers… anybodys guess as I have never had opportunity to hook one to a scope.
The pulses are generated sequentially, therefore the order in which you read the pulses is important. If you read the pulses in the wrong order you have to wait 20mS + for the pulse to make it’s way around to being generated again. I do not know of an easy way to determine the optimum order to read the pulses. I don’t think the manufacturers publish this sort of information.
Hey is there an echo in here?
The big problem I see is that with a computer based receiver, like most spread spectrum receivers, there is no reason for the signals to be sequential.
…echo in here?
As for determining the “optimum” order, or even if the signals are coming in synchronously, you could certainly write an algorithm to poll the i/o pins and decipher the order of arrival. Then you would assign the pulsin channel poll order based on that deciphered order.
…ere?
Oh, lol, fast typers anyway…
Of course you willl still be trying to read 4 2ms pulses. If one pulse begins right after the previous pulse ends you will probably miss the front edge of the second pulse so you end up waiting 20ms to get the next pulse anyway. If there is sufficient delay from when the first pulse finishes till when the second pulse begins you may be able to group your reads 1,2,3,4 and take only approx 8ms total to read all four channels. In actual fact you’ll be reading upto 2.5 or 3ms pulses since the mid point of the servo pulse is at 1.5ms and can be upto ±1.5ms(though most are ±.5ms) from that point.
Thanks everyone for the valuable input! Im commited to make this project work so since im really new to micros you will read about me a lot around here.
I think that at this point the hardware capture solution that Acid´s is bringing is more processing effective but i wonder what solution is left for hardware driving the servos once the four capture pins are the same than HPWM command use. Hservo approach would work instead?
Im trying to save as much proccesing power as possible for sensor fusion and PIDs.
My goal is:
- Reading 4 PPM channels (Hardware based thru FTIOA-FTIOD ???)
- Reading 4 Analog sensors (ADIN command or hardware based???)
- Reading 1 SPI sensor (This would be great but can get rid of it if its too much in terms of pin count or processor overhead)
- Compute sensor readings and generating output data.
- Serial outputting for telemetry data (HSEROUT pins 19/20?)
- Otputting to 4 servos (Hardware based??)
I know that every approach may have its own restrictions and iterations with other commands, so first step would be successfully having the 4 PPM channels captured, analog sensor readings and the output for the 4 servos, then the rest.
I was not aware about the serialization of the PPM channels, i was expecting no more than 2-3ms for each channel reading (PULSIN) but it seems that is taking 20ms every channel, now i know what happens! Im reading channel 1 to 4 but maybe internal serialization is in different order.
Thanks again for all the feedback, I hope you can help me.
But even if there isn’t enough delay you could benefit by changing the order of the channels you read. For example if they are generated in order, 1,2,3,4 and there is no delay bewteen the pulses you could read them in the following order. 1,3,2,4. This should take alot less time to read as you only have to have one unnecessary cycle instead of 3.
Jim,
I can try it, but this approach may not work well with all receivers (different brands and models may have different sequence) involved in the project, that is why i think hardware solution is better. Im going to make some tests right now anyways, im working on it.
Ive just tested several sequences of PULSIN commands but no significant improvements. The more channels the more delay no matter the order.
If the pulses come in at the same time then there is no simple software way to do it with good accuracy. if polling is acceptable then you may be able to code a real tight loop in assembly but I still think this would be hard to balance so all 4 channels had accurate and repeatable results for any combination of inputs.
If you need to do it with hardware I think an important question becomes does the microcontroller used on the BAP actually have 4 capture/compare channels and 4 seperate hardware PWM channels?
There are just two hardware capture peripherals on the Atom PRO. As far as I know, all the DIP packaged PIC controllers and many, if not most, 8 but MCUs only have two hardware captures. I have not done much research into the 16 and 32 bit MCUs yet, so don’t know much about what they provide for capture peripherals. Most of the time, the capture pins are shared with hardware PWM and other peripherals. I believe I have seen some specialized controllers or peripherals with four hardware captures.
8-Dale
Actually on the AtomPro there are 4 hardware capture pins(P9-P12, also called FTIOA-D). The are also capable of compare operations(eg timing external events). FTIOB-D are also the HPWM pins.
The regular Atom only has 2 CCP capable pins(Capture/Compare/PWM).
Acidtech,
Ive been testing this code using the WKP service:
Code:
[code]
ONINTERRUPT WKPINT_0,MyWKPIntHandler0 ;point to where I want to go when an interrupt on WKP0 accurs.
PMR5.bit0 = 1 ;enables pin as WKP interrupt instead of normal I/O
IEGR2.bit0 = 0 ;this is the default so doesn’t have to be in your code. Pin will interrupt on a falling edge.
;Change to 1 to interrupt on a rising edge.
canal0 var word
enable WKPINT_0 ;sets the IENR1 bit to enable the WKP0 interrupt
main
debug "ch1 ",dec canal0 , 13]
goto main
MyWKPIntHandler0 ;On entry the IWPR bit for Wkp0 is automatically cleared.
disable ;with no arguments disable disables the global interrupt enable flag
rctime 0,1,canal0
enable ;re-enable global interrupt flag.
resume ;you must always resume(not return) from an interrupt or you will eventually crash.[/code]
It works erratic, sometimes returns weird readings…What i am doing wrong?
First are you running in debug. I see a debug statement. Debug mode will slow everything down and may cause rctime to not be started before the end of the pulse causing the rctime to get “weird” readings. SInce you are almost certainly running in debug mode(since you wouldn’
t get any feedback if you weren’t) I’d suggest using serout instead and running in normal mode.
Also an example of the data(both wierd and not weird) would be helpful.
Also, you are reading Servo pulses so you want to WKP on the RISING edge. Then rctime till the falling edge to get the pulse width. That may also be why you are getting “weird” readings sometimes.
Also another thing you can do instead of using rctime to read the remainder of the pulse is to setup timerw running at clk/8 speed. Then when the wkp happens clear TCNT and change the wkp int to int on the falling edge. When the second int happens read tcnt to get the time. THis has the advantage of not waiting around for the falling edge of the servo pulse using rctime.
Just to be clear:
- Setup TimerW to count at clk/8
- Set WKP to int on rising edge
- do other stuff.
- When WKP int happens, clear TCNT(TimerW timer reg) and set WKP to int on falling edge. Resume
- do other stuff.
- When WKP int happens, read TCNT and set WKP to int on rising edge.Resume
- Do stuff with pulse width read from TCNT. The value will be in .5us increments just like pulsin and rctime.
Note this will only work with one pulse at a time. If you need to get multiple pulses at the same time(eg they all start at the same time) you can’t clear TCNT. You’d need to store the value of TCNT at the rising edge of each pulse and then keep track of any overflows of TCNT and then when the falling edge int happens calculate the difference from the first TCNT to the last TCNT of each pulse.
Hmm, I may add an hpulsin command based on this method.
AcidTech,
Thanks for the kind assistance, im working on the code now. The r/c receiver im using for this test (cheap GWS 8 chs) triggers the int like in the code i posted above seems to output inverted pulses.
I imagined that debug statement was interfering with timings, i will output readings to terminal1 thru com1 (BB is connected to com1).
Thank you Very Much again
You might want to try Chuck’s “Servo Gismo”. As I recall, it is connected to an R/C receiver, and it “decodes” the PWM intended for R/C servos.
You might want to use a PIC chip like this ahead of your other uP, or maybe you can learn from it and incorporate it’s logic into your design.
Alan KM6VV

AcidTech,
Thanks for the kind assistance, im working on the code now. The r/c receiver im using for this test (cheap GWS 8 chs) triggers the int like in the code i posted above seems to output inverted pulses.
I imagined that debug statement was interfering with timings, i will output readings to terminal1 thru com1 (BB is connected to com1).Thank you Very Much again
Are you cennected directly to the servo outputs on the receiver? If it’s outputing inverted pulses I don’t see how it could possible control a servo unless there is something between the servos and ther receiver that re-inverts them back to normal.
Not exactly the above situation but i kept trying different things, i got stucked a little on Acidtech Int solution for capturing pulses so i went back to the pulsein solution to test other things until i fully understand the int approach.
This time I used the bit banged pulsin function to read 3 pins and scale the readings for driving 3 servos attached to pins 10-12 using HPWM function. It works ok when only one HPWM sentence is present, if you add a second the three servos start oscillating, here it is the code:
[code]
canal1 var word
canal2 var word
canal3 var word
control_loop
PULSIN P4,0,canal1
PULSIN P5,0,canal2
PULSIN P6,0,canal3
serout S_OUT,i9600,"ch1 ", dec canal1, " ", "ch2 ", dec canal2, " ", "ch3 ", dec canal3,13]
canal1 = (canal1-900)*12+16000
canal2 = (canal2-900)*12+16000
canal3 = (canal3-900)*12+16000
HPWM 10,320000,canal1 ; if only one HPWM sentence it works ok
HPWM 11,320000,canal2 ; adding this new HPWM line generate jitters in all 3 servos
HPWM 12,320000,canal3 ; same as above
goto control_loop[/code]
Alan,
Thanks for the interesting link! but i need the serial channel free for telemetry tasks
ps. I also discovered that HSERVO interferes in some way with PULSEIN reading, is there any way to stop the HSERVO service while executing PULSEIN and then reactivate it?
Working on the code to capture pulses using WKP.
I did it on a single pin just to ensure it is working…it works…BUT: HSERVO function doesnt work anymore…
Here it is the code…
[code];Interrupt init
ONINTERRUPT WKPINT_0,handle_intp0
PMR5.bit0 = 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.
; 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
ENABLE WKPINT_0
ENABLEHSERVO
;Variable declaration
pulse_ch1 var long
pass0 var byte
pass0 = 0
control_loop
HSERVO [P10\pulse_ch1*10]
;HPWM 10,320000,pulse_ch110
serout S_OUT,i2400,"ch1 ", dec pulse_ch1, 13]
;pulsout 10, pulse_ch12
;servo P10, (pulse_ch1-1500)*2, 2
goto control_loop
handle_intp0
If pass0 = 0 then
TCNT = 0
IEGR2.bit0 = 0 ;interrupt on a falling edge
pass0 = 1
elseif pass0 = 1
pulse_ch1 = TCNT/2 ; divide by 2 to obtain us
IEGR2.bit0 = 1 ;interrupt on a rising edge
pass0 = 0
endif
Resume[/code]
As you can see i also tried other ways to drive servos but none seems to work, seems to be a timing problem caused by the capture code.
ACIDTECH come to help!!!