Communication I2C, Maitre-Esclace, deux Arduino 2560

Bonjour à tous,

Je développe chez moi un projet de domotique au travers de deux Arduino 2560 et je cherche à bien appréhender la communication dur bus I2C entre les Arduino.

Je suis débutant sur Arduino.

J’ai fait l’acquisition des deux cartes 2560 et d’un kit de développement.

Pour bien commencé, j’ai monté un bouton poussoir sur l’Arduino Maitre, et à chaque impulsion j,envoie un message à l’Arduino Esclave.

En retour l’esclave répond 1 byte.

J’ai créé les codes Maitre et Esclave à l’aide des différentes doc du site, mais le résultat n’est pas totalement concluant.

Le maitre envoie bien à l’esclave le texte “Ready”
L’esclave reçoit bien le texte et l’envoie dans sa console.
L’esclave répond la valeur de val, soit 1, et l’envoie aussi dans sa console.

C’est maintenant que ça se gâte un peu…
J’utilise une fonction requestFrom définie à 1 byte et envoie la valeur dans la console du Maitre, la valeur est de 0 et non pas 1 comme envoyée par l’Esclave!!!

De plus,
je ne sais pas comment faire pour renvoyer plusieurs bytes depuis l’esclave?
je ne sais pas comment faire pour renvoyer un texte à la place d’une valeur?

Pouvez-vous m’aider en ligne ou à l’aide d’un tuto?

Merci d’avance à tous,
Gérard

Je vous joint les deux codes :

// Maitre Arduino 2560
#include <Wire.h>
const int bp = 2;    // Entrée bp

void setup()
{
Wire.begin();       // Init I2C maître
Serial.begin(9600);  // Init Serie
pinMode(bp, INPUT);  // Bouton poussoir
}

void loop()
{
int etatbp; 
etatbp = digitalRead(bp);
if(etatbp == HIGH)
{EnvoieRecoit();}
}

void EnvoieRecoit()
{ 
Wire.beginTransmission(0x01); // Ouvre la comm avec esclave 0x01
Wire.write("Ready");          // Charge la valeur à envoyer
Wire.endTransmission();       // envoie et ferme la comm avec esclave 0X01
delay(1000);
Wire.requestFrom(0x01, 1);    // recoit le retour de l'esclave, 1 byte
while(Wire.available() > 0){
  int retour = Wire.read();
  Serial.println(retour);
 }
}

// Esclave Arduino 2560
#include <Wire.h>
int rep = 0;

void setup()
{
Wire.begin(0x01); 
Wire.onReceive(reception);
Serial.begin(9600);
}

void loop()
{
delay(100);
if(rep == 1){
repond();}
}

void repond()

{ int val = 1;
Serial.print(rep);
rep = 0;
Wire.beginTransmission(0x00);
Wire.write(val);
Wire.endTransmission();
Serial.print("=");
Serial.print(rep);
Serial.print(" : val envoyee =");
Serial.println(val);
delay(500);
}

void reception(int NbByte)
{
while(Wire.available() > 0)
{
  char recudumaitre = Wire.read();
  Serial.print(recudumaitre);
}
 Serial.print(" : ");
 Serial.print(NbByte);
 Serial.print(" byte(s): rep =");
 rep = 1;
}

_2016-10-23_Arduino_Maitre.ino (705 Bytes)

_2016-10-23_Arduino_Esclave.ino (658 Bytes)

Bonjour Gérard et bienvenue !

  1. édite ton post pour mettre le code entre balises

  2. concernant tes questions, si tu mets, dans la réponse de l'esclave "Serial.println("1");" au lieu de "Serial.println(val);", cela donne quoi ?

Bonjour Trimarco232,

merci pour ta réponse,

Balise, j'avais pas trouvé, sympa comme cela.

En mettant "1" dans dans la réponse de l'esclave "Serial.println("1");" au lieu de "Serial.println(val);", cela donne sans surprise un 1 sur la console de l'esclave, alors que le val est envoyé depuis l'esclave par Wire.write (val);, c'est ici que tu souhaitais que je teste le caractère "1", toutefois je l'ai fait, en premier lieu dans "Serial.println(val);", donc oui 1 dans la console esclave et 0 dans la console maitre, et ensuite je mets "1" à la place de val dans Wire.write (val), malheureusement, c'est idem 1 dans la console esclave et 0 dans la console maitre...

Qu'en penses-tu?

Bon ben, j’ai bien avancé là!

Code du Maitre :

// Maitre Arduino 2560
#include <Wire.h>
const int bp = 2;    // Entrée bp

void setup()
{
Wire.begin();       // Init I2C maître
Serial.begin(9600);  // Init Serie
pinMode(bp, INPUT);  // Bouton poussoir
}

void loop()
{
int etatbp; 
etatbp = digitalRead(bp);
if(etatbp == HIGH)
{EnvoieRecoit();}
}

void EnvoieRecoit()
{ 
Wire.beginTransmission(0x01); // Ouvre la comm avec esclave 0x01
Wire.write("Ready ?");          // Charge la valeur à envoyer
Wire.endTransmission();       // envoie et ferme la comm avec esclave 0X01
delay(1000);
Wire.requestFrom(0x01, 11);    // recoit le retour de l'esclave, 1 byte
while(Wire.available()){
   char retour = Wire.read();
   Serial.print(retour);
 }
 Serial.println();
}

Code de l’esclave :

// Esclave Arduino 2560
#include <Wire.h>
int rep = 0;
void setup()
{ Wire.begin(0x01); 
  Wire.onReceive(reception);      // fonction de lecture appellée quand un msg du Maitre est arrivé
  Serial.begin(9600);
  Wire.onRequest(requestEvent);}  // fonction d'écriture appellée en réponse d'un msg du Maitre

void loop()
{delay(100);}

void reception(int NbByte)
{ while(Wire.available() > 0)
    {char recudumaitre = Wire.read();
     Serial.print(recudumaitre);}
  Serial.print(" : ");
  Serial.print(NbByte);
  Serial.println(" byte(s)");}

void requestEvent()
{
  Wire.write("Yes Ready !"); // Répondre avec un message de 6 octets (bytes)
                        // comme attendu par le maître.
}

Maintenant je voudrai que la requête du Maitre soit un question précise et que la réponse de l’esclave y soit indexée, le tout en plusieurs requêtes différentes,
Exemple :
Maitre <-> Esclave
Couleur <-> Rouge
Poids <-> 10
Nombre <-> 20
Etc…

En fait je dois maintenant trouver le moyen d’indexer le Wire.onRequest de l’esclave au Wire.write du Maitre si je comprend bien!..

ok, et si au lieu de renvoyer 1 tu renvoies 49 ?

trimarco232:
ok, et si au lieu de renvoyer 1 tu renvoies 49 ?

Ca marche Trimarco232,

Maintenant je voudrai que la requête du Maitre soit un question précise et que la réponse de l’esclave y soit indexée, le tout en plusieurs requêtes différentes,
Exemple :
Maitre <-> Esclave
Couleur <-> Rouge
Poids <-> 10
Nombre <-> 20
Etc…

En fait je dois maintenant trouver le moyen d’indexer le Wire.onRequest de l’esclave au Wire.write du Maitre si je comprend bien!..