Why does servos not work with this code ?

hi all,
for model railway issues i have a lot of servos to manage with Arduino Mega,
but use A.Nano for test of PWM over PCA9685.
Have 2 pieces of PCA9685,called Modules in progress, individually run correctly !

One Servo (SG90) is connected to PIN 0 of module1,
two Servos(SG90) are connected to PIN 0 and 1 of module2
A0 is jumpered on module2.
All wires are checked for correct connections between
A.Nano I2C-Pins and the modules.

But in mdules chained, the servos don't move !

the red LED's on PCA are lighted pwm1 led illuminates continously strong ,
but on pwm2 illuminates sometimes and not so strong

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

//--- multi_pwm_test_adaf_chain_1
//- created : 30.06.2023

// called this way, it uses the default address 0x40
Adafruit_PWMServoDriver pwm1 = Adafruit_PWMServoDriver(0x40); //setup the board address 0
Adafruit_PWMServoDriver pwm2 = Adafruit_PWMServoDriver(0x41); //setup the board address 0
// you can also call it with a different address you want
//Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x41);
// you can also call it with a different address and I2C interface
//Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x40, Wire);

// 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  150 // This is the 'minimum' pulse length count (out of 4096)
#define SERVOMAX  600 // This is the 'maximum' pulse length count (out of 4096)
//#define USMIN  600 // This is the rounded 'minimum' microsecond length based on the minimum pulse of 150
//#define USMAX  2400 // This is the rounded 'maximum' microsecond length based on the maximum pulse of 600

//- auch damit wird der Angle kleiner
//#define SERVOMIN  50 // This is the 'minimum' pulse length count (out of 4096)
//#define SERVOMAX  300 // This is the 'maximum' pulse length count (out of 4096)
//-- try to modify Angle
#define USMIN  100 // This is the rounded 'minimum' microsecond length based on the minimum pulse of 150
#define USMAX  700 // This is the rounded 'maximum' microsecond length based on the maximum pulse of 600

#define SERVO_FREQ 50 // Analog servos run at ~50 Hz updates

#define MY_DELAY 1500

uint8_t p1_servonum = 0;
uint8_t p2_servonum = 1;
uint16_t pulselen = SERVOMIN;
uint8_t my_angle = 50;

void setup() {
  Serial.begin(9600);
  Serial.println("Setup Start Servo test mit 2 Modulen !");

  pwm1.begin();
  pwm2.begin();
  pwm1.setOscillatorFrequency(27000000);
  pwm1.setPWMFreq(SERVO_FREQ);  // Analog servos run at ~50 Hz updates
  pwm2.setOscillatorFrequency(27000000);
  pwm2.setPWMFreq(SERVO_FREQ);  // Analog servos run at ~50 Hz updates
  
  delay(10);
  //Wire.setClock(400000);
  Serial.println("Setup ready !");
}

void loop()
{
  my_angle = 50;
  Serial.println("PWM_port : 1 Servo "+String(p1_servonum)+" : Angle : "+String(my_angle));
  pwm1.setPWM(p1_servonum, 0, my_angle);
  elapse_servo_time(1);  
  
  delay(MY_DELAY);
  my_angle = 200;
  Serial.println("PWM_port : 1 Servo "+String(p1_servonum)+" : Angle : "+String(my_angle));
  pwm1.setPWM(p1_servonum, 0, my_angle);
  elapse_servo_time(1);

  delay(MY_DELAY);
  my_angle = SERVOMAX;
  Serial.println("PWM_port : 2 Servo "+String(p2_servonum)+" : Angle : "+String(my_angle));
  pwm2.setPWM(p2_servonum, 0, my_angle);  
  elapse_servo_time(2);
  
  delay(MY_DELAY);
  my_angle = 120;
  Serial.println("PWM_port : 2 Servo "+String(p2_servonum)+" : Angle : "+String(my_angle));
  pwm2.setPWM(p2_servonum, 0, my_angle);
  elapse_servo_time(2);

  delay(MY_DELAY);
  my_angle = SERVOMAX-50;
  Serial.println("PWM_port : 2 Servo "+String(p2_servonum+1)+" : Angle : "+String(my_angle));
  pwm2.setPWM(p2_servonum+1, 0, my_angle);  
  elapse_servo_time(2);
  
  delay(MY_DELAY);
  my_angle = 160;
  Serial.println("PWM_port : 2 Servo "+String(p2_servonum+1)+" : Angle : "+String(my_angle));
  pwm2.setPWM(p2_servonum+1, 0, my_angle);
  elapse_servo_time(2);
  
}

void elapse_servo_time(uint8_t serv_pwm_num)
{
  for (uint16_t microsec = USMAX; microsec > USMIN; microsec--)
  {
    if(serv_pwm_num == 1)
      pwm1.writeMicroseconds(p1_servonum, microsec);
    if(serv_pwm_num == 2)
    {  
      pwm2.writeMicroseconds(p2_servonum, microsec);  
      pwm2.writeMicroseconds(p2_servonum+1, microsec);  
    }  
  } 

}

i'm not experienced with this module..

how do you power the servos ?

you can read this detailed info Overview | Adafruit PCA9685 16-Channel Servo Driver | Adafruit Learning System

thanks JML

all servos are powered Only the separate green jack in the middle of modules
V+ and OE are Not used

So I wonder a little, that in the documentation you told me, there is a 6-wire-connection between modules..at now, i had only 4 wires for GND, SCL,SDA, VCC..

so, i'll add 2 wires for OE and V+ anyways..,then test again

How do you get power for the second module if you don't have that ?

As per the tutorial, this would be the typical setup when you have multiple PCA9685

(I actually would wire the main Servo power directly to the extra modules rather than daisy chaining )

A4 and A4 are for I2C communication on the UNO - as you have a MEGA, you would not use those pins but pin 20 and 21 (the ones marked SCL and SDA).

hi all,

yes, i'written that, and different i2c-wiring in metion for mega..
so, its not wrong only chain per 4 wires as written..
and module2 has power, otherwise the led would not be enlightened.

what about the pwm1- , pwm2-variables holding the object :wink: should i check
it on null for the case it would not be filled ?
there is no public status-function or status-variable available int the pwm-class..

what is the meaning of the leds ?
has this to do with the i2c-bus ?
why do they illuminate differently ?

if you look closely at the pins

you have two power pins. One is for driving the logic components and probably the activity leds (Vcc) and one is for powering the servos (driving the output pin) V+

if you only connected Vcc then you did not daisy chain the higher power needed for the servos.

You need to bring V+ to the second board, either by connecting at the top with the screw terminal or by adding the V+ link between the two boards (meaning the full power needed by the second board will go through the copper traces of the first board - on top of what's needed for the first board - and that put more strain on the module. That's why I was suggesting to connect the power supply to the screw terminals in parallel directly)

thats what i have done already !

meanwhile i have found a broken wire..
now pwm1 is working, but pwm2 does nothing..

The LED indicate if the board has V+ power
Has nothing to do with I2C
You have a wrong connection a missing connection, a bad solder joint or any combination of the three

can you post a photo of your setup?

hi,
now i have checked the connections between input and output side,
what are responsible for chaining..
I found, that on one board there was a connection between VCC-points,
on the other Not !
All other pins are connected, so i assume, this is the problem !

So i will wire the VCC-Pins externally and see, what happens..
will report later on, okay ?

hi
SUSCCESS ! This was it !
Thanks for your help !

good news - have fun

Glad you found the problem

ok,
SOLVED !

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.