Measuring 8 Hobby Servo Signals

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Anonymous
Not applicable

I need a way to measure 16 Hobby Servo Signals (1 to 2 ms pulse length and roughly 20ms repetition rate) with low resolution (10us resolution is more than enought). The signals are from different sources (asynchronous) and can have a different repetition rate.

   

What is the most efficient way to measure them with a PSoC5LP without excessive Interrupt use?

0 Likes
13 Replies
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

I used for that purpose UDB Timer-components and connected enable and capture, so that during the input high phase was counted my provided clock and at hi->low transition the value got captured.

   

In the interrupt handler I stopped the timer, removed the interrupt cause(!!!), red/calculated the pulse width and restarted the timer again. The 16 interrupts within 20ms do not put a hevy load on the ARM M3. Just avoid long loops.

   

Do not forget to declare all global variables that are modified in the interrupt handlers as "volatile"

   

You will needsomething like a 20 MHz clock and a 16-bit timer.

   

 

   

Bob

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

Two projects, one that does PW measurement, but both frequency measurement as well -

   

 

   

    

   

          https://www.dropbox.com/sh/prpc74bdga7yijz/AAAeC-Dmmn5sYbWwRrl0-ZUoa?dl=0

   

 

   

One uses interrupts, but they are low rate, at the pulse edge of the 20 mS in your case.

   

 

   

Regards, Dana.

0 Likes
Anonymous
Not applicable

The demo projects are working well with a few signals, but not with 16. I have massive problems with jitter and chip resources.

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Can you post your actual complete project, so that we all can have a look at all of your settings? To do so, use
Creator->File->Create Workspace Bundle (minimal)
and attach the resulting file.



Bob
 

   

PS: Grüß Gott, Herr Inschenör!

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

Since you have to mux the PW and Freq measurement operation you

   

have, in control theory, a lot of latency from measurement to action.

   

There are quite a few solutions, both linear and non linear, to resolve

   

a problem like this. Beyond the scope of simple post soultions.

   

 

   

Or do a fully HW solution. Possibly verilog. Or consider using DFB engine.

   

 

   

If you start with 10 uS resolution, then you would sample / count at 5 uS.

   

The max period is 20 mS so worst case, each channel, you have to wait

   

18 mS to initiate first edge of pW measurement. So latency for each channel

   

from measurement to action is 20 mS x 16 = 320 mS, a very long time from

   

measurement to measurement in a specific channel.

   

 

   

Go parallel in design, several measurement engines ? One possibility.

   

 

   

What are you trying to do with the measurement results ? How many PWM

   

periods can you allow in each channel before action from that channel

   

is required ?

   

 

   

Regards, Dana.

0 Likes
lock attach
Attachments are accessible only for community members.
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Try this for the first 12 servos. If that fits, we can start to think over the remaining four.

   

 

   

Bob

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Back from dinner I am thinking about whether it is needed to write to the counter-register of the timer between stop() and start() or if the Start() allone will reload the counter from the period-register. Someone should try that.

   

 

   

Bob

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

If the measured PW is from 1 - 2 mS then in Bobs solution only 8 bit

   

counters needed. 1  mS / .01 mS = 100 count.

   

 

   

To cut down on brute force solution consider a mux sampling each input

   

every 10 uS, driven by a 4 bit counter, and edge detection, say a LUT,

   

to detect rising and falling edge, and / or a 2 bit SR to detect sample to

   

sample edge. You could increase sample rate to 1 uS to minimize jitter.

   

 

   

   

 

   

Each channel when edge detected 10 uS counter value stored, if falling

   

edge then subtract rising edge count - falling edge count, and store in a

   

variable for that channel.

   

 

   

Just a thought in case the Bob solution eats up too many resources

   

for your design.

   

 

   

In verilog this should be a fairly straighforward solution I would think

   

(he who does not know verilog yet thinks....)

   

 

   

Regards, Dana.

0 Likes
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

I tried a few things and I was not really successful 😞

   

Generating synchronized servo signal was surprisingly easy compared to other microcontrollers, but I have Problems measuring them correctly. I tried a few approaches and neither is working.

0 Likes
lock attach
Attachments are accessible only for community members.
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

So let me concentrate on one servo and one solution.

   

See (untested) project

   

 

   

Bob

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

Are you trying to generate 16 PWM signals, or measure 16 PWM signals ?

   

 

   

Regards, Dana.

0 Likes
Anonymous
Not applicable

I need to generate 16 servo signals (transmitter) and to measure them (receiver)

   

I'm abusing hobby equipment for my RV, but that's another story.

0 Likes
WaMa_286156
Level 5
Level 5
First comment on blog 100 replies posted 50 replies posted

 I don't know if this will work, but here goes.

   

  create a 1mhz clock.  That will give you a 1us resolution.

   

   Put it into a count down timer.  Trigger an interrupt every 10us, have the timer interrupt at TC, and reload at TC.

   

   in the interrupt from the TC,  scan all the input pins for current state (high/low)

   

   increment a "high" counter for every pin that is high.  Once the pin goes low, move the "high" count for that pin to a staging variable and reset the high counter for that pin.

   

  In your main loop, check  the staging variable for non-zero, take it, calculate with it.

   

  Run your PSoC ARM processor as fast as possible.  If you run at 80mhz, then you should be able execute 800 assembly instructions every 10us.  A tight isr might work for a pin or four.

   

  It may be you can handle 3, 4, 5, 10, reliably, but no more.  In that case, buy another $10.00 cy8cKit-059 board and use it as your second, third, etc processor for the additional signals.

   

   I could see using 3 boards ($30) and have two feed into one main one using SPI, so that you can then do whatever you wish to the data without having too many issues with lag.

   

   Another way to do it is to bring the pin into an AND gate, and feed the AND gate from the 10us pulse from the countdown timer.  Feed the AND gate output to a counter, it will count a "high" every 10us.

   

  That provides your count.  Once you see the Pin go low in your ISR, pull the counts from the up counter and store in the staging variables.  That should be faster in code. Your mainloop code would then do differences to get the uptime, so it would need to store the last value read that it used.

0 Likes