1st Arduino Project: A Simulated Baseball Batter's Running Time

Hello!

Longtime forum veteran, including reading posts here, but this is my first post after hiding in the weeds!

I have researched the Arduino for other projects before, but this is the first project that I have moved forward with (I have friends patiently waiting to push my rear into gear this time! ;D).

Here is the setup: friend 1 hits a ground ball, then Friend 2 fields the ball and throws it to first (usually me, sometimes a net). The issue is that with no runner there is no way to know how well the fielder is doing. Is he rushing, too slow, etc.

So my planned solution is simple. Use an Arduino, a sound detector, and a large 7 segment display (actually two of them) to capture the sound of the bat hitting the ball and countdown on the display from 4.3 seconds to 0 (the average time from home to first), then reset after a few seconds.

Here is what I'm thinking of using...
SparkFun Arduino Board
SparkFun Sound Detector (Not sure if I want the headers or not, it seems like installation is easier with them, but I guess it depends on what hardware I am using.)
SparkFun Large 7 Segment Display
I will also need a large digit driver which comes separately.

SparkFun makes it pretty simple as it gives the code for the 7 segment driver as well as the sound detector. My main question related to code is the timer. I've seen different codes like millis() and blink without delay, etc., but don't see anything for what I would want to use. In my mind, it should be pretty simple... start at 4.3 seconds, countdown to zero, wait 3 seconds, reset and wait for new input (sound detection). But I already know that's not how code works! :smiley:

Can anyone point me in the correct direction to get me started? Thanks for the help and sorry for the long void setup()! :wink:

jeff88:
I've seen different codes like millis() and blink without delay, etc., but don't see anything for what I would want to use.

Then you've seen exactly what you need to use. Blink WIthout Delay toggles an LED every so often. You don't want to toggle an LED, you just want to subtract one from the number you're displaying. That just changes what you put inside the if statement for it to do every so often. The timing code remains the same.

jeff88:
start at 4.3 seconds, countdown to zero, wait 3 seconds, reset and wait for new input (sound detection). But I already know that's not how code works! :smiley:

Why do you say that?

The code below will...

start at 4.3 seconds, countdown to zero, wait 3 seconds, reset and wait for new input (sound detection).

.... except I don't have a sound detector so I used a button, and I don't have a display so that would need to be added:

//  https://forum.arduino.cc/index.php?topic=631679
//  16 august 2019 meltDown

// OP asked for "start at 4.3 seconds, countdown to zero, wait 3 seconds,
//     reset and wait for new input (sound detection)."

//meltDown has no sound detector, so just using a button
//also display stuff needs to be added

//has a proofOfLife pulse on 13 to prove there's no blocking

enum {ST_WAITING, ST_COUNTING_DOWN, ST_RESETTING} currentState = ST_WAITING;
// enum just allocates integers from the left so ST_WAITING=0, ST_ST_COUNTING_DOWN =1
//    just makes it easier to have human relatable names in the switch..case later

unsigned long previousPulseMillis;
int pulseInterval = 500;
bool pulseLedState = LOW;
byte pulseLedPin = 13;

byte soundDetector = 12; //actually just a button
int countdownPeriod = 4300;
int resetPeriod = 3000;
unsigned long weStartedTimingAt;
unsigned long weStartedResetAt;
bool messageDisplayedOnce = false;

void setup()
{
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(soundDetector, INPUT_PULLUP);
  Serial.begin(9600);
  Serial.println("Forum thread 631679");
  Serial.println("Setup done...");
}//setup

void loop()
{
  proofOfLife();
  doStates();
}//loop

void proofOfLife()
{
  if (millis() - previousPulseMillis >= pulseInterval)
  {
    pulseLedState = !pulseLedState;
    digitalWrite(pulseLedPin, pulseLedState);
    previousPulseMillis = millis();;
  }
}

void doStates()
{
  switch (currentState)
  {
    case ST_WAITING:

      if (!messageDisplayedOnce)
      {
        Serial.println("\nWaiting for hit... (actually a button press)");
        messageDisplayedOnce = true;
      }
      if (!digitalRead(soundDetector))  //ie, button is pressed
      {
        weStartedTimingAt = millis();
        messageDisplayedOnce = false;
        currentState = ST_COUNTING_DOWN;
      }

      break;

    case ST_COUNTING_DOWN:

      if (!messageDisplayedOnce)
      {
        Serial.print("Counting down from ");
        Serial.print(countdownPeriod);
        Serial.println(" (add display stuff)");
        messageDisplayedOnce = true;
      }

      if (millis() - weStartedTimingAt >= countdownPeriod)
      {
        weStartedResetAt = millis();
        messageDisplayedOnce = false;
        currentState = ST_RESETTING;
      }
      break;

    case ST_RESETTING:

      if (!messageDisplayedOnce)
      {
        Serial.print("Waiting for ");
        Serial.print(resetPeriod);
        Serial.println(" (add display stuff)");
        messageDisplayedOnce = true;
      }
      if (millis() - weStartedResetAt >= resetPeriod)
      {
        messageDisplayedOnce = false;
        currentState = ST_WAITING;
      }
      break;

  }//switch
}//doStates

In my mind, it should be pretty simple

It is....

But I already know that's not how code works!

It's exactly how code works (or it's how a programmer makes it work, anyway)

There must be lots of examples out there for counting down on a display.
Most will be for counting seconds; it’s of course quite trivial to change that to tenths or even hundredths of seconds, which is what you probably want.
You will also want some kind of sensor that can tell whether the ball arrived in time, e.g. a foot switch on first base that you press upon receiving the ball. After all that’s split second work, and it’s going to be hard to tell just by looking at the clock whether it was at +0.05 or -0.05 seconds!

Come to think of it, you may actually be better off with clock that counts up, so you can see easily how long it really took to get the ball to the first base. That 4.3 seconds may be the average a runner takes to get there; some are faster, some are slower.

Wow, quick replies here... I like it! :smiley: Thank you everyone for the help!

Delta_G:
Then you've seen exactly what you need to use. Blink WIthout Delay toggles an LED every so often. You don't want to toggle an LED, you just want to subtract one from the number you're displaying. That just changes what you put inside the if statement for it to do every so often. The timing code remains the same.

Maybe I just misread those webpages/projects and didn't understand. I've never coded before so when I saw something about "blink"ing I didn't realize I could use that for a display. I'll have to look into it more then.

meltDown:
The code below will...

That is way over my head! :smiley: I'll have to look into it more. How is it different from the BWD and millis that Delta_G referenced? Is one better than the other or is it just two paths to the same apple tree?

meltDown:
(or it's how a programmer makes it work, anyway)

That comment of mine seems to have mustered up some emotion! This is what I meant by that though. The code isn't just do x, then y, then z. A programmer has to know how to manipulate the code just right to do what they want.

BTW, your picture is spot on, exactly what I'm thinking it should do. Now to make that into reality!...

wvmarle:
You will also want some kind of sensor that can tell whether the ball arrived in time, e.g. a foot switch on first base that you press upon receiving the ball. After all that's split second work, and it's going to be hard to tell just by looking at the clock whether it was at +0.05 or -0.05 seconds!

Come to think of it, you may actually be better off with clock that counts up, so you can see easily how long it really took to get the ball to the first base. That 4.3 seconds may be the average a runner takes to get there; some are faster, some are slower.

I thought about the foot pedal thing (or something to that effect) and I might try something in the future, but was trying to get the proof of concept down first. I'll have to try countdown and countup and see which works better for us. Thanks for the input!

jeff88:
Wow, quick replies here... I like it! :smiley: Thank you everyone for the help!

Maybe I just misread those webpages/projects and didn't understand. I've never coded before so when I saw something about "blink"ing I didn't realize I could use that for a display. I'll have to look into it more then.

They just use blinking an LED to illustrate how it works. The concept extends to anything and everything that you want to do timing wise.

Go here: Useful links - check here for reference posts / tutorials - Programming Questions - Arduino Forum and read everything under General Design.