#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <Keypad.h>
#include "HX711.h"
LiquidCrystal_I2C lcd_1(0x27, 16, 2); // disply configuration
const int ROW_NUM = 4; // four rows // keypad configuration
const int COLUMN_NUM = 4; // four columns
char keys[ROW_NUM][COLUMN_NUM] = {
{ '1', '2', '3', 'A' },
{ '4', '5', '6', 'B' },
{ '7', '8', '9', 'C' },
{ '*', '0', '#', 'D' }
};
byte pin_rows[ROW_NUM] = { 9, 8, 7, 6 }; // connect to the row pinouts of the keypad
byte pin_column[COLUMN_NUM] = { 5, 4, 3, 2 }; // connect to the column pinouts of the keypad
Keypad customKeypad = Keypad(makeKeymap(keys), pin_rows, pin_column, ROW_NUM, COLUMN_NUM);
const int BUZZER_PIN = 10; // buzzer configuration
#define calibration_factor -7050.0 //This value is obtained using the SparkFun_HX711_Calibration sketch
#define LOADCELL_DOUT_PIN A0
#define LOADCELL_SCK_PIN A1
HX711 scale;
int trigPin = 12; // TRIG pin // ultrasonic sensor configuration
int echoPin = 11; // ECHO pin
float duration_us, distance_cm;
// Input buffer string
#define MAXBUF 20
char buf[MAXBUF];
// Pointer to the last string buffer char
byte ptr = 0;
bool PhoneInput = false;
// The final string containing the phone number
char PhoneNo[20];
// The entered age (0=no age entered)
byte Age = 0;
enum {
S_Idle, // defaults to 0
S_Phone, // defaults to 1
S_Age, // defaults to 2
S_Gender, // defaults to 3
S_Height, // defaults to 4
S_Weight, // defaults to 5
S_Receipt, // defaults to 6
}
State = S_Idle;
int Scale_Mode = 0;
char customKey = customKeypad.getKey();
void displayscreen() { // screen saver
lcd_1.setCursor(4, 0);
lcd_1.print("*iScale*");
lcd_1.setCursor(2, 1);
lcd_1.print("!Your Scale!");
lcd_1.scrollDisplayLeft();
delay(200);
lcd_1.scrollDisplayRight();
}
/*void weight() { // weight measurement module to be activated later
Serial.print("Reading: ");
Serial.print(scale.get_units(), 1); //scale.get_units() returns a float
Serial.print(" lbs"); //You can change this to kg but you'll need to refactor the calibration_factor
Serial.println();
delay(1000);
/*if(Scale_Mode != 0){
State = S_Phone;
}
switch (GetKey("CD")) {
case 'C':
State = S_Phone;
return;
case 'D':
State = S_Phone;
return;
}*/
//}*/
void weight2() { // weight measurement module to be activated later
Serial.print("Reading: ");
Serial.print(scale.get_units(), 1); //scale.get_units() returns a float
Serial.print(" lbs"); //You can change this to kg but you'll need to refactor the calibration_factor
Serial.println();
delay(1000);
State = S_Receipt;
}
void Height() { // height measurement module
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration_us = pulseIn(echoPin, HIGH);
distance_cm = 0.017 * duration_us;
//lcd_1.clear();
// lcd_1.setCursor(0, 1);
// lcd_1.print("Height: ");
// lcd_1.print(distance_cm);
Serial.print("Height: ");
Serial.println(distance_cm);
delay(1000);
State = S_Weight;
}
byte GetKey(const char* Allowed, bool ShowChar = true) {
byte NumAllowed = strlen(Allowed);
char customKey = customKeypad.getKey();
if (customKey != NO_KEY && ptr < MAXBUF - 1) {
for (byte i = 0; i < NumAllowed; ++i) {
if (customKey == Allowed[i]) {
Scale_Mode = 1;
tone(BUZZER_PIN, 750, 100); // make a beep sound
if (ShowChar) {
// Replace this with LCD print, if needed
Serial.print(customKey);
}
buf[ptr++] = customKey;
buf[ptr] = 0x0; // Always end the string with 0x0
return customKey;
}
}
}
return NO_KEY;
}
void BufReset() {
ptr = 0;
buf[0] = 0x0;
}
void weight3() { // weight measurement module to be activated later
switch (GetKey("0CD")) {
case 'C':
State = S_Phone;
return;
case 'D':
State = S_Phone;
return;
case '0':
State = S_Phone;
return;
}
Serial.print("Reading: ");
Serial.print(scale.get_units(), 1); //scale.get_units() returns a float
Serial.print(" lbs"); //You can change this to kg but you'll need to refactor the calibration_factor
Serial.println();
delay(400);
}
void setup() {
Serial.begin(9600);
pinMode(BUZZER_PIN, OUTPUT);
lcd_1.init(); // initialize the lcd
lcd_1.init();
// Print a message to the LCD.
lcd_1.backlight();
Serial.println("HX711 scale demo"); // load cell module to be activated
scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
//scale.set_scale(calibration_factor); //This value is obtained by using the SparkFun_HX711_Calibration sketch
//scale.tare();
// Start input
PhoneInput = true;
//Serial.print("Enter phone number ending with '#': ");
}
void loop() {
Height();
/*// DEBUG ONLY ----------------------
static int OldState = -1;
if (State != OldState) {
OldState = State;
Serial.print("State: ");
Serial.println(State);
}
// ---------------------------------
switch (State) {
case S_Idle:
weight3();
//displayscreen();
//State = S_Weight;
//State = S_Phone;
break;
case S_Phone:
GetPhone();
// Move to next state
//State = S_Age;
break;
case S_Age:
GetAge();
// Move to next state
//State = S_Gender;
break;
case S_Gender:
GetGender();
// Move to next state
//State = S_Height;
break;
case S_Height:
Height();
// Move to next state
//State = S_Weight ;
break;
case S_Weight:
weight2();
// Move to next state
/* if (Scale_Mode = 0) {
State = S_Idle; }
else if (Scale_Mode = 1) {
State = S_Receipt;
}
// State = S_Receipt;
break;
case S_Receipt:
GetReceipt();
// Move to next state
//State = S_Idle;
Scale_Mode = 0;
break;
}*/
}
void GetPhone() {
switch (GetKey("0123456789#CD")) {
case '#':
// Phone end
strcpy(PhoneNo, buf);
BufReset();
Serial.println();
// Reset buffer
PhoneInput = false;
Serial.print("Thank you, entered phone number is: ");
Serial.println(PhoneNo);
State = S_Age;
return;
case 'C':
BufReset();
Serial.println(" *CLEAR*");
// Send the prompt again
Serial.print(": ");
return;
case 'D':
BufReset();
Serial.println(" *RESET*");
State = S_Idle;
return;
}
}
void GetAge() {
switch (GetKey("0123456789CD")) {
case 'C':
BufReset();
Serial.println(" *CLEAR*");
// Send the prompt again
Serial.print(": ");
return;
case 'D':
BufReset();
Serial.println(" *RESET*");
// Next state
//State = S_WAIT;
State = S_Idle;
return;
}
if (strlen(buf) == 2) {
// Two digits have been entered!
//atoi(Age, buf);
Age = atoi(buf);
Serial.print("Thank you, your age is: ");
Serial.println(Age);
BufReset();
State = S_Gender;
}
}
void GetGender() {
//Serial.println("please select your Gender");
//Serial.println("Male=* / Female=#");
switch (GetKey("*#CD")) {
case 'C':
BufReset();
Serial.println(" *CLEAR*");
// Send the prompt again
Serial.print(": ");
return;
case 'D':
BufReset();
Serial.println(" *RESET*");
State = S_Idle;
return;
case '*':
BufReset();
Serial.println(" *You are a male*"); // this data to be sent to the computer for furthur calculations
State = S_Height;
return;
case '#':
BufReset();
Serial.println(" *You are a female*");
State = S_Height;
return;
}
}
void GetReceipt() {
switch (GetKey("0*#CD")) {
case '0':
State = S_Phone;
return;
case 'C':
BufReset();
Serial.println(" *CLEAR*");
// Send the prompt again
Serial.print(": ");
return;
case 'D':
BufReset();
Serial.println(" *RESET*");
State = S_Idle;
return;
case '*':
BufReset();
Serial.println(" *You choose to print a receipt *"); // this data to be sent to the computer for furthur calculations
displayscreen();
State = S_Idle;
return;
case '#':
BufReset();
Serial.println(" *You choose not to print a receipt*");
displayscreen();
State = S_Idle;
return;
}
}