#include <LiquidCrystal_I2C.h>
#include <HX711.h>

#define DOUT A3
#define CLK A2
#define TARE_PIN 7
#define UNIT_PIN 8
#define LED_PIN 9
#define BUZZER 2

enum Unit {GRAM, OZ};

HX711 scale;
LiquidCrystal_I2C lcd(0x27, 16, 2);

float calibration_factor = 373;
float gram_to_oz = 0.035274;
float threshold_weight = 4000; // in grams
float last_data;
float weight;
Unit unit = GRAM;

void setup() {
  lcd.init();
  lcd.backlight();
  lcd.clear();

  Serial.begin(9600);

  scale.begin(DOUT, CLK);
  scale.set_scale(calibration_factor);
  scale.tare();

  pinMode(TARE_PIN, INPUT_PULLUP);
  pinMode(UNIT_PIN, INPUT_PULLUP);
  pinMode(LED_PIN, OUTPUT);

  lcd.print(" Digital Weight ");
  lcd.setCursor(0, 1);
  lcd.print(" Scale  Arduino ");
  delay(3000);
  lcd.clear();
  lcd.print("By Haris.Galang");
  lcd.setCursor(0, 1);
  lcd.print("Anilasari. Desta");
  delay(3000);
  lcd.clear();
}

void loop() {
  weight = scale.get_units(15);
  lcd.setCursor(0, 0);
  lcd.print("Weight: ");
  if (unit == GRAM) {
    lcd.print(weight, 0);
    lcd.setCursor(0, 1);
    lcd.print("Unit  : gram");
  } else {
    lcd.print(weight * gram_to_oz, 1);
    lcd.setCursor(0, 1);
    lcd.print("Unit  : oz");
  }

  Serial.print("Weight: ");
  Serial.print(weight, 1);
  Serial.println(" gram");

  if (digitalRead(TARE_PIN) == LOW) {
    last_data = weight;
    scale.tare();
    lcd.setCursor(0, 1);
    lcd.print("   Tare done!   ");
    delay(2000);
    lcd.clear();
  }

  if (digitalRead(UNIT_PIN) == LOW) {
    unit = (Unit)(1 - unit);
    lcd.setCursor(0, 1);
    lcd.print(" Unit  changed! ");
    delay(2000);
    lcd.clear();
  }
  
  blink_led();
}

void blink_led() {
  if (unit == GRAM) {
    if (weight + last_data >= threshold_weight) {
      digitalWrite(LED_PIN, HIGH);
      digitalWrite(BUZZER, HIGH);
      delay(300);
      digitalWrite(LED_PIN, LOW);
      digitalWrite(BUZZER, LOW);
      delay(300);
    }
  } else {
    if (weight + last_data >= threshold_weight * gram_to_oz) {
      digitalWrite(LED_PIN, HIGH);
      digitalWrite(BUZZER, HIGH);
      delay(300);
      digitalWrite(LED_PIN, LOW);
      digitalWrite(BUZZER, LOW);
      delay(300);
    }
  }
}