Go Down

Topic: Problèmes d'encodeur EC11 (Read 39817 times) previous topic - next topic

fdufnews

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

LamiRene

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é
Tous pour un et un pour tous !

Artouste

sans aucune garantie
je n'ai pas de quoi essayer mais ça comile
essaye ça pour le sender
Code: [Select]
#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 ()
{
}


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é
Tous pour un et un pour tous !

Artouste


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  :smiley-mr-green:
mais je n'ai pas le courage de chercher pour l'instant

juste pour test essaye ceci (sender) pour verifier qq points
Code: [Select]
#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 ()
{
}



LamiRene

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 :

Code: [Select]

...
// 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 :

Code: [Select]

...
// 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é
Tous pour un et un pour tous !

fdufnews


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

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

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  :smiley-mr-green:
mais je n'ai pas le courage de chercher pour l'instant

juste pour test essaye ceci (sender) pour verifier qq points
Code: [Select]
#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é
Tous pour un et un pour tous !

Artouste



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

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

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

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

LamiRene

Tous pour un et un pour tous !

LamiRene

:P 8)

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

L'ami René
Tous pour un et un pour tous !

Artouste


:~
         

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


LamiRene

C'est pas une "200 Watts", j'avais cru ! :smiley-mr-green:

Merci pour vos lumières !  ;)

L'ami René
Tous pour un et un pour tous !

Artouste

#163
Sep 18, 2014, 01:34 pm Last Edit: Sep 18, 2014, 02:24 pm by Artouste Reason: 1

...
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
http://arduino.cc/en/Reference/BitwiseAnd
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  :smiley-mr-green: 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)






LamiRene

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é
Tous pour un et un pour tous !

Go Up