I2C => Problème pour récupérer plus d'un octet sur un esclave

Bonjour,

Je suis actuellement sur une aplication avec 5 ARDUINO UNO, qui communiquent en I2C.
Mes commandes du Maitre vers les esclaves marche bien.
Et les retours vers le maitre en utilisant => Wire.write("ABCD")
fonctionne aussi.

Mais je n'arrive pas à récupérer plus de 1 octet de valeurs (en 8bits) avec la fonction: Wire.requestFrom(slave_adress, 4) // Par exemple.

Voici mes bouts de code pour récupérer des valeurs. Avez vous une solution? MERCI

MAITRE:

void setup(){
Wire.begin(0); // le Maitre est sur l'adresse #0
}

void loop(){
Wire.requestFrom(slave, 4);
s_DAT1 = Wire.read();

s_DAT2 = Wire.read();

s_DAT3 = Wire.read();

s_DAT4 = Wire.read();

}

SLAVE:

void setup(){
Wire.begin(slave);
Wire.onRequest(Transmission_I2C);
}

void loop(){

}

void Transmission_I2C(){
Wire.write(DATA1);
Wire.write(DATA2);
Wire.write(DATA3);
Wire.write(DATA4);
}

Peut être que la question est mal comprise mais la tu récupère 4 * 8bits donc 4 octets.

-Standby:
Peut être que la question est mal comprise mais la tu récupère 4 * 8bits donc 4 octets.

En fait avec ce code je ne récupère que la DATA4 du SLAVE, qui est atribué à s_DAT1 sur le MAITRE.

Avant je faisait du Microship (PIC16 et PIC18), et je n'avais pas de problème de ce genre, car je maitrisais l'arrivé des octets avec les "Acknoledge".

Mais sur Arduino avec la Librairie, je ne vois pas ce qu'il se passe pendant la transmission, mais le resulat du cas présenté, donne que seul le dernier Wire.write du SLAVE remonte et est stocker par le premier Wire.read du Maitre.

Je cherche donc une solution pour que la data 1 du SLAVE arrive dans la variable 1 du MAITRE, la 2 avec la 2... ect...

Symptômes bizarres

En principe, côté maître tout se joue dans la fonction requestFrom, qui attend l'arrivée de la quantité d'octets demandée ou bien l'expiration d'un time out.
Cette fonction retourne la valeur 0 si la quantité reçue ne correspond pas à celle demandée.

Il pourrait être utile de vérifier ce que retourne requestFrom

Je pense que ta fonction slave n'envoie pas un paquet de 4 octets mais 4 paquets de 1 octet. Ce qui du point de vue protocolaire n'est pas la même chose.
Essaye ça:

SLAVE:

void setup(){
    Wire.begin(slave);
    Wire.onRequest(Transmission_I2C);
}

void loop(){

}     

void Transmission_I2C(){
unsigned char donnees[]={DATA1,DATA2,DATA3,DATA4};
    Wire.write(donnees,4);
}

fdufnews:
Je pense que ta fonction slave n'envoie pas un paquet de 4 octets mais 4 paquets de 1 octet. Ce qui du point de vue protocolaire n'est pas la même chose.
Essaye ça:

SLAVE:

void setup(){
    Wire.begin(slave);
    Wire.onRequest(Transmission_I2C);
}

void loop(){

}

void Transmission_I2C(){
unsigned char donnees[]={DATA1,DATA2,DATA3,DATA4};
    Wire.write(donnees,4);
}

IMPECABLE!!!

Merci beaucoup, je n'avais pas du tout pensé à cette solution.

Effectivement je renvoyé 4 x 1 octet, et non 1 x 4 octets.

C'est quand même pas terrible d'avoir une fonction Wire.write qui a un comportement différent selon que l'on est maître ou esclave I2C.

Côté maître, on peut enchaîner les write, suivis d'un endTransmission

Au passage, il me semble que la réception côté maître se code de manière plus sécurisée ainsi :

if (requestFrom(adresse, nombre))
{
  nombre x Wire.read()
}
else //pas reçu le nombre d'octets attendus
{
  traitement de l'erreur
}

En fait le problème est dans la librairie twi qui est en-dessous de Wire.
La fonction write écrase le tampon à chaque nouveau write. Lorsque tu envoies 4 write consécutifs, seul le dernier "survit". Alors que lorsque tu passes un tableau en argument, celui-ci est copié dans le tampon d'émission.

non non le problème est bien dans Wire.cpp

Peu importe que l'appel soit Wire.write(octet) ou Wire.write(buffer,longueur)

Si on est esclave, la fonction write() déclenche immédiatement la primitive twi d'envoi
Si on est maître, la fonction write() ne fait qu'alimenter un buffer interne à la librairie Wire, et c'est la fonction endTransmission() qui déclenche la primitive twi d'envoi

Pas très homogène, tout ça...