Have you got a pulldown resistor holding the input pin LOW when the button is not pressed or is it floating at an unknown voltage, maybe HIGH, maybe LOW, maybe changing ?
I note that the value of currentState is never changed in the code so will never be HIGH
Thanks, that solved the problem! However, having expanded the code to display the stopwatch, it is not latching, it only switches the display if I keep the switch closed. Your input is much appreciated, it's a slow learning process!
// stopwatch for set times
#include <Arduino.h>
#include <TM1637Display.h>
#define CLK_PIN 11
#define DIO_PIN 10
TM1637Display display(CLK_PIN, DIO_PIN);
unsigned long startTime;
unsigned long currentTime;
unsigned long elapsedTime;
int countTime = 2700; // 45 minutes in seconds
int timeFactor = 1;
int currentState = 0;
int goButt = 2;
int goState = 0;
void setup() {
display.setBrightness(3); // Set the brightness of the display (0-7)
display.clear(); // Clear the display
startTime = millis(); // Record the starting time
pinMode(goButt, INPUT);
pinMode(timeButt, INPUT);
display.setBrightness(5);
digitalWrite(goButt, HIGH);
}
void loop() {
if (goState != currentState && currentState == HIGH) { // no button press
display.showNumberDecEx(0, 0b01000000, true);
goState = LOW;
} else { // if button pressed
currentTime = millis(); // Get the current time
elapsedTime = (currentTime - startTime) / 1000; // Calculate elapsed time in seconds
if (elapsedTime <= countTime) {
unsigned long remainingTime = countTime - elapsedTime;
unsigned int minutes = remainingTime / 60;
unsigned int seconds = remainingTime % 60;
display.showNumberDecEx(minutes * 100 + seconds, 0b01000000, true); // Display remaining time in Minutes:Seconds format
if (remainingTime == 0) { // Start blinking when countdown reaches 00:00
while (true) {
display.showNumberDecEx(0, 0b01000000, true); // Display "00:00"
delay(500);
display.clear(); // Clear the display
delay(500);
} // end flash end
} // remainingTime == 0
} // end elapsed time
delay(1000); // Wait for 1 second
}
currentState = digitalRead(goButt);
} // end loop
Take a look at the StateChangeDetection example in the IDE
In your sketch goState is only ever LOW so you can never detect whether its state differs from the current state of the pin which would indicate that the state of the pin has changed
How is the goButt pin wired ?
I suggest that you use INPUT_PULLUP in its pinMode() to activate the built in pullup resistor and remove the digitalWrite() that sets its state HIGH
Wire the input to go LOW when the button is pressed and make any necessary changes to the program logic to match
If I were you I would have the code detect when the button becomes pressed and when it does, change the state of a boolean variable. Then, depending on the state of the boolean run the required code
It will work only because the input is mechanically locked on or off. If that suits your project then you have a solution, albeit not the one that you originally asked for
Your code seems to have a few issues. To make the display alternate between two numbers when a momentary button is pressed, you can try the following changes:
Initialization: You should initialize currentState to the initial state of the button to avoid the initial display showing the second number. You can do this in the setup function.
Debouncing: For a momentary button, you might want to add some debouncing logic to avoid false readings when the button is pressed. You can achieve this by adding a small delay after reading the button state.
Here's an updated version of your code with these changes:
#include <Arduino.h>
#include <TM1637Display.h>
#define CLK_PIN 11
#define DIO_PIN 10
TM1637Display display(CLK_PIN, DIO_PIN);
int goButt = 2;
int currentState = LOW;
int lastState = LOW;
void setup() {
display.setBrightness(3); // Set the brightness of the display (0-7)
display.clear(); // Clear the display
pinMode(goButt, INPUT);
display.setBrightness(5);
}
void loop() {
currentState = digitalRead(goButt);
// Check if the button state has changed
if (currentState != lastState) {
delay(50); // Debounce
currentState = digitalRead(goButt); // Read the button again
if (currentState == HIGH) {
// Button is pressed, alternate between numbers
if (display.getColon()) {
display.showNumberDecEx(1, 0b01000000); // Display 1 without colon
} else {
display.showNumberDecEx(301, 0b01000000); // Display 301 without colon
}
}
}
lastState = currentState;
}
This code will toggle between the two numbers when the button is pressed, and it includes a debounce delay to ensure reliable button press detection.
Optimize #include directives: Only include necessary libraries. If you're not using some functions or classes from libraries, exclude them.
Use const for pin definitions: Declare the pin numbers as const to improve code readability and prevent accidental changes.
Avoid setting brightness multiple times: You set the display brightness twice in the setup() function. You can remove the first call to setBrightness() since you set it to 5 at the end.
Use millis() for debouncing: Instead of using delay(50) for debouncing, use millis() to create a non-blocking delay. This way, your loop can continue to run without interruption.
Use a function for button press handling: Create a separate function to handle button presses for better code organization and readability.
Here's the optimized code:
#include <Arduino.h>
#include <TM1637Display.h>
#define CLK_PIN 11
#define DIO_PIN 10
TM1637Display display(CLK_PIN, DIO_PIN);
const int goButt = 2;
int currentState = LOW;
int lastState = LOW;
unsigned long lastDebounceTime = 0;
const unsigned long debounceDelay = 50;
void setup() {
display.clear();
pinMode(goButt, INPUT);
display.setBrightness(5);
}
void handleButtonPress() {
if (currentState == HIGH) {
if (display.getColon()) {
display.showNumberDecEx(1, 0b01000000); // Display 1 without colon
} else {
display.showNumberDecEx(301, 0b01000000); // Display 301 without colon
}
}
}
void loop() {
currentState = digitalRead(goButt);
if (currentState != lastState) {
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
handleButtonPress();
}
lastState = currentState;
}
This code is more organized and avoids blocking delays, which allows your loop to run smoothly.