Here is code for a load sensor. I use the on chip EE of the Atmega328. You should be able to pick out the EE code
/*
2022-09-01
v001
2022-09-06 v002 Added display and display calculations.
2022-09-15 v003 (open) add tare and gScale inputs and calculations.
2022-10-18 v005.1 Tare (K1) and scale (K2) function.
Scale has no display prompt simply put the 200gr
on the loadcell then press K2.
_____________________________________________________________________
HX711 device prove out code.
Reads the HX711 Raw data. Developed using YZC-133 Load Cell
HX711 outputs 24 bits: -8,388,608 to 8,388,607
"filler" code converts the 24 bit two's compliment value
to a 32 bit two's compliment value, which the compiler understands.
https://www.exploringbinary.com/twos-complement-converter/
Notes on YZC-133 5kg
Rated Output: 1.0 ± 0.15mV / V
if Vexcitation = 4.07V
5kg = 1mv * 4.07 = 4.07mv = 5kg.
@gain = 128 then we are using only 1/5 of our range.
8,388,607 *4.07 / 20 = ± 1,707,081
*/
/*
Pin Assignments:
2 Input HX711 Data Pin
3 Output HX711 Clock Pin
8 Input Pullup Initiate Tare
9 Input Pullup Initiate gScale (pgm assumes gScale is based on 200mg mass)
*/
#define uint unsigned int
#define int32 int32_t
#define uint32 uint32_t
#include <Wire.h>
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"
#include <EEPROM.h>
//#define period 3000
#define I2C_ADDRESS 0x3C
#define _pin_data 2
#define _pin_slk 3
#define _pin_tare 9 // K1
#define _pin_gScale 8 // K2
#define _countsTOoz 7.054792
#define gTOoz 28.3 // 28 grams / oz
#define period 3000
/*
#define gTareMinLimit 50000
#define gTareMaxLimit 60000
#define g200MinLimit 130000
#define g200MaxLimit 140000
*/
SSD1306AsciiWire oled;
//-- Declare Globals ------------------------------------------------------------
const int32_t g200CountInit = 133000; // counts at 200 grams
const int32_t g000CountInit = 56000;
int32_t g000Count;
int32_t g200Count; // counts at 200 grams
uint g000length = sizeof(g000Count);
byte gEEbaseAddress = 0;
uint32_t gStartMillis;
uint32_t gCurrentMillis;
char disp[14];
uint widthDisp;
//-- Function Prototpyes ------------------------------------------------------------
int32_t getValue(void);
void oledInit(void);
//-------------------------------------------------------------------------------
void setup() {
pinMode(_pin_data, INPUT);
pinMode(_pin_slk, OUTPUT);
pinMode(_pin_tare, INPUT_PULLUP);
pinMode(_pin_gScale, INPUT_PULLUP);
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, 0); // force ED off else it flickers sometimes
oledInit();
// if EEPROM has not been written to, save default values.
byte value = EEPROM.read(0);
if (value != 11) {
EEPROM.put(gEEbaseAddress, 11);
EEPROM.put(gEEbaseAddress + 1, g000CountInit);
EEPROM.put(gEEbaseAddress + g000length + 1, g200CountInit);
// initialize counts on very first startup (when EEPROM empty)
g000Count = g000CountInit;
g200Count = g200CountInit;
} else {
g000Count = EEPROM.get(gEEbaseAddress + 1, g000Count);
g200Count = EEPROM.get(gEEbaseAddress + g000length + 1, g200Count);
}
oled.clear();
oled.print(" setup v005.1");
delay(3000);
oled.setCursor(2 * 8, 0);
oled.print(g000Count);
oled.clearToEOL();
oled.setCursor(2 * 8, 2);
oled.print(g200Count);
delay(1000);
oled.SSD1306Ascii::setCursor(1 * 8, 0);
oled.print("grams = ");
oled.SSD1306Ascii::setCursor(1 * 8, 2);
oled.print("ounces = ");
} // --- setup ---------------------------------------------------------------------
//------------------------------------------------------------------------------------
void loop() {
gCurrentMillis = millis();
if (gCurrentMillis - gStartMillis >= period) { //cannot use "millis()" in if statement
gStartMillis = gCurrentMillis;
int32_t measCounts = getValue();
// calculations:
float weightGrams = (200.0 / (g200Count - g000Count)) * (measCounts - g000Count);
float weightOz = (7.054792 / (g200Count - g000Count)) * (measCounts - g000Count);
//dtostrf(float_value, min_width, num_digits_after_decimal, where_to_store_string)
dtostrf(weightGrams, 3, 1, disp);
uint dispLengthChar = strlen(disp);
uint widthDispPix = oled.fieldWidth(dispLengthChar);
oled.setCursor(8 * 8, 0); // should be after units.
oled.clearToEOL();
oled.setCursor( 120 - widthDispPix, 0); //dispLengthChar * 8, 0);
oled.print(weightGrams);
dtostrf(weightOz, 3, 1, disp);
dispLengthChar = strlen(disp);
widthDispPix = oled.fieldWidth(dispLengthChar);
oled.setCursor(9 * 8, 2); // should be after units.
oled.clearToEOL();
oled.setCursor( 120 - widthDispPix, 2); //dispLengthChar * 8, 0);
oled.print(weightOz);
/*
we now have:
display width in pixels
width of data in pixels
width of data in characters
What to do:
format right hand justification - 8 pixels = 120 pixels
*/
}
// Tare function: ---------------------------------------------
if (digitalRead(_pin_tare) == 0) {
delay(20);
if (digitalRead(_pin_tare) == 0) {
oled.print("... reading tare");
g000Count = getValue();
EEPROM.put(gEEbaseAddress + 1, g000Count);
}
}
if (digitalRead(_pin_gScale) == 0) {
delay(20);
if (digitalRead(_pin_gScale) == 0) {
oled.print("... reading Scale");
g200Count = getValue();
EEPROM.put(gEEbaseAddress + g000length + 1, g200Count);
}
}
// Scale function: --------------------------------------------
/*
if ( digitalRead(_pin_gScale) == 0){
delay(100);
if ( digitalRead(_pin_gScale) == 0){
oled.clear();
oled.print("place 200g on Scale, press again to continue");
// wait up to 10 seconds for _pin_Scale to go low
if( digitalRead(_pin_gScale) == 1)
delay(5000); // else pin might still be low
while(_pin_gScale) {
}
g200Count = getValue();
EEPROM.put( gEEbaseAddress + g000length + 1, g200Count);
}
}
*/
// ------------------------------------------------------------
} // --- loop ------------------------------------------------
//--- Functions ----------------------------------------------------------------------
int32 getValue() {
byte data[3];
while (digitalRead(_pin_data)) {} // wait for data pin to go low.
for (byte j = 3; j--;) {
for (char i = 8; i--;) {
digitalWrite(_pin_slk, HIGH);
bitWrite(data[j], i, digitalRead(_pin_data));
digitalWrite(_pin_slk, LOW);
}
}
// add 25th clock pulse to put next reading at gain 128
// logic analyzer shows no delay is req'd to meet HX711 input req.
digitalWrite(_pin_slk, HIGH);
digitalWrite(_pin_slk, LOW);
// Replicate the most significant bit to pad out a 32-bit signed integer
uint filler;
if (data[2] & 0x80) {
filler = 0xFF;
} else {
filler = 0x00;
}
// Construct a 32-bit signed integer
int32 value = (static_cast<unsigned int32>(filler) << 24
| static_cast<unsigned int32>(data[2]) << 16
| static_cast<unsigned int32>(data[1]) << 8
| static_cast<unsigned int32>(data[0]));
return value;
}
void oledInit(void) {
Wire.begin();
Wire.setClock(100000L);
oled.begin(&Adafruit128x32, I2C_ADDRESS);
oled.setFont(ZevvPeep8x16); // Screen = 4 (0,2,4,6) lines X 16 characters (0 to 15)
uint widthDisp = oled.displayWidth();
oled.clear();
oled.displayRemap(true); // rotate display 180 deg.
}
// --- eof ------------------------------------------------------------------