Created
October 1, 2016 18:08
-
-
Save FabianInostroza/a883c35e6e6135a71cbf0d2b3536628a to your computer and use it in GitHub Desktop.
two complement and endianness test
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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