#include <HX711_ADC.h>
#include <EEPROM.h>
// pins:
const int HX711_dout = 4; // mcu > HX711 dout pin
const int HX711_sck = 5; // mcu > HX711 sck pin
const int alarm_pin = 8; // mcu > HX711 sck pin
const int sitting_threshold = 30;
const int break_threshold = 300;
const float weight_threshold = 1.0;
bool sitting_flag = false;
bool break_flag = false;
bool print_flag = false;
bool take_break = false;
int break_time = 0;
int sitting_time = 0;
// HX711 constructor:
HX711_ADC LoadCell(HX711_dout, HX711_sck);
const int calVal_eepromAdress = 0;
unsigned long t = 0;
unsigned long sitting_start_time = 0;
unsigned long sitting_end_time = 0;
unsigned long break_start_time = 0;
unsigned long break_end_time = 0;
float load_cell_data = 0.0;
void setup()
{
pinMode(alarm_pin, OUTPUT);
digitalWrite(alarm_pin, LOW);
Serial.begin(57600);
delay(10);
Serial.println();
Serial.println("Starting...");
LoadCell.begin();
float calibrationValue = 3.52;
EEPROM.get(calVal_eepromAdress, calibrationValue);
Serial.print("Calibration value: ");
Serial.println(LoadCell.getCalFactor());
unsigned long stabilizingtime = 2000; // preciscion right after power-up can be improved by adding a few seconds of stabilizing time
boolean _tare = true; // set this to false if you don't want tare to be performed in the next step
LoadCell.start(stabilizingtime, _tare);
if (LoadCell.getTareTimeoutFlag())
{
Serial.println("Timeout, check MCU>HX711 wiring and pin designations");
while (1)
;
}
else
{
LoadCell.setCalFactor(calibrationValue); // set calibration value (float)
Serial.print("Calibration value: ");
Serial.println(LoadCell.getCalFactor());
Serial.println("Startup is complete");
}
}
void loop()
{
static boolean newDataReady = 0;
const int serialPrintInterval = 1000; // increase value to slow down serial print activity
const int vibrationInterval = 500;
// check for new data/start next conversion:
if (LoadCell.update())
newDataReady = true;
// get smoothed value from the dataset:
if (newDataReady)
{
if (millis() > t + serialPrintInterval)
{
float i = LoadCell.getData();
load_cell_data = i/1000;
Serial.print("Load_cell output val: ");
Serial.println(load_cell_data);
newDataReady = 0;
t = millis();
}
}
// receive command from serial terminal, send 't' to initiate tare operation:
if (Serial.available() > 0)
{
char inByte = Serial.read();
if (inByte == 't'){
LoadCell.tareNoDelay();
}
else if (inByte == 'l')
{
delay(10);
if (Serial.available() > 0)
{
load_cell_data = Serial.parseFloat();
Serial.print("Load_cell_data set to: ");
Serial.println(load_cell_data);
}
}
else if (inByte == 's')
{
delay(10);
if (Serial.available() > 0)
{
long myint = Serial.parseInt(SKIP_ALL, '\n');
sitting_time = int(myint);
Serial.print("sitting_time set to: ");
Serial.println(sitting_time);
}
}
else if (inByte == 'b')
{
delay(10);
if (Serial.available() > 0)
{
long myint = Serial.parseInt(SKIP_ALL, '\n');
break_time = int(myint);
Serial.print("break_time set to: ");
Serial.println(break_time);
}
}
}
// check if last tare operation is complete:
if (LoadCell.getTareStatus() == true) {
Serial.println("Tare complete");
}
if (load_cell_data > weight_threshold) // think about getting values till sensor is stabilized
{
if (take_break)
{
// keep ringing the alarm
if (print_flag)
{
Serial.println("telling user to take a break, ringing alarm");
}
if (millis() > t + vibrationInterval)
{
digitalWrite(alarm_pin, !digitalRead(alarm_pin));
t = millis();
}
}
if (print_flag)
{
Serial.print("Someone is sitting, load_cell_data is: ");
Serial.println(load_cell_data);
print_flag = !print_flag;
}
if (break_flag) // if the user was on a break and is sitting back down
{
Serial.print("user was on a break, break_flag is: ");
Serial.println(break_flag);
break_flag = false;
break_end_time = millis();
break_time += int((break_end_time - break_start_time) / 1000); // getting time in seconds here because break is short
if ((break_threshold - break_time) > 45)
{ // check if the user is sitting sooner than the recommended break, or if the difference is greater than at least 45 seconds
Serial.print("did not take the recommended break, difference in seconds is: ");
Serial.println(break_threshold - break_time);
if (sitting_time >= sitting_threshold)
{ // if the user had been sitting for longer than threshold time
Serial.print("total sitting time is more than recommended, prompting for a break, sitting time is: ");
Serial.println(sitting_time);
take_break = true; // prompt them to take a break again
}
else
{ // otherwise they can take a break again later, before their sitting time exceeds thresholds
Serial.print("total sitting time is under threshold, resetting all except for total time ,sitting time is: ");
Serial.println(sitting_time);
resetAllTimesAndFlags();
}
}
else
{ // the user took atleast the recommended break time
Serial.println("user took recommended break, resetting everything for next round");
resetAllTimesAndFlags(); // reset everything, the user is good to sit back down for the next 30 minutes (sitting threshold time)
break_time = 0;
sitting_time = 0;
}
}
if (sitting_start_time <= 0)
{ // this means starting timer for 30 minutes of sitting, happens only if everything was reset
Serial.print("starting timer for sitting since it was not already started yet, sitting time is: ");
Serial.println(sitting_time);
sitting_start_time = millis();
sitting_flag = true;
}
}
else
{ // someone got up from the chair, or there's no load on chair
if (take_break)
{ // user finally got up, so no need to keep ringing the alarm
// set alarm low
take_break = false;
// code to stop the alarm here
digitalWrite(alarm_pin, LOW);
Serial.println("user got up for a break, load cell data is: ");
Serial.print(load_cell_data);
Serial.println("alarm off");
break_start_time = millis();
if (sitting_end_time <= 0)
{
sitting_end_time = millis();
sitting_time += int((sitting_end_time - sitting_start_time) / 60000);
Serial.print("sitting end time was not set, setting time now, sitting time is: ");
Serial.println(sitting_time);
}
break_flag = true;
sitting_flag = false;
}
if (!print_flag)
{
Serial.print("no one is sitting, load_cell_data is: ");
Serial.println(load_cell_data);
print_flag = !print_flag;
}
if (sitting_flag)
{ // check other conditions only if someone was sitting and then stood up
Serial.print("someone was sitting and now stood up, sitting time is: ");
Serial.println(sitting_time);
Serial.print("break time is: ");
Serial.println(break_time);
break_start_time = millis(); // if someone got up then they're taking a break
if (sitting_end_time <= 0)
{
sitting_end_time = millis();
sitting_time += int((sitting_end_time - sitting_start_time) / 60000);
Serial.print("sitting end time was not set, setting time now, sitting time is: ");
Serial.println(sitting_time);
}
break_flag = true;
sitting_flag = false;
}
}
// if someone was sitting, and has been sitting for more than threshold time
if (sitting_flag && !take_break && ((millis() - sitting_start_time) / 60000 + sitting_time) >= sitting_threshold) // divide by 60 to convert milliseconds to minutes
{
Serial.println("someone was sitting and had been sitting for more than threshold, time to take a break");
Serial.print("total sitting time is: ");
Serial.println((millis() - sitting_start_time) / 60000 + sitting_time);
take_break = true;
}
}
void resetAllTimesAndFlags()
{
sitting_start_time = 0;
sitting_end_time = 0;
sitting_flag = false;
break_start_time = 0;
break_end_time = 0;
break_flag = false;
}