Je réalise en ce moment un programme qui a pour but de tester si des sondes de température fonctionne correctement. Les sondes sont des esclaves qui communique par bus I2C. Le programme que j'ai actuellement me permet de lire les valeurs sur les sonde qui fonction, mais si je branche mon groupe de sonde défectueuse, le programme semble se bloquer et plus rien ne se passe. Je me retrouve obligée de recharger le programme pour pouvoir réalisé une nouvelle mesure.
J'ai l'impression que le programme reste bloquer dans une des demandes de communication (peut-être à cause du manque de réponse). Sauriez-vous s'il est possible d'avoir une sortie de cette communication si l'esclave ne répond pas ?
Voici mon code, il existe peut être une amélioration qui puisse régler mon problème
#define Sensor1Adress 0x48
#define Sensor2Adress 0x49
#include <Wire.h>
// Pin distribution
const int ButtonPin = 4 ;
const int PinSCL = 3 ;
const int PinSDA = 2 ;
// setting variable
int ButtonState = 0 ; // Button to start temperature mesurement
int MemoState = 0 ; // Memory of the last state of the button, allows a mesurement to be made only on a rising edge
float SensorValue = 0 ; // Value of the sensor at the end of the mesurement
float InterValue = 0 ; // Intermediate value, using for the calcul of the temperature
byte SensorValueMSB = 0 ; // Most Significant Byte provided by the sensor
byte SensorValueLSB = 0 ; // Least Significant Byte provided by the sensor
boolean a = 0 ;
boolean b = 0 ;
void setup() {
// initialize the pushbutton pin as an input :
pinMode(ButtonPin, INPUT_PULLUP);
//I2C communication sensors
Wire.begin(); // Initialise serial communication, set baud rate = 9600
Serial.begin(9600); // Start I2C Transmission
Wire.beginTransmission(Sensor1Adress); // Select configuration register
Wire.write(0x01); // Continuous conversion, comparator mode, 12-bit resolution
Wire.write(0x60);
Wire.write(0xA0); // Stop I2C Transmission
Wire.endTransmission();
a = 1 ;
Wire.beginTransmission(Sensor2Adress); // Select configuration register
Wire.write(0x01); // Continuous conversion, comparator mode, 12-bit resolution
Wire.write(0x60);
Wire.write(0xA0); // Stop I2C Transmission
Wire.endTransmission();
b = 1 ;
delay(300);
}
void loop() {
ButtonState = digitalRead(ButtonPin);
if(ButtonState == LOW & ButtonState != MemoState){
if(a==1){
Serial.println ("Sensor 1 ready") ;
a=0 ;
}
if(b==1){
Serial.println ("Sensor 2 ready") ;
b=0 ;
}
Serial.print("Debut de mesure");
Serial.println();
Serial.print("Sonde de temperature 1 :");
ReadTemp (Sensor1Adress) ;
Serial.print("Sonde de temperature 2 :");
ReadTemp (Sensor2Adress) ;
}
MemoState =ButtonState ;
}
// Reading temperature
int ReadTemp (int adress) {
Wire.beginTransmission(adress) ; // Request the temperature value from one of the sensor
Wire.write(0x00) ;
Wire.endTransmission() ;
Wire.requestFrom(adress, 2) ;
if (2 <= Wire.available()) { // Reading the answer from the slave
SensorValueMSB = Wire.read() ;
SensorValueLSB = Wire.read() ;
}
InterValue = (SensorValueMSB*256 + SensorValueLSB)/16 ; // Transform the binary answer on a decimal one
SensorValue = InterValue*0.0625; // Passing value on degre celsuis
Serial.print(SensorValue);
Serial.println(" degres Celsuis");
Je dois faire quelque chose de faux, car cela ne change rien à mon problème.
Jai essayé de recopier le code de la référence sur le mien. Peut importe les test que je fais (tester une sonde qui marche avant la défectueuse ou directement un sonde défectueuse), dés qu'il tombe sur une partie du code ou il faut interroger ou écrire à la sonde défectueuse le programme se bloque
void setup() {
#if defined(WIRE_HAS_TIMEOUT)
Wire.setWireTimeout(3000 /* us */, true /* reset_on_timeout */);
#endif
// initialize the pushbutton pin as an input :
pinMode(ButtonPin, INPUT_PULLUP);
//I2C communication sensors
Wire.begin(); // Initialise serial communication, set baud rate = 9600
Serial.begin(9600); // Start I2C Transmission
Wire.beginTransmission(Sensor1Adress); // Select configuration register
Wire.write(0x01); // Continuous conversion, comparator mode, 12-bit resolution
Wire.write(0x60);
Wire.write(0xA0); // Stop I2C Transmission
byte error1 = Wire.endTransmission(); // run transaction
if (error1) {
a = 1 ;
}
Wire.beginTransmission(Sensor2Adress); // Select configuration register
Wire.write(0x01); // Continuous conversion, comparator mode, 12-bit resolution
Wire.write(0x60);
Wire.write(0xA0); // Stop I2C Transmission
byte error2 = Wire.endTransmission(); // run transaction
if (error2) {
b = 1 ;
}
delay(300);
}
void loop() {
ButtonState = digitalRead(ButtonPin);
if(ButtonState == LOW & ButtonState != MemoState){
if(a==1){
Serial.println ("Erreur1") ;
a=0 ;
}
if(b==1){
Serial.println ("erreur2") ;
b=0 ;
}
Serial.print("Debut de mesure");
Serial.println();
Serial.print("Sonde de temperature 1 :");
ReadTemp (Sensor1Adress) ;
#if defined(WIRE_HAS_TIMEOUT)
Wire.clearWireTimeoutFlag();
#endif
byte len = Wire.requestFrom(8, 1); // request 1 byte from device #8
if (len == 0) {
Serial.println("Error occured when reading");
#if defined(WIRE_HAS_TIMEOUT)
if (Wire.getWireTimeoutFlag())
Serial.println("It was a timeout");
#endif
}
delay(100);
Serial.print("Sonde de temperature 2 :");
ReadTemp (Sensor2Adress) ;
#if defined(WIRE_HAS_TIMEOUT)
Wire.clearWireTimeoutFlag();
#endif
byte len1 = Wire.requestFrom(8, 1); // request 1 byte from device #8
if (len1 == 0) {
Serial.println("Error occured when reading");
#if defined(WIRE_HAS_TIMEOUT)
if (Wire.getWireTimeoutFlag())
Serial.println("It was a timeout");
#endif
}
delay(100);
}
MemoState =ButtonState ;
}
// Reading temperature
int ReadTemp (int adress) {
Wire.beginTransmission(adress) ; // Request the temperature value from one of the sensor
Wire.write(0x00) ;
byte error = Wire.endTransmission(); // run transaction
if (error) {
Serial.println("Error occured when writing");
if (error == 5)
Serial.println("It was a timeout");
}
Wire.requestFrom(adress, 2) ;
if (2 <= Wire.available()) { // Reading the answer from the slave
SensorValueMSB = Wire.read() ;
SensorValueLSB = Wire.read() ;
}
InterValue = (SensorValueMSB*256 + SensorValueLSB)/16 ; // Transform the binary answer on a decimal one
SensorValue = InterValue*0.0625; // Passing value on degre celsuis
Serial.print(SensorValue);
Serial.println(" degres Celsuis");
}
J'ai essayé de tester directement l'exemple donner dans la reference : [setWireTimeout() - Arduino Reference]
Mais ce programme ne marche pas sur mon pc. Après investigation, je crois que le problème vient de ma version de la librairie, j'ai essayé de la mettre à jour directement depuis le logiciel, mais ça ne semble rien faire.
Le ".setWireTimeout" reste en gris contrairement aux autres.
J'ai aussi lu qu'elle pouvait ne pas être disponible pour toutes les plateformes, mais je n'ai pas pu trouvé les quels exactement.
Est-ce que quelqu'un saurait me dire lesquels peuvent être utilisée ?
La librairie Wire fait partie du package standard.
Pour quelle plateforme développes-tu?
Quelle version de l'IDE?
Qu'entends-tu par sondes défectueuses?
En principe s'il n'y a pas de sonde sur la ligne ou si une sonde ne répond pas le système n'est pas bloqué. Le scanner de bus I²C fonctionne sans utiliser le timeout et il ne plante pas. Par contre, si un périphérique verrouille le bus à zéro, là il peut y avoir blocage.
J'ai lu que la première version du package Wire ne comprenait pas le timeout et la librairie sur mon pc date de 2012, en l'ouvrant comme dossier texte je n'ai rien trouver sur ce point.
Je travaille sur un arduino micro avec la version 1.8.6 (mise à jour hier, avant ce devait être le version 1.6.5)
Mon programme permet de tester des groupes de 2 sondes de température tmp112. Pour mes tests j'ai trois groupes de sondes, deux pour lesquels le programme fonctionne et me donne leur température. Et le dernier qui ne fonctionne pas et fait planter le programme.
Pour tester ce qui ne marche pas, j'ai ajouté une ligne de texte à afficher entre chacune des lignes du code et j'ai pu voir qu'il se bloque systématiquement sur le "Wire.endTransmission()"