Problèmes d'encodeur EC11

Bonjour Artouste,

OK, j'y vais, test xyz.

L'ami René

Alors voilà :

Code Nano :

#include "Wire.h"

// Adresse de la communication I2C de l'Arduino Mega avec Nano.
const byte ADRESSE_NANO_1 = 1;// Adresse requise pour l'esclave Tiny i2c.

byte Variable_X = 0;
byte Variable_Y = 0;
byte Variable_Z = 0;

void EnvoyerDonnees ()
{
  Variable_X = Variable_X + 1;
  Variable_Y = Variable_Y + 2;
  Variable_Z = Variable_Z + 3;
  Wire.write (Variable_X);
  Wire.write (Variable_Y);
  Wire.write (Variable_Z);
  // Écriture dans le moniteur série de l'IDE d'Arduino des valeurs lues.
  Serial.print (", Variable_X = ");
  Serial.print (Variable_X);
  Serial.print (", Variable_Y = ");
  Serial.print (Variable_Y);
  Serial.print (", Variable_Z = ");
  Serial.print (Variable_Z);
  Serial.println ();
}

void setup ()
{
  Serial.begin (115200);
  Serial.print ("* Debut setup Nano *");
  Serial.println ();
  // Joindre le bus I2C.
  Wire.begin (ADRESSE_NANO_1);
  // Enregistrer l'événement pour lorsqu'une demande arrive.
  Wire.onRequest (EnvoyerDonnees);
  Serial.print ("* Fin setup Nano *");
  Serial.println ();
  Serial.print ("* Debut loop Nano *");
  Serial.println ();
  Serial.println ();
}

void loop ()
{
}

Sortie terminal série Nano :

  • Debut setup Nano *
  • Fin setup Nano *
  • Debut loop Nano *

, Variable_X = 1, Variable_Y = 2, Variable_Z = 3
, Variable_X = 2, Variable_Y = 4, Variable_Z = 6
, Variable_X = 3, Variable_Y = 6, Variable_Z = 9
, Variable_X = 4, Variable_Y = 8, Variable_Z = 12
, Variable_X = 5, Variable_Y = 10, Variable_Z = 15
, Variable_X = 6, Variable_Y = 12, Variable_Z = 18
, Variable_X = 7, Variable_Y = 14, Variable_Z = 21
, Variable_X = 8, Variable_Y = 16, Variable_Z = 24
, Variable_X = 9, Variable_Y = 18, Variable_Z = 27
, Variable_X = 10, Variable_Y = 20, Variable_Z = 30
, Variable_X = 11, Variable_Y = 22, Variable_Z = 33
, Variable_X = 12, Variable_Y = 24, Variable_Z = 36
, Variable_X = 13, Variable_Y = 26, Variable_Z = 39
, Variable_X = 14, Variable_Y = 28, Variable_Z = 42
, Variable_X = 15, Variable_Y = 30, Variable_Z = 45
, Variable_X = 16, Variable_Y = 32, Variable_Z = 48
, Variable_X = 17, Variable_Y = 34, Variable_Z = 51

Code Mega :

#include "Wire.h"

// Adresse de la communication I2C de l'Arduino Mega avec Nano.
const byte ADRESSE_MEGA_0 = 0;// Adresse optionnelle pour un maître i2c.
const byte ADRESSE_NANO_1 = 1;// Adresse requise pour l'esclave Tiny i2c.

byte Variable_X = 0;
byte Variable_Y = 0;
byte Variable_Z = 0;

void setup ()
{
  Serial.begin (115200);
  Serial.print ("* Debut setup Mega *");
  Serial.println ();
  Wire.begin (ADRESSE_MEGA_0);// Joindre le bus I2C.
  Serial.print ("* Fin setup Mega *");
  Serial.println ();
  Serial.print ("* Debut loop Mega *");
  Serial.println ();
  Serial.println ();
}

void loop ()
{
  // Lecture de 3 octets (byte) depuis l'esclave #1.
  // L'adresse i2c = ADRESSE_NANO_1, le nombre d'octets = 3 et oui (true) pour 
  // l'envoi d'un message arrêt à la fin de l'envoi des octets.
  Wire.requestFrom (int (ADRESSE_NANO_1), 3, true);
  Serial.print ("* Wire.available () = ");
  Serial.print (Wire.available ());
  // Recoit la valeur indiquant le nombre de pas fait par l'encodeur depuis la 
  // dernière demande de l'Arduino maître de la communication i2c.
  Variable_X = Wire.read ();
  Variable_Y = Wire.read ();
  Variable_Z = Wire.read ();

  // Écriture dans le moniteur série de l'IDE d'Arduino des valeurs lues.
  Serial.print (", Variable_X = ");
  Serial.print (Variable_X);
  Serial.print (", Variable_Y = ");
  Serial.print (Variable_Y);
  Serial.print (", Variable_Z = ");
  Serial.print (Variable_Z);
  Serial.println ();
  delay (1000);
}

Sortie terminale série Mega :

  • Debut setup Mega *

  • Fin setup Mega *

  • Debut loop Mega *

  • Wire.available () = 0, Variable_X = 255, Variable_Y = 255, Variable_Z = 255

  • Wire.available () = 0, Variable_X = 255, Variable_Y = 255, Variable_Z = 255

  • Wire.available () = 0, Variable_X = 255, Variable_Y = 255, Variable_Z = 255

NOTE : Lancement du Mega avec bouton RESET sur le Nano... de là, les 3 premiers « * Wire.available () = 0 », mais je ne comprends pas, déjà les « , Variable_X = 255, Variable_Y = 255, Variable_Z = 255 ».

  • Wire.available () = 3, Variable_X = 3, Variable_Y = 255, Variable_Z = 255
  • Wire.available () = 3, Variable_X = 6, Variable_Y = 255, Variable_Z = 255
  • Wire.available () = 3, Variable_X = 9, Variable_Y = 255, Variable_Z = 255
  • Wire.available () = 3, Variable_X = 12, Variable_Y = 255, Variable_Z = 255
  • Wire.available () = 3, Variable_X = 15, Variable_Y = 255, Variable_Z = 255
  • Wire.available () = 3, Variable_X = 18, Variable_Y = 255, Variable_Z = 255
  • Wire.available () = 3, Variable_X = 21, Variable_Y = 255, Variable_Z = 255
  • Wire.available () = 3, Variable_X = 24, Variable_Y = 255, Variable_Z = 255
  • Wire.available () = 3, Variable_X = 27, Variable_Y = 255, Variable_Z = 255
  • Wire.available () = 3, Variable_X = 30, Variable_Y = 255, Variable_Z = 255
  • Wire.available () = 3, Variable_X = 33, Variable_Y = 255, Variable_Z = 255
  • Wire.available () = 3, Variable_X = 36, Variable_Y = 255, Variable_Z = 255
  • Wire.available () = 3, Variable_X = 39, Variable_Y = 255, Variable_Z = 255
  • Wire.available () = 3, Variable_X = 42, Variable_Y = 255, Variable_Z = 255
  • Wire.available () = 3, Variable_X = 45, Variable_Y = 255, Variable_Z = 255
  • Wire.available () = 3, Variable_X = 48, Variable_Y = 255, Variable_Z = 255
  • Wire.available () = 3, Variable_X = 51, Variable_Y = 255, Variable_Z = 255
  • Wire.available () = 3, Variable_X = 54, Variable_Y = 255, Variable_Z = 255
  • Wire.available () = 3, Variable_X = 57, Variable_Y = 255, Variable_Z = 255
  • Wire.available () = 3, Variable_X = 60, Variable_Y = 255, Variable_Z = 255

Votre avis ?!?

En pièce jointe les deux fichiers.

L'ami René

MegaI2CNanoTestXYZ Master et Slave.zip (1.8 KB)

LamiRene:
Alors voilà :

...
Votre avis ?!?

En pièce jointe les deux fichiers.

L'ami René

Il semblerait que te ne lise que Z(nano)
Je regarde ça plus tard
NB , j'ai edité ma reponse plus haut avec qq reflexions :grin:

L'I²C ne fonctionne pas comme ça.
C'est le maître qui rythme les transferts.
L'esclave attends une requête du maître pour parler. Il doit utiliser onRequest pour retourner la donnée au bon moment.
Regardes les exemples dans l'IDE. Il y a un exemple qui s'appelle slave_sender

Bonjour fdufnews,

C'est ce que je fais, il me semble !

Le Mega avec sa commande « Wire.requestFrom (int (ADRESSE_NANO_1), 3, true);
» et le Nano répond avec « Wire.onRequest (EnvoyerDonnees);
», non !?!?

L'ami René

sans aucune garantie
je n'ai pas de quoi essayer mais ça comile
essaye ça pour le sender

#include "Wire.h"

// Adresse de la communication I2C de l'Arduino Mega avec Nano.
const byte ADRESSE_NANO_1 = 1;// Adresse requise pour l'esclave Tiny i2c.

byte Variable_X = 0;
byte Variable_Y = 0;
byte Variable_Z = 0;
byte Varsend[3];
void EnvoyerDonnees ()
{
  Variable_X = Variable_X + 1;
  Variable_Y = Variable_Y + 2;
 Variable_Z = Variable_Z + 3;
 
 Varsend[0]=Variable_X;
 Varsend[1]=Variable_Y;
 Varsend[2]=Variable_Z;
  //Wire.write (Variable_X);
  //Wire.write (Variable_Y);
  //Wire.write (Variable_Z);
  Wire.write (Varsend,3);
  // Écriture dans le moniteur série de l'IDE d'Arduino des valeurs lues.
  Serial.print (", Variable_X = ");
  Serial.print (Variable_X);
  Serial.print (", Variable_Y = ");
  Serial.print (Variable_Y);
  Serial.print (", Variable_Z = ");
  Serial.print (Variable_Z);
  Serial.println ();
}

void setup ()
{
  Serial.begin (115200);
  Serial.print ("* Debut setup Nano *");
  Serial.println ();
  // Joindre le bus I2C.
  Wire.begin (ADRESSE_NANO_1);
  // Enregistrer l'événement pour lorsqu'une demande arrive.
  Wire.onRequest (EnvoyerDonnees);
  Serial.print ("* Fin setup Nano *");
  Serial.println ();
  Serial.print ("* Debut loop Nano *");
  Serial.println ();
  Serial.println ();
}

void loop ()
{
}

Bonjour Artouste,

Bon, les valeurs côté Mega semblent bonnes avec ton code !

Alors, là, faut donc comprendre qu'il y a une gestion interne plus ou moins invisible (transparente) du nombre d'octets a envoyer ?

Y-a une explication ?

L'ami René

LamiRene:
Bonjour Artouste,

Bon, les valeurs côté Mega semblent bonnes avec ton code !

Alors, là, faut donc comprendre qu'il y a une gestion interne plus ou moins invisible (transparente) du nombre d'octets a envoyer ?

Y-a une explication ?

L'ami René

il y a evidemment une explication :grin:
mais je n'ai pas le courage de chercher pour l'instant

juste pour test essaye ceci (sender) pour verifier qq points

#include "Wire.h"

// Adresse de la communication I2C de l'Arduino Mega avec Nano.
const byte ADRESSE_NANO_1 = 1;// Adresse requise pour l'esclave Tiny i2c.

byte Variable_X = 0;
byte Variable_Y = 0;
byte Variable_Z = 0;
byte Varsend[10] = {0, 0, 0, 30,40,50,60,70,80,100};
void EnvoyerDonnees ()
{
  Variable_X = Variable_X + 1;
  Variable_Y = Variable_Y + 2;
 Variable_Z = Variable_Z + 3;
 
 Varsend[0]=Variable_X;
 Varsend[1]=Variable_Y;
 Varsend[2]=Variable_Z;
 
  //Wire.write (Variable_X);
  //Wire.write (Variable_Y);
  //Wire.write (Variable_Z);
  Wire.write (Varsend,10);
  // Écriture dans le moniteur série de l'IDE d'Arduino des valeurs lues.
  Serial.print (", Variable_X = ");
  Serial.print (Variable_X);
  Serial.print (", Variable_Y = ");
  Serial.print (Variable_Y);
  Serial.print (", Variable_Z = ");
  Serial.print (Variable_Z);
  Serial.println ();
}

void setup ()
{
  Serial.begin (115200);
  Serial.print ("* Debut setup Nano *");
  Serial.println ();
  // Joindre le bus I2C.
  Wire.begin (ADRESSE_NANO_1);
  // Enregistrer l'événement pour lorsqu'une demande arrive.
  Wire.onRequest (EnvoyerDonnees);
  Serial.print ("* Fin setup Nano *");
  Serial.println ();
  Serial.print ("* Debut loop Nano *");
  Serial.println ();
  Serial.println ();
}

void loop ()
{
}

Bonjour Artouste et toutes et tous,

Il est clair pour moi que sans votre aide, je n'aurais pas trouvé ce type de problème et cette solution !

Alors, j'apprécie vraiment grandement votre aide ! Merci !

Voici comment le problème est réglé dans le code :

Côté Mega :

...
// Variables pour les données de l'encodeur 5 :
byte         Encodeur_5_BoutonEtat    = 0;
byte         Encodeur_5_PasFait       = 0;
byte         Encodeur_5_PasDirection  = 0;
...
  // Lire l'encodeur 5.
  // Lecture de 3 octets (byte) depuis l'esclave Tiny #1.
  // L'adresse i2c = ADRESSE_TINY_1, le nombre d'octets = 3 et oui (true) pour 
  // l'envoi d'un message arrêt à la fin de l'envoi des octets.
  Wire.requestFrom (int (ADRESSE_TINY_1), 3, true);
  if (Wire.available () > 2)
  { 
    // Recoit la valeur indiquant l'état pressé ou non d'un bouton.
    Encodeur_5_BoutonEtat = Wire.read ();
    // Recoit la valeur indiquant si au moins un pas est fait sur  l'encodeur.
    Encodeur_5_PasFait = Wire.read ();
    // Recoit la valeur indiquant si au moins un pas est fait sur  l'encodeur.
    Encodeur_5_PasDirection = Wire.read ();

    // Vérifier s'il le bouton de l'encodeur a été pressé.
    if (Encodeur_5_BoutonEtat == 1)
    { // Si enfoncé, émettre un son.
      EnvoyerCommandeX_Plane ("sim/instruments/barometer_2992");
    }

    if (Encodeur_5_PasFait == 1)
    {// Pas fait = oui.
      if (Encodeur_5_PasDirection == 1)
      {// Pas positif.
        EnvoyerCommandeX_Plane ("sim/instruments/barometer_up");
      }
      else if (Encodeur_5_PasDirection == 2)
      {// Pas négatif.
        EnvoyerCommandeX_Plane ("sim/instruments/barometer_down");
      }
    }
  }
...

Côté Nano :

...
// Recoit la valeur indiquant l'état pressé ou non d'un bouton.
byte          Encodeur_1_BoutonEtat    = 0;
boolean       Encodeur_1_Direction     = 0;
byte          Encodeur_1_EtatActuel    = 0;
byte          Encodeur_1_EtatPrecedent = 0;
int           Encodeur_1_NombreDePas   = 0;
byte          Encodeur_1_Valeurs [3];
...
//*****************************************************************************
// FONCTION ActionsEncodeurs.
//*****************************************************************************
void ActionsEncodeurs ()
// Fonction qui est exécutée lorsque des données sont demandées par le Maître.
// Cette fonction est enregistrée comme un événement ("event" en anglais),
// voir la fonction setup ().
{
  if ((Encodeur_1_BoutonEtat != 0) or (Encodeur_1_NombreDePas != 0))
  {
    Encodeur_1_Valeurs [0] = Encodeur_1_BoutonEtat;
    
    if (Encodeur_1_NombreDePas >= 2)
    {
      Encodeur_1_Valeurs [1] = 1;
      Encodeur_1_Valeurs [2] = 1;
    }
    else if (Encodeur_1_NombreDePas <= -2)
    {
      Encodeur_1_Valeurs [1] = 1;
      Encodeur_1_Valeurs [2] = 2;
    }
    else
    {
      Encodeur_1_Valeurs [1] = 0;
      Encodeur_1_Valeurs [2] = 0;
    }

    Wire.write (Encodeur_1_Valeurs, 3);

    Encodeur_1_NombreDePas = 0;
    Encodeur_1_BoutonEtat = 0;
  }
}
//*****************************************************************************
...

Pour le cas ou... en pièce jointe tout le code source.

Et là, je retourne tester le dernier code de Artouste et reviens avec les constats.

Encore Merci !

L'ami René

MegaNano01xEnco Master et Slave.zip (30.5 KB)

LamiRene:
C'est ce que je fais, il me semble !

Décidément aujourd'hui je suis vraiment à coté de la plaque.

Artouste:

LamiRene:
Bonjour Artouste,

Bon, les valeurs côté Mega semblent bonnes avec ton code !

Alors, là, faut donc comprendre qu'il y a une gestion interne plus ou moins invisible (transparente) du nombre d'octets a envoyer ?

Y-a une explication ?

L'ami René

il y a evidemment une explication :grin:
mais je n'ai pas le courage de chercher pour l'instant

juste pour test essaye ceci (sender) pour verifier qq points

#include "Wire.h"

// Adresse de la communication I2C de l'Arduino Mega avec Nano.
const byte ADRESSE_NANO_1 = 1;// Adresse requise pour l'esclave Tiny i2c.

byte Variable_X = 0;
byte Variable_Y = 0;
byte Variable_Z = 0;
byte Varsend[10] = {0, 0, 0, 30,40,50,60,70,80,100};
void EnvoyerDonnees ()
{
  Variable_X = Variable_X + 1;
  Variable_Y = Variable_Y + 2;
Variable_Z = Variable_Z + 3;

Varsend[0]=Variable_X;
Varsend[1]=Variable_Y;
Varsend[2]=Variable_Z;

//Wire.write (Variable_X);
  //Wire.write (Variable_Y);
  //Wire.write (Variable_Z);
  Wire.write (Varsend,10);
  // Écriture dans le moniteur série de l'IDE d'Arduino des valeurs lues.
  Serial.print (", Variable_X = ");
  Serial.print (Variable_X);
  Serial.print (", Variable_Y = ");
  Serial.print (Variable_Y);
  Serial.print (", Variable_Z = ");
  Serial.print (Variable_Z);
  Serial.println ();
}

void setup ()
{
  Serial.begin (115200);
  Serial.print ("* Debut setup Nano ");
  Serial.println ();
  // Joindre le bus I2C.
  Wire.begin (ADRESSE_NANO_1);
  // Enregistrer l'événement pour lorsqu'une demande arrive.
  Wire.onRequest (EnvoyerDonnees);
  Serial.print ("
Fin setup Nano ");
  Serial.println ();
  Serial.print ("
Debut loop Nano *");
  Serial.println ();
  Serial.println ();
}

void loop ()
{
}

Rebonjour Artouste,

Il est clair pour moi que sans votre aide..., alors Merci !

Pour votre dernier code, pas de changement perceptible au niveau des sorties terminal série côté Mega ou Nano. L’alignement doit se faire sur la fonction « Wire.requestFrom (int (ADRESSE_NANO_1), 3, true); » du Mega "Master" et non pas sur la fonction « Wire.write (Varsend,10); » du Nano "Slave" ou la taille de la variable « Varsend[10] ».

Il y aurait un autre test que vous souhaiteriez que je faire ?

Encore Merci Artouste !

L'ami René

fdufnews:

LamiRene:
C'est ce que je fais, il me semble !

Décidément aujourd'hui je suis vraiment à coté de la plaque.

:grin:
[HUM]
Si elle est chauffante, brulante, etc : c'est aussi une excellente initiatitive de prise de position :grin:

Le "cousin René" est aussi quelquefois difficile à decoder :slight_smile:

:~

:stuck_out_tongue: 8)

Le moment est propice à la détente !...

L'ami René

LamiRene:
:~

:grin:
[HUM]
Bonne nuit pour ce soir 8)
si j'ai d'autres tests à faire ce soir, ce sera avec "ma 100 watts" :grin:

C'est pas une "200 Watts", j'avais cru ! :grin:

Merci pour vos lumières ! :wink:

L'ami René

LamiRene:
...
Pour votre dernier code, pas de changement perceptible au niveau des sorties terminal série côté Mega ou Nano. L’alignement doit se faire sur la fonction « Wire.requestFrom (int (ADRESSE_NANO_1), 3, true); » du Mega "Master" et non pas sur la fonction « Wire.write (Varsend,10); » du Nano "Slave" ou la taille de la variable « Varsend[10] ».

bonjour
c'est ce qu'intuitivement je pensais
maintenant retour au serieux et à l'efficacité
je reviens à la concision de transmission
pourquoi ne pas passer à un byte "par encodeur" ?
ça devient simplement de la gestion de bit facilement gerable avec les bitwise

c'est assez trivial d'encoder/decoder sur un seul byte :

  • etat bouton poussoir
  • sens de rotation encodeur
  • valeur encodeur sur 32 points ( c'est déjà enorme :grin: et parfaitement inexploitable)

et pas besoin d'artifice de reconstruction en reception , juste utiliser du masquage bit à bit

10 byte = 10 encodeurs et encore je suis à peu pres persuadé que fonctionnellement on peu faire "tenir" 2 encodeurs avec BP sur un seul byte (en passant la valeur max de variation sur 2 bits=4)

Bonjour Artouste,

Je connais la théorie et les principes, mais je ne maîtrise pas du tout cette technique. J’appelle ça des techniques de tordeux de bits, des programmeurs en assembleur. Mois je suis plus du genre programmeur en Pascal, didactique avec beaucoup de commentaires dans le code. Je cherche plus a avoir un code source qui soit le plus littéral que possible.

Si j'étais à la limite des ressources mémoires des puces, je penserais peut-être a utiliser ces techniques, mais pour le moment, j'en suis très loin. Pour moi, ce serait faire compliqué quand je peux faire simple.

Merci pour l'idée ! Je garde tout de même, sous le coude, si un jour j'en ai besoin.

L'ami René

LamiRene:
...

Si j'étais à la limite des ressources mémoires des puces, je penserais peut-être a utiliser ces techniques, mais pour le moment, j'en suis très loin. Pour moi, ce serait faire compliqué quand je peux faire simple.

je raisonnais plus en temps de transmission et concision de l'information
Si à terme tu gere comme tu le souhaite tout tes encodeurs "externes" , alors conserve ta methode actuelle