Conflit entre HX711 et autres capteurs?

Bonjour

Je suis en train de réaliser un projet à base de ESP32, capteur d'humidité DHT22, lecteur de carde SD et HX711.

Pour ma loadcell, j'utilise la lib HX711_ADC qui est celle recommandée par le vendeur et la seule qui fonctionne correctement pour mon cas.

Voici mon souci: lorsque je fais tourner un sketch exemple de la lib HX711-ADC, aucun problème. Une fois pour factor modifié, je tombe au gramme au poids effectif.

En revanche, avec le meme cablage mais tout le reste du projet en //, j'ai une valeur -20378.01 lue et elle ne bouge pas.

Dans la lib HX711_ADC il est indiqué que si le MCU est deja bien solicité, c'est mieux de le faire tourner avec un interrupt.
C'est ce que j'ai fait mais rien n'a changé.
Honnetement je commence à bloquer.
Les exemples de la libHX711_ADC fonctionnent parfaitement et sur mon projet plus rien alors que tous les indicateurs sont au vert;, aucun message d'erreur ni rien.

#include "DHT.h"
#include "FS.h"
#include "SD.h"
#include "SPI.h"
#include <ArduinoJson.h>
#include <WiFi.h>
#include "ESPAsyncWebServer.h"
#include <HX711_ADC.h>


#define DHTPIN 17     // Digital pin connected to the DHT sensor
#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321

const int HX711_dout = 16; //mcu > HX711 dout pin
const int HX711_sck = 4; //mcu > HX711 sck pin

//HX711 constructor:
HX711_ADC LoadCell(HX711_dout, HX711_sck);
volatile boolean newDataReady = false;

long pointold = 0;
long pointnew = 0;
float weight1 = 0;
float weight2 = 0;

//Webserver start
const char* ssid     = "ESP32-Access-Point";
const char* password = "123456789";

AsyncWebServer server(80);

String header;

//DHT start
DHT dht(DHTPIN, DHTTYPE);

double round2(double value) {
   return (int)(value * 100 + 0.5) / 100.0;
}

String readJSON() {
  String finalText="";
  File file = SD.open("/data/data.json", FILE_READ);

while (file.available()) {
      finalText+=(char)file.read();
    }
  
  file.close();
  Serial.print("JSON txt sent:");
  //Serial.println(finalText);
  return String(finalText);
}

//interrupt routine:
void dataReadyISR() {
  if (LoadCell.update()) {
    newDataReady = 1;
  }
}

void setup() {
  // put your setup code here, to run once:
  
  
  Serial.begin(9600);

  //HX711 setup & start
  unsigned long stabilizingtime = 2000; // preciscion right after power-up can be improved by adding a few seconds of stabilizing time
  boolean _tare = false;
  float calibrationValue = -411.65;
  LoadCell.start(stabilizingtime, _tare);
  if (LoadCell.getTareTimeoutFlag()) {
    Serial.println("Timeout, check MCU>HX711 wiring and pin designations");
    while (1);
  }
  else {
    LoadCell.setCalFactor(calibrationValue); // set calibration value (float)
    Serial.println("Startup is complete");
  }

  //interrupt HX711
  attachInterrupt(digitalPinToInterrupt(HX711_dout), dataReadyISR, FALLING);
  Serial.println("Startup is complete");

  //DHT22 begin
  dht.begin();

  //Webserver start
  Serial.print("Setting AP (Access Point)…");
  // Remove the password parameter, if you want the AP (Access Point) to be open
  WiFi.softAP(ssid, password);

  IPAddress IP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(IP);

  //SD Start
  delay(1000);
  if(!SD.begin()){
        Serial.println("Card Mount Failed");
        return;
    }
    uint8_t cardType = SD.cardType();

    if(cardType == CARD_NONE){
        Serial.println("SDSC");
    } else if(cardType == CARD_SDHC){
        Serial.println("SDHC");
    } else {
        Serial.println("UNKNOWN");
    }

  File file = SD.open("/data/pointnew.txt", FILE_READ);

  pointnew =f ile.parseInt();
  Serial.print("last starting point:");
  Serial.println(pointnew);
  file.close();

  //Webserver commands
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(SD, "/index.html", "text/html");
  });
  server.serveStatic("/", SD, "/");

  server.on("/JSON", HTTP_GET, [](AsyncWebServerRequest *request){
  request->send_P(200, "text/plain", readJSON().c_str());
  });
  server.begin();
  
}

void loop() {
  // put your main code here, to run repeatedly:
  delay(2000);
  
  //Read DHT22
  float h = dht.readHumidity();
  float t = dht.readTemperature();
  if (isnan(h) || isnan(t)) {
    Serial.println(F("Failed to read from DHT sensor!"));
    return;
  } 
  //If interrupt, read HX711
  if (newDataReady) {
    weight1 = LoadCell.getData();
    Serial.println(weight1);
    newDataReady = 0;
  }
  
  //Debug variables
  Serial.print(F("pointnew:"));
  Serial.print(pointnew);
  Serial.print(F("Humidity: "));
  Serial.print(h);
  Serial.print(F("%  Temperature: "));
  Serial.print(t);
  Serial.print(F("°C "));
  Serial.print(F("weight1:"));
  Serial.println(weight1);
  pointnew = pointnew +1;


  //JSON
  DynamicJsonDocument doc(10000);

  // Read the file
  File file = SD.open("/data/data.json", FILE_READ);
  deserializeJson(doc, file);
  file.close();
  
  
  // Append new element
  JsonObject obj = doc.createNestedObject();
  obj["point"] = pointnew;
  obj["temp"] = round2(t);
  obj["humidity"] = round2(h);
  obj["weight1"] = round2(weight1);
  obj["weight2"] = round2(weight2);

  // Write the file
  file = SD.open("/data/data.json", FILE_WRITE);
  serializeJson(doc, file);
  file.close();
  
  //SD.open("/data/pointnew.txt", FILE_REMOVE);
  File file2 = SD.open("/data/pointnew.txt", FILE_WRITE);
  file2.print(pointnew);
  //Serial.println(pointnew);
  file2.close();

}

Merci pour votre aide

Bonsoir @vibram

Ton message n'étaint pas à sa place dans le sous forum explicitement dédié "à la présentation de projets complets et fonctionnels", je le déplace à l'endroit approprié comme précisié dans les Bonnes Pratiques du Forum

1 Like

Dans la lib HX711_ADC il est indiqué que si le MCU est deja bien solicité, c'est mieux de le faire tourner avec un interrupt.
C'est ce que j'ai fait mais rien n'a changé.

Ta routine d'interruption calquée sur ce qui fait avec les microcontrolleurs 8 bits AVR ne parait pas vraiment adaptée aux ESP32

Prends modèle sur l'exemple GPIOInterrupt.ini fourni avec l'extension ESP32 pour Arduino
Tu y verras un attribut spécifique à utiliser pour déclarer les routines d'interruption

Dans des tutoriels un peu plus anciens l'attribut est different mais il a le même rôle : implanter en RAM la routine d'interruption.

Merci je vais jeter un œil.
Demain je mettrai une version sans interruption qui me donne exactement le même résultat. Je pense que ça doit venir d'ailleurs...

Je mets le sketch demain matin

Voici le sketch sans interruption qui me donne le meme résultat:

#include "DHT.h"
#include "FS.h"
#include "SD.h"
#include "SPI.h"
#include <ArduinoJson.h>
#include <WiFi.h>
#include "ESPAsyncWebServer.h"
#include <HX711_ADC.h>


#define DHTPIN 17     // Digital pin connected to the DHT sensor
#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321

const int HX711_dout = 16; //mcu > HX711 dout pin
const int HX711_sck = 4; //mcu > HX711 sck pin

//HX711 constructor:
HX711_ADC LoadCell(HX711_dout, HX711_sck);


long pointold = 0;
long pointnew = 0;
float weight1 = 0;
float weight2 = 0;

//Webserver start
const char* ssid     = "ESP32-Access-Point";
const char* password = "123456789";

AsyncWebServer server(80);

String header;

//DHT start
DHT dht(DHTPIN, DHTTYPE);

double round2(double value) {
   return (int)(value * 100 + 0.5) / 100.0;
}

String readJSON() {
  String finalText="";
  File file = SD.open("/data/data.json", FILE_READ);

while (file.available()) {
      finalText+=(char)file.read();
    }
  
  file.close();
  Serial.print("JSON txt sent:");
  //Serial.println(finalText);
  return String(finalText);
}

void setup() {
  // put your setup code here, to run once:
  
  
  Serial.begin(9600);

  //HX711 setup & start
  unsigned long stabilizingtime = 2000; // preciscion right after power-up can be improved by adding a few seconds of stabilizing time
  boolean _tare = false;
  float calibrationValue = -411.65;
  LoadCell.start(stabilizingtime, _tare);
  if (LoadCell.getTareTimeoutFlag()) {
    Serial.println("Timeout, check MCU>HX711 wiring and pin designations");
    while (1);
  }
  else {
    LoadCell.setCalFactor(calibrationValue); // set calibration value (float)
    Serial.println("Startup is complete");
  }

  //interrupt HX711
  Serial.println("Startup is complete");

  //DHT22 begin
  dht.begin();

  //Webserver start
  Serial.print("Setting AP (Access Point)…");
  // Remove the password parameter, if you want the AP (Access Point) to be open
  WiFi.softAP(ssid, password);

  IPAddress IP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(IP);

  //SD Start
  delay(1000);
  if(!SD.begin()){
        Serial.println("Card Mount Failed");
        return;
    }
    uint8_t cardType = SD.cardType();

    if(cardType == CARD_NONE){
        Serial.println("SDSC");
    } else if(cardType == CARD_SDHC){
        Serial.println("SDHC");
    } else {
        Serial.println("UNKNOWN");
    }

  File file = SD.open("/data/pointnew.txt", FILE_READ);

  pointnew = file.parseInt();
  Serial.print("last starting point:");
  Serial.println(pointnew);
  file.close();

  //Webserver commands
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(SD, "/index.html", "text/html");
  });
  server.serveStatic("/", SD, "/");

  server.on("/JSON", HTTP_GET, [](AsyncWebServerRequest *request){
  request->send_P(200, "text/plain", readJSON().c_str());
  });
  server.begin();
  
}

void loop() {
  // put your main code here, to run repeatedly:
  delay(2000);
  static boolean newDataReady = false;

  if (LoadCell.update()) {
    newDataReady = true;
    Serial.println("newdataready");
  }
  
  //Read DHT22
  float h = dht.readHumidity();
  float t = dht.readTemperature();
  if (isnan(h) || isnan(t)) {
    Serial.println(F("Failed to read from DHT sensor!"));
    return;
  } 
  //read HX711
  if (newDataReady) {
    weight1 = LoadCell.getData();
    Serial.println(weight1);
    newDataReady = 0;
  }
  
  //Debug variables
  Serial.print(F("pointnew:"));
  Serial.print(pointnew);
  Serial.print(F("Humidity: "));
  Serial.print(h);
  Serial.print(F("%  Temperature: "));
  Serial.print(t);
  Serial.print(F("°C "));
  Serial.print(F("weight1:"));
  Serial.println(weight1);
  pointnew = pointnew +1;


  //JSON
  DynamicJsonDocument doc(10000);

  // Read the file
  File file = SD.open("/data/data.json", FILE_READ);
  deserializeJson(doc, file);
  file.close();
  
  
  // Append new element
  JsonObject obj = doc.createNestedObject();
  obj["point"] = pointnew;
  obj["temp"] = round2(t);
  obj["humidity"] = round2(h);
  obj["weight1"] = round2(weight1);
  obj["weight2"] = round2(weight2);

  // Write the file
  file = SD.open("/data/data.json", FILE_WRITE);
  serializeJson(doc, file);
  file.close();
  
  //SD.open("/data/pointnew.txt", FILE_REMOVE);
  File file2 = SD.open("/data/pointnew.txt", FILE_WRITE);
  file2.print(pointnew);
  //Serial.println(pointnew);
  file2.close();

}

Ce que je ne comprends pas c'est qu'on initialise bien la valeur à 0 et ensuite elle passe à -20K puis ne change plus.
Voici un CC du serial monitor:

Startup is complete
Setting AP (Access Point)…AP IP address: 192.168.4.1
SDHC
last starting point:804
newdataready
-20378.01
pointnew:804Humidity: 59.60%  Temperature: 7.20°C weight1:-20378.01
newdataready
-20378.01
pointnew:805Humidity: 59.50%  Temperature: 7.00°C weight1:-20378.01
newdataready
-20378.01
pointnew:806Humidity: 59.50%  Temperature: 7.00°C weight1:-20378.01
newdataready
-20378.01

Vous noterez la température agréable pour bricoler ... :smiley:

Je me permets un petit up si quelqu'un a la motivation de regarder la version sans interruption.
Jai encore passé du temps dessus hier sans succès.

Bonjour @vibram

etudier un code qui utilise une bibliothèque pour HX711 inconnue du plus grand nombre demande 'un certain temps', il n'est pas évident d'en disposer.....

es-tu intervenu sur le fichier config..h de la bibilothèque , en particulier pour valider le delay comme recommandé pour l'ESP32 ?

1)Peut être tenter d'agir sur config.h pour que la bibliothèque accapare moins l'ESP32 ?

2)Cesser de travailler en aveugle , se doter d'un petit analyseur logique pour découvrir ce qui se passe sur DOUT et SCK quand le HX711 'décroche' ?

Bonjour,

j'ai tenté une autre voie, celle de ralentir la cadence mais avec un code propre car la source que j'avais sur le HX711 utilisait une version de code qui n'était plus supportées.
code:

#include "DHT.h"
#include "FS.h"
#include "SD.h"
#include "SPI.h"
#include <ArduinoJson.h>
#include <WiFi.h>
#include "ESPAsyncWebServer.h"
#include <HX711_ADC.h>

#define DHTPIN 17     // Digital pin connected to the DHT sensor
#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321

const int HX711_dout = 16; //mcu > HX711 dout pin
const int HX711_sck = 4; //mcu > HX711 sck pin

//HX711 constructor:
HX711_ADC LoadCell(HX711_dout, HX711_sck);


long pointold = 0;
long pointnew = 0;
float weight1 = 0;
float weight2 = 0;

//Webserver start
const char* ssid     = "ESP32-Access-Point";
const char* password = "123456789";

AsyncWebServer server(80);

String header;

//DHT start
DHT dht(DHTPIN, DHTTYPE);

double round2(double value) {
   return (int)(value * 100 + 0.5) / 100.0;
}

String readJSON() {
  String finalText="";
  File file = SD.open("/data/data.json", FILE_READ);

while (file.available()) {
      finalText+=(char)file.read();
    }
  
  file.close();
  Serial.print("JSON txt sent:");
  //Serial.println(finalText);
  return String(finalText);
}

void setup() {
  // put your setup code here, to run once:
  
  
  Serial.begin(9600);
  setCpuFrequencyMhz(80);
  int cpuSpeed = getCpuFrequencyMhz();
  Serial.print("Frequence du CPU :");
  Serial.println(cpuSpeed);

  //HX711 setup & start
  unsigned long stabilizingtime = 2000; // preciscion right after power-up can be improved by adding a few seconds of stabilizing time
  boolean _tare = false;
  float calibrationValue = -411.65;
  LoadCell.start(stabilizingtime, _tare);
  if (LoadCell.getTareTimeoutFlag()) {
    Serial.println("Timeout, check MCU>HX711 wiring and pin designations");
    while (1);
  }
  else {
    LoadCell.setCalFactor(calibrationValue); // set calibration value (float)
    Serial.println("Startup is complete");
  }

  //interrupt HX711
  Serial.println("Startup is complete");

  //DHT22 begin
  dht.begin();

  //Webserver start
  Serial.print("Setting AP (Access Point)…");
  // Remove the password parameter, if you want the AP (Access Point) to be open
  WiFi.softAP(ssid, password);

  IPAddress IP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(IP);

  //SD Start
  delay(1000);
  if(!SD.begin()){
        Serial.println("Card Mount Failed");
        return;
    }
    uint8_t cardType = SD.cardType();

    if(cardType == CARD_NONE){
        Serial.println("SDSC");
    } else if(cardType == CARD_SDHC){
        Serial.println("SDHC");
    } else {
        Serial.println("UNKNOWN");
    }

  File file = SD.open("/data/pointnew.txt", FILE_READ);

  pointnew = file.parseInt();
  Serial.print("last starting point:");
  Serial.println(pointnew);
  file.close();

  //Webserver commands
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(SD, "/index.html", "text/html");
  });
  server.serveStatic("/", SD, "/");

  server.on("/JSON", HTTP_GET, [](AsyncWebServerRequest *request){
  request->send_P(200, "text/plain", readJSON().c_str());
  });
  server.begin();
  
}

void loop() {
  // put your main code here, to run repeatedly:
  delay(2000);
  static boolean newDataReady = false;

  if (LoadCell.update()) {
    newDataReady = true;
    Serial.println("newdataready");
  }
  
  //Read DHT22
  float h = dht.readHumidity();
  float t = dht.readTemperature();
  if (isnan(h) || isnan(t)) {
    Serial.println(F("Failed to read from DHT sensor!"));
    return;
  } 
  //read HX711
  if (newDataReady) {
    weight1 = LoadCell.getData();
    Serial.println(weight1);
    newDataReady = 0;
  }
  
  //Debug variables
  Serial.print(F("pointnew:"));
  Serial.print(pointnew);
  Serial.print(F("Humidity: "));
  Serial.print(h);
  Serial.print(F("%  Temperature: "));
  Serial.print(t);
  Serial.print(F("°C "));
  Serial.print(F("weight1:"));
  Serial.println(weight1);
  pointnew = pointnew +1;


  //JSON
  DynamicJsonDocument doc(10000);

  // Read the file
  File file = SD.open("/data/data.json", FILE_READ);
  deserializeJson(doc, file);
  file.close();
  
  
  // Append new element
  JsonObject obj = doc.createNestedObject();
  obj["point"] = pointnew;
  obj["temp"] = round2(t);
  obj["humidity"] = round2(h);
  obj["weight1"] = round2(weight1);
  obj["weight2"] = round2(weight2);

  // Write the file
  file = SD.open("/data/data.json", FILE_WRITE);
  serializeJson(doc, file);
  file.close();
  
  //SD.open("/data/pointnew.txt", FILE_REMOVE);
  File file2 = SD.open("/data/pointnew.txt", FILE_WRITE);
  file2.print(pointnew);
  //Serial.println(pointnew);
  file2.close();

}

Résultat identique pourtant on voit qu'on tourne bien a 80Mz

Frequence du CPU :80
Startup is complete
Startup is complete
Setting AP (Access Point)…AP IP address: 192.168.4.1
SDHC
last starting point:847
newdataready
-20378.01
pointnew:847Humidity: 48.50%  Temperature: 5.70°C weight1:-20378.01
newdataready
-20378.01

Je vais faire un test en ralentissant encore plus
edit: on ne peut pas aller plus bas que 80 en fait

Bonsoir,

Bon je suis reparti sur la librairie standard HX711 et le CPU a 80Mz
Ca fonctionne bien :slight_smile:

Maintenant je dois regarder comment gérer le sketch pour passer toutes les taches sous interruption toutes les heures pour ne pas polluer l'access point

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.