Conditional timer for sensor

Hey guys. New to programming in Arduino here so sorry about my poor code structure. If you look at my attached code I have a load cell that is detecting weight and I have if statements that display triggers when the weight is over the weight threshold. Different if statements will execute as time goes on as I have an unsigned long called timesitting which is measured in millis. I only want my timer to start once my load cell detects weight that is over the weight threshold. If anyone can help that would be appreciated. once again apolose if this hurts your brain because I haven't displayed code correctly.

weight_snsor_respondingprogress.ino (1.93 KB)

boolean timing = false;

void setup()
{
    ...
}

void loop()
{
    if (!timing && weight >= threshold)
    {
       start time = millis();
       timing = true;
    }
}

As written the timesitting variable is updated each time through loop()

I only want my timer to start once my load cell detects weight that is over the weight threshold.

You need to save the value of millis() when the weight becomes more than the threshold (not is more than the threshold). Then you can determine how much time has passed since then by subtracting the start time from the time now.

Look at the StateChangeDetection example in the IDE and the BlinkWithoutDelay example

For a more in depth explanation and ideas look at Using millis() for timing. A beginners guide and Several things at the same time

Thanks for the reply guys I will look into both options. evanmars your code doesn't seem to work sorry. not sure if and what way I need to modify it to suit my code.

Definitely would be needed to be modified. I'm on a phone so couldn't see your code.

It was a bit of code to show how to grab the time when the weight reached the threshold value.
State Change.

Conorw117:
I only want my timer to start once my load cell detects weight that is over the weight threshold.

I like to use a 0 in the StartTime to indicate that the timer is not running. It saves having a separate boolean flag to keep track of that bit of information.

unsigned long StartTime;
const unsigned long Interval = 30000;
void setup()
{
    StartTime = 0;  // Timer is not running
}
void loop()
{
    if (StartTime == 0)
    {
        // Timer is not running.  Check for condition to start the timer.
        if (weight > threshold)
            StartTime = millis();  // Start the timer
    }
    else // Timer is running
    {
        if (millis() - StartTime >= Interval)
        {
            // Timer was running and has expired
            StartTime = 0;  // Stop the timer
       
            // DO YOUR TIMER EXPIRED STUFF HERE
        }
    }
}

There is one millisecond every 40+ days where the timer start will be delayed by one millisecond.

Johnwasser Thank you your code is working however in the serial monitor it says 0 then counts when weight is used then once lifted will go back to 0, however, when I then press on the weight again it goes from zero to the number it would be if I had not let go. so, in other words, it still counts upwards. Also once the program starts it immediately starts counting zeros without input.

(example)

0
0
0
0
0
0
0
1000
2000
3000
4000
5000
0
0
0
0
0
0
0
0
6000
7000
8000

my example might have ailed to demonstrate. it's more like this

0
0
3000
0
0
0
0
0
10000
11000
12000
0
0
0
0
0
0
0
0
0
22000
23000

You must have added code to make it print something. Perhaps you used the example incorrectly?

The example I provided does not look at the weight while the timer is running so it can't be causing the value to change when you take the weight away.

Your sketch seems to be producing output once per second. Do you have a delay()? Or a separate timing loop to only check at one second intervals?

I think I have used the example incorrectly. I have #define breakreminder 8000 and 15000 and I want a message to display after the weight => threshold for 8 seconds then again after 15 seconds. no matter when the weight is >=threshold but this cannot be done as it continues to go up 1000 a second and never going back down again. yes, it returns to zero but will resume from the last number as soon as weight >= threshold.

Conorw117:
I think I have used the example incorrectly.

Perhaps. It's hard to say because I can't see your sketch from here. The example only implemented one timer and it sounds like you have two different intervals to time.

here my code. sorry about the structure. im new

#include <HX711.h>
#include <SD.h>
#include <pcmConfig.h>
#include <pcmRF.h>
#include <TMRpcm.h>
#define BREAKREMINDERS 15000//Second break reminder
#define BREAKREMINDERT 30000// Third break reminder
#define BREAKREMINDER 8000
#define WEIGHT_THRESHOLD 4 //Threshold to count for person sitting
#define SD_ChipSelectPin 4 // SD CARD IN PIN 4
#define SPEAKER 9 // SPEAKER OUTPUT IN PIN 9
#define DOUT 3
#define CLK 2
TMRpcm tmrpcm;
HX711 scale;

float calibration_factor = -7050; //-7050 worked for my 440lb max scale setup
float weight;
unsigned long StartTime; //Sitting timer
const unsigned long Interval = 5000;

void SetupSound() {
// put your setup code here, to run once:
tmrpcm.speakerPin = SPEAKER;
tmrpcm.CSPin = SD_ChipSelectPin;

if (!SD.begin(SD_ChipSelectPin))

{
Serial.println("failed to read card..");
return;
}

tmrpcm.setVolume(5);
Serial.println("Card read success..");

}

void setup() {

Serial.begin(9600);
Serial.println("HX711 calibration sketch");
Serial.println("Remove all weight from scale");
Serial.println("After readings begin, place known weight on scale");
Serial.println("Press + or a to increase calibration factor");
Serial.println("Press - or z to decrease calibration factor");

scale.begin(DOUT, CLK);
scale.set_scale();
scale.tare(); //Reset the scale to 0

long zero_factor = scale.read_average(); //Get a baseline reading
Serial.print("Zero factor: "); //This can be used to remove the need to tare the scale. Useful in permanent scale projects.
Serial.println(zero_factor);

StartTime = 0; // Timer is not running

SetupSound();

}

void loop() {

if (StartTime == 0)
{
// Timer is not running. Check for condition to start the timer.
if (weight > WEIGHT_THRESHOLD)
StartTime = millis(); // Start the timer
}
else // Timer is running
{
if (millis() - StartTime >= Interval)
{
// Timer was running and has expired
StartTime = 0; // Stop the timer

// DO YOUR TIMER EXPIRED STUFF HERE

}

}

Serial.println(StartTime);

weight = scale.get_units();
weight = weight;
if ( weight < 12000 ) {
weight = 0;
}

if ( weight >= WEIGHT_THRESHOLD ) {

Serial.println("trigger..");
tmrpcm.play("123.wav");

}

if (( weight >= WEIGHT_THRESHOLD) && (StartTime > BREAKREMINDER )){

Serial.println("trigger2..");
tmrpcm.play("124.wav");

}

}