Master Arduino Com i2C à "n" Arduino Esclave Balance rucher.

Salut,
Voila j'ai un petit projet bien compliqué pour moi. Je souhaite faire un balance pour rucher avec Arduino Maitre qui demande aux Arduino esclave la masse des ruches en i2c.

J'arrive a faire communiquer facilement l'Arduino maitre avec un Arduino esclave sans problème pour du texte mais impossible pour passer une valeur double "la masse de la ruche"

J'ai besoin de vos lumières il est possible de faire cela en code j'ai déjà fait le code pour la partie balance mesure de la masse de la ruche sur l'esclave. Je me retrouve avec une valeur DOUBLE le problème c'est que j'arrive pas a mettre cette valeur en attente pour que l’Arduino maitre la lise et ensuite l’écrive dans une carte SD log.

Merci de m'avoir lu jusqu'ici.
Alors voila si vous avez des pistes des idées de bout de code ou juste une envie d'en parler je suis preneur je ne trouve pas de solution.

Le code esclave : (il ne marche pas pour le com i2C)

/*-/////////////////////////////////////////////// /SLAVE ARDUINO/////////////////////////////////////////*/
/*-//////////////////////////////////////////////////VOID SCOOP/////////////////////////////////////////*/
/*/ Balance /*/
#include <Hx711MIB.h>
Hx711 scale(A3, A2); // Hx711.DOUT - pin #A2 // Hx711.SCK - pin #A3
/*/ Balance /*/

/*/ Communication I2C /*/
#include <Wire.h>
/*/ Communication I2C /*/
int masseenkg;


/*-//////////////////////////////////////////////////VOID SETUP/////////////////////////////////////////*/


void setup() {

    Serial.begin(9600);
  
    Wire.begin(8); // Adresse de l'aruino esclave
    Wire.onRequest(requestEvent); // Com

  scale.setScale(36); // Réglage pour 1Kg = 1Kg Scale correction.

  float ruche =(scale.getGram());
  float masseruche =(ruche - 3230); // Valeur a changer pour les corrections defaut ZERO. (ruche - "Valeur du zero".
  float masseenkg = (masseruche *0.001);

  Serial.println("Masse de la ruche 01:");

  Serial.print(masseenkg);
  Serial.print("kg");
  delay(500);



}


/*-//////////////////////////////////////////////////VOID LOOP/////////////////////////////////////////*/

void loop() {
}

void requestEvent() {
  Wire.write(masseenkg); // respond with message of 6 bytes
  // as expected by master
  delay(5000);

}

Le code maitre : (il ne marche pas non plus)

/*-/////////////////////////////////////////////// /MASTER ARDUINO/////////////////////////////////////////*/
/*-//////////////////////////////////////////////////VOID SCOOP/////////////////////////////////////////*/
#include <Hx711MIB.h>
Hx711 scale(A2, A3); // Hx711.DOUT - pin #A2 // Hx711.SCK - pin #A3
#include <Wire.h>
int masseenkg;
/*-//////////////////////////////////////////////////VOID SETUP/////////////////////////////////////////*/

void setup() {
  Serial.begin(9600);
  Wire.begin(); // Adresse de l'aruino Master. Com
 
}


/*-//////////////////////////////////////////////////VOID LOOP/////////////////////////////////////////*/

void loop() {
  Wire.requestFrom(8, 1);    // request 6 bytes from slave device #8

  while (Wire.available()) { // slave may send less than requested
    char Ruche01 = Wire.read(); // receive a byte as character
    
    Serial.println(Ruche01);// print the character
    
  }
   delay(500);
}

Merci Salut!

ça ce n'est pas bon:  Wire.write(masseenkg); // respond with message of 6 bytes

Lisez la doc de Wire.write()... ça n'envoit qu'un seul octet or votre valeur qui est de type float tient sur 4 octets.

Il faut utiliser la forme Wire.write(data, length) doncWire.write(&masseenkg, sizeof(masseenkg));

Bien sûr de l'autre côté il faut demander le bon nombre d'octets - lisez l'exemple

Merci pour votre réponse.
J'ai refait mon code mais je pense ne pas avoir compris...

//////////////// Arduino Master \\\\\\\\

// Bibliothèque 
#include <Wire.h>

// Bibliothèque 

//////////////// VOID SETUP  \\\\\\\\\\\\\\\

void setup() {
  Wire.begin(10); // Joindre le BUS i2C. Pas d'adresse pour le master ou adresse "10".
  Wire.onReceive(receiveEvent); // Enregistrer un événement.
  Serial.begin(9600); // Activation de le communication Serial.
 
}

//////////////// VOID LOOP \\\\\\\\\\\\\\\

void loop() {
  delay(100);
}

void receiveEvent(int howMany) {
  while (1 < Wire.available()) { // loop through all but the last
    char c = Wire.read(); // receive byte as a character
    Serial.print(c);         // print the character
  }
  int x = Wire.read();    // receive byte as an integer
  Serial.println(x);         // print the integer
}

//////////////// Arduino Slave \\\\\\\\

// Bibliothèque 
#include <Wire.h> // Communication I2C.
#include <Hx711MIB.h> // Calcule masse ruche.
Hx711 scale(A3, A2); // Hx711.DOUT - pin #A2 // Hx711.SCK - pin #A3.

// Bibliothèque 




//////////////// VOID SETUP  \\\\\\\\\\\\\\\

void setup() {
  Wire.begin(11); // Joindre le BUS i2C. Adresse supp a < 10
  Serial.begin(9600);
  scale.setScale(36); // Réglage milivolt pour 1Kg Scale correction.
delay(200);

}


//////////////// VOID LOOP  \\\\\\\\\\\\\\\

void loop() {
  
  double ruche =(scale.getGram());
  double masseruche =(ruche - 3855); // Valeur a changer pour les corrections defaut ZERO. (ruche - "Valeur du zero".
  double masseenkg = (masseruche *0.001);

  Serial.println("Masse de la ruche:");
  Serial.print(masseenkg);
  Serial.print(" Kg");
  Serial.println();
  delay(500);
  
  // Communication avec le maitre.
  
  Wire.beginTransmission(10); // transmit to device #10 master.
  Wire.write("Ruche 01: ");       
  Wire.write(&masseenkg, sizeof(masseenkg));             
  Wire.endTransmission();    // stop transmitting

  delay(5000);
}

J'ai cette erreur :
exit status 1
no matching function for call to 'TwoWire::write(double*, unsigned int)'

Autre question je voudrai que l'arduino maitre demande la valeur a une adresse précise.
Genre : Arduino maitre demande a Esclave 2 masse ruche...
Je ne sais pas si cela est possible ou si vous savez ou je peux trouvez des bouts de code pour comprendre comment je dois faire.

Merci Bonne soirée

write attend un tableau de bytes.
Faire

Wire.write((char*)&masseenkg, sizeof(masseenkg));

Merci pour ton aide. Il y a du mieux X).

//////////////// Arduino Slave \\\\\\\\

// Bibliothèque 
#include <Wire.h> // Communication I2C.
#include <Hx711MIB.h> // Calcule masse ruche.
Hx711 scale(A3, A2); // Hx711.DOUT - pin #A2 // Hx711.SCK - pin #A3.


// Bibliothèque 




//////////////// VOID SETUP  \\\\\\\\\\\\\\\

void setup() {
  

  Wire.begin(11); // Joindre le BUS i2C. Adresse supp a < 10
  Serial.begin(9600);
  scale.setScale(36); // Réglage milivolt pour 1Kg Scale correction.
delay(200);

}


//////////////// VOID LOOP  \\\\\\\\\\\\\\\

void loop() {
  
  double ruche =(scale.getGram());
  double masseruche =(ruche - 4050); // Valeur a changer pour les corrections defaut ZERO. (ruche - "Valeur du zero".
  double masseenkg = (masseruche *0.001);

  Serial.println("Ruche 03: ");
  Serial.print(masseenkg);
  Serial.print(" Kg");
  Serial.println();


  delay(500);
  
  // Communication avec le maitre.
  
  Wire.beginTransmission(10); // transmit to device #10 master.
  Wire.write("Ruche 03: ");       
  Wire.write((char*)&masseenkg, sizeof(masseenkg));            
  Wire.endTransmission();    // stop transmitting

  delay(500);
}

résulta sur le Moniteur serie :
Serial.print = Ruche 03: 0.00 Kg

//////////////// Arduino Master \\\\\\\\

// Bibliothèque 
#include <Wire.h>

// Bibliothèque 

//////////////// VOID SETUP  \\\\\\\\\\\\\\\

void setup() {

  Wire.begin(10); // Joindre le BUS i2C. Pas d'adresse pour le master ou adresse "10".
  Wire.onReceive(receiveEvent); // Enregistrer un événement.
  Serial.begin(9600); // Activation de le communication Serial.
 
}

//////////////// VOID LOOP \\\\\\\\\\\\\\\

void loop() {
  delay(100);
}

void receiveEvent(int howMany) {
  while (1 < Wire.available()) { // loop through all but the last
    char c = Wire.read(); // receive byte as a character
    Serial.print(c);         // print the character
  }
  
  int  x = Wire.read();    // receive byte as an integer
  Serial.println(x);         // print the integer
      
}

résulta sur le Moniteur serie :
Serial.print = Ruche 03: Š©+190

J'arrive pas a lire une valeur de la masse de la ruche j'ai un résulta bizarre avec des chiffres et lettres.
Merci pour votre aide Bonne journée.

Faut être logique, tu as envoyé un flottant comme un tableau de 4 octets. Donc à la réception il faut faire la manip inverse.

Déclarer un float
Passer un pointeur sur ce float à la fonction de réception pour qu'elle y place les 4 octets
Utiliser le float comme d'habitude.

Merci pour la réponse mais j'arrive pas a écrire la ligne de code.

//////////////// Arduino Master \\\\\\\\

// Bibliothèque 
#include <Wire.h>
#include <LiquidCrystal_I2C_AvrI2C.h> // Type d'ecran.
LiquidCrystal_I2C_AvrI2C lcd(0x27, 20, 4); // Type d'ecran.
// Bibliothèque 

//////////////// VOID SETUP  \\\\\\\\\\\\\\\

void setup() {
  lcd.begin();
  Wire.begin(10); // Joindre le BUS i2C. Pas d'adresse pour le master ou adresse "10".
  Wire.onReceive(receiveEvent); // Enregistrer un événement.
  Serial.begin(9600); // Activation de le communication Serial.
 
}

//////////////// VOID LOOP \\\\\\\\\\\\\\\

void loop() {
  delay(100);
}

void receiveEvent(int howMany) {
  while (1 < Wire.available()) { // loop through all but the last
    char c = Wire.read(); // receive byte as a character
    Serial.print(c);         // print the character
  }
  double x = Wire.read();    // receive byte as an integer
  Serial.println(x);         // print the integer
    
lcd.setCursor(0, 1); lcd.print(x);
lcd.setCursor(10, 1); lcd.print(" Kg");

}

le code marche po

Encore Merci pour ton aide.

UP si il y a une personne qui peut m'aider?
Merci :smiley:

Pourquoi pensez vous qu'après avoir vidé et jeté à la poubelle tout le buffer d'entrée sauf 1 octet avec votre boucle while (1 < Wire.available()) { // loop through all but the last il va vous rester magiquement 4 octets à lire avec une instruction qui n'en lit qu'un seul en essayant de faire double x = Wire.read();    // receive byte as an integer ?

Sérieusement vous pensez que ça a une chance de fonctionner?

par ce que j'ai aucune idée de ce que je fais. Voila pour quoi je sollicite votre aide...
Si j'avais une solution a ma question je ne viendrai pas sur un Forum pour demander de l'aide.

Vous comprenez le code que vous avez écrit?

 void receiveEvent(int howMany) {
  while (1 < Wire.available()) { // loop through all but the last
    char c = Wire.read(); // receive byte as a character
    Serial.print(c);         // print the character
  }
  double x = Wire.read();    // receive byte as an integer
  Serial.println(x);         // print the integer
    ...

Sinon il faut partir de là.

Bah déjà je comprends pas mais je veux que mon maitre arduino demande aux esclaves arduino donc je vois plus un

je comprendrai mieux un
Wire.requestFrom(11, 2); //Ruche 01
if (2 <= Wire.available())
int ruche01 = Wire.read();
Serial.println(ruche01);

Wire.requestFrom(12, 2); //ruche 02
if (2 <= Wire.available())
int ruche02 = Wire.read();
Serial.println(ruche02);

... //ruche 0x
Mais j'arrive a rien je ne trouve pas comment faire.

Ce qu'il vous manque comme info c'est que Wire.read(); ne lit qu'un seul octet, hors l'info que vous envoyez tient sur plusieurs octets. Donc il faut tenir compte dans la fonction void receiveEvent(int howMany) de la variable howMany qui vous dit combien d'octets sont dispos, ce sera votre message à décoder

c'est bien la que j'ai un probleme comment je fais pour tenir compte de la variable howMany ?

Merci pour votre aide.

Une boucle qui va lire (read()) howMany octets

Vous envoyez quoi ? Un int ? Ce sera sur 2 octets ->Pour rebâtir votre int il faut utiliser les fonctions de décalage des bits (<<). Vous lisez le premier octet dans un int, vous décalez de 8 positions
Vous lisez le second octet et vous l'ajoutez au premier -> vous vous retrouvez bien avec les deux octets à la bonne place dans votre int

laisse tombé

Ok