Mesure incohérente avec Uno et HX711 à 80Hz

Bonjour,

J’effectue actuellement des mesures de force à une fréquence d’environ 40Hz et dans 1 ou 2% des cas je me retrouve avec une valeur totalement absurde. :o
Au repos par exemple lorsque je mesure 0N (après tarrage), il m’arrive par exemple de détecter 888N ou 968N (après conversion de la valeur numérique) toutes les 50 ou 100mesures. Ces entiers completement absurdes ne sont pas aléatoires puisque je retrouve à peu près toujours les mêmes.

J’utilise actuellement un montage composé d’un Arduino UNO, d’un convertisseur amplificateur HX711 et d’une cellule de force.
Mon HX711 est bien en 80Hz (j’ai ouvert manuellement la jonction au dos de la carte).

Je me demande actuellement si je n’ai pas du bruit sur des bits bien spécifiques, ce qui me ferais passer à des valeurs bien particulières.
En regardant la doc technique, j’ai vu que le bruit de la mesure était accru lorsque l’on passer de 10Hz à 80Hz, mais que cela se jouait uniquement sur les bits les moins significatifs.

Ma question est donc : est-il possible d’avoir du bruit sur des bits spécifiques? Et si non, comment cela se fait-il que j’ai un tel problème?

Ah oui, pour ne pas fonctionner completement en boîte noire je n’utilise pas la bibliothèque liée aux cellules de forces, mais mon propre programme qui lit les valeurs directement envoyées par le HX711. :smiley: Voici le sous programme que j’execute à 40Hz:

long mesure ()
{
byte data[3]={0};
byte filler = 0x00; 
unsigned long value = 0;
for (byte j = 3; j--;) {
for (char i = 8; i--;) {
digitalWrite(A0, HIGH);      
bitWrite(data[j], i, digitalRead(A1));  
digitalWrite(A0, LOW);
    }
  }
  data[2]= data[2]-200; //sorte de tarage puisqu'au repos data[2] vaut déja 243. Pas de risque de passer à 255 puis ensuite à 0. 
 value = ( static_cast<unsigned long>(filler) << 24
      | static_cast<unsigned long>(data[2]) << 16
      | static_cast<unsigned long>(data[1]) << 8
      | static_cast<unsigned long>(data[0]) );
      
 return static_cast<long>(value);
   }

Merci d’avance pour vos lumières, :slight_smile:
Arthur

arthurfr: Mon HX711 est bien en 80Hz (j'ai ouvert manuellement la jonction au dos de la carte).

Bonjour RATE est en l'air ou à VDD ?

J'ai ouvert manuellement la jonction en grattant le jumper. J'ai pas trouvé de photo adéquate, mais c'est exactement le même que sur cette carte : |500x500

J'ai coupé au milieu. mais rien relié de plus.

En mesurant avec un Ohmmetre j'avais vu que c'était déjà relié à VDD.

arthurfr: J'ai ouvert manuellement la jonction en grattant le jumper. J'ai pas trouvé de photo adéquate, mais c'est exactement le même que sur cette J'ai coupé au milieu. mais rien relié de plus.

En mesurant avec un Ohmmetre j'avais vu que c'était déjà relié à VDD.

en regardant le schema on voit que le pin RATE est mis à DVDD au travers d'une resistance 10K. donc le probleme ne vient surement pas de là. Mets ton code complet , je regarderais demain si c'est reproductible chez moi.

Merci de ton aide,

Voila le code :

#include "SparkSoftLCD.h"

#define LCD_TX 1  // LCD transmit pin
SparkSoftLCD lcd = SparkSoftLCD(LCD_TX); //LCD connected to pin 1

//Variables

long calibration=0;
long average=0; 
long intermediatevalue=0;
long finalvalue=0;

long mesure ()
{
byte data[3]={0};
byte filler = 0x00;
unsigned long value = 0;
for (byte j = 3; j--;) {
for (char i = 8; i--;) {
digitalWrite(A0, HIGH);      
bitWrite(data[j], i, digitalRead(A1));
digitalWrite(A0, LOW);
    }
  }
  data[2]= data[2]-200;
// Construct a 32-bit signed integer
 value = ( static_cast<unsigned long>(filler) << 24
      | static_cast<unsigned long>(data[2]) << 16
      | static_cast<unsigned long>(data[1]) << 8
      | static_cast<unsigned long>(data[0]) );
     
return static_cast<long>(value);
   }

//Initialisation Programm  
void setup() {
pinMode(LCD_TX, OUTPUT); 
pinMode(A0, OUTPUT);//A0 clock
pinMode(A1, INPUT); //A1 read
delay(1000);
lcd.begin(9600);
lcd.clear();  
lcd.cursor(0); 
lcd.print("Calibration Programm");
lcd.cursorTo(3,1);
lcd.print("decharger svp");
delay(10000);
lcd.clear();
lcd.print("calibration : "); 
calibration=mesure();
delay(500);´
calibration=calibration+mesure();
delay(500);
calibration=calibration+mesure();
delay(500);
calibration=calibration+mesure();
average=calibration/4;
lcd.cursorTo(2,1); 
lcd.print(average); 
delay(3000);
}

//MAIN LOOP
void loop()
{
delay(25);
intermediatevalue=mesure()-average;
lcd.clear();
lcd.cursorTo(1,1);
lcd.print("Charger");
lcd.cursorTo(2,1);
lcd.print("Valeur celluleforce"); 
lcd.cursorTo(4,1);
lcd.print(intermediatevalue);
}

Certains delay ne sont pas necessaires, mais c’est juste histoire de ne pas aller trop vite.
L’affichage est sur un LCD maintenant, mais en affichant l’integralité des valeurs sur le Serial de mon PC, on voit bien que toutes les 50-100valeurs on a une erreur.

Bonjour
fais un ficher log de qq secondes avec le prog ci-dessous et poste le.
conditions de la manip :
jauge debranchée de A+ A- E+ E-
entree A+ A- pontée (court-circuit)
entrée B+ B- idem

//Variables

long calibration=0;
long average=0;
long intermediatevalue=0;
long finalvalue=0;

long mesure ()
{
byte data[3]={0};
byte filler = 0x00;
unsigned long value = 0;
for (byte j = 3; j--;) {
for (char i = 8; i--;) {
digitalWrite(A0, HIGH);     
bitWrite(data[j], i, digitalRead(A1));
digitalWrite(A0, LOW);
    }
  }
  //data[2]= data[2]-200;
// Construct a 32-bit signed integer
 value = ( static_cast<unsigned long>(filler) << 24
      | static_cast<unsigned long>(data[2]) << 16
      | static_cast<unsigned long>(data[1]) << 8
      | static_cast<unsigned long>(data[0]) );
     
return static_cast<long>(value);
   }

//Initialisation Programm 
void setup() {
Serial.begin(115200);
pinMode(A0, OUTPUT);//A0 clock
pinMode(A1, INPUT); //A1 read
delay(1000);


}

//MAIN LOOP
void loop()
{
delay(25);
//Serial.print("X,");  
//Serial.print(millis());
//Serial.print(",");
Serial.println(mesure()); 


}

Merci encore :) , alors ca a donné quoi chez toi?

Je vois ou tu veux en venir, chez moi le sous programme "mesure()" dure entre 0 et 1 milliseconde avec la fonction millis(), en passant en micro() j'obtiens entre 370 et 400 microsecondes.

Je comprends pas tes conditions de manipulation par contre :confused: qu'appelles tu A+ et A- ?les entrées lectures? et E+, E- la tension d'excitation? Qu'est-ce que signifie B+ et B- ?

arthurfr: Merci encore :) , alors ca a donné quoi chez toi?

Je vois ou tu veux en venir, chez moi le sous programme "mesure()" dure entre 0 et 1 milliseconde avec la fonction millis(), en passant en micro() j'obtiens entre 370 et 400 microsecondes.

Je comprends pas tes conditions de manipulation par contre :confused: qu'appelles tu A+ et A- ?les entrées lectures? et E+, E- la tension d'excitation? Qu'est-ce que signifie B+ et B- ?

ce sont les entrees de mesure canaux A et B et sortie excitation la manip consiste à mesurer l'entree A en condition de court-circuit , il demeure du bruit residuel et les abberations sont simples à detecter. OK je comprend : tes jauges sont connectée sur le combinateur = debranche tes jauges |500x318

arthurfr: j'obtiens entre 370 et 400 microsecondes.

Multiplié par 100 ou 50 on obtient la période secteur (ou un sous-multiple).

fdufnews: Multiplié par 100 ou 50 on obtient la période secteur (ou un sous-multiple).

bonjour fdufnews c'est pour ça que j'ai demandé un log des datas brutes episodiquement la lecture renvoie les 24 bits à 1 le HX711 s'occupe de la rejection 50 et 60 Hz Simultaneous 50 and 60Hz supply rejection à noter aussi que le format de sortie est un format signé (complement à 2) ce qui n'est pas pris en compte dans son" programme il me semble.

Je crois avoir tout compris, J'ai tout relié comme tu indiques (je courtcircuite la cellule de force) et je fais des mesures à 40Hz. J'ai encore certaines erreurs qui reviennent avec des valeurs absurdes. Mais je n'ai plus les valeurs intermédiaires. En gros soit j'ai 14000N ou -1000N mais plus de valeurs de l'ordre de 800-900N. Du coup ca viendrait d'un bruit de mesure, et ces valeurs completement absurdes sont facilement filetrables via un "if".

Maintenant il reste à trouver une explication pour les valeurs intermédiaires fausses qui apparaissent dans la réalité mais qui disparaissent en court circutant la cellule de force. Tu aurais une idée? Un mauvais contact dans la cellule?

Edit: Periode secteur? c'est possible ou pas du coup sachant que c'est filtré. Enfin la periode doit legerement varier aussi non? du coup on peut pas forcement tout tout filtrer...

C'est vraiment top ton aide, encore merci :)

arthurfr: Je crois avoir tout compris, J'ai tout relié comme tu indiques (je courtcircuite la cellule de force) et je fais des mesures à 40Hz. J'ai encore certaines erreurs qui reviennent avec des valeurs absurdes. Mais je n'ai plus les valeurs intermédiaires. En gros soit j'ai 14000N ou -1000N mais plus de valeurs de l'ordre de 800-900N.

c'est la valeur brute de la lecture du canal A qui est interessante , pas le resultat de tes calculs en N çà ne permet pas de regarder le motif binaire de 24 bits

Quelle nouille je suis! Oui bien sur qu'il faut les valeurs brutes :) J'en profite pour dire que l'ordinateur qui me sert à programmer n'est pas relié à internet... (longue longue histoire). C'est donc un peu dur de faire du copier coller.

Les valeurs que j'ai au repos (enfin pas tout a fait, un vérin est fixé sur la cellule), disons les valeurs que je peux exploiter via un tarage sont 16771850 //1111 1111 1110 1011 0000 1010 16771891 //1111 1111 1110 1011 0011 0011 16771882 //1111 1111 1110 1011 0010 1010 16771865 //1111 1111 1110 1011 0001 1001 ... Ce que je peux dire c'est que le 16771 du début est completement stable, le reste varie avec le bruit.

Au debut de ma programmation j'avais utilisé une une autre cellule de force et le premier octet (celui qui vaut 255 ici a chaque fois) prenais toujours la valeur 243, j'avais trouvé cela bizarre de ne pas commencer aux alentours de 0, et du coup j'avais rajouté dans mon programme de mesure data[2]=data[2]-200; pour commencer à 43 et non plus à 243.

fais un fichier log de qq secondes (500/600 enregistrments) avec le prog en #6
et poste le, sans ça “on” n’avancera pas.
Meme si ton ordi n’est pas connecté à internet , ce n’est pas compliqué de faire une copie ensuite sur un connecté.

Voila mes resultats de lecture en pièce jointe.
Aucune erreur n’est detectée maintenant.
Mais lorsque je relance mon programme avec la conversion en force, je me retrouve avec les mêmes erreurs que précedemment. Environ toutes les 200 mesures, j’ai quelque chose d’absurde.

Resultat lecture valeur.txt (10 KB)

arthurfr: Voila mes resultats de lecture en pièce jointe. Aucune erreur n'est detectée maintenant. Mais lorsque je relance mon programme avec la conversion en force, je me retrouve avec les mêmes erreurs que précedemment. Environ toutes les 200 mesures, j'ai quelque chose d'absurde.

bonjour Je n'ai pas compris cette phrase : "conversion en force" ? et le log n'est pas le log brut issu du programme posté en #6