Communication multi-cartes i2c + PCA9685

Bonjour à tous, je viens vers vous car je suis un peu perdu dans mon projet :slight_smile:
Je travaille sur un projet de robotique (un r2d2 taille réelle) qui utilise plusieurs cartes UNO communiquant entre elles via un système i2c (jusqu'ici tout va bien). Sur la dernière carte (esclave) de la chaine je souhaite utiliser un module PCA9685, en suivant quelques tutos et docs j'arrive à faire fonctionner le module seul.
(mon code de base pour faire réagir le PCA)

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

Adafruit_PWMServoDriver pwm1 = Adafruit_PWMServoDriver();

void setup() {
  Serial.begin(9600);
  pwm1.begin();
  pwm1.setPWMFreq(60);

  // Déplacement initial des servos
  pwm1.setPWM(0, 0, 150);  // Servo 0 position basse
  pwm1.setPWM(1, 0, 150);  // Servo 1 position basse
}

void loop() {
  // Exemple simple pour tester
  pwm1.setPWM(0, 0, 300);  // Servo 0 position haute
  delay(1000);
  pwm1.setPWM(0, 0, 150);  // Servo 0 position basse
  delay(1000);
}

Vient maintenant mon problème, en voulant additionner ce code ainsi que le système i2c, je n'ai plus rien qui fonctionne, lors de la réception d'une commande, tout le système freeze. J'ai beau vérifier mes branchements, tout est à sa place. J'ai également remarqué qu'une fois la carte connectée aux autres via les ports SCL et SDA, même l'ancien code ne répond plus non plus , pourtant mon module PCA est connecté aux bornes A4 et A5.
(mon code de base pour le PCA + le code i2c)

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

//nommage "pwm1"et adressage de la carte "0x40"
Adafruit_PWMServoDriver pwm1 = Adafruit_PWMServoDriver(0x40);

void setup()
{
  Wire.begin(4);                // join i2c bus with address #4
  Wire.onReceive(receiveEvent); // register event
  pwm1.begin();
  pwm1.setPWMFreq(60);  // Analog servos run at ~60 Hz updates
  //initialisation de la positions de départ des servos
  pwm1.setPWM(0,0,20);  //setPWM(numeros du servos, 0, impulstion à donner au servos)
  pwm1.setPWM(1,0,20);  //je ne sais pas encore à quoi correspont le "0" central
  Serial.begin(9600);   // start serial for output
}

void loop()
{
  //delay(100);
}

void topOuvrir(){
  pwm1.setPWM(0,0,90);
}
void topFermer(){
  pwm1.setPWM(0,0,20);
}
void bottomOuvrir(){
  pwm1.setPWM(1,0,90);
}
void bottomFermer(){
  pwm1.setPWM(1,0,20);
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany)
{
  String commande = "";
  while(Wire.available()) // loop through all but the last
  {
    char c = Wire.read(); // receive byte as a character
    commande += c;
  }
  Serial.println(commande);
  if (commande == "01"){
    topOuvrir();
  } 
  if (commande == "02"){
    topFermer();
  }
  if (commande == "03"){
    bottomOuvrir();
  }
  if (commande == "04"){
    bottomFermer();
  }
}

Il y a quelque chose que je dois surement avoir raté ou mal compris mais malgré mes recherches je ne trouve actuellement pas la réponse, j'ai essayé d'attribué l'adresse 0x40 au PCA, cela ne change rien. Je suis sur de bien recevoir les commandes de ma carte maitre, les 3 autres esclaves reçoivent bien aussi les commandes (et le print s'affiche bien avant de crash).
Merci d'avance à ceux qui prendront le temps de me répondre,
bonne soirée,
Yann

Souvent, les problèmes de plantages en I2C sont causés soit par un bus trop long, mal câblé ou mal adapté. Donc quelques questions:

  • Il y a bien des résistances de pullup sur les signaux SCL et SDA? Quelle valeur?
  • les bus I2C n'est pas câblé en étoile?
  • Le bus n'est pas trop long? Quelle longueur?

Hello, merci de ta réponse, pour répondre à tes questions :

  • non je n'ai pas mis de résistance sur les signaux SCL et SDA
  • le cablage à tendance à partir en étoile entre mes deux dernières cartes en effet
  • j'ai actuellement un bus composé d'une carte maitre, 3 cartes esclaves et le PCA, idéalement il en faudrait encore 4-5 pour pouvoir réaliser toutes les fonctionnalités du robot.

La topologie d'un bus I2C est la suivante

Bus unique sans faire de branches avec une résistance de tirage au plus pour SCL et SDA.

Comme dit dans le commentaire au-dessus du synoptique les résistance sont nécessaires.

La valeur des résistances de tirage est à adapter en fonction de la longueur du bus et du nombre de charges sur celui-ci. Lorsqu'il n'y a qu'un ou deux clients sur le bus et que celui-ci est court (10-20 cm) on préconise souvent 10kΩ. Mais si le bus est long et/ou qu'il y a plusieurs clients sur le bus il ne faut pas hésiter à descendre la valeur.
On peut aussi réduire la vitesse de SCL pour réduire les erreurs de transmission.

Il ne faut pas mixer les clients en interface 5V et ceux en interface 3.3V. Si on est dans ce cas il faut utiliser un circuit d'adaptation pour séparer le bus en une portion 5V et une autre portion 3.3V

Bonjour yann377

Si tu as un réseau i2C avec un master et des slaves, si tu ajoutes un PCA9685 "dans" un slave ce ne peut être que le master qui peut le commander, ton PCA9685 est vu, sur ton réseau, quoi que "sur" un UNO, comme les autres UNO en i2C, comme un slave.
Donc, l'initialisation du PCA9685, comme son traitement, doit se faire depuis le master.

En résumé, dans un réseau i2C, tu ne peut pas commander un module slave( PCA9685) depuis un UNO slave.

A+
Cordialement
jpbbricole

Salut jpbbricole, merci pour ta réponse, je vais transférer le code pour contrôler le PCA sur la carte maitre.
Pour la partie branchement, je dois laisser le PCA connecté à un esclave ou il faut aussi que je les transfère sur la carte maitre ? Actuellement, il est connecté aux bornes A4 et A5 de ma 4ème carte esclave, est-ce que ça pose problème ? ou dois-je ajouter la carte à tout le réseau de bus i2c comme si c'était une carte UNO à elle toute seule ?

Merci encore,
Cordialement
Yann

le PCA, esclave, doit impérativement être géré directement par un/le maître comme tous les esclaves :

Un esclave ne peut en gérer un autre (le PCA)

Bonjour yann377

Non, il pourrait même être sur n'importe quel autre carte, y compris sur la master, du fait qu'il est connecté sur le bus i2C (A4 et A5 pour un UNO). Imagé, le PCA9685 est au même "niveau" que les UNO slaves.

A+
Cordialement
jpbbricole

Bonjour jpbbricole,
je suis désolé d'avoir mis autant de temps a répondre, j'en ai manqué ces dernières semaines, j'ai pu tester la configuration ce matin et... ça fonctionne, merci beaucoup, je vais pouvoir fermer ce sujet :slight_smile:
Merci encore :grin:
A+
Cordialement
Yann377

Bonjour yann377

Super, bonne continuation :wink:

Cordialement
jpbbricole

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