Newbie needs help with a timer setup and digital inputs

Hello there,

I'm fairly "new" to Arduino as in, I had basically no experience with programming prior to this project.
However, for my students job I was asked to upgrade an older physics experiment from the physics lecture with digital aspects. It's an air track for the demonstration of one dimensional movement types.
I was given 2 Arduino UNI WIFI REV2 boards as later on, all the data is supposed to be sent from one board at the track to another board at the lecturerer's device, but for the wireless communication, I'll probably make another post once I'm there.

That said, I started this project about 6 months ago (with a 3 month break due to lectures and exams) and now that I've come back, my old code doesn't work anymore and I'm beyond confused.
What is it supposed to do?
I have a total of 3 photoelectric barriers, although for simplicity I only included 2 in my code for now. While the air track is turned on (externally) a sled will be sent across it and the barriers are supposed to start and stop a timer to measure the time. The time is then used to calculate the velocity (and later with the 3rd barrier the acceleration).
For now, all the program is supposed to do is start counting the time when the sled passes the first barrier and stop and spit out the time when it reaches the second barrier.

What is my problem?
The triggering doesn't work as intended and I can pretty much exclude all hardware issues. I'm here to talk about potential coding errors.
Right now, the timer doesn't start as intended. Sometimes it does, often it doesn't. The second barrier will always be ignored. Stopping the time rarely works with the second barrier. In fact, it's mostly the first barrier that starts AND stops the time, which the latter it shouldn't even do.
Also, sometimes the timer starts and stops with more than a second of delay.

Below is the code that last worked (about 4 months ago), however, it doesn't work as it did anymore.

// Pin Definition
const int barrierPinA = 7; // Pin for Barrier A
const int barrierPinB = 8; // Pin for Barrier B
unsigned long startTime = 0; // Variable saves start time
unsigned long stopTime = 0; // Variable saves stop time
bool barrierStateA = false; // Variable checks the state of barrier A
bool barrierStateB = false; // Variable checks the state of barrier B 

void setup() {
  // Starts Serial Communication
  Serial.begin(9600);

  // Set the barrier pin as input
  pinMode(barrierPinA, INPUT);
  pinMode(barrierPinB, INPUT);

  // Attach an interrupt to the barrier pin to detect state change
  attachInterrupt(digitalPinToInterrupt(barrierPinA), barrierAStateChanged, CHANGE);
  attachInterrupt(digitalPinToInterrupt(barrierPinB), barrierBStateChanged, CHANGE);
}

void loop() {
  // Check if the barrier is currently blocked
  if (barrierStateA && !barrierStateB) {
    // If barrierA is blocked and barrierB is UNblocked, start the timer
    startTime = millis();
  }

  //Check if barrierA is UNblocked and barrierB is blocked
  if (!barrierStateA && barrierStateB) {
    // If barrierA is UNblocked and barrierB is blocked, stop the timer
    stopTime = millis();

    // Calculate the time difference
    unsigned long elapsedTime = stopTime - startTime;

    // Print the elapsed time
    Serial.print("Elapsed Time (ms): ");
    Serial.println(elapsedTime);
  }

  delay(100);
}

  // Interrupt service routine to handle changes in the barrier state
  void barrierAStateChanged() {
    // Read the state of the barrier
    barrierStateA = digitalRead(barrierPinA);
  }
  void barrierBStateChanged() {
    barrierStateB = digitalRead(barrierPinB);
  }

I appreciate any constructive help on this problem as I have absolutely no clue what's wrong suddenly and how I fix it.
Even overhauls of the code are appeciated, I just want to finally make some progress on this.

how they are connected/wired ?

how long period is expected? under 16 seconds?

look this over

const byte PinStart = A1;
const byte PinStop  = A2;

unsigned long msecStart;
bool          run;

void
loop (void)
{
    unsigned long msec = millis ();

    if (LOW == digitalRead (PinStart))  {
        msecStart = msec;
        run       = true;
    }

    if (run && LOW == digitalRead (PinStop))  {
        Serial.println (msec - msecStart);
        run = false;
    }
}

void
setup (void)
{
    Serial.begin (9600);

    pinMode (PinStart, INPUT_PULLUP);
    pinMode (PinStop,  INPUT_PULLUP);
}
  • buttons are typically connected between the pin and ground, the pin configured as INPUT_PULLUP to use the internal pullup resistor which pulls the pin HIGH and when pressed, the button pulls the pin LOW.

a button press can be recognized by detecting a change in state and becoming LOW and may need to be debounced (e.g. delay (20); )

  • no need for interrupts, the processor is more that fast enough to detect input changes

how they are connected/wired ?

Each of them 3 cables. 5V supply, GND/Neutral and Signal.
Presumably the 5V power supplies either a UV or IR Diode. Since the Arduino only offers one 5V supply, I'm using an external power supply (from the inventory of the lecture experiments) with 5V and <0.1A output to operate the second one. I've tried both the GND of that external PSU, as well as connecting the second barriers ground to the board's ground pins.
And then there's the signal cable which does exactly what it sounds like. The first barrier's signal cable is connected to Pin 7 and the second one's to Pin 8 on the board, both given Digital Input in the code.

how long period is expected? under 16 seconds?

Yes. The Air Track isn't all that long. 16 seconds seems very hard to go beyond and isn't realistic for any of the regular experiments that are performed in the lectures.

const int barrierPinA = 7; // Pin for Barrier A
const int barrierPinB = 8; // Pin for Barrier B

void setup() {
  Serial.begin(115200);
}

void loop() {
  static unsigned long startTime = 0; // Variable saves start time

  // Check if the barrier is currently blocked
  if (digitalRead(barrierPinA)) { //if barrier A activated as HIGH
    startTime = micros();
    while (!digitalRead(barrierPinB)); //waiting to Barrier B go HIGH

    // Calculate the time difference
    unsigned long elapsedTime = micros() - startTime;

    // Print the elapsed time
    Serial.print("Elapsed Time (µs): ");
    Serial.println(elapsedTime);
    delay(100);
  }
}

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