Using ServoTimer2 and ServoDecode with 8MHz Arduino

Hello, all,

I've looked through as many forum topics as I could and can't seem to find an answer for this:

Does anyone happen to know if mem's ServoTimer2 and ServoDecode libraries can be used on Arduinos running at other speeds (i.e. 3V3 Pro Mini running at 8MHz)? Do I need to adjust timing due to the difference in processor timing?

Bump.

Hi,
My guess is that yes, you will have to change the code. The Servo library (not ServoTimer2) uses clock ticks to determine when to pulse the servo pin high or low so changing the clock frequency changes the mapping between the number of clock ticks and the time that the pin should be pulsed.

Extending my guess, its a very simple change to make, this is till a guess, but there is probably a single macro or function which is used to do the conversion from milliseconds to CPU ticks, you just need to adjust this to reflect the slower clock. There is probably another function which makes the opposite conversion - ticks to milliseconds, you should also adjust this.

Are you using a Mega, if not, which board ?

Duane B.

rcarduino.blogspot.com

Duane,
Thanks for your reply. That was exactly my suspicion, however, I'm not exactly sure what I'm looking for in the library. I don't have a lot of experience with the inner workings of Arduino or Atmegas. Do you have any hints as to what I might be looking for? I've tried running my code as-is and I get (as expected) strange outputs (servo set to 1500ms drives to well beyond full—2000ms—range).

I'm trying to run these on a Pro Mini running at 3V3/8MHz.

Nathan

Hi,
Its a slightly irrelevant questions as my thoughts on the ServoTimer2 library were based on my knowledge of the Servo library, but still, why ServoTimer2 not Servo ?

Duane.

rcarduino.blogspot.com

I want to use the ServoDecode library (to decode an RC PPM signal) and that library uses Timer1, thereby conflicting with the standard Servo library (also based on Timer1). This leaves me with ServoTimer2, which is based on Timer2, to then control the servos. At least that is my understanding of these libraries.

I'm guessing that the setting I need to adjust is found is this part of the code:

static void initISR()
{
	for(uint8_t i=1; i <= NBR_CHANNELS; i++) {  // channels start from 1
	   writeChan(i, DEFAULT_PULSE_WIDTH);  // store default values
	}
	servos[FRAME_SYNC_INDEX].counter = FRAME_SYNC_DELAY;   // store the frame sync period

	Channel = 0;  // clear the channel index
	ISRCount = 0;  // clear the value of the ISR counter;

	/* setup for timer 2 */
	TIMSK2 = 0;  // disable interrupts
	TCCR2A = 0;  // normal counting mode
	TCCR2B = _BV(CS21); // set prescaler of 8
	TCNT2 = 0;     // clear the timer2 count
	TIFR2 = _BV(TOV2);  // clear pending interrupts;
	TIMSK2 =  _BV(TOIE2) ; // enable the overflow interrupt

	isStarted = true;  // flag to indicate this initialisation code has been executed
}

Specifically, the "TCCR2B = _BV(CS21)" line (i.e. the prescaler). Any ideas on what this should be adjusted to for an 8MHz processor instead of the standard 16MHz?

Hi,
Have you had a look at the code for reading from an RC Receiver on my blog ? it uses interrupts and the micros function to measure the time between pulses. In my Child Mode project I use this together with the servo library to put the Arduino between my Receiver and electronic speed controller. While you may be aiming for a different outcome, the nature of the project - read RC Receiver, do something with the signal, then output a servo/ESC signal from Arduino - would appear to be the same.

I like this approach because there is only one Timer1 and to my mind its better used to drive servos than to measure an inherently noisy signal. The micros function will give you accuracy in the region of 4ms, but in my test the original signal can vary by as much as 40ms from one pulse to the next, so using the 16 bit timer1 to get increased accuracy in the measurement is to my mind, not the best use of the available resources.

Now some good news -

Reading through the Servo library and some of the other Arduino header files, I have come across F_CPU, my guess is that if you investigate this, it may turn out to be a system wide definition of the CPU frequency. You will hopefully find that all well written libraries use this or functions that reference it in which case you can make a single change to have your Arduino adjust all/most/many of its functions to the new frequency. Without having investigated it fully my guess is that micros will include a reference to F_CPU and so my approach to measuring RC Input and generating the output should be portable between clock speeds.

You can find some code to test at different clock speeds here, but remember to adjust F_CPU first -

EDIT : F_CPU is defined in the make file, not an include file.

Duane B

rcarduino.blogspot.com

I've had a decent look at your blog—it has piqued my interest in RC cars, especially when it comes to using them with my daughter!

Unfortunately, what I'm trying to do is decode the multi-channel PPM signal that comes directly from an RC transmitter for tuning and verification purposes. The signal is (or should be) very clean and accuracy counts. This is actually for use with a submarine that I'm building a multi-Arduino/AVR-based controller for. I may have gone a little over my head on this one, but I'll keep digging to try to get around this stumbling block.

Hi,
Are you reading the signal directly from the transmitter or from a port on the receiver ?

As for the cars, you can have a lot of fun with a Tamiya M03, small, fast enough, tough to break, and simple enough that a child can help with some of the building.

See here for a few of my own M03's and some advice you won't ever get a hobby shop -

Duane B.

rcarduino.blogspot.com

The intention here is to read it directly from the transmitter.

I actually had already looked at your Newbie advice. I got a kick out of that and completely agree with you, that's what got me thinking about RC cars again.

Hi

Have you got a change to run ServoTimer2.h with arduino pro mini 5v 16mhz? I have just tested it and the servos are not moving at all. If I change to Servo.h than everything works fine.

The code is simple, it is the sample from the official arduino website:

"// this sketch cycles three servos at different rates

#include <ServoTimer2.h>  // the servo library

ServoTimer2 myservo;  // create servo object to control a servo 
                // a maximum of eight servo objects can be created 
 
int pos = 0;    // variable to store the servo position 
 
void setup() 
{ 
  myservo.attach(8);  // attaches the servo on pin 9 to the servo object 
} 
 
 
void loop() 
{ 
  for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees 
  {                                  // in steps of 1 degree 
    myservo.write(pos);              // tell servo to go to position in variable 'pos' 
    delay(15);                       // waits 15ms for the servo to reach the position 
  } 
  for(pos = 180; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees 
  {                                
    myservo.write(pos);              // tell servo to go to position in variable 'pos' 
    delay(15);                       // waits 15ms for the servo to reach the position 
  }   
}

Thanks

Sorry, late to the party but only recently needed Servotimer2 library to run on a 3v3 8mhz Promini.
I searched and only found people asking for an 8mhz version, no 8mhz library, so here it is.
I'm posting this to (belatedly) answer the OP's question, and in the hopes that it might be useful.
Here is a link to my modified version, its 99% Mem's original but I've changed it for 8mhz operation.
Just unzip to your arduino\libraries folder.
http://www.mccrash-racing.co.uk/files/ServoTimer2_8mhz-master.zip
Cheers
Phil