PCA9685 Module controlling 10 servo motors issue

i have made a set up 10 sg90 servo motors onto one PCA9685 Module, i have followed a youtube tutorial by robojax to calibrate the motors but i am having huge issues with the sketch i have written, i need to be able to control these servos exactly how i want, as i am trying to make a robot hand that can play a keyboard piano, however when i run the sketch, only 2 of the 5 servos i had in the sketch actually do as the program says, the other 3 dont move, or just get a random jolt and then either buzz or stop moving, and a couple of motors that werent even included in the program start to move, one of which moves continiously in one direction which is extremely confusing to me, and the other jolts and start to lightly hum and vibrate(the one that i picked up and shook a little bit) i have uploaded a video to youtube just temporarily so that you guys can see what i mean, everything i described above is in this video, here is the link

and here is the exact code that i am using, which i got from robojax and modified slightly

/*


Get early access to my videos via Patreon and have your name mentioned at end of very
videos I publish on YouTube here: http://robojax.com/L/?id=63 (watch until end of this video to list of my Patrons)


or make donation using PayPal http://robojax.com/L/?id=64

    • This code is “AS IS” without warranty or liability. Free to be used as long as you keep this note intact.*
  • This code has been download from Robojax.com
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see https://www.gnu.org/licenses/.
*/

/***************************************************
This is an example for our Adafruit 16-channel PWM & Servo driver
Servo test - this will drive 16 servos, one after the other

Pick one up today in the adafruit shop!
------> http://www.adafruit.com/products/815

These displays use I2C to communicate, 2 pins are required to
interface. For Arduino UNOs, thats SCL → Analog 5, SDA → Analog 4

Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!

Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, all text above must be included in any redistribution
****************************************************/

#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

// called this way, it uses the default address 0x40
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
// you can also call it with a different address you want
//Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x41);

// Depending on your servo make, the pulse width min and max may vary, you
// want these to be as small/large as possible without hitting the hard stop
// for max range. You’ll have to tweak them as necessary to match the servos you
// have!
// Watch video V1 to understand the two lines below: http://youtu.be/y8X9X10Tn1k
#define SERVOMIN 125 // this is the ‘minimum’ pulse length count (out of 4096)
#define SERVOMAX 575 // this is the ‘maximum’ pulse length count (out of 4096)

// our servo # counter
uint8_t servonum = 0;

void setup() {
Serial.begin(9600);
Serial.println(“16 channel Servo test!”);

pwm.begin();

pwm.setPWMFreq(60); // Analog servos run at ~60 Hz updates

//yield();
}

// the code inside loop() has been updated by Robojax
void loop() {

//watch video for details: https://youtu.be/bal2STaoQ1M
for(int i=0; i<16; i++)
{
for( int angle =0; angle<181; angle +=10){
delay(50);
pwm.setPWM(1, 0, 30 );
delay(500);
pwm.setPWM(2, 0, 110 );
delay(500);
pwm.setPWM(4, 0, 140 );
delay(500);
pwm.setPWM(7, 0, 50 );
delay(500);
pwm.setPWM(9, 0, 120 );
delay(500);
}

}

// robojax PCA9865 16 channel Servo control
delay(1000);// wait for 1 second

}

/*
/* angleToPulse(int ang)

  • @brief gets angle in degree and returns the pulse width
  • @param “ang” is integer represending angle from 0 to 180
  • @return returns integer pulse width
  • Usage to use 65 degree: angleToPulse(65);
  • Written by Ahmad Shamshiri on Sep 17, 2019.
  • in Ajax, Ontario, Canada
  • www.Robojax.com
    */

int angleToPulse(int ang){
int pulse = map(ang,0, 180, SERVOMIN,SERVOMAX);// map angle of 0 to 180 to Servo min and Servo max
Serial.print("Angle: “);Serial.print(ang);
Serial.print(” pulse: ");Serial.println(pulse);
return pulse;
}

Also i would like to add that when i calibrated the motors i was told they would buzz and no longer carry on in that direction when the range of motion was reached, but mine didnt that just stayed silent, vibrated slightly and stopped moving, i also tested all of these servos in a script that ran all 10 of them one by one, to 0 to 180 degrees and it worked perfectly with this script, so why not for the script i wrote?
thank you for reading

Could you take a few moments to Learn How To Use The Forum.
Other general help and troubleshooting advice can be found here.
It will help you get the best out of the forum in the future.

Hi,
Welcome to the forum.

Please read the post at the start of any forum , entitled "How to use this Forum".
OR
http://forum.arduino.cc/index.php/topic,148850.0.html.
Then look down to item #7 about how to post your code.
It will be formatted in a scrolling window that makes it easier to read.

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?
Please not a Fritzy diagram.

What are you using to power the servos?

Tom... :slight_smile:

You have a couple of for loops which are really confusing...you never use either i or angle so what exactly are those loops for?

Steve

hello ther and thanks for responding, the servos motor driver board is running on 5.5 volts to all 10 servos, however they will not all be running at the same timei kpet getting an errorwhen i tried to attach the picture of my circuit diagram, i really hope you are still able to offer help, whats really got me confused is how some of the motors not even included in the uploaded script, managed to move aswell, im going to find out as much as i can on servo motors tonight to see if that explains it, please get back to me when you can because im stumped with this one thank you :slight_smile:

What is producing the 5.5V and what is the maximum current it can supply?

Have you done anything about those for loops yet? If so post the modified code.

And could you please try to write in sentences with some punctuation and the odd capital letter? You'll be more likely to get help if your posts are easier to read.

Steve

slipstick:
What is producing the 5.5V and what is the maximum current it can supply?

Have you done anything about those for loops yet? If so post the modified code.

And could you please try to write in sentences with some punctuation and the odd capital letter? You’ll be more likely to get help if your posts are easier to read.

Steve

The sketch that i used is from a youtube tutorial of the PCA9685 module that im using in this circuit, by robojax, this is how i have modified it.

#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

// called this way, it uses the default address 0x40
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
// you can also call it with a different address you want
//Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x41);

// Depending on your servo make, the pulse width min and max may vary, you 
// want these to be as small/large as possible without hitting the hard stop
// for max range. You'll have to tweak them as necessary to match the servos you
// have!
#define SERVOMIN  95 // this is the 'minimum' pulse length count (out of 4096)
#define SERVOMAX  670 // this is the 'maximum' pulse length count (out of 4096)


uint8_t servonum = 9;

void setup() {
  Serial.begin(9600);
  Serial.println("16 channel Servo test!");

  pwm.begin();
  
  pwm.setPWMFreq(60);  // Analog servos run at ~60 Hz updates

}

void loop() 


 {
    delay(500);
    pwm.setPWM(1, 0, 30 );
    delay(500);
      pwm.setPWM(2, 0, 110 );
    delay(500);
      pwm.setPWM(4, 0, 140 );
    delay(500);
         pwm.setPWM(7, 0, 50 );
    delay(500);
         pwm.setPWM(9, 0, 120 );
    delay(500);
    
  

  delay(1000);
 
}

i made a sketch that could run each motor individually (just for testing and calibration of the servo’s minimum and maximum range of motion), and that one worked fine.
Until i uploaded this new sketch that you see above, once i uploaded its didnt work as planned you can see in the video i have temporarily posted to youtube, and then i have tried to test the motors again and instead of moving they just make a buzzing noise, which i understand is due to the servo motors exceeding thier limits of thier range of motion which may damage the servos.

But the thing is i have already calibrated these servo motors twice now, and twice this same thing has happened which causes me to have unplug everything, and start all over again calibrating the motors, im really not sure whats causing it theres not much specific help out there for something like this so i came to this forum, i apologize if my previous posts have been difficult to read, i was just rushing

Ngrace94:
i tried to attach the picture of my circuit diagram,

Hi,
Make sure the image file is jpg or png, and advisedly 1M or less in size.
Tom... :slight_smile:

So you calibrated the servos and decided they need a minimum signal of 95 and maximum of 670.

Then you write to them using values that look more like servo.write() angles, including things like 30 and 50 which are very definitely not in the range 95-670. What exactly is it that you are trying to do?

And are you going to answer my question about what's powering the servos?

Steve

slipstick:
So you calibrated the servos and decided they need a minimum signal of 95 and maximum of 670.

Then you write to them using values that look more like servo.write() angles, including things like 30 and 50 which are very definitely not in the range 95-670. What exactly is it that you are trying to do?

And are you going to answer my question about what's powering the servos?

Steve

The current that the batteries are giving is 1.5 amphours, am new to programming, i think i got muddled up in the tutorial because it was a little bit unclear for me, what im trying to do is make a 3d printed hand with fingers attached to servo motors, capable of playing a keyboard, so i only want these servo motors to have a range of motion of about 30 degrees each,

thank you for getting back to me

I have never heard of such a thing as a 5.5V 1.5Ah battery. Can you post a link to this battery so I know what we're dealing with? I'm pushing this because about 95% of the problems we see with servos end up being caused by insufficient/incorrect power. BTW Amp hours is battery capacity NOT the current it can supply.

So if you're looking for 30 degrees movement (out of a possible 180 for an SG90) then initially try it with one servo If the 95-670 is correct then the servo is centred at about 380 and a 30 degree move should be a difference of about 100. So make your loop() just

void loop(){
    pwm.setPWM(1, 0, 330 );
    delay(1000);
    pwm.setPWM(1, 0, 430 );
    delay(1000);
}

That should give you about 30 degrees movement and avoid any possibility of the servo stalling by getting too close to the end stops. If that's o.k. then add a few more servos by duplicating those lines changing just the servo number.

Steve

slipstick:
I have never heard of such a thing as a 5.5V 1.5Ah battery. Can you post a link to this battery so I know what we’re dealing with? I’m pushing this because about 95% of the problems we see with servos end up being caused by insufficient/incorrect power. BTW Amp hours is battery capacity NOT the current it can supply.

So if you’re looking for 30 degrees movement (out of a possible 180 for an SG90) then initially try it with one servo If the 95-670 is correct then the servo is centred at about 380 and a 30 degree move should be a difference of about 100. So make your loop() just

void loop(){

pwm.setPWM(1, 0, 330 );
    delay(1000);
    pwm.setPWM(1, 0, 430 );
    delay(1000);
}



That should give you about 30 degrees movement and avoid any possibility of the servo stalling by getting too close to the end stops. If that's o.k. then add a few more servos by duplicating those lines changing just the servo number. 

Steve

the PCA9685 is a powered using this AA battery holding case

https://www.ebay.co.uk/itm/AA-x-4-Battery-Holder-Box-Case-PCB-Mount/2819785068754

Housing 4 AA batteries in the link below

https://groceries.asda.com/product/aa-batteries/asda-long-life-super-alkaline-aa-batteries/910001481431

They are very cheap batteries which is why i brought them, could you suggest which battery you think is best for powering 10 servo motors?

thank you for educating me further as i am a beginner

If you want to check to see f it is a power supply issue, disconnect all but one or two servos and see if they work as expected. The battery holder link does not work, but if it is one of the spring types, they often don't work well in high current situations. Also make sure you have appropriate grounding between the servos, board, and battery pack.

Hi,
Do you have a DMM to measure circuit parameters?

Thanks.. Tom... :slight_smile:

Cheap AA batteries are nowhere near good enough for 10 servos unless you can guarantee there will never be more than one moving at a time (and that would be pretty terrible keyboard playing). If it must be battery powered you're probably going to need Lipos.

However the AAs should work for a single servo so have you tried the simple code I gave you?

Steve

zoomkat:
If you want to check to see f it is a power supply issue, disconnect all but one or two servos and see if they work as expected. The battery holder link does not work, but if it is one of the spring types, they often don’t work well in high current situations. Also make sure you have appropriate grounding between the servos, board, and battery pack.

It is one of the spring types im using, ive set it up with 1 servo motor (that i have calibrated the end stops to) and its still not acting as it should, so i tried switching that one out with other servo motors and each of them acted differently in thier own way, some just vibrated and hummed without moving, or barely moving, some of them turned to one position once and stopped at that without going back and forth, and some just continuously turned on direction.
This is the sketch i am running

pwm.setPWM(1, 0, 330 );
    delay(1000);
    pwm.setPWM(1, 0, 430 );
    delay(1000);

im also trying this code and barely get any movements from any of the servos :frowning:

#include <Servo.h>
Servo servo1;
int pos1 = 0;

void setup() {
  servo1.attach(1);
  
}

void loop() {

for(pos1 = 0; pos1 < 90; pos1 += 1)
{
  servo1.write(pos1);
  delay(10);
}
for(pos1 = 90; pos1>=1; pos1-=1)
{
  servo1.write(pos1);
  delay(10);
}
}

Im getting a better 5 volt power supply, but what would you guys suggest for powering 20 servo motors? (because i plan on having 20 servos in the end)

and also do you know anywhere i can find out more about servo motors and how to calibrate them? because im not sure what ive done wrong, at one point all 10 of the ones i had set up were working as they should, but then they started not working properly, and i have to disconnect them all and calibrate them again.

"Im getting a better 5 volt power supply, but what would you guys suggest for powering 20 servo motors? (because i plan on having 20 servos in the end)"

You need a really good ~6v power supply for the servos, perhaps a lead acid type battery with a charger. Below is some simple servo teat code you can use to test your servos. Bottom is how the servo power should be wired.

// zoomkat 7-30-10 serial servo test
// type servo position 0 to 180 in serial monitor
// for writeMicroseconds, use a value like 1500
// Powering a servo from the arduino usually *DOES NOT WORK*.

String readString;
#include <Servo.h> 
Servo myservo;  // create servo object to control a servo 

void setup() {
  Serial.begin(9600);
  myservo.attach(9);
}

void loop() {

  while (Serial.available()) {

    if (Serial.available() >0) {
      char c = Serial.read();  //gets one byte from serial buffer
      readString += c; //makes the string readString
      delay(3);
    } 
  }

  if (readString.length() >0) {
    Serial.println(readString);
    int n = readString.toInt();
    Serial.println(n);
    myservo.writeMicroseconds(n);
    //myservo.write(n);
    readString="";
  } 
}

servo power.jpg

For an SG90 servo the stall current, which it takes for an instant on starting to move, is 650mA. So your supply needs to provide that times the number of servos which can be moving at the same time.

To be completely safe you need 20 x 0.65A = 13A but if you know how many will move at once you can maybe reduce that. Of course if you're going to use different servos you may need to recalculate.

Steve

slipstick:
For an SG90 servo the stall current, which it takes for an instant on starting to move, is 650mA. So your supply needs to provide that times the number of servos which can be moving at the same time.

To be completely safe you need 20 x 0.65A = 13A but if you know how many will move at once you can maybe reduce that. Of course if you're going to use different servos you may need to recalculate.

Steve

how many servos that move at once will depend on the song, ill choose an appropriate song, if i had say 4 servos running at once i would need 2.6A, that might be do able

ill get back to you all in 2 days to let you know what the results, thanks for the help :slight_smile: