Skip to content

Fixed the handling of the sign of values from the ADC #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 1, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 19 additions & 8 deletions src/SparkFun_Qwiic_Scale_NAU7802_Arduino_Library.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ uint8_t NAU7802::getRevisionCode()

//Returns 24-bit reading
//Assumes CR Cycle Ready bit (ADC conversion complete) has been checked to be 1
uint32_t NAU7802::getReading()
int32_t NAU7802::getReading()
{
_i2cPort->beginTransmission(_deviceAddress);
_i2cPort->write(NAU7802_ADCO_B2);
Expand All @@ -208,9 +208,20 @@ uint32_t NAU7802::getReading()

if (_i2cPort->available())
{
uint32_t value = (uint32_t)_i2cPort->read() << 16; //MSB
value |= (uint32_t)_i2cPort->read() << 8; //MidSB
value |= (uint32_t)_i2cPort->read(); //LSB
uint32_t valueRaw = (uint32_t)_i2cPort->read() << 16; //MSB
valueRaw |= (uint32_t)_i2cPort->read() << 8; //MidSB
valueRaw |= (uint32_t)_i2cPort->read(); //LSB

// the raw value coming from the ADC is a 24-bit number, so the sign bit now
// resides on bit 23 (0 is LSB) of the uint32_t container. By shifting the
// value to the left, I move the sign bit to the MSB of the uint32_t container.
// By casting to a signed int32_t container I now have properly recovered
// the sign of the original value
int32_t valueShifted = (int32_t)(valueRaw << 8);

// shift the number back right to recover its intended magnitude
int32_t value = ( valueShifted >> 8 );

return (value);
}

Expand All @@ -219,9 +230,9 @@ uint32_t NAU7802::getReading()

//Return the average of a given number of readings
//Gives up after 1000ms so don't call this function to average 8 samples setup at 1Hz output (requires 8s)
uint32_t NAU7802::getAverage(uint8_t averageAmount)
int32_t NAU7802::getAverage(uint8_t averageAmount)
{
unsigned long total = 0;
long total = 0;
uint8_t samplesAquired = 0;

unsigned long startTime = millis();
Expand Down Expand Up @@ -261,7 +272,7 @@ int32_t NAU7802::getZeroOffset()
//Call after zeroing. Provide the float weight sitting on scale. Units do not matter.
void NAU7802::calculateCalibrationFactor(float weightOnScale, uint8_t averageAmount)
{
uint32_t onScale = getAverage(8);
int32_t onScale = getAverage(averageAmount);
float newCalFactor = (onScale - _zeroOffset) / (float)weightOnScale;
setCalibrationFactor(newCalFactor);
}
Expand All @@ -281,7 +292,7 @@ float NAU7802::getCalibrationFactor()
//Returns the y of y = mx + b using the current weight on scale, the cal factor, and the offset.
float NAU7802::getWeight(bool allowNegativeWeights)
{
uint32_t onScale = getAverage(8);
int32_t onScale = getAverage(8);

//Prevent the current reading from being less than zero offset
//This happens when the scale is zero'd, unloaded, and the load cell reports a value slightly less than zero value
Expand Down
6 changes: 3 additions & 3 deletions src/SparkFun_Qwiic_Scale_NAU7802_Arduino_Library.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,8 @@ class NAU7802
bool isConnected(); //Returns true if device acks at the I2C address

bool available(); //Returns true if Cycle Ready bit is set (conversion is complete)
uint32_t getReading(); //Returns 24-bit reading. Assumes CR Cycle Ready bit (ADC conversion complete) has been checked by .available()
uint32_t getAverage(uint8_t samplesToTake); //Return the average of a given number of readings
int32_t getReading(); //Returns 24-bit reading. Assumes CR Cycle Ready bit (ADC conversion complete) has been checked by .available()
int32_t getAverage(uint8_t samplesToTake); //Return the average of a given number of readings

void calculateZeroOffset(uint8_t averageAmount = 8); //Also called taring. Call this with nothing on the scale
void setZeroOffset(int32_t newZeroOffset); //Sets the internal variable. Useful for users who are loading values from NVM.
Expand Down Expand Up @@ -202,7 +202,7 @@ class NAU7802
const uint8_t _deviceAddress = 0x2A; //Default unshifted 7-bit address of the NAU7802

//y = mx+b
uint32_t _zeroOffset; //This is b
int32_t _zeroOffset; //This is b
float _calibrationFactor; //This is m. User provides this number so that we can output y when requested
};
#endif