2

PROGRESS, now I have this (WITH GREAT HELP):

void setup() {
   Serial.begin(9600);
// initialize digital pin 13 as an output.
}
uint32_t timer_start = 0;
int timer_running = false;



void loop()
 {
// Get LDR information
  int sensorValue = analogRead(A0);         // read the input on analog pin 0
  float voltage = sensorValue * (5.0 / 1023.0);     // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V)
  float lux = voltage * 100;

 if (lux>150) {
    if (!timer_running) {
      // Timer is not already running, so capture the start time
      timer_start = millis();
      timer_running = true;
    }
  } else {
    if (timer_running) {
      // The timer is currently running; stop it calculate/print the run time
      timer_running = false;
      Serial.println((millis()-timer_start) / 1000.0, 3); // format however you like here

    }
  }

 }

This now tells me how many millis the gymnast is in the air, divided by 1000.0 with 3 decimals. If I start the Serial Monitor when the gymnast is in the trampoline bed, then I can get the seconds of air_time the gymnast has. Is there a way to have this script running ONLY for 10 loops?

  • 2
    You test if the lux is above 150 and always execute that code as long as the lux is above 150. You need to know the moment that the lux is above 150 for the first time. Have a look at this example: arduino.cc/en/Tutorial/StateChangeDetection Turning millis into minutes and seconds can be done with /60 and %60 after the elapsed millis is divided by 1000. – Jot Oct 8 '18 at 15:18
  • I think you need to maintain a static unsigned long last_off = 0; state variable in loop{}, resetting at the end of the else clause: last_off = millis(); and also report at the beginning of the else clause if some on_time=millis()-last_off is greater than some threshhold. Are you having problems with the formatting? Or with calculating the on time? – Dave X Oct 8 '18 at 15:20
  • With your updated code, you did not maintain the same code structure as in the given example. In your updated code, the if (lux>150) {...} block has the timer start and stop code, where instead, the if (lux>150) {...} block should have the timer starting code, and the else {...} block (meaning, where lux<=150) should have the timer stopping code. – jose can u c Oct 10 '18 at 1:20
3

Declare a global (or static) boolean variable to keep track of whether the timer is running or not, as well as a variable to hold the start millis() value. When the lux drops below your threshold, subtract the current millis() from the start value, and you have the duration in milliseconds, which is trivial to convert to mm:ss.sss format.

Example code (not a complete sketch)

uint32_t timer_start = 0;
uint8_t timer_running = false;

void loop() {
  if (lux>150) {
    if (!timer_running) {
      // Timer is not already running, so capture the start time
      timer_start = millis();
      timer_running = true;
    }
  } else {
    if (timer_running) {
      // The timer is currently running; stop it calculate/print the run time
      timer_running = false;
      Serial.print(millis()-timer_start); // format however you like here
    }
  }
}

This now tells me how many millis the gymnast is in the air, divided by 1000.0 with 3 decimals. If I start the Serial Monitor when the gymnast is in the trampoline bed, then I can get the seconds of air_time the gymnast has. Is there a way to have this script running ONLY for 10 loops?

Certainly. If it is assumed that you want a cumulative total air-time, then you need to declare another global or static variable to hold the cumulative air-time, and you need to have another variable to keep track of how many cycles have passed.

void setup() {
   Serial.begin(9600);
// initialize digital pin 13 as an output.
}
uint32_t timer_start = 0;
int timer_running = false;
uint32_t total_time = 0;
uint8_t jump_count = 0;

void loop()
{
// Get LDR information
  int sensorValue = analogRead(A0);         // read the input on analog pin 0
  float voltage = sensorValue * (5.0 / 1023.0);     // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V)
  float lux = voltage * 100;

  if (jump_count<10) {
    if (lux>150) {
      if (!timer_running) {
        // Timer is not already running, so capture the start time
        timer_start = millis();
        timer_running = true;
      }
    } else {
      if (timer_running) {
        // The timer is currently running; stop it calculate/print the run time
        timer_running = false;
        // Add this-jump air time to the cumulative total:
        total_time += millis()-timer_start;
        // Increment jump_count
        jump_count++;

        Serial.println((millis()-timer_start) / 1000.0, 3); // format however you like here
      }
    }
  } else {
    // Print the total air-time for 10 jumps;
    Serial.println((total_time)) / 1000.0, 3);
  }
}
  • Why uint16_t and uint8_t? Why not just int? – AgoraLive Oct 9 '18 at 15:55
  • 1
    Those types are not critical. On Arduino, memory is tight, so it's simply a preference to use the smallest necessary variable type. timer_running can fit in the smallest type, uint8_t, while any result from millis() is an unsigned long, equivalent to uint32_t (fixed in the example code; should not have been uint16_t) – jose can u c Oct 9 '18 at 15:57
  • Alright, thx. Now for the timer_running, what is the reason for the "!" exclamation mark? And does the timer go in the void setup, in the void loop or in between? – AgoraLive Oct 9 '18 at 16:08
  • ! is the negation operator. So you are checking if NOT(timer_running) then do whatever. So if the timer is already running, you do not save the current millis() because you're already counting time. – jose can u c Oct 9 '18 at 16:10
  • What it is counting? All I see are 1 and 0's? – AgoraLive Oct 9 '18 at 20:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.