One step left!

Hi Arduino veterans!

I am using an circuit on TinkerCAD to simulate the actual circuit I’m going to run. I thought I had the code down, but I realised that I’m not sure how to offset my workStart back to 0.

Basically, when the ldr is covered for a certain period of time intervalrisk, the led will light up. To switch the led off, the ldr must be uncovered for time intervalrest. Then ideally, workStart can somehow be returned to zero.

Since intervalrisk depends on workStart, which takes current time of the Arduino using millis() in my code, my led will always glow whenever i recover the ldr.

Most of the code I find on the forums will either need me to scrap my 10 hours of coding on the project when I still have homework from other subject to do, aren’t what I need or will break the arduino. I have asked my friends who did Arduino before and for much longer than me, and all of them can’t figure it out either.

What exact strings of code can I add to my current code, or how can I rework my code such that my workStart starts at 0 whenever the ldr is uncovered?

I have attached the image of the circuit, the code I’m using and the link to the tinkerCAD simulation I’m using. Please help out this sleep-deprived college student :’).

tinkercad: https://www.tinkercad.com/things/hIUr2FwotT7-daring-bombul-crift/editel?sharecode=UnLErLli9dtess2O-UhqI6P0xjNfHItF6v8gCN65yBI=

const int ldrPin = 0;//ldr on pin A0
int L;//ldr reading
int led = 3;//led on pin D3
int ledState = LOW;//led is initally off
unsigned long workStart =0;//used to timestamp start of work
unsigned long restStart =0;//used to timestamp start of rest
unsigned long workTime =0;//duration of work
unsigned long restTime =0;//duration of rest
int intervalrest = 1000;//good rest duration
int intervalrisk = 2000;//bad work duration
 

void setup() {
  // put your setup code here, to run once:
  pinMode(led,OUTPUT);//motor will output
  Serial.begin(9600);//start takin analog measurements

}

void loop() {
  // put your main code here, to run repeatedly:
  L = analogRead(ldrPin);//P has value of fsr pin

  if (L<600){//wrist touch wristbed
      workStart=millis();
      Serial.println("Contact. Working for ___ ms.");//print Contact on serial monitor
      workTime=millis();//take current timestamp of cycle as starting work first time wrist touch
          Serial.println(workTime);
        if (workTime - workStart > intervalrisk){//if duration of work exceeds risk
            Serial.println("Take a break!");
            if (ledState==LOW){//if motor off
            digitalWrite(led,HIGH);//motor on
            } 
        }
     
  } 
      
  
  if (L>600){//wrist leaves wristbed
      Serial.println("No contact. Rested for _____ ms");
      restTime=millis()-workTime;//take timestamp of restTime
      Serial.println(restTime);
      if (restTime - restStart > intervalrest){
          Serial.println("Risk avoided! Resume work if needed.");
          digitalWrite(led,LOW);
      }      
             
        else if (restTime - restStart < intervalrest){
          Serial.println("Take a longer break.");
        }
      
    }
      
      
        
        
      
}
}

ainulmr98:
I am using an circuit on TinkerCAD to simulate the actual circuit I'm going to run. I thought I had the code down, but I realised that I'm not sure how to offset my workStart back to 0.

I don't mean to sound unkind but I cannot make sense of what you have written. The way you have written your Post you seem to be assuming that we already know all about your project and your program.

Tell us what you are trying to make and how it is intended to work.

...R

workStart=millis();
      Serial.println("Contact. Working for ___ ms.");//print Contact on serial monitor
      workTime=millis();//take current timestamp of cycle as starting work first time wrist touch
          Serial.println(workTime);
        if (workTime - workStart > intervalrisk)

At the time you get to that if statement you have just in the last three statements set both of those variables, workTime and workStart equal to millis. So what do you think the chances are that they are really different bu more than 1 ms?

Seems like you need to keep a variable to remember whether or not the ldr was covered on the last pass of loop and only get those start times when the sensor changes from covered to uncovered or vice versa. See the state change example for an example of how to do this with a digital pin. The concept for what you are doing will be the same.

Sorry about that. Didn’t want to make my first post too long.

This is how the simulation is supposed to go.:

The Process:
1)when LDR is covered, L(DR reading) < 600

2A) When L<600 for 2000ms or more, the led will light up
2B) To switch the LED off, LDR must be uncovered for at least 1000ms . Otherwise, the LED continues to light up.
2C) When LDR is uncovered for 1000ms or more, the LED switches off and the timer will reset to 0 from >2000ms

3A) When the ldr is uncovered (L>600) during the 2000ms interval,
3B) If ldr is uncovered for less than 1000ms, the millis continue counting towards the 2000s until 2A happens
3C) If ldr is uncovered for 1000ms or more, the 2000ms resets and the timer starts counting again from when the LDR is next covered.

Basically, from the time the LDR is first covered, a duration of at least 2000ms will light the led. To switch off the led and/or reset the timer( measuring the time from the first covering of the LDR), the ldr should be uncovered for at least 1000ms. If the ldr is covered for elss than 1000ms, the timer will continue timing and not reset

OK, forget code for a minute. Imagine how you would do that if you were the little man inside the processor. You have a clock (millis) and a piece of paper (variables) that you can use to get and record the time and you have the ability to read the sensor and light the led. You don’t have any “timer” that you can set, but you don’t need one with the clock and the paper. How would you do it then.

if (the led is OFF){
    if ( LDR < 600 and the last LDR reading was > 600){
          record the time LDR was first covered
    }
    if ( the current time minus the first LDR covering is > 2000)
         light the LED
    }
}
if (the LED is ON){
    similar logic here