0

How do you make a load cell's amp HX711 measure both positive and negative values, or how do you set the center value for it? The main point is how to set the reference voltage (?) or something else so it can work like a joystick axis set it the center position, and work with an only lc or an extra one added, only one is preferable, say like a simple POT here.

That's a code for it.

#include <HX711.h>
#include <Joystick.h>
#define calibration_factor 400// Change this value to give accurate reading with your known mass.
#define DOUT  1
#define CLK  0
HX711 scale;
/*
Please check out our YouTube video series, Make your own loadcell pedals for sim racing
 
www.gpsimrigs.com
 
www.facebook.com/gpracesim
  */
Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,
  JOYSTICK_TYPE_MULTI_AXIS, 4, 3,
  false, false, true, false, false, false,
  false, true, true, true, false);
 
 
 
int brake = 0;
int lastBrakeValue = 0;
 
void setup() {
  // Ranges are 1023 by default
   Joystick.setBrakeRange(0, 1023);
  
 
  Joystick.begin();
  Serial.begin(38400);
 
  scale.begin(DOUT, CLK);
  scale.set_scale(calibration_factor);
  scale.tare();
}
void loop() {
 
//Displays reading in Serial Monitor
 
    Serial.println (brake);
brake = scale.get_units(); // if the value is inverted put a - sign in front like -scale.get
 
   if (brake < 0 or brake < 1) {
    brake = 0;
  }
 
   if (lastBrakeValue != brake) {
     Joystick.setBrake(brake);
     lastBrakeValue = brake;
  }
}
Sieben
  • 59
  • 7
  • 1
    As you can see in fig 1 of the datasheet, inputs are differential. You need just setting the "middle point". Be aware that sensitivity is "high" +/- 20mV or +/- 40 mV. And you have inputs A and B. – Antonio51 Dec 22 '21 at 12:16
  • Antonio51, how to do it? Extra resistors in the lc white green wires? Or tweaks in hx711? – Sieben Dec 22 '21 at 12:23
  • 1
    4 (?) Extra resistors are to be added to the "bridge", so that voltages are in the middle of the power supply voltage. – Antonio51 Dec 22 '21 at 12:28
  • Sound good! Don't you know how much shall be placed, just around at least? And shall they be placed on both of A&B channels. Or shall be put just to power line on red wire? Thanks! – Sieben Dec 22 '21 at 12:32

2 Answers2

2

Example of Schematic to be used, resistors (1k ?) to the adjusted midpoint (+/-) at inputs within 20 or 40 mV (scale). Depends on the joystick used (100 Ohm ?).

EDIT: these resistors are not needed if you don't care about Common Mode input voltage : min=AGND+1.2V and max=AVDD-1.3V. If used, then take same resistors from the same "lot", "paired" if possible, and well "placed". I could use at full scale of measuring, in my case, some uV ...

Using the two inputs (A and B) let one use an x-y joystick, just mounting 2 pots in parallel.

enter image description here

Antonio51
  • 11,004
  • 1
  • 7
  • 20
  • Thank You very much! It's so cool! I will try that. The load cell are those of a beam like tipe for arduino scales for example. – Sieben Dec 22 '21 at 12:51
  • 1
    Ok. I did only use HX711 as a nanoVoltmeter :-) with "noise". Very good as microvoltmeter if one takes a mean of "some" samples. – Antonio51 Dec 22 '21 at 12:54
  • as far as i get it, we need a physical access for the load cells on a beam then. And how to make it with this sort of thing, is may be an another story. https://www.majju.pk/assets/uploads/2019/03/0-5Kg-Weight-Load-Cell-strain-gauge-pressure-Sensor-for-Electronic-Balance-scaled.jpg – Sieben Dec 22 '21 at 13:17
  • 1
    Is the pcb, one something as this https://www.sparkfun.com/products/13879. Anyway, you have access on all pins. Or do you want to use the load cell ... as joystick ? :-) – Antonio51 Dec 22 '21 at 13:19
  • Oh, yes. My fault. The pcb is similar. Misunderstood the schematics. ) Like joystick x or y axis. It works but need a center here. – Sieben Dec 22 '21 at 13:23
  • Well, still. with gauge as above example, won't go. They are covered with a glue. And an amp is not for single lC's. And is like that. https://mcustore.ru/img/site/drajver-tenzodatchikov-hx711.jpg – Sieben Dec 22 '21 at 13:47
  • E+ is just for V_AVDD, E- is for ground ... and the others are for inputs A(+&-) and B(+&-). X3 and X2 on my picture are used for centering voltage (constant data for Arduino). Then X1 and X4 are joystick pots (x & y direction). No more op-amp needed. – Antonio51 Dec 22 '21 at 14:11
  • I mean that the load cell itself, acts as a pot. But it goes from, say, 0-1025 (0-5kg load as an example).and, i need to set it to around 512 electronically. So it's on center position. I can't connect x1,and x2, in this layouts. – Sieben Dec 22 '21 at 15:32
2

Sorry, but adding any components to the schematics is fighting a problem that does not exist.

Not to mention introducing additional components with their own thermal characteristics, on top of thermal drifts in the chip and load cells. This can only be justified if you add very complex schematics with thermistor, carefully calibrated for compensation.

HX711 already provides you with differential output, the only problem is that the combination of the chip with load cell has quite huge offset.

So, all you have to do is take a reading in the neutral position and then subtract it every time you read later. Or better yet, take several readings and calculate an average, for better precision.

When you do this all positive values would mean pressure applied in one direction, all negative values would be for other direction.

However keep in mind that many load cells will not return exactly to the center position when pressure removed. The usual way to deal with this is to have "dead zone" in your software, where any input is treated as zero.

UPDATE

Here is some primitive code I've used before to read two load cells with one chip. All you have to do is call Update() function often enough to keep reading data. You don't need any additional components for second load cell. Connect it as shown in the datasheet only use INB+, INB- inputs, there should not be much cross-talk between the channels.

#define GAIN_A_128  1   // Gain 128 (channel A) +/- 20mV @5V
#define GAIN_B_32   2   // Gain 32 (channel B) +/- 80mV @5V
#define GAIN_A_64   3   // Gain 64 (channel A) +/- 40mV @5V

int32_t value_a = 0;
int32_t value_b = 0;
bool current_ch = false;    // channel a = true, channel b = false

int ReadAndSetGain(int gain)
{
    // read chip data
    int ret = 0;
    // pulse clock pin 24 times to read the data as 2's complement value
    for (int i = 0; i < 24; i++)
    {
        gpio_set(clk_out_pin, true);
        gpio_set(clk_out_pin, false);
        ret = (ret << 1) + (gpio_get(data_in_pin) ? 1 : 0);
    }
    // set the channel and gain factor for next reading using clock pin
    for (int i = 0; i < gain; i++)
    {
        gpio_set(clk_out_pin, true);
        gpio_set(clk_out_pin, false);
    }
    // propagate sign bit
    if (ret & 0x800000) ret |= 0xFF000000;
    return ret;
}

// Call this function every 13 ms if HX711 data rate is 80 Hz,
// every 101 ms if data rate is 10 Hz to keep channel values updated.
// Note that default gain after reset is GAIN_A_128, so the channel values
// will be incorrect until after three successful readings.
void Update()
{
    // make sure data is available
    if (gpio_get(data_in_pin)) return;
    if (current_ch) {   // reading channel A
        value_a = ReadAndSetGain(GAIN_B_32);
    } else {            // reading channel B
        value_b = ReadAndSetGain(GAIN_A_64);
    }
    current_ch = !current_ch;
}

You can modify this code to suit your needs, of course. For example, instead of calling Update() periodically, you can read channels only when you need them:

int offset_a = 0;
int offset_b = 0;

int ReadA()
{
    while (current_ch) Update();    // make sure channel A has been read
    return value_a - offset_a;
}

int ReadB()
{
    while (!current_ch) Update();   // make sure channel B has been read
    return value_b - offset_b;
}

// call this in the beginning of a program when sensors are in neutral position
void Tare()
{
    // reset previous offsets
    offset_a = 0;
    offset_b = 0;
    // read and discard to initialize chip gain
    ReadB(); 
    // store current values as new offsets
    offset_a = ReadA();
    offset_b = ReadB();
}
Maple
  • 11,755
  • 2
  • 20
  • 56
  • With INA122 people connect together two cells with cross connection of the signal channels. And it works. But INA122 is an analog and HX711 is digit. I tried to do the same but doesn't go also. Also connected each with t's own amp - all the same. Also do the mechanical preload, but it has an impact then on the another axis, because it becomes extra sensitive. And I don't know how to implement the negative readings from all the same cell, if to read it from the zero load position. May some coding help out? – Sieben Dec 22 '21 at 17:47
  • P.s. with some kind of offset, the readings seem to be good enough i.m. when soldered second cell to the common HX711, it gave 30% offset, but only till the next arduino replug from usb. – Sieben Dec 22 '21 at 17:47
  • 1
    As far as I remember, it sends data in 2's complement format. It is described in details in the datasheet. Also if you use one chip to read two sensors keep in mind that inputs A and B have different gains, so you need additional division to bring higher gain input to the same scale. – Maple Dec 22 '21 at 18:20
  • 1
    @Sieben I've added small code sample to help you move along – Maple Dec 23 '21 at 00:13
  • That' is so cool. After compile gives errors. 'gpio_set' was not declared in this scope, 'clk_out_pin' was not declared in this scope, In function 'int ReadAndSetGain(int)': suggested alternative: 'fpos_t' gpio_set(clk_out_pin, true); – Sieben Dec 23 '21 at 11:40
  • Previous is solved, now some more) In function 'void loop()',,,a function-definition is not allowed here before '{' token { ^ https://drive.google.com/file/d/1g206QS8JaE2gM4Nce9dpA3yVfGsQVixo/view?usp=sharing – Sieben Dec 23 '21 at 12:37
  • 1
    @Sieben You realize that I have no idea what platform you are developing on or even what language. The code samples should be treated as pseudo-code that shows you the logic. It is up to you to adapt it to your framework. – Maple Dec 23 '21 at 15:57
  • It's Arduino. And i have no idea on coding)) – Sieben Dec 23 '21 at 16:08
  • Bay the way. Just to know. How can I add this code to initial for lc joystick in the beginning of the thread . This one: the code should output a value close to half of 224. This allows the load cell to measure both positive and negative load. https://makersportal.com/blog/2019/5/12/arduino-weighing-scale-with-load-cell-and-hx711 – Sieben Dec 23 '21 at 16:17
  • 1
    @Sieben any code added to setup function() will be executed once at the beginning of the program. code added to loop() function will be repeated over and over again after that. The blog that you linked to has all you need to understand how to scale output of the load cell (ReadA/ReadB functions in my example) to the desired range. It is basic math, after all. You don't have to achieve that "224" or any special number. You are getting pressure data in _some_ range, and it is entirely up to you how to use it. The rest is pure software domain that is outside of this site purview – Maple Dec 23 '21 at 18:14
  • Ok, thanks. Asked exactly about arduino ide. How to set it there)). Thank you pal! – Sieben Dec 23 '21 at 19:40