[Résolu] I2C, Traitement de la trame

Bonjour,
Je travaille en ce moment sur le bus I2C.
J'ai un mega en maitre et un nono en esclave, une horloge.

J'arrive à établir le dialogue entre tous mes éléments. Mais maintenant, je voudrai traiter ce que je reçois sur mon esclave. J'ai donc créé un protocole de com affin d’aiguiller les message pour mieux les traiter.

Protocole de communication:

Type: Tableau de char
Syntax: 'x x x x x x'
| | | | | |
La classe <-+ | | | | |
Lecture 0/ecriture 1 <----+ | | | |
| | | |
Demande <-------+-+-+-+

Mon souci, viens de 'wire.onReceive(fonction)', je n'arrive pas à retourner de résultat.

Merci pour votre aide.

je donne mon code:

#include <Wire.h>

String reception;    //Recu du maitre
char reception2;
String Transfert;
char Transfert2;

String b;

int l;
int m;


//##########################################################################
//                                Setup
//##########################################################################

//SetUp
//-------------------------------------------------------------------------------------
void setup() {
  Wire.begin(10);
  Serial.begin(9600);

  //Entrée
  pinMode(4, INPUT);           //Aquitement

  Serial.println("Demarage...");
}


//##########################################################################
//                               Loop
//##########################################################################

void loop() {

  delay(1000);
  //Transfert = "000021";           //Demande lecture base
  Transfert = "000031";             //Demande lecture base
  //Transfert = "400001";           //Demande heure

  if (digitalRead(4) == 1)          //BP Aquitement
  {
    Serial.println("  Aquitement");
    Transfert = "510001";           //Aquitement
  }

  Dialogue();
}


//##########################################################################
//                             Fonction
//##########################################################################

//--------------------------------------------------------------------------
void Demande()
{
  Serial.println("Demande");

  char Transfert2 [Transfert.length() + 1];                  // tableau de char de la taille du String Transfert+1 (caractère de fin de ligne)
  Transfert.toCharArray(Transfert2, Transfert.length() + 1); // récupère Transfer2 dans le tableau de char

  Serial.println(Transfert2);
  Wire.write(Transfert2);                                    // demande
  //Wire.endTransmission();                                  // stop la transmission
}

//--------------------------------------------------------------------------
String Reception() //Recevoir du master
{
  Serial.println("Reception");

  l = Wire.available();        //nb d'octé à recevoir
  Serial.print("nb octe: ");
  Serial.println(l);
  char reception2[l];

  while (Wire.available())
  { delay(100);
    char c = Wire.read();     // receive un char
    m = Wire.available();
    m = l - m - 1;
    reception2[m] = c;
  }
  String reception = String(reception2);
  Serial.println(reception);
}

//--------------------------------------------------------------------------
void Dialogue()
{
  Wire.onRequest(Demande);
  delay(1000);

  Wire.onReceive(Reception);
  delay(1000);

   b=reception[0];
if(b.toInt()==5)   //Classe5 Dialogue
  {
    b=reception[3];
if(b.toInt()==1)   //Scan Surveillance
  {
    b=reception[4];
    switch (b.toInt())
      {
        case 1:                   //Zone1
        break;
        case 2:                   //Zone2
        if(reception[5]==1)     //Al
        {
          Serial.println("Detection Volumetrique");
        }
        if(reception[5]==2)     //Ap
        {
          Serial.println("AP Zone2");
        }
        if(reception[5]=='3')     //Al+Ap
        {
          Serial.println("AP+AL Zone2");
        }
        break;
        case 3:                   //Zone3
        break;
        case 4:                   //Zone4
        break;
        case 5:                   //Zone5
        break;
        case 6:                   //Zone6
        break;
  }
  }
  }
}

Salut,
regarde ce ce coté, cela devrait t'aider même si ce n'est pas un Attiny :

Merci, je vais y faire un tour.

Je viens d’essayer les codes maitre/esclave. C'est pas mal, mais si j’emploie cette méthode, je dois reprendre tout mon code qui est basé sur des char et des string. Je transfert des entier, mais aussi des message texte. Si je n'ai pas le choix, je m'adapterai, mais là, le dialogue est bon , il y à juste que je n'arrive pas à récupérer le message 'Message=Wire.onReceive(Fonction);'

Vous n'avez pas bien compris l'usage des callbacks

Wire.onReceive(handler) dit à la librairie wire que lorsque l'esclave va recevoir une communication du maître, il faudra appeler la fonction handler(). cette fonction doit respecter un format bien défini

void myHandler(int numBytes)
{
// ici faire des Wire.read() pour lire les numBytes envoyés
}

C'est documenté ici ou cf ma réponse dans l'autre post

Bonsoir,
Dans mon code, je fais déjà mais à l’intérieur de la fonction "int numBytes=Wire.available();".

J'arrive à établir une communication j'ai également modifié avec "c_str()". c'est très efficace. J'ai aussi ajouté le caractère nul (je partais en mémoire en fin de message).
Globalement, c'est plus efficace, plus propre.

Mais j'ai toujours mon probléme sur la réception: le résultat de la fonction de "Reception" appelé par "Wire.onReceive(Reception);" reste dans la fonction et ne peut pas être exploité une fois sortie.

...


void Demande()
{
  Serial.println("Demande");
  Serial.println(Transfert.c_str());
  Wire.write(Transfert.c_str());     // demande
  //Wire.endTransmission();          // arrêter la transmission
}

//--------------------------------------------------------------------------
String Reception()                      //Recevoir du master
{
  Serial.println("Reception");

  l = Wire.available();                  //nb d'octé à recevoir
  Serial.print("nb octe: ");
  Serial.println(l);
  char reception2[l];

  while (Wire.available())

  { delay(100);
    char c = Wire.read();             // receive un char
    m = Wire.available();
    m = l - m - 1;
    reception2[m] = c;
  }
  String reception = String(reception2);
  Serial.println(reception);



  

}

//--------------------------------------------------------------------------
void Dialogue()
{
  Wire.onRequest(Demande);
  delay(1000);
  Wire.onReceive(Reception);
  delay(1000);

...

Votre handler est incorrect, je vous l'ai déjà dit...

ce que vous écrivez n'est pas ce qui est prévu par la librairie; vous DEVEZ déclarer une fonction qui ne retourne RIEN et qui prend en paramètre le nombre d'octets. Cette fonction est appelée de manière asynchrone. Vous ne pouvez pas faire Message=Wire.onReceive(Fonction);

On déclare dans le setup Wire.onReceive(Fonction); pour dire à la librairie Wire, "quand tu reçois une communication du maître, appelle cette fonction"

Vous pouvez voir cela un peu comme une interruption. votre loop() tourne et quand le maître parle, la loop() s'interrompt, la fonction handler est appelée puis la loop() reprend; si vous mettez un drapeau dans cette fonction et la chaîne reçue dans un tableau global (vraiment arrêtez d'utiliser des Strings, vous aurez des bugs très difficiles à trouver et régler si votre programme doit tourner longtemps) alors la loop() peut y avoir accès et traiter le message du maître

Pour les Strings, si vous lisez l'anglais allez lire ce post

Bonsoir J-M-L,
Merci, j'ai écouté vos conseil et ça fonctionne enfin. Je n'avais pas saisie la notion d'interruption. Maintenant, je travaille également avec des tableau de char pour les données reçu et je vai faire de même pour ce que j'envoie.
Merci!

Super - bravo

Bonne continuation