Go Down

Topic: ppm (sum) in to servo output, possible timer issue (Read 3 times) previous topic - next topic


I have an arduino project I am working on that involves reading a ppm stream from a receiver and spitting out servo control.
In between there is some GPS goodness to act as a RTH.
This is a personal project I'm doing for fun, I already have OSDs I like and don't fell like spending $200+ for a full OSD RTH fancy thing when all I want to something very simple. For use in rc cars, gliders etc that only require steering or the rudder to turn, things like that.

Anywho the reason I have come and asked for help, I have ppm decoding (using timer 1) and I was planning on using the servotimer2 library for driving my servos but these 2 bits of code don't play nice together. Although it works, every ~30s or so all the outputs glitch (I suspect they all drop to 1000 or 0, ether way the throttle cuts for a moment and servos twitch.) which makes it non usable (on servos the effect is almost unnoticeable but on esc's/motors the effect is rather dramatic). All the ppm decoding code I have found uses timer 1 so that can't change, the servo library built into arduino can't be used as it uses timer 1 and software servo is less then ideal as well.

I'm trying to stick with using a 328 as I have a number of them and they are cheap, I could use a 2560 as it has extra timers that could be used to drive servos with the default library but this is a lazy method and costs considerably more. I also fly multicopters and as shown by multiwii 328s are capable of doing the above job + alot more so it is possible, but maybe not with such simple code.....

I have tried multiple sets of hardware so can rule that out.
I have also constructed this very minimal code snipit to test the bare ppm in servo out functions together, before this I thought it could have been the GPS code casing the issues.

Talking to a friend he suspects that there is a clash between the 2 timers that cases this issue.
Looking at the inputs and outputs with serial prints shows nothing out of the ordinary, without getting the scope out it is otherwise hard to narrow the problem down more, I have reached the limit of my skill set for the time.

If anyone has run into something similar or has an idea of whats happening that'd be great.

Thanx Hadley

Code: [Select]

// libraries
#include <ServoTimer2.h>

// pins for servos
#define rollPin  3
#define throttlePin 7

// declare variables for servos
ServoTimer2 servoRoll;   
ServoTimer2 servoThrottle;

//*************ppm capture variables*****************
#define ICP_PIN      8           // this interrupt handler must use pin 8
#define TICKS_PER_uS 2            // counter increments by two counts each microsecond (at 16mhz)
#define SYNC_GAP_LEN 3000         // synch gap 3000 microseconds long
volatile unsigned int pulses[9];  // array holding channel pulses width value in microseconds
volatile uint8_t  channel = 1;   // number of channels detected so far in the frame (first channel is 1)

//*********************timer for ppm stream receiving*************************************
  if( bit_is_set(TCCR1B ,ICES1)){  //rising edge detected because bit ICES1=1

  else{            //falling edge detected]

    TCNT1 = 0;    // reset the counter
      channel = 1;
      pulses[channel++] = ICR1/TICKS_PER_uS;
  TCCR1B ^= _BV(ICES1);   // toggle bit ICES1 to trigger on the other edge       


void setup(){   


  //Comfigure ppm stream in on pin 8

  TCCR1A = 0x00;    // COM1A1=0, COM1A0=0 => Disconnect Pin OC1 from Timer/Counter 1 -- PWM11=0,PWM10=0 => PWM Operation disabled
  TCCR1B = B00000010;     //0x02;    // 16MHz clock with prescaler means TCNT1 increments every .5 uS (cs11 bit set
  TIMSK1 = _BV(ICIE1);   // enable input capture interrupt for timer 1

    // attach a pin to the servos and they will start pulsing


void loop(){

  //Write values to outputs


The timer theory sounds plausible.

As a workaround just to prevent the glitches being so annoying while you figure out how to fix the problem, you could do a sanity check on the received pulse length and smooth out abrupt changes? I guess you would only need to deal with a few samples. If the problem is reproducible, it would be worth writing a test sketch that looks for the glitch and captures a range of samples before/after so that you can see exactly what's happening. That would make it easier to design a workaround, and might also give you some extra insight into what's going wrong.
I only provide help via the forum - please do not contact me for private consultancy.


you could do a sanity check on the received pulse length and smooth out abrupt changes

I'm guessing you mean the ppm sum received by the arduino? I have checked and although each channel fluctuates by up to ~8us it is nowhere near (at least)1000us glitch that can be observed.
Would a short video of the glitch in action help explain??
In the above sketch each channels values are being feed straight though from ppm to 2 outputs, so the input and output is the same value. I can use my soundcard Oscope to get a trace on the signal being feed to the servo, would be interesting to see how the glitch being seen by the servos/esc.
Will report back once I get some data.


Try this, its a PPM reader, servo driver that uses timer1 only. The same library manages reading the PPM and generating the servo signals so no clashes.


and the reason I wrote it -


PM me if you want a zip file rather than cutting and pasting web pages

Duane B



I was really keen to try it out so quickly copied all the files from your blog and chucked them in the appropriate locations. The example code complies fine but when I copy the ppm input demo code from your blog I get the following error "multiple definition of `__vector_1'". I saw there are some comments on the blog that pertain to a similar error but didn't really have a resolved answer.
How do you increase the number of ouput serovs as well??
Sorry I may bombard you with a torrent of questions as I figure this out.

Go Up