Store weight to EEPROM and find difference-> SOLVED, new question about accuracy

Hello to the forum,

i’m working on a project with arduino and load sensors and i’m stuck at the point which i want to store the weight value to eeprom and then calculate the difference with the value taken after.

Here is the code, i haven’t worked with eeprom and i’m sure there will be some mistake.
Any help appreciated.

#include "HX711.h"
#include <EEPROM.h>

#define DOUT  3 //HX711 DOUT pin
#define CLK  2 //HX711 CLK pin

HX711 scale(DOUT, CLK);


int address = 0;      //EEPROM address counter

float calibration_factor = -22390; //
float weight; //Variable to save the weight
float lastmass;
float difference;


void setup() {
  
 Serial.begin(9600);

 //Start HX711 module
  setuphx711();
  delay(1000);
  
}

void loop() {
  
  scale.power_up();
  delay(1000); 
    
  readhx711();
  delay(1000);
  
  Serial.print("weight: ");
  Serial.print(weight, 1);
  Serial.print(" kg");
  Serial.println();
  
  lastmass = EEPROM.read(address);
  difference = weight - lastmass;   

  Serial.print("difference: ");
  Serial.print(difference);
 // Serial.print(" grams");
  Serial.println();

  delay(5000);
}

void setuphx711() {
  // Start up the library
// zero factor from SparkFun_HX711_Calibration by sarahalmutlaq
 //long zero_factor = scale.read_average(); //Get a baseline reading
  long zero_factor = -47037;//-49634;//-46406; //-10000;
  scale.set_scale(calibration_factor);   // this value is obtained by calibrating the scale with known weights; see the README of the library for details
 //scale.tare();      // reset the scale to 0
  scale.set_offset(zero_factor); //Zero out the scale using a previously known zero_factor for a permanent weight on the scale
}


void readhx711(){

  weight = scale.get_units(10), 1; //Average of 10 measurements
 
  EEPROM.write(address, lastmass);         //write value to current address counter address
  
  delay(100);
  
  scale.power_down();             // put the ADC in sleep mode
  delay(1000);
  
  }
EEPROM.write(address, lastmass);

EEPROM.write() writes a single byte, not a float

Take a look at the EEPROM.put() and EEPROM.get() functions to save and load a float (or any other type of variable) using a single command

Thank you for your answer, i made the changes you suggested but still cant get it to work.
The code with put and get :

#include "HX711.h"
#include <EEPROM.h>

#define DOUT  3 //HX711 DOUT pin
#define CLK  2 //HX711 CLK pin

HX711 scale(DOUT, CLK);


int address = 0;      //EEPROM address counter

float calibration_factor = -22390; //
float weight; //Variable to save the weight
float lastmass;
float difference;


void setup() {
 
 Serial.begin(9600);

 //Start HX711 module
  setuphx711();
  delay(1000);
 
}

void loop() {
 
  scale.power_up();
  delay(1000);
   
  readhx711();
  delay(1000);
 
  Serial.print("weight: ");
  Serial.print(weight, 1);
  Serial.print(" kg");
  Serial.println();
 
  lastmass = EEPROM.get(address, weight);
  difference = lastmass - weight;   

  Serial.print("difference: ");
  Serial.print(difference, 1);
 // Serial.print(" grams");
  Serial.println();

  delay(5000);
}

void setuphx711() {
  // Start up the library
// zero factor from SparkFun_HX711_Calibration by sarahalmutlaq
 //long zero_factor = scale.read_average(); //Get a baseline reading
  long zero_factor = -47037;//-49634;//-46406; //-10000;
  scale.set_scale(calibration_factor);   // this value is obtained by calibrating the scale with known weights; see the README of the library for details
 //scale.tare();      // reset the scale to 0
  scale.set_offset(zero_factor); //Zero out the scale using a previously known zero_factor for a permanent weight on the scale
}


void readhx711(){

  weight = scale.get_units(10), 1; //Average of 10 measurements
 
  EEPROM.put(address, weight);
  delay(100);
 
  scale.power_down();             // put the ADC in sleep mode
  delay(1000);
 
  }

but still cant get it to work.

Can you be more specific about what in the program is failing.

What are you trying to do here?

weight = scale.get_units(10), 1;

In setup(), you need to GET from EEPROM, the value that you previously PUT.

cattledog:
Can you be more specific about what in the program is failing.

What are you trying to do here?

weight = scale.get_units(10), 1;

Arduino connected to hx711 amplifier and then the load sensor measures the weight, this the keyword from the library to get the load presented as weight in average of 10 measurements and show it with one demical place.

I can't get it to work because the difference is always wrong measurement or 0.I think that it store it on eeprom but can't do the calculation of difference which is the the current weight - previous weight measurement.

Why would you use EEPROM to store a value for each "loop"? That's not a good idea since EEPROM wears out after ~100k writes.

You are storing "weight" to EEPROM and then recovering it as "lastmass" and comparing it to "weight". "lastmass" and "weight" will therefore always be equal. You should recover "lastmass" before storing a new value to EEPROM to make it work.

I'm storing on EEPROM because after the weight measurement the arduino will shutdown until ane external timer wake it up.I will try what you suggested, thanks.

If you only want the code to take one measurement, you should do it in "setup()" and not in "loop()".

aristosmarkos:
Arduino connected to hx711 amplifier and then the load sensor measures the weight,
this the keyword from the library to get the load presented as weight in average of 10 measurements
and show it with one demical place.

This is what you hope it will do, but it is not what the code really does.

weight = scale.get_units(10), 1;

Do something with the scale, throw the result away and store a 1 into weight.

See: Comma operator - Wikipedia

Sorry but this mistake may seem obvious but i'm beginner on programing, i changed the line you mentioned to:

weight = scale.get_units(10);

I understood the mistake after reading, although this doesn't solved the problem of the difference calculation.
Any ideas how to retrieve from EEPROM the last measurement (lastmass) - the current weight (weight)?

aristosmarkos:
Any ideas how to retrieve from EEPROM the last measurement (lastmass) - the current weight (weight)?

UKHeliBob:
Take a look at the EEPROM.put() and EEPROM.get() functions to save and load a float (or any other type of variable) using a single command

weight = scale.get_units(10), 1;

Sorry but this mistake may seem obvious but i'm beginner on programing, i changed the line you mentioned to:
weight = scale.get_units(10);

Great. The syntax to print a float to one decimal point is not valid for other operations.

Now please post the current code, and an explanation of "the problem with the difference calculation."

The workflow in "setup()" should be something like:

  1. Initialize serial and scale
  2. Get "lastmass" from EEPROM
  3. Get "weight" from scale
  4. Store "weight" to EEPROM
  5. Subtract "lastmass" from "weight" and print to serial

Your "loop()" can be empty if you only want one measurement.

After trial and error and help from all the kind people above i finally made it to work.
All the inputs where to the right direction and the result is the code below.

#include "HX711.h"
#include <EEPROM.h>

#define DOUT  3 //HX711 DOUT pin
#define CLK  2 //HX711 CLK pin

HX711 scale(DOUT, CLK);


int address = 0;      //EEPROM address counter

float calibration_factor = -22420; //
float weight; //Variable to save the weight
float lastmass;
float difference;


void setup() {
 
 Serial.begin(9600);

 //Start HX711 module
  setuphx711();
  delay(1000);
 
}

void loop() {
 
  scale.power_up();
  delay(1000);

  lastmass = EEPROM.get(address, weight);
   
  readhx711();
  delay(1000);
 
  Serial.print("weight: ");
  Serial.print(weight, 1);
  Serial.print(" kg");
  Serial.println();
 
  
  difference = weight - lastmass;   

  Serial.print("difference: ");
  Serial.print(difference * 1000, 1);
  Serial.print(" grams");
  Serial.println();

  delay(5000);
}

void setuphx711() {
  // Start up the library
// zero factor from SparkFun_HX711_Calibration by sarahalmutlaq
 //long zero_factor = scale.read_average(); //Get a baseline reading
  long zero_factor = -45666;//-49634;//-46406; //-10000;
  scale.set_scale(calibration_factor);   // this value is obtained by calibrating the scale with known weights; see the README of the library for details
 //scale.tare();      // reset the scale to 0
  scale.set_offset(zero_factor); //Zero out the scale using a previously known zero_factor for a permanent weight on the scale
}


void readhx711(){

  weight = scale.get_units(10); //Average of 10 measurements
 
  EEPROM.put(address, weight);
  delay(100);
 
  scale.power_down();             // put the ADC in sleep mode
  delay(1000);
 
  }

Additionally to this is there any way to be as much as possible precise to the measurements of HX711 and load sensors? I mean is there any filter or code that could be applied to take into account the temperature changes that affect the measurements?

Note that

  lastmass = EEPROM.get(address, weight);

could be written as

  EEPROM.get(address, lastmass);

You might like to calculate how many times the EEPROM will be written to in say 24 hours bearing in mind the 100,000 write guaranteed life of the EEPROM