I am examining the HX711 library (which reads data from loadcell) written for Arduino. While reviewing the read() function that reads the values of the loadcell within this structure, I noticed something. In this function, a Union structure named “v” is used to store the value to be returned. This structure contains an array named “data” and a variable named “value”. The read values are written to the “v.data” array, and the result is returned with the “v.value” variable. However, there is no part where we fill the “v.value” value with the values in the “v.data” array. Does the Union do this automatically? How does this structure work exactly?
Here is the read() function I mentioned:
float HX711::read()
{
// this BLOCKING wait takes most time...
while (digitalRead(_dataPin) == HIGH) yield();
union
{
long value = 0;
uint8_t data[4];
} v;
// blocking part ...
noInterrupts();
// Pulse the clock pin 24 times to read the data.
// v.data[2] = shiftIn(_dataPin, _clockPin, MSBFIRST);
// v.data[1] = shiftIn(_dataPin, _clockPin, MSBFIRST);
// v.data[0] = shiftIn(_dataPin, _clockPin, MSBFIRST);
v.data[2] = _shiftIn();
v.data[1] = _shiftIn();
v.data[0] = _shiftIn();
// TABLE 3 page 4 datasheet
//
// CLOCK CHANNEL GAIN m
// ------------------------------------
// 25 A 128 1 // default
// 26 B 32 2
// 27 A 64 3
//
// only default 128 verified,
// selection goes through the set_gain(gain)
//
uint8_t m = 1;
if (_gain == HX711_CHANNEL_A_GAIN_128) m = 1;
else if (_gain == HX711_CHANNEL_A_GAIN_64) m = 3;
else if (_gain == HX711_CHANNEL_B_GAIN_32) m = 2;
while (m > 0)
{
// delayMicroSeconds(1) needed for fast processors?
digitalWrite(_clockPin, HIGH);
if (_fastProcessor)
delayMicroseconds(1);
digitalWrite(_clockPin, LOW);
if (_fastProcessor)
delayMicroseconds(1);
m--;
}
interrupts();
// yield();
// SIGN extend
if (v.data[2] & 0x80) v.data[3] = 0xFF;
_lastRead = millis();
return 1.0 * v.value;
}
As you can see, there is no place where we fill the “v.value”. The shiftIn() method doesn’t do this, I’ve checked. If we wanted to do this, we would need to pass the reference of the “v” structure to the method like that _shiftIn(&v)
, right? I was hoping to see a code like this to be able to do that, but it’s not there:
// This is just an example mathematical operation I wrote to explain its logic.
v.value = v.data[0] + v.data[1] * v.data[2] / v.data[3];
return v.value * 1;