Skip to content

Commit 2771c40

Browse files
committed
Create Example7_ExternalCalibration.ino
1 parent 05d38a5 commit 2771c40

File tree

1 file changed

+193
-0
lines changed

1 file changed

+193
-0
lines changed
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
/*
2+
Use the Qwiic Scale to read load cells and scales
3+
By: Paul Clark @ SparkFun Electronics
4+
Date: February 25th, 2024
5+
License: MIT - see License.md for more details.
6+
7+
This example shows how to setup a scale complete with zero offset (tare),
8+
and linear calibration using the NAU7802's external calibration mode.
9+
10+
This is similar to Example2, except here we use the NAU7802's external calibration
11+
function and internal offset register to store the zero point. By default .begin
12+
performs an _internal_ calibration. In this example we overwrite the offset register
13+
with the result of the _external_ calibration.
14+
15+
If you know the calibration and offset values you can send them directly to
16+
the library and NAU7802. This is useful if you want to maintain values between power cycles
17+
in EEPROM or Non-volatile memory (NVM). If you don't know these values then
18+
you can go through a series of steps to calculate the offset and calibration value.
19+
20+
SparkFun labored with love to create this code. Feel like supporting open
21+
source? Buy a board from SparkFun!
22+
https://www.sparkfun.com/products/15242
23+
24+
Hardware Connections:
25+
Plug a Qwiic cable into the Qwiic Scale and a RedBoard Qwiic
26+
If you don't have a platform with a Qwiic connection use the SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425)
27+
Open the serial monitor at 115200 baud to see the output
28+
*/
29+
30+
#include <Wire.h>
31+
#include <EEPROM.h> //Needed to record user settings
32+
33+
#include "SparkFun_Qwiic_Scale_NAU7802_Arduino_Library.h" // Click here to get the library: http://librarymanager/All#SparkFun_NAU8702
34+
35+
NAU7802 myScale; //Create instance of the NAU7802 class
36+
37+
//EEPROM locations to store 4-byte variables
38+
#define EEPROM_SIZE 100 //Allocate 100 bytes of EEPROM
39+
#define LOCATION_CALIBRATION_FACTOR 0 //Float, requires 4 bytes of EEPROM
40+
#define LOCATION_ZERO_OFFSET 20 //Must be more than 4 away from previous spot. 24-bit signed, stored as int32_t. Requires 4 bytes of EEPROM
41+
42+
bool settingsDetected = false; //Used to prompt user to calibrate their scale
43+
44+
//Average the weight over this many samples. This helps smooth out jitter.
45+
const uint8_t avgWeights = 20; //At 40 SPS, this will produce readings at 2Hz
46+
47+
//Allow negative weights. Why not?
48+
const bool allowNegative = true;
49+
50+
void setup()
51+
{
52+
EEPROM.begin(EEPROM_SIZE); //Some platforms need this. Comment this line if needed
53+
54+
delay(1000); //Some platforms need this. Comment this line if needed
55+
56+
Serial.begin(115200);
57+
Serial.println(F("Qwiic Scale Example"));
58+
59+
Wire.begin();
60+
Wire.setClock(400000); //Qwiic Scale is capable of running at 400kHz if desired
61+
62+
if (myScale.begin() == false) //begin performs an internal calibration. We will overwrite this with readSystemSettings
63+
{
64+
Serial.println(F("Scale not detected. Please check wiring. Freezing..."));
65+
while (1);
66+
}
67+
Serial.println(F("Scale detected!"));
68+
69+
myScale.setSampleRate(NAU7802_SPS_40); //Set sample rate: 10, 20, 40, 80 or 320
70+
myScale.setGain(NAU7802_GAIN_16); //Gain can be set to 1, 2, 4, 8, 16, 32, 64, or 128.
71+
myScale.setLDO(NAU7802_LDO_3V0); //Set LDO (AVDD) voltage. 3.0V is the best choice for Qwiic
72+
73+
readSystemSettings(); //Load NAU7802 offset and calibrationFactor from EEPROM
74+
75+
Serial.print(F("NAU7802 offset register: "));
76+
Serial.println(myScale.getChannel1Offset());
77+
Serial.print(F("Library calibration factor: "));
78+
Serial.println(myScale.getCalibrationFactor());
79+
80+
Serial.println(F("\r\nPress 'c' to calibrate the scale\r\n"));
81+
}
82+
83+
void loop()
84+
{
85+
if (myScale.available() == true)
86+
{
87+
float currentWeight = myScale.getWeight(allowNegative, avgWeights);
88+
89+
Serial.print(F("Weight: "));
90+
Serial.print(currentWeight, 2); //Print 2 decimal places
91+
92+
if(settingsDetected == false)
93+
{
94+
Serial.print(F("\tScale not calibrated. Press 'c'."));
95+
}
96+
97+
Serial.println();
98+
}
99+
100+
if (Serial.available())
101+
{
102+
byte incoming = Serial.read();
103+
104+
if (incoming == 'c') //Calibrate
105+
calibrateScale();
106+
}
107+
}
108+
109+
//Gives user the ability to set a known weight on the scale and calculate a calibration factor
110+
void calibrateScale(void)
111+
{
112+
Serial.println();
113+
Serial.println();
114+
Serial.println(F("Scale calibration"));
115+
116+
Serial.println(F("Setup scale with no weight on it. Press a key when ready."));
117+
while (Serial.available()) Serial.read(); //Clear anything in RX buffer
118+
while (Serial.available() == 0) delay(10); //Wait for user to press key
119+
120+
//Perform an external offset - this sets the NAU7802's internal offset register
121+
myScale.calibrateAFE(NAU7802_CALMOD_OFFSET); //Calibrate using external offset
122+
123+
Serial.print(F("New NAU7802 offset register: "));
124+
Serial.println(myScale.getChannel1Offset());
125+
126+
Serial.println(F("Place known weight on scale. Press a key when weight is in place and stable."));
127+
while (Serial.available()) Serial.read(); //Clear anything in RX buffer
128+
while (Serial.available() == 0) delay(10); //Wait for user to press key
129+
130+
Serial.print(F("Please enter the weight, without units, currently sitting on the scale (for example '4.25'): "));
131+
while (Serial.available()) Serial.read(); //Clear anything in RX buffer
132+
while (Serial.available() == 0) delay(10); //Wait for user to press key
133+
134+
//Read user input
135+
float weightOnScale = Serial.parseFloat();
136+
Serial.println();
137+
138+
//Tell the library how much weight is currently on it
139+
//We are sampling slowly, so we need to increase the timeout too
140+
myScale.calculateCalibrationFactor(weightOnScale, 64, 3000); //64 samples at 40SPS. Use a timeout of 3 seconds
141+
Serial.print(F("Weight on scale: "));
142+
Serial.println(weightOnScale, 2);
143+
Serial.print(F("New library calibration factor: "));
144+
Serial.println(myScale.getCalibrationFactor(), 2);
145+
146+
recordSystemSettings(); //Commit these values to EEPROM
147+
148+
settingsDetected = true; //Mark the settings as detected
149+
}
150+
151+
//Record the current system settings to EEPROM
152+
void recordSystemSettings(void)
153+
{
154+
//Get various values from the library and commit them to NVM
155+
EEPROM.put(LOCATION_CALIBRATION_FACTOR, myScale.getCalibrationFactor());
156+
EEPROM.put(LOCATION_ZERO_OFFSET, myScale.getChannel1Offset());
157+
158+
EEPROM.commit(); //Some platforms need this. Comment this line if needed
159+
}
160+
161+
//Reads the current system settings from EEPROM
162+
//If anything looks weird, reset setting to default value
163+
void readSystemSettings(void)
164+
{
165+
float settingCalibrationFactor; //Value used to convert the load cell reading to lbs or kg
166+
int32_t offsetRegister; //Zero value that is found when scale is tared
167+
168+
//Look up the calibration factor
169+
//If the EEPROM has been erased, default to 1.0
170+
EEPROM.get(LOCATION_CALIBRATION_FACTOR, settingCalibrationFactor);
171+
if (settingCalibrationFactor == 0xFFFFFFFF)
172+
{
173+
settingCalibrationFactor = 1.0; //Default to 1.0
174+
EEPROM.put(LOCATION_CALIBRATION_FACTOR, settingCalibrationFactor);
175+
}
176+
177+
//Look up the offset register
178+
//If the EEPROM has been erased, default to 0
179+
EEPROM.get(LOCATION_ZERO_OFFSET, offsetRegister);
180+
if (offsetRegister == 0xFFFFFFFF)
181+
{
182+
offsetRegister = 0; //Default to 0 - i.e. no offset
183+
EEPROM.put(LOCATION_ZERO_OFFSET, offsetRegister);
184+
}
185+
186+
//Pass these values to the library and NAU7802
187+
myScale.setCalibrationFactor(settingCalibrationFactor);
188+
myScale.setChannel1Offset(offsetRegister);
189+
190+
settingsDetected = true; //Assume for the moment that there are good cal values
191+
if (settingCalibrationFactor == 1.0 || offsetRegister == 0)
192+
settingsDetected = false; //Defaults detected. Prompt user to cal scale.
193+
}

0 commit comments

Comments
 (0)