13 Replies Latest reply on Jun 16, 2015 6:31 PM by WaMa_286156

    Measuring 8 Hobby Servo Signals

      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?

        • 1. Re: Measuring 8 Hobby Servo Signals

          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.





          • 2. Re: Measuring 8 Hobby Servo Signals

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










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




            Regards, Dana.

            • 3. Re: Measuring 8 Hobby Servo Signals

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

              • 4. Re: Measuring 8 Hobby Servo Signals

                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.



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

                • 5. Re: Measuring 8 Hobby Servo Signals

                  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.

                  • 6. Re: Measuring 8 Hobby Servo Signals

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





                    • 7. Re: Measuring 8 Hobby Servo Signals

                      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.





                      • 8. Re: Measuring 8 Hobby Servo Signals

                        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.

                        • 9. Re: Measuring 8 Hobby Servo Signals

                          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.

                          • 10. Re: Measuring 8 Hobby Servo Signals

                            So let me concentrate on one servo and one solution.


                            See (untested) project





                            • 11. Re: Measuring 8 Hobby Servo Signals

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




                              Regards, Dana.

                              • 12. Re: Measuring 8 Hobby Servo Signals

                                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.

                                • 13. Re: Measuring 8 Hobby Servo Signals

                                   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.