Data Input Pin stays HIGH

I am running this code

// general constants
#define startButton 8
#define stopButton 9
#define DEBUG true

// general global variables
unsigned long start = 0.0;
unsigned long finished = 0.0;
unsigned long elapsed = 0.0;

// forward declarations
// output calculation results
void displayResult();


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

 // tell 'em who we are, man
 Serial.println("Stopwatch.ino");
 Serial.println();

 // initialize buttons
 pinMode(startButton, INPUT);
 pinMode(stopButton, INPUT);
 digitalWrite(startButton, LOW);
 digitalWrite(stopButton, LOW);
}  //  end setup()

void loop()
{
 // give instructions
 Serial.println();
 Serial.println("Press left button for Start/Reset");
 Serial.println("Press right button for elapsed time");
 Serial.println();

 if (digitalRead(startButton) == HIGH)
 {
 if (DEBUG) Serial.println("startButton was HIGH");

 start = millis();
 finished = 0.0;
 delay(200);  //  debounce
 Serial.println("Started ...");

 if (DEBUG) digitalWrite(startButton, LOW);
 }

 if (digitalRead(stopButton) == HIGH);
 {
 if (DEBUG)Serial.println("stopButton was HIGH");

 finished = millis();
 delay(200);  //  debounce
 displayResult();

 if (DEBUG) digitalWrite(stopButton, LOW);
 }

 if (DEBUG) delay(2000);
}  //  end loop()


/*==========================================*/


// output calculation results
void displayResult()
{
 // local variables
 float h, m, s, ms;
 unsigned long over;

 // get elapsed
 finished = millis();
 elapsed = finished - start;

 // calculate time elements
 h = int(elapsed / 3600000);
 over = elapsed % 3600000;
 m = int(over / 60000);
 over = over % 60000;
 s = int(over / 1000);
 ms = over % 1000;

 // display time elements
 Serial.print("Raw elapsed time: ");
 Serial.print(elapsed);
 Serial.println(": ms");

 Serial.print("Elapsed time: ");
 Serial.print(h, 0);
 Serial.print("h ");
 Serial.print(m, 0);
 Serial.print("m ");
 Serial.print(s, 0);
 Serial.print(" s ");
 Serial.print(ms, 0);
 Serial.println("ms");
 Serial.println();
 Serial.println();
}  //  end displayResult()

on this layout
180119-1609-Stopwatch_Layout-640x478.jpg
My problem is that the stopButton is permanently high (even when the power lead is disconnected from the stopButton)

Press left button for Start/Reset
Press right button for elapsed time

startButton was HIGH
Started ...
stopButton was HIGH
Raw elapsed time: 401: ms
Elapsed time: 0h 0m 0 s 401ms



Press left button for Start/Reset
Press right button for elapsed time

stopButton was HIGH
Raw elapsed time: 2635: ms
Elapsed time: 0h 0m 2 s 635ms



Press left button for Start/Reset
Press right button for elapsed time

stopButton was HIGH
Raw elapsed time: 4870: ms
Elapsed time: 0h 0m 4 s 870ms



Press left button for Start/Reset
Press right button for elapsed time

stopButton was HIGH
Raw elapsed time: 7104: ms
Elapsed time: 0h 0m 7 s 104ms

When I put a DMM across it the stopSwitch is HOT when button pressed and COLD when not. Video confirmation at Youtube.

The start button behaves itself.

How do I get the stopButton to go LOW when the button is not pressed?

Thanks

180119-1609-Stopwatch_Layout-640x478.jpg

Hi

The first thing that comes to mind is that you code uses pins D8 and D9 but your wiring photo shows you have wired the switches to pins D7 and D8.

That would leave D9 floating and could well give you the results you're seeing.

Ian

IanCrowe:
The first thing that comes to mind is that you code uses pins D8 and D9 but your wiring photo shows you have wired the switches to pins D7 and D8.

I didn't. I didn't. I really didn't! :-[

180119-1700-Stopwatch-Pins-640x478.png

Check if that ground en Vcc bus on he breadboard goes all the way.

And some tips:

If you change to pinMode(pin, INPUT_PULLUP) you don't need to add resistors. Just connect the button between a pin and GND. But remember the logic is flipped, reading a LOW means a pressed button.

#define startButton 8

The safe C++ alternative:

const byte StartButton = 8;

Gives better to read errors (when you have one) as well :slight_smile:

#define DEBUG true

This is the only case of valid use of a macro IF you change the if

unsigned long start = 0.0;

Loading an integer with a float constant is a bit weird :wink:

Serial.println("Press left button for Start/Reset");

Using the F() macro saves a lot of RAM

Serial.println(F("Press left button for Start/Reset"));
delay(200);  //  debounce

That is a blocking way of debouncing the button. That will limit the response of the button. You can make life easy by grabbing a library to handle buttons like Bounce2.

 float h, m, s, ms;
  //...
  h = int(elapsed / 3600000);

If yu just used integers to start with you didn't have to cast i to an int :wink:

1 Like

Try swapping the pins in D8 and D9.

Hi,
Try this bit of code please;

// general constants
#define startButtonPin 8
#define stopButtonPin 9

byte startButtonStatus = LOW;
byte stopButtonStatus = LOW;

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

void loop()
{
  startButtonStatus = digitalRead(startButtonPin);
  stopButtonStatus = digitalRead(stopButtonPin);
  if (startButtonStatus == HIGH)
  {
    Serial.print("Start Button HIGH");
  }
  else
  {
    Serial.print("Start Button LOW");
  }
  Serial.print("\t");
  if (stopButtonStatus == HIGH)
  {
    Serial.println("Stop Button HIGH");
  }
  else
  {
    Serial.println("Stop Button LOW");
  }
}

Thanks... Tom... :slight_smile:

Hi,
Also try disconnecting the two wires to D8 and D9 and jumper them to gnd and then to 5V.

Where are you measuring the 0 to 5V transition, at the switch or at the D8 and D9 pins of the UNO?

To make sure you have the right pins on your tactile buttons, connect to diagonally opposite pins, instead of same side pins like you have.

Tom... :slight_smile:

TomGeorge:
Try this bit of code please;

Did and got this

Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW

TomGeorge:
Also try disconnecting the two wires to D8 and D9 and jumper them to gnd and then to 5V.

Not sure what you mean here. Do you mean to unplug the two jumpers from D8 and D9 and plug them in to Gnd and 5V respectively?

TomGeorge:
Where are you measuring the 0 to 5V transition, at the switch or at the D8 and D9 pins of the UNO?

At the switch.

TomGeorge:
To make sure you have the right pins on your tactile buttons, connect to diagonally opposite pins, instead of same side pins like you have.

These results at the pin after changing to diagonally opposite

Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button HIGH
Start Button LOW	Stop Button HIGH
Start Button LOW	Stop Button HIGH
Start Button LOW	Stop Button HIGH
Start Button LOW	Stop Button HIGH
Start Button LOW	Stop Button HIGH
Start Button LOW	Stop Button HIGH
Start Button LOW	Stop Button HIGH
Start Button LOW	Stop Button HIGH
Start Button LOW	Stop Button HIGH
Start Button LOW	Stop Button HIGH
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button HIGH	Stop Button LOW
Start Button HIGH	Stop Button LOW
Start Button HIGH	Stop Button LOW
Start Button HIGH	Stop Button LOW
Start Button HIGH	Stop Button LOW
Start Button HIGH	Stop Button LOW
Start Button HIGH	Stop Button LOW
Start Button HIGH	Stop Button LOW
Start Button HIGH	Stop Button LOW
Start Button HIGH	Stop Button LOW
Start Button HIGH	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW
Start Button LOW	Stop Button LOW

The buttons produce the right answers at the pin. However, the program

// general constants
const int startButton = 8;
const int stopButton = 9;
const bool DEBUG = true;

// general global variables
unsigned long start = 0.0;
unsigned long finished = 0.0;
unsigned long elapsed = 0.0;

// forward declarations
// output calculation results
void displayResult();


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

	// tell 'em who we are, man
	Serial.println("Stopwatch.ino");
	Serial.println();

	// initialize buttons
	pinMode(startButton, INPUT);
	pinMode(stopButton, INPUT);
	digitalWrite(startButton, LOW);
	digitalWrite(stopButton, LOW);
}  //  end setup()

void loop()
{
	// give instructions
	Serial.println();
	Serial.println("Press left button for Start/Reset");
	Serial.println("Press right button for elapsed time");
	Serial.println();

	if (digitalRead(startButton) == HIGH)
	{
		if (DEBUG) Serial.println("startButton was HIGH");

		start = millis();
		finished = 0.0;
		delay(200);  //  debounce
		Serial.println("Started ...");

		if (DEBUG) digitalWrite(startButton, LOW);
	}

	if (digitalRead(stopButton) == HIGH);
	{
		if (DEBUG)Serial.println("stopButton was HIGH");

		finished = millis();
		delay(200);  //  debounce
		displayResult();

		if (DEBUG) digitalWrite(stopButton, LOW);
	}

	delay(2000);
}  //  end loop()


   /*==========================================*/


   // output calculation results
void displayResult()
{
	// local variables
	float h, m, s, ms;
	unsigned long over;

	// get elapsed
	finished = millis();
	elapsed = finished - start;

	// calculate time elements
	h = int(elapsed / 3600000);
	over = elapsed % 3600000;
	m = int(over / 60000);
	over = over % 60000;
	s = int(over / 1000);
	ms = over % 1000;

	// display time elements
	Serial.print("Raw elapsed time: ");
	Serial.print(elapsed);
	Serial.println(": ms");

	Serial.print("Elapsed time: ");
	Serial.print(h, 0);
	Serial.print("h ");
	Serial.print(m, 0);
	Serial.print("m ");
	Serial.print(s, 0);
	Serial.print(" s ");
	Serial.print(ms, 0);
	Serial.println("ms");
	Serial.println();
	Serial.println();
}  //  end displayResult()

still produces this output

Stopwatch.ino


Press left button for Start/Reset
Press right button for elapsed time

stopButton was HIGH
Raw elapsed time: 250: ms
Elapsed time: 0h 0m 0 s 250ms



Press left button for Start/Reset
Press right button for elapsed time

stopButton was HIGH
Raw elapsed time: 2485: ms
Elapsed time: 0h 0m 2 s 485ms



Press left button for Start/Reset
Press right button for elapsed time

stopButton was HIGH
Raw elapsed time: 4719: ms
Elapsed time: 0h 0m 4 s 719ms

septillion:
Check if that ground en Vcc bus on he breadboard goes all the way.

It does, but I rewired without using the bus and it makes no difference.

septillion:

#define DEBUG true

This is the only case of valid use of a macro IF you change the if

DEBUG is only a switch so I can turn off debugging info when I don't need it without deleting (and maybe replacing) the code.
I'll have a look at F() and Bounce2. Thanks

vagulus:
At the switch.

These results at the pin after changing to diagonally opposite

Start Button LOW	Stop Button LOW

Start Button LOW Stop Button LOW
Start Button LOW Stop Button LOW
Start Button LOW Stop Button HIGH
Start Button LOW Stop Button HIGH
Start Button LOW Stop Button HIGH
Start Button LOW Stop Button HIGH
Start Button LOW Stop Button HIGH
Start Button LOW Stop Button HIGH
Start Button LOW Stop Button HIGH
Start Button LOW Stop Button HIGH
Start Button LOW Stop Button HIGH
Start Button LOW Stop Button HIGH
Start Button LOW Stop Button HIGH
Start Button LOW Stop Button LOW
Start Button LOW Stop Button LOW
Start Button LOW Stop Button LOW
Start Button LOW Stop Button LOW
Start Button LOW Stop Button LOW
Start Button LOW Stop Button LOW
Start Button LOW Stop Button LOW
Start Button LOW Stop Button LOW
Start Button LOW Stop Button LOW
Start Button LOW Stop Button LOW
Start Button LOW Stop Button LOW
Start Button LOW Stop Button LOW
Start Button LOW Stop Button LOW
Start Button HIGH Stop Button LOW
Start Button HIGH Stop Button LOW
Start Button HIGH Stop Button LOW
Start Button HIGH Stop Button LOW
Start Button HIGH Stop Button LOW
Start Button HIGH Stop Button LOW
Start Button HIGH Stop Button LOW
Start Button HIGH Stop Button LOW
Start Button HIGH Stop Button LOW
Start Button HIGH Stop Button LOW
Start Button HIGH Stop Button LOW
Start Button LOW Stop Button LOW
Start Button LOW Stop Button LOW
Start Button LOW Stop Button LOW
Start Button LOW Stop Button LOW

Okay, so you now have the buttons inputting HIGHs and LOW's the the pins.

Diagonal connections to those buttons is the quickest way to make sure you have connections to each side of the switch mechanism.

Tom.... :slight_smile:
PS. I should have put a delay in the code I supplied to slow the serial display update.... :o

Hi,
Can I suggest you do this at the start of your loop;

Read the startbutton input and assign a variable that value.
Read the stopbutton input and assign a variable that value.

Then test the variable in your if statements, forget about de-bouncing, you are only looking for change of state, not a continuous state.
Forget about the 200 delay.

Trim your code back build it up.

Tom... :slight_smile:

TomGeorge:
... at the start of your loop;

Read the startbutton input and assign a variable that value.
Read the stopbutton input and assign a variable that value.

Then test the variable in your if statements, forget about de-bouncing, you are only looking for change of state, not a continuous state.
Forget about the 200 delay.

It works!

Code is

// general constants
const int startButton = 8;
const int stopButton = 9;
const bool DEBUG = true;

// general global variables
unsigned long start = 0.0;
unsigned long finished = 0.0;
unsigned long elapsed = 0.0;

// forward declarations
// output calculation results
void displayResult();


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

  // tell 'em who we are, man
  Serial.println("Stopwatch.ino");
  Serial.println();

  // initialize buttons
  pinMode(startButton, INPUT);
  pinMode(stopButton, INPUT);
  digitalWrite(startButton, LOW);
  digitalWrite(stopButton, LOW);
}  //  end setup()

void loop()
{
  // local variables
  int startButtonState = digitalRead(startButton);
  int stopButtonState = digitalRead(stopButton);

  // give instructions
  Serial.println();
  Serial.println("Press left button for Start/Reset");
  Serial.println("Press right button for elapsed time");
  Serial.println();

  if (startButtonState == HIGH)
  {
    if (DEBUG) Serial.println("startButton was HIGH");

    start = millis();
    elapsed = 0.0;
    Serial.println("Started ...");

    if (DEBUG) digitalWrite(startButton, LOW);
  }

  if (stopButtonState == HIGH)
  {
    if (DEBUG)Serial.println("stopButton was HIGH");

    finished = millis();
    displayResult();

    if (DEBUG) digitalWrite(stopButton, LOW);
  }

  delay(5000);
}  //  end loop()


/*==========================================*/


// output calculation results
void displayResult()
{
  // local variables
  float h, m, s, ms;
  unsigned long over;

  // get elapsed
  finished = millis();
  elapsed = finished - start;

  // calculate time elements
  h = int(elapsed / 3600000);
  over = elapsed % 3600000;
  m = int(over / 60000);
  over = over % 60000;
  s = int(over / 1000);
  ms = over % 1000;

  // display time elements
  Serial.print("Raw elapsed time: ");
  Serial.print(elapsed);
  Serial.println(": ms");

  Serial.print("Elapsed time: ");
  Serial.print(h, 0);
  Serial.print("h ");
  Serial.print(m, 0);
  Serial.print("m ");
  Serial.print(s, 0);
  Serial.print(" s ");
  Serial.print(ms, 0);
  Serial.println("ms");
  Serial.println();
  Serial.println();
}  //  end displayResult()

Output is

Stopwatch.ino


Press left button for Start/Reset
Press right button for elapsed time


Press left button for Start/Reset
Press right button for elapsed time


Press left button for Start/Reset
Press right button for elapsed time

startButton was HIGH
Started ...

Press left button for Start/Reset
Press right button for elapsed time


Press left button for Start/Reset
Press right button for elapsed time


Press left button for Start/Reset
Press right button for elapsed time

stopButton was HIGH
Raw elapsed time: 15070: ms
Elapsed time: 0h 0m 15 s 70ms



Press left button for Start/Reset
Press right button for elapsed time


Press left button for Start/Reset
Press right button for elapsed time


Press left button for Start/Reset
Press right button for elapsed time

stopButton was HIGH
Raw elapsed time: 30192: ms
Elapsed time: 0h 0m 30 s 192ms



Press left button for Start/Reset
Press right button for elapsed time


Press left button for Start/Reset
Press right button for elapsed time

startButton was HIGH
Started ...

Press left button for Start/Reset
Press right button for elapsed time


Press left button for Start/Reset
Press right button for elapsed time


Press left button for Start/Reset
Press right button for elapsed time

stopButton was HIGH
Raw elapsed time: 15069: ms
Elapsed time: 0h 0m 15 s 69ms



Press left button for Start/Reset
Press right button for elapsed time


Press left button for Start/Reset
Press right button for elapsed time


Press left button for Start/Reset
Press right button for elapsed time

startButton was HIGH
Started ...

Press left button for Start/Reset
Press right button for elapsed time

stopButton was HIGH
Raw elapsed time: 5046: ms
Elapsed time: 0h 0m 5 s 46ms



Press left button for Start/Reset
Press right button for elapsed time

Thanks Tom. The puzzle is "Why did one pin accept the digitalRead(startButton) and the other ignore digitalRead(stopButton)?

Arduino Fairies? :sunglasses: