Go Down

Topic: PCA9685 Module controlling 10 servo motors issue (Read 396 times) previous topic - next topic

Ngrace94

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 

https://www.youtube.com/watch?v=k0HqqQFjAcg



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

/*
 * Original sourse: https://github.com/adafruit/Adafruit-PWM-Servo-Driver-Library
 *
 * This is the Arduino code PAC6985 16 channel servo controller
 * watch the video for details (V1) and demo http://youtu.be/y8X9X10Tn1k
 *  This code is #1 for V2 Video Watch the video :https://youtu.be/bal2STaoQ1M
 *  I have got 3 codes as follow:
   #1-Arduino Code to run one by one all servos from 0 to 180°   
   #2-Arduino Code to control specific servos with specific angle
   #3-Arduino Code to run 2 or all servos at together
   
 * Written/updated by Ahmad Shamshiri for Robojax Video channel www.Robojax.com
 * Date: Dec 16, 2017, in Ajax, Ontario, Canada
 * Permission granted to share this code given that this
 * note is kept with the code.
 * Disclaimer: this code is "AS IS" and for educational purpose only.
 * this code has been downloaded from http://robojax.com/learn/arduino/
 
 * Get this code and other Arduino codes from Robojax.com
Learn Arduino step by step in structured course with all material, wiring diagram and library
all in once place. Purchase My course on Udemy.com http://robojax.com/L/?id=62

****************************
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;
}

Ngrace94

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

ballscrewbob

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.
It may not be the answer you were looking for but its the one I am giving based on either experience, educated guess, google or the fact that you gave nothing to go with in the first place so I used my wonky crystal ball.

TomGeorge

#3
Feb 25, 2020, 02:18 pm Last Edit: Feb 25, 2020, 02:19 pm by TomGeorge
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... :)
Everything runs on smoke, let the smoke out, it stops running....

slipstick

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

Ngrace94

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 :)

slipstick

#6
Feb 25, 2020, 08:52 pm Last Edit: Feb 25, 2020, 08:55 pm by 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

Ngrace94

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.

 
Code: [Select]
#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

TomGeorge

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... :)
Everything runs on smoke, let the smoke out, it stops running....

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

Ngrace94

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

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
Code: [Select]

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

Ngrace94

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
Code: [Select]

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

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.
Google forum search: Use Google Search box in upper right side of this page.
Why I like my 2005 Rio Yellow Honda S2000  https://www.youtube.com/watch?v=pWjMvrkUqX0

TomGeorge

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

Thanks.. Tom... :)
Everything runs on smoke, let the smoke out, it stops running....

Go Up