PROBLEME DE COMMUNICATION I2C

Bonjour à tous,
j’essaye en vain depuis 2 jours de faire communiquer mon PcDuino V2 avec une carte Mega2560 mais je n’y arrive pas…

J’ai bien configurer les vitesses de communication du bus I2C a 200 kHz, car c’est celle du PcDuino…

Coté Arduino:

void setup()

{

  Wire.begin(0x02);        // Active I2C en esclave
  Wire.setClock(200000L); // Configure la vitesse a 200 kHz comme le PcDuino

  Wire.onReceive(receiveEvent);
  Wire.onRequest(requestEvent);

}

 

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©;         // print the character
  }
  x = Wire.read();    // receive byte as an integer
  Serial.println(x);         // print the integer
   
} // Fin du void receiveEvent(int howMany)

 

void requestEvent()
{
// Attends la demande du PcDuino pour envoyer les données en I2C
  Hydrometrie = 1;
  Temperature = 2;
  Luminosite = 3;

  Wire.write(Hydrometrie);    
  Wire.write(Temperature);
  Wire.write(Luminosite);

} // Fin du void requestEvent()

Et cote PcDuino:

def Reception_Donnees_I2C():

    global Hydrometrie, Temperature, Luminosite

 

    Hydrometrie = i2c.read_byte(Pcb_Relayage) # Lit un octet sur la carte relayage
    Temperature = i2c.read_byte(Pcb_Relayage) # Lit un octet sur la carte relayage
    Luminosite = i2c.read_byte(Pcb_Relayage) # Lit un octet sur la carte relayage

 

    print Hydrometrie
    print Temperature
    print Luminosite

En faite, je récupère 3 variables en RF 433MHz via la carte Mega 2560 qui sont des données de température, d’hydrométrie et de luminosité de mes capteurs, je les stocke dans la mémoire de la 2560 et je l’envoie par I2C lorsque le maitre(PcDuino), le demande… Mais voila le problème, je reçoit en retour dans le terminal, une valeur qui ne correspond a rien qui est 5. J’ai vérifié a l’analyseur I2C, la carte 2560 envoi bien un 5 au lieu des valeurs qu’elle a en mémoire… Elle a bien les bonnes valeurs dans ses variables car je les récupères avec un serial.print et elles sont OK… Je n’y comprend plus rien…

Pouvez vous m’aider a trouver ce qui ne va pas dans mon code.

Merci d’avance

@+

Bonjour,

Tu as essayé d'envoyer une seule valeur au lieu de 3 ?

bsr
merci de ta reponse,
oui, j'ai essayé et j'obtiens 5 au lieu de 34 comme valeur...
Une autre idée peut etre
Merci d'avance
@+

Re,
il y a une chose aussi, que j'ai retiré pour mes derniers tests mais, j'arrive bien à communiquer dans le sens PcDuino vers Arduino mais pas l'inverse...
j'ai envoyé une trame I2C de 2 octets, ce qui correspond à l'adresse de l'Arduino et un octet commandant un relais et cela fonctionne. Par contre, un wire.write depuis l'Arduino vers le Pc Duino me retourne des valeurs mauvaises...

arnaudf09:
oui, j'ai essayé et j'obtiens 5 au lieu de 34 comme valeur...

Pourquoi au lieu de 34 ? Il est où ce 34 dans ton code ?

34 proviens de mon capteur d'hydrometrie donc normal. Par contre, j'arrive a recevoir une bonne valeur mais pas les autres....

Tu veux dire que tout fonctionne bien quand le capteur d'hygrométrie est seul ?

Bjr,
Le capteur d'hydrometrie est inclus au capteur de temperature donc il devrait fonctionner ensemble... Sur l'arduino, j'ai bien les 3 valeurs qui sont envoyé avec ce morceau de code:

void requestEvent()
{
// Attends la demande du PcDuino pour envoyer les données en I2C
  
  Wire.write(Hydrometrie);  
 
  Wire.write(Temperature); 
   
  Wire.write(Luminosite); 
   
  
  Serial.println("Envoi des donnees au PcDuino");
  Serial.println(Hydrometrie);
  Serial.println(Temperature);
  Serial.println(Luminosite);

  

} // Fin du void requestEvent()

et coté PcDuino

def Reception_Donnees_I2C():

 global Hydrometrie, Temperature, Luminosite
 
 Hydrometrie = i2c.read_byte(Pcb_Relayage) # Lit un octet sur la carte relayage

 Temperature = i2c.read_byte(Pcb_Relayage) # Lit un octet sur la carte relayage

 Luminosite = i2c.read_byte(Pcb_Relayage) # Lit un octet sur la carte relayage


 Serial.println(Hydrometrie)
 Serial.println(Temperature)
 Serial.println(Luminosite)

Par contre, je ne reçois que la dernière valeur qui est 79 (79% de luminosité) sur les 3 variables. et lorsque je regarde a l'analyseur réseau, le PcDuino fait bien sa demande de requête mais il apparait 0x4F qui correspond à 79, apres plus de 2mS après la requête... Je ne comprend plus rien...

!(http://M:\ANALYSEUR TRAMEI2C.JPG)

Personnellement, j'utilise pyA20 et je fais quelque chose comme ça:

Sur pcDuino:

from pyA20 import i2c

...

def setup():

    ...
    
    i2c.init("/dev/i2c-2")
    i2c.open(0x60)

    ...

def loop():
    global i
    i = i+1
    s.enterabs( T0 + (i * dt), 1, CalculVitesse, ())
    s.run()

def CalculVitesse():
    ...

    # Mesure de la vitesse des moteurs grâce aux codeurs incrémentaux
    try:
        lstData = i2c.read(12)
        sData = ''
        for aByte in lstData:
            sData = sData + chr(aByte)
        codeurDroitDeltaPos = int((sData.split("|"))[0])
        codeurGaucheDeltaPos = int((sData.split("|"))[1])
        codeurDroitDeltaPosPrec = codeurDroitDeltaPos
        codeurGaucheDeltaPosPrec = codeurGaucheDeltaPos
    except:
        codeurDroitDeltaPos = codeurDroitDeltaPosPrec
        codeurGaucheDeltaPos = codeurGaucheDeltaPosPrec
        print "Problème de lecture des vitesse moteurs"

    ...

Côté Arduino:

...

void requestEvent() { 
  char charBuf[12];
  String toSend = String(codeurDroitDeltaPos);
  toSend += "|";
  toSend += String(codeurGaucheDeltaPos);
  toSend += "|";
  Wire.write( toSend.c_str() );
}

...

En clair, j'envoie côté Arduino mes deux données d'un seul coup sous forme de String, avec un nombre de caractères fixes (12 au total) et je découpe cette chaine côté pcDuino.
J'ai fait ça pour des questions de performance: ça prend moins de temps de faire un envoi global plutôt que plusieurs envois séparés.

A quel endroit tu mets tes librairies sur le pcduino ?

J'ai fait simplement:

pip install pyA20

tu fais comment coté pcduino pour faire un write, j'essaye mais j'ai des erreurs...

i2c.open(0x60) correspond à l'initialisation du maitre avec son adresse, c'est bien ca ?

Bonjour,

arnaudf09:
i2c.open(0x60) correspond à l'initialisation du maitre avec son adresse, c'est bien ca ?

En général le maître n'a pas d'adresse, essaye

i2c.open();

arnaudf09:
tu fais comment coté pcduino pour faire un write, j'essaye mais j'ai des erreurs...

Quelles erreurs ?

arnaudf09:
i2c.open(0x60) correspond à l'initialisation du maitre avec son adresse, c'est bien ca ?

0x60 est l'adresse de l'esclave (l'Arduino)

J’obtiens une seule valeur en sortie, celle ci est correcte, je n’avais pas bien mis l’adresse de l’esclave… Mais comment fait tu si tu as plusieurs esclave, juste avant de les utiliser, tu fais un open ?
sur mes 2 autres valeurs, j’obtiens ce message :

Bon, j'obtiens une liste de valeur coté pcduino comme celle ci

[73, 255, 255]

par contre, le 73 est la 3eme valeur envoyé par l'arduino et les 2 autres sont mauvaises...

j'utilise le code suivant cote PcDuino:

value = i2c.read(3) #Read 3 byte

print value

et cote arduino

void requestEvent()
{
  Wire.write(Hydrometrie);  
 
  Wire.write(Temperature); 
   
  Wire.write(Luminosite); 

  Serial.println("Envoi des donnees au PcDuino");
  Serial.println(Hydrometrie);
  Serial.println(Temperature);
  Serial.println(Luminosite);


} // Fin du void requestEvent()

Ca y est, c'est bon, j'ai bien le résultat voulu. Un grand merci pour l'aide que vous m'avez apporté...
Pour ceux à qui cela intéresse, je met mon code a disposition...

Coté Arduino:

#define Nombre_Octets_A_Recevoir 3 

  byte Temperature;
  byte Luminosite;
  byte Hydrometrie;

  byte Data[Nombre_Octets_A_Recevoir];

...

void setup()
{
  Wire.begin(Adr_PCB_Relayage);        // Active I2C en esclave
  Wire.setClock(200000L); // Configure la vitesse a 200 kHz comme le PcDuino
  Wire.onReceive(receiveEvent); // register event
  Wire.onRequest(requestEvent); // register event

...

}

void requestEvent()
{
  Data[0] = Hydrometrie;
  Data[1] = Temperature; // double sur 4 octets
  Data[2] = Luminosite;
  
  Wire.write(Data,Nombre_Octets_A_Recevoir);
  
  Serial.println("Envoi des donnees au PcDuino");
  Serial.println(Data[0]);
  Serial.println(Data[1]);
  Serial.println(Data[2]);

} // Fin du void requestEvent()

Coté PcDuino:

def Reception_Donnees_I2C():

	global Hydrometrie, Temperature, Luminosite, value

     value = i2c.read(3) #Read 3 bytes

     print value

Super !
Mais j'imagine que ce commentaire est faux:

Data[1] = Temperature; // double sur 4 octets

Oui, un oubli d’effacement