RobTillaart / HX711

Arduino library for HX711 24 bit ADC used for load cells and scales.
MIT License
88 stars 29 forks source link

How does one get the raw data scaled in milivolts? #53

Closed busypete closed 2 months ago

busypete commented 2 months ago

I am using the HX711 on an experiment with a strain gauge, and do not need to convert or scale to weight units, I only need the output in +-20 milivolts (128 gain). However, I am struggling a bit around the concept of the conversion from the raw serial data from the ADC to the IEEE754 float mantissa. I cannot seem to match the data bits seen on the scope to the ones saved on the float. How can I extract or scale this data to represent the input in volts?

RobTillaart commented 2 months ago

Interesting question, I need to do some reading.

RobTillaart commented 2 months ago

However, I am struggling a bit around the concept of the conversion from the raw serial data from the ADC to the IEEE754 float mantissa.

The ADC returns a 24 bit value which is read in read()

  v.data[2] = _shiftIn();
  v.data[1] = _shiftIn();
  v.data[0] = _shiftIn();

these are the raw bits converted to a signed long (mapping with union) By design I use convert this long into a float (as most math of the lib is float)

  return 1.0 * v.value;

The bit layout of a float uses some tricks to encode a value, details see IEEE754 That is why it does not match the bits of the long value.

It would be possible to add a function to access the rawADC bits of the last measurement. Store the bits received in a private variable and wrap a function to fetch this value around it.

RobTillaart commented 2 months ago

I only need the output in +-20 milivolts (128 gain).

Process how I would try to get mV's (not tested)

Calibration

Put 0.0 mV on the A port, Call read() to get the zero point. (Expect the ADC returns zero +- some noise) Put 20.0 mV on the A port Call read to get the max value. Put -20.0 mV on the A port Call read to get the min value.

Interpolation

Then interpolate between those points to get your measurements in milliVolts. If needed more interpolation points can be needed (check HX711_MP)

Example code (not tested)

If 0.0 mV equals a read of 12345 And max equals 24365155

In code you need something like

float getmV()
{
  float zeroV = 12345.0
  float maxV = 24365155.0;
  float raw = HX.read();    <<<<<<<<<<<<<<<<<<< you might use different modi like average or median etc.
  return 20.0 * (raw - zeroV) / (maxV - zeroV) ;
}

Can you do the above test, I have no HW setup free to do so. Please post your results.

If it works well I can add it as part of the interface of the HX711 class.

RobTillaart commented 2 months ago

Idea!

In a bright(?) moment I had the following thought:

then the float get_units(uint8_t times = 1); should return voltages

RobTillaart commented 2 months ago

@busypete Did the above replies answer your question?

RobTillaart commented 2 months ago

@busypete As there is no answer to my question I assume the issue is solved. Feel free to reopen if this is not the case.

RobTillaart commented 2 months ago

Added a section in the readme.md of my local develop branch to keep this idea.