Friday, February 3, 2012

Can I Control More Than X Servos With An Arduino ? Follow Up Results

The servo library can be uses a single Arduino Timer to control upto 12 Servos.

See here for a detailed overview and sample code - How To Control X Servos and MultiSweep Example

To achieve this the library attaches an interrupt service route to the timer which is called around 50 times per second for each connected servo. In the case of 12 Servos, this is 600 times per second.

Within the timer service routine, there are array access operations, function calls and also a few calculations are performed. It is reasonable to expect that repeating these operations 600 times per second may have a performance impact on the Arduino.

To measure the impact I have modified the multi sweep sketch to run a busy loop and a hardware timer. When the timer counts down to 0, the loop exits and prints the number of loops completed during the countdown. The countdown period is approximately 3.8 seconds.

With no servos attached, the busy loop is executed 219,744 times per countdown. We will consider this bench mark as equivalent to 100% available processing power.

With 12 Servos attached, the busy loop is executed 217,719 times per second, based on the no servo bench mark this is equivalent to 99% meaning that to drive 12 servos, only 1% of available processing power is required.

If my logic and calculations are correct, thats very Impressive.

Try it for yourself -

// Multi Servo Benchmark
// The loop tests the base load for the Arduino Servo
// library to maintain positions on upto 12 connected servos
// to change the number of servos change the CONNECTED_SERVOS value

#include <Servo.h>
// Sample sketch for driving 12 Servos from an Arduino UNO, servos are attached to digital pins 2,3,4,5,6,7,8,9,10,11,12,13

#define CONNECTED_SERVOS 12

// macro just adds two - the first servo is attached to digital pin 2, this gives us upto 12 servos - digital 2 to 13
#define SERVO_TO_PIN(x) (x+2)

Servo myServos[CONNECTED_SERVOS];

#define COUNT_DOWN -1
#define COUNT_UP +1
#define INCREMENT 10 // move in steps of 10 milliseconds

int nPulseWidth = DEFAULT_PULSE_WIDTH ; // 1500, defined in servo.h
int nDirection = COUNT_UP;

volatile unsigned long ulStart = 0;
volatile unsigned long ulStartToEnd = 0;


#define CLICK_START 255

volatile short sClicks = CLICK_START;
volatile unsigned long ulAnother = 0;

ISR(TIMER2_OVF_vect)
{
  if(sClicks)
  {
    sClicks--;
  }
};

void setup()
{
  TCCR2A = 0;
  TCCR2B = (1<<CS02|1<<CS01|1<<CS00);
  TIMSK2 = 1<<TOIE2;
 
  Serial.begin(9600);

  // attach the servos
  for(int nServo = 0;nServo < CONNECTED_SERVOS;nServo++)
  {
    myServos[nServo].attach(SERVO_TO_PIN(nServo));
  }
 
  pinMode(13,OUTPUT);
 
  digitalWrite(13,LOW);
}

void loop()
{
   unsigned int uiOuter = 0;
   unsigned int uiInner = 0;
  
   for(;sClicks && uiOuter < 0xFFFF;uiOuter++)
   {
    uiInner = 0;
    for(;sClicks && uiInner < 0xFFFF;uiInner++)
    {
     int nTemp = uiInner%10;
     ulAnother = uiOuter/nTemp;
    }
   }
  
   Serial.println(uiOuter);
   Serial.println(uiInner);
  
   sClicks = CLICK_START;
}



Duane B.

Wednesday, February 1, 2012

Newbie Advice and A New Take On An Everyday RC Experience

Speed isn't everything. 

The following quote from an RC forum thread about building cars for maximum speed sums this up nicely - 'I built my car up to go as fast as possible, I got it over 100km/h, but, it got boring very quickly.'

It's true, fast model cars are just not very interesting. It's easy to build or buy a car that will crack 100km/h, but really, what are you going to do with a car that goes from 0 to out of sight in 3 seconds ?

Most of us that have a long term involvement in RC started with something moderately fast, learned to control it, upgraded it, then bought something faster. Many of us actually end up selling the faster cars and building a growing collection of moderately fast cars.


Part of my collection of moderately fast Tamiya M-Chassis Cars



A New Take On An Everyday RC Experience

Its a universal experience shared by RC Enthusiasts all over the world, your driving your model, working on your line through a fast s-bend you have marked up in the street. Someone approaches you, they could be of any age, race, or background and the conversation will be exactly the same -



Passerby: How fast does it go ?
You: Answer whatever you like ...
PasserBy: I have one that goes 100km/h
You: Thats interesting, where is it ?
 

Choose one -
PasserBy:I don't use it much (we knew that, fast cars are boring aren't they)
PasserBy:Its broken I need to get get it fixed (it was too fast for me, I crashed it, I would get it fixed, but it wasn't that much fun anyway so i never got around to it)

The interesting thing is that these guys who bought the faster cars and since lost interest, they always make the effort to come over and talk to you. 


It often feels like they want to show off.

I am trying to see it a different way -

They see you skillfully threading your model through the corner,fine tuning your line at each pass, the car looks amazing, braking slightly on entry, turning in, holding the speed through the corner and then accelerating out. It's everything they wanted their own RC Experience to be, they just bought the wrong car.

Do I ever offer these guys a turn of my own car ? If I am honest, no! never.

But now that I understand them a bit better, next time I will slow my car down and offer them a chance to see how much fun a moderately fast car can be.

Can I Control More Than X Servos With An Arduino ? Follow Up

I can't help feeling that the original post is incomplete. While I have shown how to control 12 Servos using the Arduino Servo library, I have not provided any indication of the performance impact. If it takes 90% of the available processing time to control the 12 Servos, using a single Arduino is not a very practical solution.

Its not that big problem either, anything that requires 12 Servos could probably benefit from the additional processing power and sensor inputs that one or more additional Arduinos would bring. When an additional Arduino can be built for less than 10 dollars there is no good reason not to take this approach.

Anyway, in the interest of finishing the original post and learning a little more about the Atmega architecture, I plan to follow up a few ideas I have for using Timer0 and a set of loops to measure the impact of 0,1, 6 and 12 servos. At the moment I am several thousand miles from home but will get onto this in the next few days.

Duane B