Partage
  • Partager sur Facebook
  • Partager sur Twitter

Arduino I2C - mauvaise valeur envoyée

Valeur envoyée divisée par deux

Sujet résolu
    12 juin 2019 à 20:36:48

    Bonjour,

    Je travaille actuellement sur un projet de station météo connectée.

    La station météo est composée de deux microcontrôleurs: un Arduino UNO et un ESP8266MOD D1 mini. Pour l'instant, il n'y a comme capteur qu'un DHT22 mais, par la suite, je prévois d'en rajouter d'autres.

    La carte Aduino s'occupe de récupérer toutes les mesures des capteurs. L'ESP s'occupe de la transmission wifi avec mon serveur JEEDOM.

    Les deux cartes sont reliés via un bus I2C: l'ESP8266 est le maître, l'arduino UNO est l'esclave.


    Mon problème:

    Le problème que je rencontre est que, lorsque la carte maître demande une mesure, la valeur est systématiquement reçue divisée par deux.

    Voici le programme de l'ESP8266MOD

    //Microcontrôleur maître - ESP8266MOD
    #include <Wire.h> #include <ESP8266WiFi.h> #include <ESP8266HTTPClient.h> #define I2C_ADRESSE_ARDUINO 20 #define INTERVALLE_ACTUALISATION_MIN 10 //Paramétrage réseau const char* ssid = "SSID"; // SSID const char* password = "MOT DE PASSE"; // mot de passe const String host = ""; // IP serveur //Paramétrage JEEDOM const int idTemperature = 18; float temperature; byte demanderMesureI2C() { byte mesure = 255; //On réclame la mesure (1 octet demandé) Wire.requestFrom(I2C_ADRESSE_ARDUINO, 1); //On réceptionne la mesure while(Wire.available()) { mesure = Wire.read(); } return mesure; } int envoiMesureJeedom(int idMesure, float valeur) { HTTPClient http; String requete, urlPage, plugin, apikey, mesure; urlPage = "http://" + host + "/core/api/jeeApi.php?"; plugin = "plugin=virtual&type=virtual"; apikey = "&apikey=APIKEY"; mesure = String("&id=") + String(idMesure) + String("&value=") + String(valeur); requete = urlPage + plugin + apikey + mesure; http.begin(requete); //On indique le contenu de la requête à envoyer return http.GET(); //On utilise la méthode GET et renvoie le résultat } void setup() { delay(2000); Serial.begin(9600); Serial.print("Connexion à "); Serial.print(ssid); //On se connecte au réseau wi-fi WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println("\nWiFi connecté"); Serial.print("Adresse IP: "); Serial.println(WiFi.localIP()); //Initialisation de l'I2C Wire.begin(); } void loop() { //On récupère la mesure temperature = demanderMesureI2C(); Serial.print("Température: "); Serial.println(temperature); //Transmission de la mesure à JEEDOM envoiMesureJeedom(idTemperature, temperature); //Intervalle d'actualisation en minutes delay(INTERVALLE_ACTUALISATION_MIN * 60 * 1000); }

     Et voici celui de l'Arduino UNO:

    //Microcontrôleur esclave - Arduino UNO
    #include <Wire.h>
    #include "DHT.h"
    
    //Paramétrage du DHT
    #define DHT_PIN 4
    #define DHT_TYPE DHT22
    
    #define I2C_ADRESSE_ARDUINO 20
    
    byte temperatureATransmettre = 255;
    
    DHT dht(DHT_PIN, DHT_TYPE);
    
    void setup() {
      //Configuration de l'I2C
      Wire.begin(I2C_ADRESSE_ARDUINO);
      Wire.onRequest(demandeMesure);
    
      Serial.begin(9600);
      dht.begin();
    }
    
    void loop(){
      float mesure = 0;
      
      //On fait les mesures
      mesure = dht.readTemperature();
    
      //Arrondi à l'entier près
      temperatureATransmettre = round((byte)mesure);
    }
    
    //Interruption déclenchée sur réclamation de données sur le bus
    void demandeMesure() {
    
      Wire.write(temperatureATransmettre);
      Serial.print("Température envoyée: ");
      Serial.println(temperatureATransmettre);
    }

    Pensant que le problème venait du capteur, j'ai modifié le code en attribuant la valeur 50 à la variable temperatureATransmettre. Le maître reçoit, à chaque prise de parole sur le bus, la valeur 25.

    J'ai refait le même test en remplaçant l'instruction:

    Wire.write(temperatureATransmettre);

    par:

    Wire.write(50);

    Mais le résultat reste le même.

    J'ai ajouté à mon circuit deux pull-up de 10kohm sur les fils de données et d'horloge sans succès.

    J'ai aussi tenté avec deux programmes I2C basiques (l'un des microcontrôleur demande à l'autre de lui envoyer un octet, l'autre lui répond en lui envoyant une valeur) mais le résultat reste le même.

    Je pourrais toujours préalablement multiplier la valeur transmise par deux, mais ça reviens à résoudre un bug en créant un bug, ce qui n'a aucun intérêt.

    Si quelqu'un a une idée, je suis preneur.

    -
    Edité par Natars 12 juin 2019 à 20:45:38

    • Partager sur Facebook
    • Partager sur Twitter
    Natars, technicien informatique
      13 juin 2019 à 12:13:58

      Bonjour,

      Tu peux essayer de jouer avec Wire.setClockStrechLimit pour voir si ça change quelque chose: https://github.com/esp8266/Arduino/issues/3977

      • Partager sur Facebook
      • Partager sur Twitter
        13 juin 2019 à 13:15:27

        Bonjour,

        Après quelques tests en lecture et écriture, tout semble rentré dans l'ordre.

        Merci bien pour la solution. :p

        Cordialement

        -
        Edité par Natars 13 juin 2019 à 18:22:59

        • Partager sur Facebook
        • Partager sur Twitter
        Natars, technicien informatique

        Arduino I2C - mauvaise valeur envoyée

        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
        • Editeur
        • Markdown