Passation de pouvoir en I2C

Salut à tous,

Je me suis lancé dans l’i2c après avoir fait tout plein de tuto et je me trouve bloqué, surement à cause de mon niveau en code … :sweat_smile:

J’ai deux mega que j’arrive à faire communiquer M/E et E/M, mais ce que je veux c’est que le maître soit définit au moment de l’alimentation, cad que la carte qui est alimentée devient le maître et l’autre l’esclave.
L’idée est d’avoir un seul code pour les deux cartes avec une condition au moment de l’alimentation

Dans le code le problème est au niveau de la fonction Wire.onReceive(receiveEvent) qui je pense ne peux pas appartenir au code de la carte maître donc je me trouve un bloqué :confused:

Je vous remercie d’avance ! :grinning:

Je mets le code en espérant qu’il ne soit pas trop flou:

#include <Wire.h>

int tension;
int etat;
int x;

const int LV = 2;
const int LJ = 3;
const int LR = 4;
const int bouton = 5;

void setup()
{
Wire.begin(4);
Wire.onReceive(receiveEvent);
Serial.begin(9600);

pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, INPUT);

etat = HIGH;

digitalWrite(2, HIGH);
digitalWrite(3, HIGH);
digitalWrite(4, HIGH);

}

void loop()
{

tension = analogRead(0);
etat = digitalRead(5);

if( etat == HIGH)
{
x=0;
}

else
{
x=1;
}

if(tension!=0){

digitalWrite(2, LOW);
delay(250);
digitalWrite(2, HIGH);
delay(250);

Wire.beginTransmission(4);
Wire.write(x);
delay(250);
Wire.endTransmission();
delay(250);

}

else{

void receiveEvent(int howMany)

{

int x = Wire.read();

if(x == 1)
{
digitalWrite(LJ, LOW);
delay(250);
digitalWrite(LJ, HIGH);
delay(250);
}

if(x == 0)
{
digitalWrite(LJ, HIGH);
}
}
}
}

Merci de mettre ton code entre balise dédié.

Je comprend pas du tout ton principe de choix du Maître. C'est quoi ton histoire d'alimentation? Il y a un certain timing entre la mise sous tension des 2 cartes? Si oui qu'est ce qui le définis?

Ce serait en effet bien mieux avec le code entre balise, et avec une indentation sensée.
Cela étant, je ne suis pas certain que l'on puisse écrire ça:

void loop(){
  ...
  if(...){
    ...
  }else{
    void receiveEvent(int howMany){
      ...
    }
  }
}

Je crois qu'il vaudrait mieux quelque chose de ce genre:

void loop(){
  ...
  if(...){
    ...
  }else{
    receiveEvent(x){
      ...
    }
  }
}

void receiveEvent(int howMany){
  ...
}

Concernant le problème de choix du maître et de l'esclave au moment de l'initialisation, quel est l'intérêt pratique? Je suppose que la carte qui doit devenir le maître est allumée en premier. Si c'est le cas, il suffirait que le programme s'initialise par défaut en maître, scanne le bus I2C, et s'il trouve l'adresse d'une carte déjà "référencée", qu'il bascule en esclave, non?

Si le mode de fonctionnement de la carte est déterminé à la mise sous tension il faut alors activer les modules de réception ou d’émission dans setup() et non dans loop().
Comme dit au-dessus receiveEvent() doit être définie globalement sinon elle ne sera pas vue dans setup() mais seulement à l’intérieur du bloc où elle est déclarée.

Bonjour,

Comme le dit troisiemetype la première chose à faire est de formater correctement le source (sous l'ide il y a une fonction de formatage auto avec CTRL T).
La tu t’apercevras que receiveEvent est déclaré à l'intérieur de loop ce qui est interdit en C++. Ce qui donne l'erreur sur Wire.onReceive car receiveEvent est non défini.

Je vous remercie pour toutes ces réponses rapides ! :slight_smile:

Je vais reprendre de puis le début et être beaucoup plus précis

Le système que je veux concevoir a pour but d'être (en théorie infinis), je m'explique;

chaque carte est un contrôleur midi, donc il y a une carte avec des boutons, une autre carte avec des potentiomètres ... et lorsque je branche la première carte elle est directement reconnu en tant que controleur midi par mon logiciel (Ableton) et ce que je veux pouvoir faire c'est connecter une seconde carte mais pas par port usb car si j'ai 5 prototypes ça fait un sacré nombres de cables et donc je veux me passer de ça en connectant la deuximeme carte sur la premiere

La deuxieme carte elle est alimenté par la premiere du 5 V au Vin et et la premiere est alimenté par le meme cablage comme ça que se soit la premiere ou la deuxieme carte qui soit branchée les deux sont alimentés (et on peux imaginer ça avec 3 ou 4 cartes en plus).

Et pour Pepe, non durant le fonctionnement il n'y a pas de changement de maitre, c'est définit lors de la mise en tension, la carte qui est branchée au pc devient le maitre et les autres les esclaves, mais si le lendemain je branche une autre carte sur le pc je veux que ce soit elle qui devienne le maitre

Je vais regarder de plus près les idées de codes, bien prendre le temps de tout comprendre parce que je suis pas énormément calé niveau code

Après comme je souhaite utiliser les montages dans le domaines de la musique, l'I2C est il plus adapté que la SPI pour ce genre d'application ? (la question me viens un peu tardivement mais je voudrai pas faire fausse route)

En attendant je regarde toutes vos idées, je vous tiens au courant mercredi - jeudi

Merci à tous :wink:

Je comprends mieux le pourquoi du comment.
Par contre, ce que je ne comprends pas bien, c'est:

  • Pourquoi il faut une carte maître et une carte esclave? Est-ce que les signaux des différentes cartes sont traités en série (comme des pédales d'effet de guitare, par exemple)?
  • Pourquoi les brancher par USB pose problème? un câble usb ça ne coûte pas grand chose, un répartiteur non plus si besoin, ça me semble être plus simple que de mettre en place un système dédié avec des câbles qu'il faudra faire, avec des détrompeurs, etc.