Arduino mega PCA9685 servotreiber

Hallo
Ich baue momentan einen Roboter und habe folgendes Problem:
Anfangs hatte ich alles über den arduino uno gesteuert und habe den scetch auch so konzepiert
dass er mit dem arduino uno funktioniert. ich steuer die servos mit dem PCA9685 servotreiber. Da ich dann aber mehr anschlüsse benötigte bin ich zu dem arduino mega gewechselt. Mittlerweile funktioniert jetzt auch das display und alles andere außer der servotreiber. ich bin mir sehr sicher das ich alles richtig angeschlossen habe.

weiß vielleicht jemand was dann wahrscheinlich an dem scetch falsch ist?
Vielleicht ist ja irgendeine library oder so nicht mit dem arduino mega kompatibel.

Ich habe schon eine woche versucht das problem zu fixen aber ich habe es nicht geschafft.

schonmal danke :slight_smile:

hier der scetch:

#include <Adafruit_NeoPixel.h>
#include <HCPCA9685.h>
#include <Wire.h>
#include <VarSpeedServo.h>
#include <Adafruit_PWMServoDriver.h>
#include <LiquidCrystal.h>

#define LED_PIN 6
#define I2CAdd 0x40
#define NUM_LEDS 1
HCPCA9685 HCPCA9685(I2CAdd);

int zeitsens = 0;

Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
 const int rs = 11, en = 12, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
 LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

void setup() {

  strip.begin();
  strip.show();
  
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(13, OUTPUT);
  
HCPCA9685.Init(SERVO_MODE);
HCPCA9685.Sleep(false);

pinMode(10,INPUT);
Serial.begin(9600);

lcd.begin(0x27, 16, 2);

delay(10);

lcd.setCursor(0, 1);                                             
      lcd.print("Hi Master      ");
      delay(1000);
}

void loop() {
   const int rs = 11, en = 12, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
 LiquidCrystal lcd(rs, en, d4, d5, d6, d7); 

  int servo6;
  int servoDU;
  int servoL;
  int servoR;
  int servoF;
 
  Serial.print("poti ");                      //serieller monitor
  Serial.print(analogRead(A3) );
  Serial.println();
  Serial.print("taster ");
  Serial.print(digitalRead(7) );
  Serial.println();
  Serial.print("zeitsens ");
  Serial.print(zeitsens );
  Serial.println();
  Serial.print("bewegungssensor ");
  Serial.print(digitalRead(10) );
  Serial.println();
  Serial.print("servo6 ");
  Serial.print(servo6 );
  Serial.println();
  Serial.print("servoDU ");
  Serial.print(servoDU );
  Serial.println();

  if (digitalRead(7) == LOW){
    lcd.setCursor(0, 1);                                             
      lcd.print("                            ");
  }
 
//if (digitalRead(10) == HIGH){                     // bewegungssensor 
//zeitsens = 0;
//}
//else{
//}

//if (digitalRead(10) == LOW){
//  zeitsens++;
//}
//else{
//}

//if (zeitsens == 0){  
//    strip.setPixelColor(0, strip.Color(0, 255, 0));
//  strip.show();                           
//}
//else{
//}

//if (zeitsens > 100){
//    strip.setPixelColor(0, strip.Color(0, 0, 255));
//  strip.show();
//}
//else{
//}

if (( ( analogRead(A3) < 80 ) && ( analogRead(A3) > 0 ) && (digitalRead(10) == HIGH) ))
{
      lcd.setCursor(0, 1);                                             
      lcd.print("started        ");
      lcd.setCursor(0, 0);
      lcd.print("test           ");    

      strip.setPixelColor(0, strip.Color(0, 255, 0));
      strip.show();  
      HCPCA9685.Servo(0, 200);  
      HCPCA9685.Servo(1, 100);
      HCPCA9685.Servo(2, 300);  
      HCPCA9685.Servo(3, 100);      
      delay(500);
      HCPCA9685.Servo(2, 230);  
      HCPCA9685.Servo(3, 160);
      delay(500);
      HCPCA9685.Servo(4, 160);
      HCPCA9685.Servo(5, 290);
      delay(500);
      HCPCA9685.Servo(4, 210);
      HCPCA9685.Servo(5, 335);

      servoDU = 90;
      for (int i = 0; i < 18; i++) {
      servoDU ++;servoDU ++;servoDU ++;servoDU ++;servoDU ++;
      HCPCA9685.Servo(6, servoDU);
      delay(50);
      }

      for (int i = 0; i < 36; i++) {
      servoDU --;servoDU --;servoDU --;servoDU --;servoDU --;
      HCPCA9685.Servo(6, servoDU);
      delay(50);
      }

      for (int i = 0; i < 18; i++) {
      servoDU ++;servoDU ++;servoDU ++;servoDU ++;servoDU ++;
      HCPCA9685.Servo(6, servoDU);
      delay(50);
      } 

   delay(500);
      HCPCA9685.Servo(7, 200);
      delay(500);
      HCPCA9685.Servo(7, -25);
      delay(500);
      servoR = 60;
      servoL = 0;

      for (int i = 0; i < 6; i++) {
      servoL ++;servoL ++;servoL ++;servoL ++;servoL ++;servoL ++;servoL ++;servoL ++;servoL ++;servoL ++;
      servoR --;servoR --;servoR --;servoR --;servoR --;servoR --;servoR --;servoR --;servoR --;servoR --;
      HCPCA9685.Servo(10, servoL);
      HCPCA9685.Servo(9, servoR);
      delay(80);
      }

      delay(500);

      for (int i = 0; i < 12; i++) {
      servoR ++;servoR ++;servoR ++;servoR ++;servoR ++;servoR ++;servoR ++;servoR ++;servoR ++;servoR ++;
      servoL --;servoL --;servoL --;servoL --;servoL --;servoL --;servoL --;servoL --;servoL --;servoL --;
      HCPCA9685.Servo(10, servoL);
      HCPCA9685.Servo(9, servoR);
      delay(80);
      }

      delay(500);

      for (int i = 0; i < 6; i++) {
      servoL ++;servoL ++;servoL ++;servoL ++;servoL ++;servoL ++;servoL ++;servoL ++;servoL ++;servoL ++;
      servoR --;servoR --;servoR --;servoR --;servoR --;servoR --;servoR --;servoR --;servoR --;servoR --;
      HCPCA9685.Servo(10, servoL);
      HCPCA9685.Servo(9, servoR);
      delay(80);
      }

      delay(500);
      servoF = 90;

      for (int i = 0; i < 18; i++) {
      servoF ++;servoF ++;servoF ++;servoF ++;servoF ++;
      HCPCA9685.Servo(8, servoF);
      delay(20);
      }

      delay(500);

      for (int i = 0; i < 36; i++) {
      servoF --;servoF --;servoF --;servoF --;servoF --;
      HCPCA9685.Servo(8, servoF);
      delay(20);
      }

      delay(500);

      for (int i = 0; i < 18; i++) {
      servoF ++;servoF ++;servoF ++;servoF ++;servoF ++;
      HCPCA9685.Servo(8, servoF);
      delay(20);
      }
      strip.setPixelColor(0, strip.Color(0, 0, 0));
      strip.show(); 
}      

    if (( ( analogRead(A3) < 80 ) && ( analogRead(A3) > 0 ) ))           //falls 0 -50
  { 
    lcd.setCursor(0, 0);
    lcd.print("test           ");                                     
  }

    if (( ( analogRead(A3) < 170 ) && ( analogRead(A3) >80  ) && (digitalRead(10) == HIGH) ))                    // UMGEBUNGSSCAN
    {
      HCPCA9685.Servo(0, 200);  
      HCPCA9685.Servo(1, 100);
    HCPCA9685.Servo(6, servo6);
  int servo6 = 0; // Deklariere Variable servo6 und setze sie auf 0
  for (int i = 0; i <62 ; i++) { // Inkrementiere 180 Mal
    servo6++;
    servo6++;
    servo6++;
    delay(1);
    if (zeitsens == 0){  
    strip.setPixelColor(0, strip.Color(0, 255, 0));
  strip.show(); 
  delay(100);
  strip.setPixelColor(0, strip.Color(0, 0, 0));
      strip.show();
  delay(50);
  strip.setPixelColor(0, strip.Color(0, 255, 0));
      strip.show();
      delay(500);
  strip.setPixelColor(0, strip.Color(0, 0, 0));
      strip.show();
      delay(50);
  strip.setPixelColor(0, strip.Color(0, 255, 0));
      strip.show(); 
  delay(1000);
}
else{
  strip.setPixelColor(0, strip.Color(0, 0, 255));
  strip.show();
}
if (digitalRead(10) == HIGH){                     // bewegungssensor 
zeitsens = 0;
}
else{
}

if (digitalRead(10) == LOW){
  zeitsens++;
}
else{
}
    HCPCA9685.Servo(6, servo6);
       Serial.print("servo6 ");
  Serial.print(servo6 );
  Serial.println();
     Serial.print("zeitsens ");
  Serial.print(zeitsens );
  Serial.println();
      Serial.print("bewegungssensor ");
  Serial.print(digitalRead(10) );
  Serial.println();
  }
  
  for (int i = 0; i < 62; i++) { // Dekrementiere 180 Mal
    servo6--;
    servo6--;
    servo6--;
    delay(1);
    if (zeitsens == 0){  
    strip.setPixelColor(0, strip.Color(0, 255, 0));
  strip.show();  
  delay(2000);      
}
else{
  strip.setPixelColor(0, strip.Color(0, 0, 255));
  strip.show();
}
if (digitalRead(10) == HIGH){                     // bewegungssensor 
zeitsens = 0;
}
else{
}

if (digitalRead(10) == LOW){
  zeitsens++;
}
else{
}
    HCPCA9685.Servo(6, servo6);
      Serial.print(servo6 );
  Serial.println();
     Serial.print("zeitsens ");
  Serial.print(zeitsens );
  Serial.println();
      Serial.print("bewegungssensor ");
  Serial.print(digitalRead(10) );
  Serial.println();
  }
}

else{
          HCPCA9685.Servo(0, 80);
      HCPCA9685.Servo(1, 205); 
      
      strip.setPixelColor(0, strip.Color(0, 0, 0));
      strip.show();
}

    if (( ( analogRead(A3) < 270 ) && ( analogRead(A3) > 170 ) ))
       
                                                                        //falls 250 -350 
  {
  
    noTone(8);
    lcd.setCursor(0, 0);
    lcd.print("???               ");                                      //???

  }

    if (( ( analogRead(A3) < 370 ) && ( analogRead(A3) > 270 ) ))       
                                                                        //falls 350 -450 
  {  
    noTone(8);
    lcd.setCursor(0, 0);
    lcd.print("???               ");                                      //???
  }

    if (( ( analogRead(A3) < 470 ) && ( analogRead(A3) > 370 ) ))    //falls 450 -550 
  {  
    noTone(8);
    lcd.setCursor(0, 0);
    lcd.print("???               ");                                      //???
  }

    if (( ( analogRead(A3) < 570 ) && ( analogRead(A3) > 470 ) ))  //falls 550 -650 
  {  
    noTone(8);
    lcd.setCursor(0, 0);
    lcd.print("???               ");                                      //???
  }

    if (( ( analogRead(A3) < 670 ) && ( analogRead(A3) > 570 ) ))  //falls 650 -750 
  {  
    noTone(8);
    lcd.setCursor(0, 0);
    lcd.print("???               ");                                      //???
  }

    if (( ( analogRead(A3) < 770 ) && ( analogRead(A3) > 670 ) )) //falls 750 -850 
  {  
    noTone(8);
    lcd.setCursor(0, 0);
    lcd.print("???               ");                                      //???
  }

    if (( ( analogRead(A3) < 870 ) && ( analogRead(A3) > 770 ) ))   //falls 850 -950 
  {  
    noTone(8);
    lcd.setCursor(0, 0);
    lcd.print("???               ");                                      //???
  }

    if (( ( analogRead(A3) < 970 ) && ( analogRead(A3) > 870 ) ))  //falls 950 -1023 
  {  
    noTone(8);
    lcd.setCursor(0, 0);
    lcd.print("hallohallohallo                    ");                                      //???
  }

      if (( ( analogRead(A3) < 1024 ) && ( analogRead(A3) > 970 ) ))//falls 850 -950 
  {  
    noTone(8);
    lcd.setCursor(0, 0);
    lcd.print("???               ");                                      //???
  }
  
  digitalWrite(13, HIGH);
  delay(100);
  digitalWrite(13, LOW);
}

An welchen Pin´s hast du SCL und SDA am Mega angeschlossen?? Ich nehme mal an genauso wie am Uno auf A4 und A5 ?? Die müßen auf 21 und 22.

ich habe den sda pin vom servotreiber am arduino mega an pin 20 und den scl pin vom servotreiber an pin 21 am arduino mega angeschlossen.

im loop:
Zeile 47 "int servo6;"
Zeile 220 "int servo6 = 0; // Deklariere Variable servo6 und setze sie auf 0"

Jemand der sich in c besser auskennt al ich. Was macht eine zweite Declaration einer Variable in einer Funktion.
Grüße Uwe

Schritt 1: Mit dem I2C Scanner prüfen ob der PCA9685 erkannt wird. Wenn ja - ergebnis vom I2C Scanner postern.

Schritt 2: das Beispiel aus der PCA9685 Library probieren und prüfen ob es funktioniert wie es soll.

ich kenn mich kaum besser aus, aber diese Zeile 220 legt in diesem Scope (im If) eine neue Variable an und überdeckt damit die globale Variable.

danke schonmal für die antworten :+1:
Ich mache mal das mit dem I12C Scanner.

ich habe jetz diesen test mal durchgeführt und das ist das ergebnis:

Devices found:
0x40
0x70

ok, der PCA9685 reagiert also.

jetzt - was macht der Beispiel Sketch aus der Library?
Funktioniert das?

Verlinke auch welche Library die HCPTCA9685.h exakt ist? Bitte verlinke deren Repository damit wir sehen was das ist.

was ist genau dieser

das wäre die HCPTCA9685.h library:
https://forum.hobbycomponents.com/viewtopic.php?t=2034

Habe andere Quelle

das wäre jetzt der beisplielcode der HCPTCA9685.h library:

/* FILE: HCPCA9685_PWM_Example
DATE: 10/06/16
VERSION: 0.1
AUTHOR: Andrew Davies

Sketch created by Hobby Components Ltd (HOBBYCOMPONENTS.COM)

10/06/16 version 0.1: Original version

This example demonstrates how to use the HCPCA9685 library together with the PCA9685
to set the frequency and ON/OFF times of one of the 16 PWM outputs on the PCA9685.
The example has been written particularly for the 16 Channel 12-bit PWM Servo Motor
Driver Module (HCMODU0097) available from hobbycomponents.com

To use the module connect it to your Arduino as follows:

PCA9685...........Uno/Nano
GND...............GND
OE................N/A
SCL...............A5
SDA...............A4
VCC...............5V

External 5V Power for the PWM output pins can be supplied by the V+ and GND input of
the screw terminal block or via the V+ and GND pins on the HCMODU0097 module header.

PLEASE NOTE: At 5V, each PWM pin has a maximum 25 mA current sink capability and a
10 mA source capability. You should therefore not use these pins to directly drive
high current devices such as a DC motor. For LEDs a sufficient current limiting
resistor should be provided.

You may copy, alter and reuse this code in any way you like, but please leave
reference to HobbyComponents.com in your comments if you redistribute this code.
This software may not be used directly for the purpose of selling products that
directly compete with Hobby Components Ltd's own range of products.

THIS SOFTWARE IS PROVIDED "AS IS". HOBBY COMPONENTS MAKES NO WARRANTIES, WHETHER
EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ACCURACY OR LACK OF NEGLIGENCE.
HOBBY COMPONENTS SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR ANY DAMAGES,
INCLUDING, BUT NOT LIMITED TO, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY
REASON WHATSOEVER.
*/

/* Include the HCPCA9685 library */
#include "HCPCA9685.h"

/* I2C slave address for the device/module. For the HCMODU0097 the default I2C address
is 0x40 */
#define I2CAdd 0x40

/* Create an instance of the library */
HCPCA9685 HCPCA9685(I2CAdd);

void setup()
{
/* Initialise the library */
HCPCA9685.Init();

/* Wake the device up */
HCPCA9685.Sleep(false);
}

void loop()
{
/* Set the period frequency to 100Hz. The period frequency is the frequency of one
full high/low cycle of the PWM output. The frequency can be set anywhere between
24 (24Hz) to 1526 (1.526KHz) */
HCPCA9685.SetPeriodFreq(100);

/* Set the ON and OFF times for PWM output 0. This function takes 3 parameters,
the first is the PWM output pin to control (0 to 15), the second sets the point
at which to pull the output high (0 to 4095), the third sets the point at which to
pull the pin low again (0 to 4095). With the values below the output will
immediately go high at the start of a cycle and then go low half way though the
cycle giving a 50% duty cycle. */
HCPCA9685.Output(0, 0, 2047);
}

hat aber leider nicht funktionier.
liegt es dann an der library?

ich habe jetzt auch noch den scetch der verlinkten webseite von @noiasca getestet.
Ich habe den servo an pin 3 vom servotreiber angeschlossen aber es hat wieder nicht funktioniert.

dann würde ich dir mal empfehlen die Adafruit library für den PCA9685 über den Bibliotheksmanager zu installieren und auszuprobieren.
Funktioniert diese am Mega bei dir?

ich habe auf dieser seite einen beispiel code für die Adafruit_PWMServoDriver library gefunden.
https://robojax.com/learn/arduino/?vid=robojax_PCA9685-V1

das ist der scetch den ich dann getestet habe:

#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 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() {

pwm.setPWM(0, 0, 125 );
delay(500);
pwm.setPWM(0, 0, 255 );
delay(500);
pwm.setPWM(0, 0, 450 );
delay(500);
pwm.setPWM(0, 0, 575 );
delay(500);	

}

ich habe einen servo auf pin 0 des servotreibers angeschlossen aber er bewegte sich nicht.

Auf welschen Pins ist das Modul angeklemmt?
hat sich erledigt der Scanner findet den

Gewöhne dich die Sketsch in Code Task posten so ist das für die Katz

Für den Beispiel muss das Servo auf 0 nicht auf 3.
Wen du schon testest muss du schon achten wo der hängt

pin vcc ist mit der klemme an pin 5v am arduino angeschlossen.
pin gnd ist mit der anderen klemme an pin gnd am arduino angeschlossen.
pin sda ist an pin sda am arduino angeschlossen.
pin scl ist an pin scl am arduino angeschlossen.

der servotreiber an ein stepdown modul angeschlossen das 5v und auch genug ampere liefert angeschlossen.

also die verkabelung sollte passen oder?

Zeichne das mall.
wo geht der OE ?
der muss auf GND

oh sry war zwei mal das selbe bild
ich weiß nicht ob das dierser OE ist aber da wo man die 5v und 0v extern anschließen muss habe ich an das stepdown modul angeschlossen
https://bit.ly/3qzqVsk