Skip to content

Instantly share code, notes, and snippets.

@FabianInostroza
Created October 1, 2016 18:08
Show Gist options
  • Save FabianInostroza/a883c35e6e6135a71cbf0d2b3536628a to your computer and use it in GitHub Desktop.
Save FabianInostroza/a883c35e6e6135a71cbf0d2b3536628a to your computer and use it in GitHub Desktop.
two complement and endianness test
long read1(uint32_t raw) {
// Byte: 0 1 2 3
// Bits: 76543210 76543210 76543210 76543210
// Data: |--------|--------|--------|--------|
// Bit#: 33222222 22221111 11111100 00000000
// 10987654 32109876 54321098 76543210
union DataBuffer {
byte data[4];
long value;
} data_buffer;
/*
// Wait for the chip to become ready
for (; !is_ready() ;) {
// Will do nothing on Arduino but prevent resets of ESP8266 (Watchdog Issue)
yield();
}
*/
// Pulse the clock pin 24 times to read the data
data_buffer.data[1] = (raw >> 16) & 0xff; //shiftIn(DOUT, PD_SCK, MSBFIRST);
data_buffer.data[2] = (raw >> 8) & 0xff; //shiftIn(DOUT, PD_SCK, MSBFIRST);
data_buffer.data[3] = raw & 0xff; //shiftIn(DOUT, PD_SCK, MSBFIRST);
/*
// Set the channel and the gain factor for the next reading using the clock pin
for (unsigned int i = GAIN ; 0 < i ; --i) {
digitalWrite(PD_SCK, HIGH);
digitalWrite(PD_SCK, LOW);
}
*/
// Replicate the most significant bit to pad out a 32-bit signed integer
if ( data_buffer.data[1] & 0x80 ) {
data_buffer.data[0] = 0xFF;
} else {
data_buffer.data[0] = 0x00;
}
// Datasheet indicates the value is a 24-bit two's complement (signed) value
// https://cdn.sparkfun.com/datasheets/Sensors/ForceFlex/hx711_english.pdf
// Flip all the bits
data_buffer.value = ~data_buffer.value;
// ... and add 1
return ++data_buffer.value;
}
long read1b(uint32_t raw) {
// Byte: 0 1 2 3
// Bits: 76543210 76543210 76543210 76543210
// Data: |--------|--------|--------|--------|
// Bit#: 33222222 22221111 11111100 00000000
// 10987654 32109876 54321098 76543210
union DataBuffer {
byte data[4];
long value;
} data_buffer;
/*
// Wait for the chip to become ready
for (; !is_ready() ;) {
// Will do nothing on Arduino but prevent resets of ESP8266 (Watchdog Issue)
yield();
}
*/
// Pulse the clock pin 24 times to read the data
data_buffer.data[2] = (raw >> 16) & 0xff; //shiftIn(DOUT, PD_SCK, MSBFIRST);
data_buffer.data[1] = (raw >> 8) & 0xff; //shiftIn(DOUT, PD_SCK, MSBFIRST);
data_buffer.data[0] = raw & 0xff; //shiftIn(DOUT, PD_SCK, MSBFIRST);
/*
// Set the channel and the gain factor for the next reading using the clock pin
for (unsigned int i = GAIN ; 0 < i ; --i) {
digitalWrite(PD_SCK, HIGH);
digitalWrite(PD_SCK, LOW);
}
*/
// Replicate the most significant bit to pad out a 32-bit signed integer
if ( data_buffer.data[2] & 0x80 ) {
data_buffer.data[3] = 0xFF;
} else {
data_buffer.data[3] = 0x00;
}
// Datasheet indicates the value is a 24-bit two's complement (signed) value
// https://cdn.sparkfun.com/datasheets/Sensors/ForceFlex/hx711_english.pdf
// Flip all the bits
data_buffer.value = ~data_buffer.value;
// ... and add 1
return ++data_buffer.value;
}
long read2(uint32_t raw) {
unsigned long value = 0;
uint8_t data[3] = { 0 };
uint8_t filler = 0x00;
// pulse the clock pin 24 times to read the data
data[2] = (raw >> 16) & 0xff;
data[1] = (raw >> 8) & 0xff;
data[0] = (raw >> 0) & 0xff;;
// Datasheet indicates the value is returned as a two's complement value
// Flip all the bits
data[2] = ~data[2];
data[1] = ~data[1];
data[0] = ~data[0];
// Replicate the most significant bit to pad out a 32-bit signed integer
if ( data[2] & 0x80 ) {
filler = 0xFF;
}else if ((0x7F == data[2]) && (0xFF == data[1]) && (0xFF == data[0])) {
filler = 0xFF;
} else {
filler = 0x00;
}
// 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]) );
// ... and add 1
return static_cast<long>(++value);
}
long read3(uint32_t raw) {
unsigned long value = 0;
uint8_t data[3] = { 0 };
uint8_t filler = 0x00;
// pulse the clock pin 24 times to read the data
data[2] = (raw >> 16) & 0xff;
data[1] = (raw >> 8) & 0xff;
data[0] = (raw >> 0) & 0xff;;
// Datasheet indicates the value is returned as a two's complement value
// Flip all the bits
//data[2] = ~data[2];
//data[1] = ~data[1];
//data[0] = ~data[0];
// Replicate the most significant bit to pad out a 32-bit signed integer
if ( data[2] & 0x80 ) {
filler = 0xFF;
} else {
filler = 0x00;
}
// 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]) );
// ... and add 1
//return static_cast<long>(++value);
return static_cast<long>(value);
}
void setup() {
// put your setup code here, to run once:
uint32_t test = 0xab00cdef;
Serial.begin(115200);
Serial.println(*(uint8_t *) &test, HEX); // what should print? ab or ef?
}
void loop() {
// your simplification
Serial.print(read1(0x7fffff)); // max value (positive)
Serial.print(",");
Serial.print(read1(0x800000)); // min value (negative)
Serial.print(",");
Serial.print(read1(0x7f0000));
Serial.print(",");
Serial.print(read1(0x8fffff));
Serial.print(" | ");
// your simplification but endianess fixed
Serial.print(read1b(0x7fffff)); // max value (positive)
Serial.print(",");
Serial.print(read1b(0x800000)); // min value (negative)
Serial.print(",");
Serial.print(read1b(0x7f0000));
Serial.print(",");
Serial.print(read1b(0x8fffff));
Serial.print(" | ");
// original code (before your pull request), returns wrong value on 0x7fffff (bad condition on padding)
Serial.print(read2(0x7fffff)); // max value (positive)
Serial.print(",");
Serial.print(read2(0x800000)); // min value (negative)
Serial.print(",");
Serial.print(read2(0x7f0000));
Serial.print(",");
Serial.print(read2(0x8fffff));
Serial.print(" | ");
// my simplification
Serial.print(read3(0x7fffff)); // max value (positive)
Serial.print(",");
Serial.print(read3(0x800000)); // min value (negative)
Serial.print(",");
Serial.print(read3(0x7f0000));
Serial.print(",");
Serial.println(read3(0x8fffff));
delay(1000);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment