Serial Display shows all counts not just the total

I am counting the time (using incrementing counter) my Morse Code keyer in pressed (key down). My sketch is supposed to count (Add + 1 to counter loop) when I have 5V to Pin 2 (HIGH) (Key Down), and when changed to Pin2 to ground (LOW) (Keyer up) only Serial.print the total count, and reset the counter to zero, and wait for the next keydown. However, when Pin 2 is HIGH the "Serial Monitor" shows every incrementing count (Should show nothing), and when Pin 2 is LOW It shows the Total (as programmed), but then continue displaying "0's". I want don't want anything to print (display) except the key down total count. What am I missing in my code to prevent from showing (displaying) the intervening counts and 0's?


/*
  Created: 31May2025 (1435 PM PDT Nevada Time) - Originator: Robert P. Hampton W6FGH
  Updated: Updated 4June2025. RPH

  READ INPUT ( Pin 7) from morse code CW Straight-Key.
  While Straight-Key is key-down then continually increment Key-Down-Counter.

  After release of CW Keyer, Print the total Count.
  Then Reset Coutner to 0, then wait for another keyer key-down.

  FUTURE CODING:

  If Key-Down-Counter is between A and B(short time) = DIT (0 bit)
  If Key-Down-Counter is between X and Y (long time) = DAH (1 bit)
  Then, Do next communications processes (TBD)

  Using Nested Loops

*/


//START APPLICATION Main:

//bool val = 0;

int KeyDownPin = 2; // Keyer input Pin 2 with 5Volts when key-down

int KeyDownCounter = 1;

int value = 0;



// START PROGRAM


void setup()
{

  pinMode(KeyDownPin, INPUT);

  Serial.begin(9600);

  Serial.println("Keyer Counter Starting");



}


void loop()
{
  int value = digitalRead(2);

  delay (10);

  Serial.println(KeyDownCounter);

  digitalRead (KeyDownPin);

  if (digitalRead (KeyDownPin) == HIGH) // Pin 2 connected to 5V pin
  {

    //  KeyDownCounter = (KeyDownCounter + 1);
    KeyDownCounter ++;

    // Add 1 to counter. Do not print any value. Go back to top checking for HIGH or LOW

  }

  else {

    if (digitalRead (KeyDownPin) == LOW) // Pin2 not connected (Open)
    {
      if (KeyDownCounter > 2) // Print only the final Count
      {
        //Serial.print (KeyDownCounter);
        Serial.println ("FINAL Stop");

        KeyDownCounter = 0;

        /* Set Reset Counter to 0. Return to main "void loop () and wait for
          next key-down (Pin7 to 5V pin) */
      }

      else // Do Nothing

      {
      }
    }
    else // Do nothing
    {

    }
  }
}

Is there anything in your circuit that keeps KeyDownPin LOW when the Morse key is not pressed or is it floating at an unknown voltage, maybe HIGH, maybe LOW ?

This comment

        if (digitalRead(KeyDownPin) == LOW)  // Pin2 not connected (Open)

would seem to indicate not

I have pin 2 permanently connected to Ground pin, and connects to 5V when Keyer is down.

Sorry, I am switching "between" GND and 5V.... NOT connecting GND and 5V together.

In that case you are shorting the 5V to GND when the key is pressed. Is there a resistor in the circuit somewhere ?

You are printing KeyDownCounter in loop() with no conditions so no wonder you see the incrementing count. Print it only when the key becomes released

Some other comments

  • there is no need to have an else clause if it does nothing
  • one of the comments in your code refers to pin 7 rather than pin 2. Which one is correct ?
  • you may need to debounce the input to avoid false counts when the key is pressed
  • as written, when the key is held down the counter will increment every 10 milliseconds. Is that what you want ?

I corrected Pin 7 to pin 2 from my earlier development Comments. I use 10 ms delays so I don't get super large numbers (I may adjust this delay). Not sure yet how to code for "Just Released", vs within the else LOW loop? I will have to figure that one out... Thank you!

I used the empty Else statements just to clarify my nested If's for documentation.

Take a look at the StateChange Detection example

You were complaining that

That should be no surprise as you print it every time through loop()

Logically, you have unreachable code.

And you are testing things that, at the point of the test, are known.

You also read the pin and... do nothing.

Here I believe is your loop with all that removed:

void loop()
{
  int value = digitalRead(2);

  delay(10);

  Serial.println(KeyDownCounter);

//  digitalRead(KeyDownPin);  // does no one any good

  if (digitalRead(KeyDownPin) == HIGH)
  {
    KeyDownCounter++;
  }
  else // it is LOW!
  {
    if (KeyDownCounter > 2)
    {
      Serial.println("FINAL Stop");
      KeyDownCounter = 0;
    }
    else
    {
    }
  }
}

As @UKHeliBob says, state change detection will serve you well. A good habit in any case is to read switches once, then use that reading for the rest of the loop.

There's a crap-ton of state change detection tutorials. Google is your friend. Read this post and the thread it finds itself on:

and this thread


HTH a7

Hi,
Can you please post a diagram of how you have the key wired to the controller?

What model Arduino are you using?

Tom.... :smiley: :+1: :coffee: :australia:

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