Communication Raspberry <-> Arduino via bus I2C ça marche un peu puis erreur

Bonjour,

Je tente de faire communiquer un Raspberry avec un Arduino via un bus I2C.
Je me suis inspiré d’un tuto, voici le code Arduino :

#include <Wire.h>
#include <RCSwitch.h>
#include <RH_ASK.h>
unsigned long prise_1_OFF  = 4527420;
unsigned long prise_1_ON   = 4527411;
int prise_1_Status = 3;
unsigned long prise_2_OFF  = 4527564;
unsigned long prise_2_ON   = 4527555;
int prise_2_Status = 3;
unsigned long prise_3_OFF  = 4527884;
unsigned long prise_3_ON   = 4527875;
int prise_3_Status = 3;
#define SLAVE_ADDRESS 0x1a
int dataReceived = 0;
String inData="";
RCSwitch mySwitch = RCSwitch();
RH_ASK driver(2000, 2, 12);
void setup() {
    Serial.begin(9600);
    Wire.begin(SLAVE_ADDRESS);
    Wire.onReceive(receiveData);
    Wire.onRequest(sendData);
  mySwitch.enableTransmit(12);
  mySwitch.setPulseLength(178);
  if (!driver.init())
    Serial.println("init RadioHead (433 mhz) failed");
}
void loop() {
    delay(100);
}
void receiveData(int byteCount){
    int i=0;
    int octetReception=0;
    char caractereRecu=0;
    inData="";
    while(Wire.available()) {
        octetReception = Wire.read();
        caractereRecu = char(octetReception);
        inData = inData+String(caractereRecu);
        Serial.print("Donnee recue : ");
        Serial.println(octetReception);
        Serial.println(caractereRecu);
        i++;
    }
    Serial.println(inData);
    int pos_equal=inData.indexOf('=');
    Serial.println(pos_equal);
    Serial.println(inData.substring(0,pos_equal));
    Serial.println(inData.substring(pos_equal+1));
    char *tab = new char[inData.substring(pos_equal+1).length() + 1];
    StringToChar(inData.substring(pos_equal+1), tab);
    unsigned long  code=atoll(tab);
        Serial.print("Code recue : ");
        Serial.println(code);
    mySwitch.send(code, 24);
}
void sendData(){
        Serial.print("Donnee to send : ");
        Serial.println(inData);
//    int envoi = dataReceived + 1;
//    Wire.write(envoi);
}
unsigned long atoll(const char* ptr) {
  unsigned long result = 0;
  Serial.print("ptr=");
  Serial.println(ptr);
  while (*ptr && isdigit(*ptr)) {
    result *= 10;
    result += *ptr++ - '0';
  }
  Serial.print("result=");
  Serial.println(result);
  return result;
}
void StringToChar(const String& s, char* tab)
{
  int i;
  for(i=0; i < s.length(); ++i)
    tab[i] = s[i];
  tab[i] = '\0';
}

Voici le code du raspberry :

#!/usr/bin/python
import smbus
import time
import sys

Remplacer 0 par 1 si nouveau Raspberry

bus = smbus.SMBus(1)
address = 0x00

def switcher1(argument):
switcher = {
« 1 »: « 4527420 »,
« 2 »: « 4527411 »,
« 3 »: « 4527564 »,
« 4 »: « 4527555 »,
« 5 »: « 4527884 »,
« 6 »: « 4527875 »
}
return switcher.get(argument, « nothing »)

def convertStrToLong(strChaine):
print(« strChaine= »+strChaine)
res=0
for c in strChaine:
res=res*10
res+=+atoi©
print(« res= »+str(res))
return(res)
def convertStrToListHex(strChaine):
print(« strChaine= »+strChaine)
lstHex = []
for c in strChaine:
lstHex.append(ord©)
print(« lstHex= »)
print(lstHex)
return lstHex

print(sys.argv[1])
address = eval(‹ 0x ›+sys.argv[1])
print(str(address))
while 1:
print « Envoi de la valeur : "
print « 1) prise_1_OFF = 4527420 »
print « 2) prise_1_ON = 4527411 »
print « 3) prise_2_OFF = 4527564 »
print « 4) prise_2_ON = 4527555 »
print « 5) prise_3_OFF = 4527884 »
print « 6) prise_3_ON = 4527875 »
print( »")
reponse = raw_input(« Votre choix »)
print(reponse)
print(switcher1(reponse))
#bus.write_byte(address, « test i2c »)
to_send=convertStrToListHex(« 433MHZ= »+switcher1(reponse))
print(to_send)
bus.write_i2c_block_data(address, 0, to_send)
# Pause de 1 seconde pour laisser le temps au traitement de se faire
time.sleep(1)
reponse = bus.read_byte(address)
print "La reponse de l’arduino : ", reponse

i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: – -- – -- – -- – -- – -- – -- –
10: – -- – -- – -- – -- – -- 1a – -- – -- –
20: – -- – -- – -- – -- – -- – -- – -- – --
30: – -- – -- – -- – -- – -- – -- – -- – --
40: – -- – -- – -- – -- – -- – -- – -- – --
50: – -- – -- – -- – -- – -- – -- – -- – --
60: – -- – -- – -- – -- – -- – -- – -- – --
70: – -- – -- – -- – --

Je fais tourner le code plusieurs fois sans problème puis à un moment j’ai l’erreur :
Traceback (most recent call last):
File « ./i2c.py », line 56, in
bus.write_i2c_block_data(address, 0, to_send)
IOError: [Errno 121] Remote I/O error

Ensuite, j’ai :
i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: 03 – -- – -- – -- – -- – -- – --
10: – -- – -- – -- – -- – -- – -- – -- – --
20: – -- – -- – -- – -- – -- – -- – -- – --
30: – -- – -- – -- – -- – -- – -- – -- – --
40: – -- – -- – -- – -- – -- – -- – -- – --
50: – -- – -- – -- – -- – -- – -- – -- – --
60: – -- – -- – -- – -- – -- – -- – -- – --
70: – -- – -- – -- – --

et si je recommence :
i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: – -- – -- – -- – -- – -- – -- –
10: – -- – -- – -- – -- – -- – -- – -- – --
20: – -- – -- – -- – -- – -- – -- – -- – --
30: – -- – -- – -- – -- – -- – -- – -- – --
40: – -- – -- – -- – -- – -- – -- – -- – --
50: – -- – -- – -- – -- – -- – -- – -- – --
60: – -- – -- – -- – -- – -- – -- – -- – --
70: – -- – -- – -- – --

Le nombre de fois où je peux envoyer des messages sur le bus est variable mais parcontre le fait qu’àprès l’erreur, la commande i2cdetect trouve l’adresse 3 puis si on la relance plus d’adresse du tout, ça c’est à chaque fois.

Quelqu’un a-t-il déjà eu ce genre de problème ?
Et une autre question, comment doit-on mettre le code ?

Amicalement,
Jean-Paul

Salut,

Désolé de te faire une fausse joie avec l’arrivée d’un nouveau message…
Ton sujet m’interesse, j’ai une arduino et je pourrais éventuellement tester mais elle est buggué plus moyen de télécharger le moindre code vers ma Uno. je regarde ca et je testerais de mettre en place une com entre les deux pour tester.

aurais-tu un liens du tuto que tu as suivi… as tu vérifié tes câblages… (mauvais contact, longueur de fil…) je ne sais pas du tout le côté physique de ton installation…

Pour ce qui est du code à mettre… je ne comprend pas bien la question ?

Bonjour,

En creusant un peu, j’ai lu qu’il pouvait être nécessaire d’ajouter des résistances de rappel sur les lignes SDA et SCL du bus. Depuis que j’ai mis des résistances de 4,7 K reliées au +, il semble que les problèmes ont disparus.

Amicalement,
Jean-Paul
Ps : pour ma question :
Et une autre question, comment doit-on mettre le code ?
je parlais d’insérer du code dans un post de ce forum.

Bon, j’ai crié victoire un peu tôt, si ça les résistances ont amélioré la situation en réduisant la fréquence des erreurs, j’ai à nouveau eu des erreurs.
J’ai modifié el fichier :
/sys/module/i2c_bcm2708/parameters/combined
pour y mettre un Y à la place d’un N
ça semble aller mieux avec un de mes scripts qui passe à tous les coups alors qu’un autre provoque une erreur presque systématiquement. Je compare et je reviendrai ici si je trouve quelque chose.

Salut, pour placer un code formaté dans un message :

exemple de code
il suffit simplement de placer 4 espaces devant la ligne
attention il faut également une ligne vide entre le texte qui
précède ton code. C'est à dire un simple "retour chariot".

Par contre pour revenir en mode texte il suffit simplement de ne pas placer 4 espaces avant la ligne et tu n’est pas obligé d’avoir un retour chariot vide après ton code.

voici une capture d’écran de mon message.


Bonjour,

Merci, je saurai pour la prochaine fois.

Pour mon problème, si le fait de mettre un Y à la place d’un N dans le fichier :

/sys/module/i2c_bcm2708/parameters/combined 

a sensiblement amélioré les choses, j’ai encore l’erreur. Moins souvent mais je l’ai encore.
Bonne journée, amicalement,
Jean-Paul

Bonjour,
Je pense avoir trouvé une solution, mon montage ne provoque plus d’erreurs deuis plusieurs jours. Il m’a suffit de modifier la vitesse du bus, voici un extrait de mon fichier /boot/config.txt :
#uncomment to overclock the arm. 700 MHz is the default.
#arm_freq=800

# Uncomment some or all of these to enable the optional hardware interfaces
dtparam=i2c_arm=on
dtparam=i2c_baudrate=10000
#dtparam=i2s=on
#dtparam=spi=on

# Uncomment this to enable the lirc-rpi module