Multiple servos on SoftwareServo chattering

Objective.
Drive small inexpensive hobby servos to switch the rails on a model train layout. I an using the SoftwareServo library and Arduino 0018, running on a duemilanove.
A bank of switches and resistor work as voltage splitters so that 3 switches can provide 8 alternative analog inputs onto an analog pin. The 8 analog inputs could dictate 2 positions to each of 3 servos using if else statements. I intended to have 11 servos controlled through the Arduino, 10 having 2 alternate positions (full left and full right) and one variable, controlled by a pot.

What happened.
Starting from zero knowledge of arduino after a few months I got as far as controlling one servo faultlessly using the if/else statements, when I increased to 3 servos and they started chattering and the separate voltage regulator started getting hot, put on 6 servos and some started acting erratically while most shivered and the voltage regulator got very hot and I quickly disconnected it

What I have tried.
I have had 3 servos physically connected to the Arduino but with the “servo,write” lines //commented out. I get 1 servo = no chatter, 2 servos = infrequent chatter , 3 servos gives a constant shiver.

I have altered the code so the if/else statements control 1 servo to a number of positions while 2 other servos are connected but the “servo,write” lines //commented out.
The single servo worked smoothly bit every few minutes I hear it give a twitch.

I conclude from the above that the Arduino digital outputs are changing when multiple servos are controlled because I think I have eliminated everything else.

Questions?
Have I been using the wrong I/O pins I just started with 1-3 then 1-6?
Is there some other error in my sketch?
Should I have used “case” instead of if/else? ( Hope not because I can't understand them)
Do I need a different approach?

Below is the code that didn't work

/* Vere Nicolson, 25,06,2010. Sketch to control 10 servos (to act as model train track switch changers)controlled by voltage splitters. 
Each of 3 voltage splitters can control 3 servos each and a 4th controls the 10th servo. A potentiometer controls an 11th servo driving a turntable.

*/
// progress, passes compiling
//Next step, upload to arduino and run with switches/3 servos before saving and progressing as 1-3
#include <SoftwareServo.h>
 SoftwareServo Servo1,Servo2,Servo3, Servo4, Servo5, Servo6, Servo7, Servo8, Servo9, Servo10, Servo11;                 //Declare Servos

int InPin123 = 1;      //
int InPin456 = 2;
int InPin789 = 3;
int InPin10 = 4;
int InPinPot = 0;
 

int val123 = 0;
int val456 = 0;
int val789 = 0;
int val10 = 0;
int val11 = 0;

void setup ( )

{
Servo1.attach(1);                    //
Servo2.attach(2);
Servo3.attach(3);
Servo4.attach(4);
Servo5.attach(5);
Servo6.attach(6);
Servo7.attach(7);
Servo8.attach(8);
Servo9.attach(9);
Servo10.attach(10);
Servo11.attach(11);
}

void loop()

{  
val123 = analogRead(InPin123);           //123 is orange wire > Analog pin1
val456 = analogRead(InPin456);            //456 is yellow wire > pin2
val789 = analogRead(InPin789);            //789 is green wire > pin3
val10 = analogRead(InPin10);              //10 is blue wire > pin4
val11 = analogRead(InPinPot);              //11 is red wire >pin0
 
 if (val123 > 900 )                    //Switches LLL 1023                   //First bank of 3 switches Orange wire

{
  Servo1.write(2);                    //
  Servo2.write(2);
  Servo3.write(2);                   //
}


  else if (val123 > 510 && val123 < 590 )                                    //Switches LLR 551

{
  Servo1.write(2);                  // 
  Servo2.write(2);
  Servo3.write(178); 
}
  else if (val123 > 650 && val123 < 710 )                                //Switches LRL 692
  
  {
  Servo1.write(2);                  // 
  Servo2.write(178);
  Servo3.write(2); 
  }
  
  

  else if (val123 > 200 && val123 < 250 )                                //Switches LRR   219
  
   {
  Servo1.write(2);                  // 
  Servo2.write(178);
  Servo3.write(178); 
  }
  
  else if (val123 > 780 && val123 < 820 )                                //Switches RLL   803
  
   {
  Servo1.write(178);                  // 
  Servo2.write(2);
  Servo3.write(2); 
  }
  
  else if (val123 > 300 && val123 < 350 )                                //Switches RLR   329
  
   {
  Servo1.write(178);                  // 
  Servo2.write(2);
  Servo3.write(178); 
  }
  
  else if (val123 > 450 && val123 < 490 )                                //Switches RRL   471
  
   {
  Servo1.write(178);                  // 
  Servo2.write(178);
  Servo3.write(2); 
  }
  
  else if ( val123 < 20 )                                //Switches RRR   0
  
   {
  Servo1.write(178);                  // 
  Servo2.write(178);
  Servo3.write(178); 
  }
  
          //   Works to here before paste 21]07]2010 
  // paste in here text file for the yellow wire once have Corrected all servo numbers from 1,2 &3 to 4,5,&6
  
  
   
  
  
  if (val456 > 900 )                    //Switches LLL 1023                   //Second bank of 3 switches/yellow wire

{
  Servo4.write(2);                    //
  Servo5.write(2);
  Servo6.write(2);                   //
}


  else if (val456 > 510 && val456 < 570 )                                    //Switches LLR 551

{
  Servo4.write(2);                  // 
  Servo5.write(2);
  Servo6.write(178); 
}
  else if (val456 > 750 && val456 < 789 )                                //Switches LRL 773
  
  {
  Servo4.write(2);                  // 
  Servo5.write(178);
  Servo6.write(2); 
  }
  
  

  else if (val456 > 400 && val456 < 450 )                                //Switches LRR   416
  
   {
  Servo4.write(2);                  // 
  Servo5.write(178);
  Servo6.write(178); 
  }
  
  else if (val456 > 790 && val456 < 820 )                                //Switches RLL   803
  
   {
  Servo4.write(178);                  // 
  Servo5.write(2);
  Servo6.write(2); 
  }
  
  else if (val456 > 300 && val456 < 350 )                                //Switches RLR   329
  
   {
  Servo4.write(178);                  // 
  Servo5.write(2);
  Servo6.write(178); 
  }
  
  else if (val456 > 591 && val456 < 620 )                                //Switches RRL   606
  
   {
  Servo4.write(178);                  // 
  Servo5.write(178);
  Servo6.write(2); 
  }
  
  else if ( val456 < 260 )                                //Switches RRR   249
  
   {
  Servo4.write(178);                  // 
  Servo5.write(178);
  Servo6.write(178); 
  }
  //Paste in here for the 3rd wire Green which has the same analog and servo values, just change 123 to 789 and servos from 12&3 to //7,8,&9
  
  //Paste in here for 4th wire Servo 10  Blue
  
  //Past in here for pot, servo 11  Red
  
  
  
          
          //re number servos/re label if else val789s
  
  

  
  delay(15);                           // waits for the servo to get there 

  SoftwareServo::refresh();

  
}

How are you powering the servos? If the voltage regulator (on the Arduino?) is getting hot, it seems like you are trying to power the servos from the Arduino. That is not a good idea, and is likely the cause of your problems.

Power the servos from a separate power supply. Connect the servo power supply ground to the Arduino ground, and the signal wires to the digital pins.

Can't the standard arduino servo library do that many servos?

Becuase that library is bit-banging the servos then I would not be surprised if that was the issue.

What happens if you try and run the servos from the standard servo library? Any chatter?

Mowcius :slight_smile:

Hello PaulS,
Thank you for your suggestions. Servos are powered separately from a wall pack via a 5v voltage regulator and the Arduino and servo power supply earths are connected as you suggest. Heating only becomes a problem when the servos are chattering.

Hello Mowcius,
Thank you for your suggestion, I will rewrite it using the standard servo library and see what happens. Not understanding the inner workings of the libraries, (But very grateful for their existance) I thought the SoftwareServo library was newer and by implication better than the standard software library.

It may be a couple of days before I can get back to it and make the changes. Hope it works but you may not have heard the last of me yet.

Cheers
Vere

It may be a couple of days before I can get back to it and make the changes. Hope it works but you may not have heard the last of me yet.

No worries :slight_smile:

Out of interest, what power supply drives the switches/resistors connected to the analogue input pins?

If this is the servo power supply then this may be your issue; the servos are pulling the voltage down, which changes the analogue input voltage, which moves the servos, which drags the voltage down (repeat and fade...).

If the resistors etc. are powered from the Arduino PSU (as they should be) then ignore this!

Hello ru,
Thanks for responding. The voltage splitter is 10K Ohm accross the arduino 5v pin just like in all the potentiometer examples on the arduino sites. As switches are moved the resistance shifts from one side of the analog input to the other, just like a potentiometer.
I sort of expected voltages could change, and I may end up using a seaparate power supply for this if I get despirate, but I will try the Servo.h idea first
I also wondered if the splitter, because it includes switches, would need debouncing but if so the problem would have shown up with just 1 servo.
Cheers
Vere

If you write to 10 servos with only one servo actually connected and the servo does not chatter, then the chatter problem is probably with the power supply to the servos and not with the number of servos being controlled by the arduino. You need to code the servo positions such that the servos are not straining against the track positions. Servos constantly trying to hold position agains something takes a lot of power and may be overloading your power supply. You need to find the position for each servo where it positions the track with iut being strained.

Hello Mowicus,
I had to give it a go and see if it worked, yes now smoothly operating 9 servos whereas it couldn't
operate 6 using softwareServo library.
It is switched on now and while inactive is completely silent, whereas with the SoftwareServo library
there was random twitching all the time with just 2 servos.
Definitely proof of concept, just need to write a bit more code for the other 2 servos, trial it then back out to the shed.
Thanks very much for the help.

Hello Zoomkat,
I had coded from 2 to 178 degrees to avoid the stops and avoid the servos straining. That seems to be
enough because the whole setup with 9 servos is silent when there is no input. Yes when working
for real I will need to re-code to suit the installation of each servo. This will be very useful because I only
need a fraction of the servo throw to do the job.
This was a prototype so when I wire up the railway layout I will probably use 6v voltage regulators
and have 1 per 3 or 4 servos because it must be fairly close to the limit now.
Thanks for your input.

The standard method for doing this uses a motor or solenoid, each one is about the cost of an Arduino!!
Servos are a couple of dollars from Hong Kong

Cheers
Vere

I had to give it a go and see if it worked, yes now smoothly operating 9 servos whereas it couldn't
operate 6 using softwareServo library.
It is switched on now and while inactive is completely silent, whereas with the SoftwareServo library
there was random twitching all the time with just 2 servos.
Definitely proof of concept, just need to write a bit more code for the other 2 servos, trial it then back out to the shed.
Thanks very much for the help.

No problem. :slight_smile:

Glad it worked.

Mowcius

It might cost a little more, but using a servo controller attached to the arduino would eliminate the arduino from having to deal with the servo timing.