Load cell - Led blinking problem

hi guys, my project is a sensitive digital scale. After I power up my project I randomly put something that is 6gr(it could be 22gr too the number doesn't matter) on the scale. And then I am gonna press a button for 5 seconds. after i remove my finger from it the OLED screen is gonna display "6gr reference weight". So from now on if I remove the weight from the scale or put something lighter or heavier than reference weight, for 1 minute a led will blink. after that 1 minute if the reference weight isn't on the scale the buzzer will work for a minute too. For shutting the buzzer the user must press the button for 3 seconds or the scale must have the reference weight.

Components:

  • -load cell 10kg
  • -HX711
  • -Button (for determining the reference weight and shutting the buzzer )
  • -On/off button
  • -Buzzer
  • -OLED screen
  • -Arduino nano

Problem:
It doesn't get the reference weight when I press the button for 5 seconds so I can't even tell if my code for led and buzzer work?

I recently worked on a similar project to this. But can seem to find my way through coding on this one

Here is my code I know its a mess:

#include <HX711_ADC.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

HX711_ADC LoadCell(10, 9);
const int buzzerPin = 12;
const int buttonPin = 5;
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

bool referenceSet = false;
bool buzzerState = false;
bool buttonPressed = false;
unsigned long buttonPressStartTime = 0;
unsigned long lastWeightChangeTime = 0;
const long LED_BLINK_INTERVAL = 60000; // 1 minute in milliseconds
const long BUZZER_INTERVAL = 60000;   // 1 minute in milliseconds
float referenceWeight = 0.0;           // User-defined reference weight

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

void setup() {
  LoadCell.begin();
  LoadCell.start(2000);
  LoadCell.setCalFactor(-230);

  pinMode(7, OUTPUT);             // LED pin
  pinMode(buzzerPin, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);

  Serial.begin(115200);

  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;) ;
  }
  delay(2000);
  display.clearDisplay();
  display.setTextSize(1.2);
  display.setTextColor(BLACK, WHITE);
  display.setCursor(0, 5);
  display.println("   Put the");
  display.println("  reference");
  display.println("   weight");
  display.display();

  // Wait for the user to set the reference weight
  while (!referenceSet) {
    LoadCell.update();
    float weight = max(0, LoadCell.getData());
    display.setTextSize(2);
    display.setCursor(20, 30);
    display.print(weight);
    display.display();
    if (digitalRead(buttonPin) == LOW) {
      referenceWeight = weight;
      referenceSet = true;
      delay(1000); // Wait for a moment to release the button
    }
  }

  display.clearDisplay();
  display.setTextSize(1.2);
  display.setTextColor(BLACK, WHITE);
  display.setCursor(3, 5);
  display.println(" Reference");
  display.println("   weight");
  display.setTextSize(2);
  display.setCursor(20, 30);
  display.print(referenceWeight);
  display.display();
  delay(2000);
}

void loop() {
  LoadCell.update();
  float weight = max(0, LoadCell.getData());

  display.clearDisplay();
  display.setTextSize(1.2);
  display.setTextColor(BLACK, WHITE);
  display.setCursor(3, 5);
  display.println("        Project       ");
  display.println();
  display.setTextColor(WHITE);
  display.setTextSize(3.2);
  display.setCursor(15, 21);
  display.print(weight);
  display.display();

  // Check if the weight is within the tolerance range of the reference weight (e.g., 0.5g)
  if (abs(weight - referenceWeight) <= 0.5) {
    digitalWrite(7, LOW); // Turn off LED
    digitalWrite(buzzerPin, LOW); // Turn off buzzer
    buzzerState = false;
    lastWeightChangeTime = millis();
  } else {
    // Check if the weight has changed and start the timer
    if (weight != referenceWeight) {
      lastWeightChangeTime = millis();
    }

    // Check if the weight has been out of range for more than 1 minute and activate LED and buzzer
    if (millis() - lastWeightChangeTime >= LED_BLINK_INTERVAL) {
      digitalWrite(7, HIGH); // Turn on LED
      if (!buzzerState) {
        digitalWrite(buzzerPin, HIGH); // Turn on buzzer
        buzzerState = true;
      }
    }

    
  

  // Button functionality
  if (digitalRead(buttonPin) == LOW) {
    // Button is pressed
    if (!buttonPressed) {
      buttonPressed = true;
      buttonPressStartTime = millis();
    }

    // If the button has been pressed for 3 seconds, turn off the buzzer
    if (buttonPressed && (millis() - buttonPressStartTime >= 3000) && buzzerState) {
      digitalWrite(buzzerPin, LOW);
      buzzerState = false;
      lastWeightChangeTime = millis(); // Reset the timer to prevent immediate activation of the buzzer
      digitalWrite(7, LOW); // Turn off LED
    }
  } else {
    // Button is released
    buttonPressed = false;
  }
}

I don't mean to bother you guys but do you guys have any idea of finding a way to the solution? :
alto777

gcjr

UKHeliBob

StefanL38

b707

LarryD

jim-p

jremington

Sure I (and very very likely the other quoted users) know of ways to the solution. Though my understanding of this forum is not for delivering ready to use code.
You have posted a pretty good description of the wanted functionality.
As in most applications you need to execute multiple tasks in "parallel"
This requires non-blocking timing.
And your application overall can be solved with a state-machine.

If you have any specific questions ask them here in the forum.
Read the linked tutorials and then ask specific questions.

best regards Stefan

What am I, sliced bologna? :slight_smile:

and.... duplicate post
https://forum.arduino.cc/t/weight-sensor-buzzer-problem/1153593/15

1 Like

hey, thanks a lot for the sources. I have been looking into them for the past few days. I solved the referenced weight issue. When I press the button for 3 seconds it captures the weight.

I do have a specific question for you. I tried one of your sources about the led blinking but I couldn't implement on it in my code, I mean in my opinion my code seems fine but when I run it nothing happens.

When I press the button for 3 seconds it captures the referenced weight, when I put something heavier than the referenced weight on top of the scale the led isnt blinking even tho I believe I code it right. Maybe I made a mistake with a curly bracelet? I am not sure. I can't seem to fix it. Can you help me please? I have been working on this for days
Heres the part about the led:

if (referenced && displayWeight > itWeight) {
    // Blink the LED and turn on the buzzer if current weight is greater
    static unsigned long previousMillis = 0;
    unsigned long currentMillis = millis();

    if (currentMillis - previousMillis >= 500) { // Blink every 500ms
      previousMillis = currentMillis;
      digitalWrite(7, !digitalRead(7)); // Toggle the LED state
    }
    }
    else {
      digitalWrite(7, LOW); // Turn off the LED
  }

and the code itself:


#include <HX711_ADC.h> 
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

HX711_ADC LoadCell(10, 9); // parameters: dt pin 6, sck pin 7;

const int buttonPin = 5; 
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

int ledPin = 7;
bool manualBuzzerOff = false;
bool buttonPressed = false;
bool referenced = false; // To indicate if the reference weight is captured
unsigned long buttonPressStartTime = 0;
float itWeight = 0; // Variable to store the reference weight
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

void setup() 
{
  LoadCell.begin(); 
  LoadCell.start(2000); 
  LoadCell.setCalFactor(-230); 
 
  pinMode(7,OUTPUT);
  pinMode(buzzerPin, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);

  Serial.begin(115200);
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }
  delay(2000);
  display.clearDisplay();
}
void loop() {
  LoadCell.update(); // retrieves data from the load cell
  float i = LoadCell.getData(); // get output value
  float displayWeight = max(0, i);
  display.clearDisplay();
  display.setTextColor(WHITE); 
  display.setTextSize(3.2);
  display.setCursor(36,21);
  display.print(displayWeight,1); 

  // Button functionality
  if (digitalRead(buttonPin) == LOW) {
    // Button is pressed
    if (!buttonPressed) {
      buttonPressed = true;
      buttonPressStartTime = millis();
    }
    
    // If the button has been pressed for 3 seconds, capture the reference weight
    if (buttonPressed && (millis() - buttonPressStartTime >= 3000)) {
      itWeight = displayWeight;
      referenced = true; // Indicate that reference weight is captured
      buttonPressed = false;
      }
    }
    else {
    // Button is released
    if (buttonPressed && referenced) {
      // Display referenced weight on OLED
      display.clearDisplay();
      display.setTextSize(1.2);
      display.setTextColor(WHITE);
      display.setCursor(0, 5);
      display.println("Referenced weight=");
      display.print(itWeight, 1);
      display.display();
      delay(3000);
    }
    buttonPressed = false;
    referenced = false; // Reset the reference weight flag
  }
  
 // Compare the current weight to the "it weight" and control the LED
  if (referenced && displayWeight > itWeight) {
    // Blink the LED and turn on the buzzer if current weight is greater
    static unsigned long previousMillis = 0;
    unsigned long currentMillis = millis();

    if (currentMillis - previousMillis >= 500) { // Blink every 500ms
      previousMillis = currentMillis;
      digitalWrite(7, !digitalRead(7)); // Toggle the LED state
    }
    }
    else {
      digitalWrite(7, LOW); // Turn off the LED
  }
  }

is this comment valid or not?
if it is valid you are using io-pin 7 as sck-pin and in parallel to blink an LED

For analysing:
checking if your hardware is OK

unsigned long MyTestTimer = 0;                   // Timer-variables MUST be of type unsigned long
const byte    LED_pin = 7;


void BlinkHeartBeatLED(int IO_Pin, int BlinkPeriod) {
  static unsigned long MyBlinkTimer;
  pinMode(IO_Pin, OUTPUT);
  
  if ( TimePeriodIsOver(MyBlinkTimer,BlinkPeriod) ) {
    digitalWrite(IO_Pin,!digitalRead(IO_Pin) ); 
  }
}


void setup() {
  Serial.begin(115200);
  Serial.println("Setup-Start");
}


void loop() {
  BlinkHeartBeatLED(LED_pin ,250);
}

For analysing what your code is really doing
add serial printing to your code

best regards Stefan

Hi, thank you for taking your time to respond to me. HX711_ADC LoadCell(10, 9); // parameters: dt pin 6, sck pin 7; that comment is not valid. I forgot to delete it after changing the pins.

I deleted this line from my code buttonPressed = false; and it worked. When I put something heavier than referenced weight the led blinks.

This is like the first step of my project I still need to figure out the 2nd and 3rd:

  1. if I remove the weight from the scale or put something lighter or heavier than reference weight, for 1 minute a led will blink.

  2. After that 1 minute if the reference weight isn't on the scale the buzzer will work for a minute too.

  3. For shutting the buzzer the user must press the button for 3 seconds or the scale must have the reference weight.*

But thank you again Stefan

Those damn curly bracelets!

Srsly,

{ braces }
[ brackets ]
( parentheses )

I know, not where you come from. I know not what your mother calls them. I know there are other valid, legal, proper, popular and widely used names for those common characters.

I do think, however, that when the subject is C or C++, that the real names (!) should be used.

a7

Darn auto-carrot again!

For what you call your 2nd and 3rd step in your project there is only one step to learn

learning how state-machines work

all in all you have more than two conditions. Whenever you have more than two conditions that make up sequences

a good way to write code for such sequences is to use a state-machine

Your process is

set reference weight

  1. if any weight is on the scale
    check if a button is pressed for 5 seconds which means take a snapshot of time and

  2. measure how much time goes by while the button is pressed down

  3. when button is pressed down for more than 5 seconds use this weight as reference weight
    and show message on display

operation after defining reference-weight

  1. check if reference-weight is on the scale
    if a different weight is measured make a snapshot of time

  2. and measure how much time goes by while weight is different
    if more than one minute has passed by

  3. switch on LED
    if more than two minutes have passed by make snapshot of time and

  4. turn on buzzer
    check if more than 1 minute has passed by since buzzer was switched on
    if more than 1 minute have passed by switch buzzer of

all in all 7 different things. You could say 7 different states.
You can code this by using many many if-elseif-elseifelseifelseif-elses
creating a big mess where to set which flag-variable true or false

Or you learn how state-machines work and once you have learned it
you never will go back to if-elseif-elseif-elseif-

The state-machine will be very easy to modify and very easy to maintain
once you have understood the basic principle.

You have avoided to already use a state-machine.
I really recommend that you are learning it

best regards Stefan

In fact, in many situations, it is simply not possible to avoid using it.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.