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)
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!
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: