// RGB LED will blink RED if RPI is not connected & will retry for some time, after that if still not connected it will glow BLUE
// RGB will glow GREEN if connected to RPI or BLUE if not connected to RPI
// RGB will blink GREEN(if connected)/BLUE(if not connected) when weight is locked
// RGB will blink white when weight is registered successfully & good is ready to be unloaded
// For the weight to lock automatically minimum delay is 2 second and maximum weight difference is (+/-)50gm.
// For the weight to unlock automatically minimum weight difference is (+/-)50gm.
// Weight data will be sent to RPI in case of lockedweight==true only and minimum lock delay must be 5 second(after locked).
#include "HX711.h"
#include <LiquidCrystal.h>
#include <CuteBuzzerSounds.h>
void setLED(int);
void image();
// LCD initialization
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);
// Scale initialization
#define DOUT 5
#define CLK 4
#define DIFF_UNITS 0.2
#define DIFF_TIME 4000
HX711 scale;
float calibration_factor = 420;
float units;
boolean weightLock = false;
float lockedWeight = 0;
// Button initialization
#define TARE_BTN 6 // make it D2
const unsigned long DebounceTime = 10;
boolean ButtonWasPressed = false;
unsigned long ButtonStateChangeTime = 0; // Debounce timer
boolean buttonContineousPress = false;
// Bluetooth Initialization
// SoftwareSerial bluetooth(2, 3); // Define a SoftwareSerial object for Bluetooth communication (TX, RX)
#define RETRY_TIME 13000
boolean isConnected = false;
// RGB led initialization
#define R A0
#define G A1
#define B A2
int ledMode = 0; // 0 = none, 1 = red-blink, 2 = blue-glow, 3 = green-glow, 4 = blue-blink, 5 = green-blink, 6 = white-glow
unsigned long previousTime = 0; // For led on/off timing
unsigned long previousWeightTime = 0; // For led on/off timing
float previousWeight = 0;
boolean onHalt = false;
// Buzzer pin
#define BUZZER_PIN 3
void setup() {
// bluetooth.begin(9600);
lcd.begin(16,2);
for (int j = 0; j < 16; j++) {
delay(20);
lcd.setCursor(abs(j-7),0);
lcd.print("#");
lcd.setCursor(abs(j+7),0);
lcd.print("#");
lcd.setCursor(abs(j-7),1);
lcd.print("#");
lcd.setCursor(abs(j+7),1);
lcd.print("#");
}
for (int j = 0; j < 16; j++) {
delay(20);
lcd.setCursor(abs(j-7),0);
lcd.print(" ");
lcd.setCursor(abs(j+7),0);
lcd.print(" ");
lcd.setCursor(abs(j-7),1);
lcd.print(" ");
lcd.setCursor(abs(j+7),1);
lcd.print(" ");
}
cute.init(BUZZER_PIN);
lcd.setCursor(0,0);
lcd.print(" WELCOME ! ");
delay(100);
// image();
// delay(20000);
cute.play(S_MODE3); //scale turned on
pinMode(TARE_BTN, INPUT_PULLUP);
pinMode(R, OUTPUT);
pinMode(G, OUTPUT);
pinMode(B, OUTPUT);
Serial.begin(9600);
for (int j = 0; j < 16; j++) {
delay(20);
lcd.setCursor(abs(j-7),0);
lcd.print("*");
lcd.setCursor(abs(j+7),0);
lcd.print("*");
lcd.setCursor(abs(j-7),1);
lcd.print("*");
lcd.setCursor(abs(j+7),1);
lcd.print("*");
}
for (int j = 0; j < 16; j++) {
delay(20);
lcd.setCursor(abs(j-7),0);
lcd.print(" ");
lcd.setCursor(abs(j+7),0);
lcd.print(" ");
lcd.setCursor(abs(j-7),1);
lcd.print(" ");
lcd.setCursor(abs(j+7),1);
lcd.print(" ");
}
// delay(200);
lcd.setCursor(0,0);
lcd.print("Connecting.");
lcd.setCursor(0,1);
lcd.print("Timeout in ");
lcd.setCursor(13,1);
lcd.print("sec");
int x = 10;
unsigned long startTime = millis();
while (millis() - startTime <= RETRY_TIME) {
int remainingTime = (RETRY_TIME/1000 - 1 - ((millis() - startTime)/1000));
lcd.setCursor(11,1);
if (remainingTime < 10) {
lcd.print("0");
lcd.setCursor(12,1);
}
lcd.print(remainingTime);
if ((millis() - previousTime) > 500) {
ledMode == 1 ? setLED(0) : setLED(1);
previousTime = millis();
if (x < 16) {
lcd.setCursor(x,0);
lcd.print(".");
x++;
} else {
x = 10;
lcd.setCursor(x,0);
lcd.print(" ");
}
}
if (Serial.available()) { // if (bluetooth.available()) {}
// String message = bluetooth.readStringUntil('\n');
String message = Serial.readStringUntil('\n');
if (message == "rpi") {
isConnected = true;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Device connected");
lcd.setCursor(0,1);
lcd.print("successfully");
setLED(2);
cute.play(S_CONNECTION); // rpi connected
break;
}
} else {
// Serial.println("Bluetooth not available !!");
}
}
if (isConnected == false) {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Device failed");
lcd.setCursor(0,1);
lcd.print("to connect");
setLED(3);
cute.play(S_DISCONNECTION); // rpi disconnected
}
delay(200);
setLED(0);
// delay(50);
scale.begin(DOUT, CLK);
scale.set_scale(calibration_factor);
scale.tare();
Serial.println("Long press button to tare");
lcd.clear();
// lcd.setCursor(0,0);
lcd.print(" Current Weight ");
previousWeightTime = millis();
}
bool wasNegative = false;
void loop() {
if ((millis() - previousTime) > 500 && onHalt == false) {
isConnected ? setLED(2) : setLED(3);
previousTime = millis();
}
units = scale.get_units(), 5;
int BTN_state = checkBTN();
if (!onHalt) {
if (previousWeight > (units - DIFF_UNITS) && previousWeight < (units + DIFF_UNITS)) {
if ((millis() - previousWeightTime) > DIFF_TIME && weightLock == false) {
if (units < 0) {
tone(BUZZER_PIN, 1100); // Pin 11, 1000Hz frequency, 150ms duration
delay(130);
noTone(BUZZER_PIN);
delay(130);
tone(BUZZER_PIN, 1100); // Pin 11, 2000Hz frequency, 300ms duration
delay(130);
noTone(BUZZER_PIN);
previousWeightTime = millis();
} else if (units > 0) {
previousWeightTime = millis();
Serial.print("diff true, at weight : ");
Serial.println(units);
weightLock = true;
lockedWeight = units;
Serial.println("Weight Locked");
lcd.setCursor(0,0);
lcd.print(" Weight Locked! ");
previousWeightTime = millis();
tone(BUZZER_PIN, 1000); // Pin 11, 1000Hz frequency, 150ms duration
delay(180);
noTone(BUZZER_PIN);
tone(BUZZER_PIN, 2000); // Pin 11, 2000Hz frequency, 300ms duration
delay(100);
noTone(BUZZER_PIN);
} else {
previousWeightTime = millis();
}
}
} else {
previousWeight = units;
previousWeightTime = millis();
}
if (weightLock == false) {
if (wasNegative == true) {
lcd.setCursor(3,1);
lcd.print(" ");
wasNegative = false;
}
if (units < 10 && units > -10) {
if (units < 0) {
wasNegative = true;
lcd.setCursor(3,1);
lcd.print("-0");
lcd.setCursor(5,1);
lcd.print(abs(units),2);
} else {
lcd.setCursor(4,1);
lcd.print(0);
lcd.print(units,2);
}
} else if (units > 9) {
lcd.setCursor(4,1);
lcd.print(units,2);
} else if (units < -9) {
lcd.setCursor(3,1);
lcd.print(units,2);
}
lcd.setCursor(10,1);
lcd.print("KG");
if(BTN_state == 2) {
if (units <= 0) {
tone(BUZZER_PIN, 1100); // Pin 11, 1000Hz frequency, 150ms duration
delay(130);
noTone(BUZZER_PIN);
delay(130);
tone(BUZZER_PIN, 1100); // Pin 11, 2000Hz frequency, 300ms duration
delay(130);
noTone(BUZZER_PIN);
} else if (units > 0) {
weightLock = true;
lockedWeight = units;
Serial.println("Weight Locked");
lcd.setCursor(0,0);
lcd.print(" Weight Locked! ");
tone(BUZZER_PIN, 1000); // Pin 11, 1000Hz frequency, 150ms duration
delay(180);
noTone(BUZZER_PIN);
tone(BUZZER_PIN, 2000); // Pin 11, 2000Hz frequency, 300ms duration
delay(100);
noTone(BUZZER_PIN);
}
}
} else if (weightLock == true) {
if ((millis() - previousWeightTime) > DIFF_TIME/2 && isConnected) {
Serial.print("Locked Weight ");
Serial.print(lockedWeight);
Serial.println(" Submitting");
if (Serial.available()) {
if (isConnected && Serial.readStringUntil('\n') == "rcv") {
setLED(0);
lcd.clear();
lcd.print("Weight Submitted");
lcd.setCursor(0,1);
lcd.print("Amount: ");
lcd.print(lockedWeight);
lcd.print("KG");
onHalt = true;
tone(BUZZER_PIN,3000);
delay(100);
setLED(4);
noTone(BUZZER_PIN);
delay(200);
setLED(0);
tone(BUZZER_PIN,3000);
delay(150);
noTone(BUZZER_PIN);
setLED(4);
previousWeightTime = millis();
}
}
}
if (abs(lockedWeight - units) > DIFF_UNITS || BTN_state == 2 || units == 0 || (units > 0-DIFF_UNITS && units < 0) ) {
weightLock = false;
Serial.println("Weight Unlocked");
tone(BUZZER_PIN, 2000); // Pin 11, 2000Hz frequency, 300ms duration
delay(180);
noTone(BUZZER_PIN);
tone(BUZZER_PIN, 1000); // Pin 11, 1000Hz frequency, 150ms duration
delay(100);
noTone(BUZZER_PIN);
// delay(220);
lcd.setCursor(0,0);
lcd.print(" Current Weight ");
}
ledMode == 2 || ledMode == 3 ? setLED(0) : setLED(99);
}
} else {
Serial.print("Scale on HALT, Remove any loads to continue, curr units : ");
Serial.println(units);
if (units >= (0 - DIFF_UNITS) && units <= DIFF_UNITS) {
onHalt = false;
tone(BUZZER_PIN,4000);
delay(100);
noTone(BUZZER_PIN);
lcd.clear();
lcd.print(" Current Weight ");
} else if (millis() - previousWeightTime > 4000) {
previousWeightTime = millis();
tone(BUZZER_PIN,8500);
setLED(0);
delay(180);
tone(BUZZER_PIN,3000);
delay(200);
setLED(4);
tone(BUZZER_PIN,2500);
delay(200);
tone(BUZZER_PIN,4000);
setLED(0);
delay(200);
noTone(BUZZER_PIN);
setLED(4);
}
}
}
int checkBTN() {
unsigned long currentTime = millis();
boolean buttonIsPressed = digitalRead(TARE_BTN) == LOW;
unsigned long timeTaken = currentTime - ButtonStateChangeTime;
if (ButtonWasPressed && buttonContineousPress == false) {
unsigned long pressedTime = currentTime - ButtonStateChangeTime;
previousWeightTime = millis();
if (pressedTime/1000 >= 2) {
buttonContineousPress = true;
lcd.setCursor(0,0);
lcd.clear();
lcd.print(" Reseting Scale");
Serial.println("Reseting Scale");
weightLock = false;
tone(BUZZER_PIN, 2000); // Pin 11, 2000Hz frequency, 300ms duration
delay(130);
tone(BUZZER_PIN, 1800); // Pin 11, 1000Hz frequency, 150ms duration
delay(130);
tone(BUZZER_PIN, 1500); // Pin 11, 1000Hz frequency, 150ms duration
delay(100);
// tone(BUZZER_PIN, 1200); // Pin 11, 1000Hz frequency, 150ms duration
tone(BUZZER_PIN, 2000); // Pin 11, 1000Hz frequency, 150ms duration
delay(50);
noTone(BUZZER_PIN);
scale.tare(); //Reset the scale to zero
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Measuring Weight");
return 99;
}
}
if (buttonIsPressed != ButtonWasPressed && timeTaken > DebounceTime)
{
ButtonWasPressed = buttonIsPressed;
ButtonStateChangeTime = currentTime;
if (!ButtonWasPressed)
{
if (buttonContineousPress == true) {
buttonContineousPress = false;
return 3;
}
buttonContineousPress = false;
// Serial.println("Burron released once");
return 2;
}
}
return 0;
}
void setLED(int mode = -1) {
// 0 = none, 1 = red-glow, 2 = green-glow, 3 = blue-glow, 4 = white-glow
(mode >= 0 && mode <= 4) ? ledMode = mode : ledMode = ledMode;
switch(ledMode) {
case 0:
digitalWrite(R, LOW);
digitalWrite(G, LOW);
digitalWrite(B, LOW);
break;
case 1:
digitalWrite(R, HIGH);
digitalWrite(G, LOW);
digitalWrite(B, LOW);
break;
case 2:
digitalWrite(R, LOW);
digitalWrite(G, HIGH);
digitalWrite(B, LOW);
break;
case 3:
digitalWrite(R, LOW);
digitalWrite(G, LOW);
digitalWrite(B, HIGH);
break;
case 4:
digitalWrite(R, HIGH);
digitalWrite(G, HIGH);
digitalWrite(B, HIGH);
break;
}
}