Errors in calculating speed after selecting menu option

Hello! First time caller, long time listener.

I am building a shutter speed tester using an Arduino Uno R3, 20x4 LCD, a KY-008 laser, and a DS18B20 (ISO203) laser sensor. I know shutter speed testers have been made by oodles of people before, but mine is a bit different. I have a switch to enable the timing process. I think of it as a faux-menu.
See my circuit below.

My problem right now is I can't figure out how to get the Arduino to calculate the amount of time the sensor reads HIGH (or 1). I have been searching posts and tinkering with code for the past 2 months, and cannot figure out how to get what I want. Currently, it automatically starts calculating the variables I have.
My code is below. I do have it printing results via Serial for debugging purposes. Eventually, I plan to have the final product able to be used by itself and print results on the LCD.

THE CODE:

#include <LiquidCrystal_I2C.h>
#include <Wire.h>

//variables that will change are below 
int Fired = 0; //when Fired = 1, that means the shutter has opened and closed. This is reset to 0 once the time has been calculated and shown on screen.
int lastSensorState = 0;
int RisingFlag = 0;
int FallingFlag = 0;
unsigned long Start;
unsigned long Stop;


//variables that will NOT change are below 
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 20, 4); 
const int STATUSLED = 13;

#define SENSOR 2 //pin 2 is the laser sensor
#define LASER 8 //pin 8 is the laser emitter

void setup()    //This part of the program is run exactly once on boot
{
  Serial.begin(9600);   //opens a serial connection.
  lcd.init();
  lcd.backlight();
  pinMode(STATUSLED, OUTPUT);    //initialize the status LED as an output:
  pinMode(LASER, INPUT);    //initialize the laser as an input. 
  pinMode(SENSOR, INPUT);    //initialize the sensor as an input.
  lcd.setCursor(0,0);
  lcd.print("Shutter Tester");
  delay(750);
  digitalWrite(STATUSLED,1);
  lcd.setCursor(0,1);
  lcd.print("V:1.3 | JMC2021");
  delay(1500);
  digitalWrite(STATUSLED,0);
  delay(1000);
  lcd.clear();
}

void loop()   // this part of the program is run, over and over again
{
  lcd.setCursor(0,0);
  lcd.print("Press Start");
  lcd.setCursor(0,1);
  lcd.print("to enable.        ");
  int enabled = digitalRead(LASER);
  while(enabled == 1)
  {
    digitalWrite(STATUSLED, 1);
    lastSensorState = 0;
    RUN();
  }
}

void RUN()
{
  int enabled = digitalRead(LASER);
  int sensorState = digitalRead(SENSOR);  //sensorState is based off of what pin 2 is reading. When starting, pin 2 should be LOW since the shutter is in blocking the laser.
  int RisingFlag = 0;
  int FallingFlag = 0;
  while(enabled == 0)
  {
    digitalWrite(STATUSLED, 0);
    loop();
  }
  if(sensorState = 0 && (lastSensorState == 0))
  {
    lcd.setCursor(0,0);
    lcd.print("Enabled!            ");
    lcd.setCursor(0,1);
    lcd.print("Fire Shutter!       ");
  }
  if(sensorState = 1 && (lastSensorState == 0))
  {
    RisingFlag = 1;
    lastSensorState = 1;
  }
  if(sensorState == 0 && (lastSensorState == 1))
  {
    FallingFlag = 1;
  }
  
  if(RisingFlag = 1)
  {
    Start = micros();
    RisingFlag = 0;
    lastSensorState = 1;
  }
  if(FallingFlag = 1)
  {
    Stop = micros();
    FallingFlag = 0;
    lastSensorState = 0;
    Fired = 1;
  }
  if(Fired == 1)
  {
    lcd.clear();
    long Speed = (Stop - Start);
      Serial.print("Start: ");
      Serial.println(Start);
      Serial.print("Stop: ");
      Serial.println(Stop);
      Serial.print("Micros: ");
      Serial.println(Speed);
      float SS = (float)Speed/1000000;
      float SS2 = 1/SS;
      Serial.print("shutter speed: ");
      if (SS2 < 1)    // if SS is shorter than 1 second, it will be shown as such.
        {
          Serial.println("1/" + String(1/SS) + "s");
            lcd.setCursor(0,0);
            lcd.print("Shutr: 1/" + String(1/SS) + "s");
            lcd.setCursor(0,1);
            lcd.println(Speed);
            lcd.setCursor(0,2);
            lcd.println(SS       );
            lcd.setCursor(8,2);
            lcd.println(SS2  );
        } 
      else        //if SS is 1 second or longer, it will display in full seconds. 
        { 
          Serial.println(String(SS) + "s");
            lcd.setCursor(0,0);
            lcd.print("Shutr2 " + String(SS) + "s");
            lcd.setCursor(0,1);
            lcd.println(Speed);
            lcd.setCursor(0,2);
            lcd.println(SS       );
            lcd.setCursor(8,2);
            lcd.println(SS2  );
        }
      Serial.println(SS);
      Serial.println(SS2);
      Serial.println();
      lcd.println();
    Start = 0;
    Stop = 0;
    Fired = 0;
    RisingFlag = 0;
    FallingFlag = 0;
    delay(2000);
    lcd.clear();
    lcd.print("FINISHED");
    delay(1000);
    lastSensorState = 0;
  }
}

I know it's not perfect, but with this being my first Arduino project, it's bound to have a few flaws.

The current result I am getting is as soon as I turn the switch on to activate RUN( );, the program immediately calculates SS2, even without me directing light to the sensor.
I just added the three "if" statements to the beginning of RUN() tonight. Originally, I had it only triggering by sensorState, but I was still having difficulty getting it to calculate how much time the sensor was triggered for.

I need a fresh set of eyes on this to see just how many things I'm doing wrong... or if this project is even feasible.
Maybe it's just nonsensical to have a switch to enable the timing process, but I just don't want the screen running on and on with results as I'm fumbling with my cameras or setting it up.

My circuit diagram is below. I can take a picture of my actual setup, but this diagram is exactly what I'm dealing with.

Thoughts?

circuit (2).png

circuit (2).png

In preferences, I have compiler warnings set to "more" ... it found 4 conditional statements with problems .
Namely, you need to use == instead of =.

Circuit diagram shows D2 connected to GND - you probably meant that its connected to the output of the laser receiver.

In your RUN() function, it calls the loop() from within a while loop. This is recursive.

  while(enabled == 0)
  {
    digitalWrite(STATUSLED, 0);
    loop();
  }

Try a new strategy that doesn't call the loop() or use a while loop.

dlloyd:
Circuit diagram shows D2 connected to GND - you probably meant that its connected to the output of the laser receiver.

I will take a photo of my setup after work tonight and post it. The laser receiver has 3 pins. VCC is to power, OUT is the trigger signal going to pin 2, and GND is to ground. I was trying to find a suitable circuit symbol that would appropriately represent what I have.

dlloyd:
In your RUN() function, it calls the loop() from within a while loop. This is recursive.

Try a new strategy that doesn't call the loop() or use a while loop.

If I understand correctly, the code is not recursive for me.
The "enabled" variable is the status of power going to the laser emitter.
When power is switched on, the code is to go to RUN(). While in RUN(), if it is turned off, it goes back to the idle screen in loop().
I wrote it like this because once the program was in RUN(), it wouldn't go back to loop() unless I told it to.
In order for me to get the switch to work appropriately, and not use the While-loop, would I just use a series of "if" statements? Or would using cases be the best option for me?
I know I need to do some more studying up of C++, but I need a bit of direction as to where or what I should study.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.