Pushbutton to toggle between units (ounces and grams) with HX711 and LCD screen

Hi, I am new to Arduino and coding in general. I am making a scale using HX711, 16x2 LCD screen, 5k load cell and Arduino Uno. I currently have a code which works fine reading weights in grams, but i am trying to implement a push button to display the readings in ounces.

There are 2 buttons installed, 1 to tare (pin9), the other to change units (pin6)
All functionality works fine, aside from the unit option, can anyone give any advice? I /**/ the portion of the code I am struggling with. Thank you

#include "HX711.h"

#define DOUT  8
#define CLK  7


#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int tarePin = 9;  //Tare button at pin 9
int unitsPin = 6; //Units button at pin 6
float tareVal = 0;
float i=0;


HX711 scale;

float calibration_factor = 220; //calibration factor for 5kg amazon load cell with gain 128 and grams as units

void setup() {
 pinMode(SCK, OUTPUT);
 pinMode(tarePin, INPUT_PULLUP);
 lcd.begin(16,2);

  scale.begin(DOUT, CLK, 128); //Start communications to HX711 pins and set gain factor 64|128 are options on Channel A
  scale.set_scale(calibration_factor);           //Required during scale startup, scale factor will be adjusted in main loop for calibration
  scale.tare();                //Reset the scale to 0

}

void loop() {

  
  lcd.print("Weight: ");
  lcd.print(scale.get_units(4), 1);
  lcd.print("g");
  delay(1000);
  lcd.clear();
    
if(digitalRead(tarePin) == LOW){
    //If tare button is pressed
        scale.tare();                //Reset the scale to 0
/*if (digitalRead(unitsPin) == LOW){        
    //If units button is pressed
    lcd.print(scale.get_units*(0.035274)(4), 1);
*/
{
  }    }}

Do you have the code for calculating the ounces?

To edit what you've got already you probably want something similar to this:

#include "HX711.h"

#include "KTS_Button.h"

#define DOUT  8
#define CLK  7

#define tarePin 9  //Tare button at pin 9
#define unitsPin 6 //Units button at pin 6

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

float tareVal = 0;
float i = 0;

HX711 scale;

float calibration_factor = 220; //calibration factor for 5kg amazon load cell with gain 128 and grams as units

KTS_Button tareButton(tarePin);
KTS_Button unitsButton(unitsPin);

enum Unit {
  grams = 0,
  ounces,
  NUM_UNITS
}; Unit currentUnit = grams;

void cycleUnits() {
  currentUnit = currentUnit + 1;
  if (currentUnit == NUM_UNITS)
    currentUnit = 0;
}

void setup() {
  Serial.begin(9600);
  pinMode(SCK, OUTPUT);
  lcd.begin(16, 2);
  scale.begin(DOUT, CLK, 128); //Start communications to HX711 pins and set gain factor 64|128 are options on Channel A
  scale.set_scale(calibration_factor);           //Required during scale startup, scale factor will be adjusted in main loop for calibration
  scale.tare();                //Reset the scale to 0
}

void loop() {

  if (tareButton.read() == SINGLE_PRESS) {
    scale.tare();
  }

  if (unitsButton.read() == SINGLE_PRESS) {
    cycleUnits();
    lcd.clear();
    lcd.print("Weight: ");

    switch (currentUnit) {
      case grams:
        lcd.print(scale.get_units * (0.035274)(4), 1);
        lcd.print("g");
        break;

      case ounces:
        // replace with ounces calc/print
        lcd.print("oz");
        break;
    }
  }
}

But you've got to get some button debouncing in there (easiest to use a button library), or you'll be playing roulette as to whether it lands on grams or ounces :smiley: I've used my own in the example above KTS_Button.h (3.6 KB) but any will do.

This is also assuming that hitting the units button, means you want to change the units to the next unit, and then also display the weight?

I've only tested this as far as serial prints, the buttons and the cycling/printing of the units. I haven't tested anything to do with the scale (I had it all commented out).

1 Like

Thank you st3v3n92

i know the conversion factor for grams to ounces is 1 gram = 0.035274 ounces, that's where my attempt in conversion came in on my original code

lcd.print(scale.get_units*(0.035274)(4), 1);
which should be
lcd.print(scale.get_units(4), 1);

thanks for sharing the KTS file! i downloaded it to the folder.

I see you left a space for the calc which would be the what the load cell is reading * 0.035274, when i try to put that after "get_units" it tells me i cant use it as a function.

case ounces:
lcd.print(scale.get_units * 0.035274, (4), 1);
lcd.print("oz");
break;

im not sure how to grab the reading and multiply it by 0.35274?

Try:
lcd.print((scale.get_units(4) * 0.035274), 1);

(providing that your numbers are correct)

1 Like

st3v3n, thanks again for all your help. I was going at this for 2 days, the button library is awsome and the unit switching works like a charm! Thanks You!

No worries at all. There are plenty of button libraries out there that do more than mine, are coded better, or are smaller, but I wrote it as a bit of a learning exercise. Anyway, glad you found it useful.

If you're able to show it, it would be fun to see! It might only be simple but it's always a buzz to see code roaming free in the real world.

1 Like

I can absolutely share the code!

It doesn't take live readings (readings every second) but it does take readings upon pressing the "Units Button"

#include "HX711.h"

#include "KTS_Button.h"

#define DOUT  8
#define CLK  7

#define unitsPin 6 //Units button at pin 6

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int tarePin = 9;  //Tare button at pin 9
float tareVal = 0;
float i = 0;

HX711 scale;

float calibration_factor = 360; //calibration factor for 5kg amazon load cell with gain 128 and grams as units

KTS_Button tareButton(tarePin);
KTS_Button unitsButton(unitsPin);

enum Unit {
  grams = 0,
  ounces,
  NUM_UNITS
}; Unit currentUnit = grams;

void cycleUnits() {
  currentUnit = currentUnit + 1;
  if (currentUnit == NUM_UNITS)
    currentUnit = 0;
}

void setup() {
  pinMode(SCK, OUTPUT);
  pinMode(tarePin, INPUT_PULLUP);
  lcd.begin(16, 2);
  scale.begin(DOUT, CLK, 128); //Start communications to HX711 pins and set gain factor 64|128 are options on Channel A
  scale.set_scale(calibration_factor);           //Required during scale startup, scale factor will be adjusted in main loop for calibration
  scale.tare();                //Reset the scale to 0
}

void loop() {
  if (tareButton.read() == SINGLE_PRESS) {
    scale.tare();
  }
 
  if (unitsButton.read() == SINGLE_PRESS) {
    cycleUnits();
    lcd.clear();
    lcd.print("Weight: ");
    delay(1000);
  

    switch (currentUnit) {
      case grams:
        lcd.print(scale.get_units (4), 1);
        lcd.print("g");
        break;
      case ounces:
        lcd.print(scale.get_units (4) * 0.03524, 1);
        lcd.print("oz");
        break;
    }
    }    }

Ah I meant seeing the scale in action but no worries.

The button library can do long presses, if you wanted to set it so that short pressing the unit button takes a reading and long press changes the units that would be very easy, just change the SINGLE_PRESS to LONG_PRESS and add the extra if statement. Saves having to cycle the units just to get a new reading.

I don't think it would be much to make it do constant 'live' readings if that's what wanted to achieve here?

Sorry for the late reply

Oh, lol, sure I can post a pic/Vid of the scale in action when I finish the project!

As for the live readings, what I was going for with the first code is an interface similar to your run of the mill kitchen or lab scale. Where if you needed, say, 16oz of water, you can gradually pour the water and watch the readout update as you pour.

Thanks again St3v3n!

Take this for a spin and see how it works for you. It should update the LCD twice a second (every 500 milliseconds), I set the update frequency (READ_FREQUENCY_MS) at the top. The faster you let it update the more the screen will flicker, then again slow updates aren't helpful on a 'live' scale so you might need to find a balance.

#include "HX711.h"

#include "KTS_Button.h"

#define READ_FREQUENCY_MS 500

#define DOUT  8
#define CLK  7

#define unitsPin 6 //Units button at pin 6

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

int tarePin = 9;  //Tare button at pin 9
float tareVal = 0;
float i = 0;

HX711 scale;

float calibration_factor = 360; //calibration factor for 5kg amazon load cell with gain 128 and grams as units

KTS_Button tareButton(tarePin);
KTS_Button unitsButton(unitsPin);

enum Unit {
  grams = 0,
  ounces,
  NUM_UNITS
}; Unit currentUnit = grams;

void cycleUnits() {
  currentUnit = currentUnit + 1;
  if (currentUnit == NUM_UNITS)
    currentUnit = 0;
}

void setup() {
  pinMode(SCK, OUTPUT);
  pinMode(tarePin, INPUT_PULLUP);
  lcd.begin(16, 2);
  scale.begin(DOUT, CLK, 128); //Start communications to HX711 pins and set gain factor 64|128 are options on Channel A
  scale.set_scale(calibration_factor);           //Required during scale startup, scale factor will be adjusted in main loop for calibration
  scale.tare();                //Reset the scale to 0
}

void loop() {
  if (tareButton.read() == SINGLE_PRESS) {
    lcd.clear();
    lcd.print("Tare");
    delay(1000);
    scale.tare();
  }

  if (unitsButton.read() == SINGLE_PRESS) {
    cycleUnits();
  }

  static uint32_t timeCapture;

  if ((millis() - timeCapture) > READ_FREQUENCY_MS) {
    timeCapture = millis();
    
    lcd.clear();
    lcd.print("Weight: ");
    lcd.setCursor(0,1);

    switch (currentUnit) {
      case grams:
        lcd.print(scale.get_units (4), 1);
        lcd.print("g");
        break;
      case ounces:
        lcd.print(scale.get_units (4) * 0.03524, 1);
        lcd.print("oz");
        break;
    }
  }
}