Adding 2 timers from 2 buttons

Hi,

I am trying to add the timing of 2 buttons. When the second button is released I am trying to have the result of button 1 timing plus the button 2 timing. Seems to be simple but I cannot figure out the problem.

int inPin2 = 2; // the pin number for input (1 push button) int inPin4 = 4; // the pin number for input (2 push button)

int current_1; // Current state of the 1 button long millis_held_1; // How long the button was held (milliseconds) long secs_held_1; // How long the button was held (seconds) long prev_secs_held_1; // How long the button was held in the previous check byte previous_1 = HIGH; unsigned long firstTime_1; // how long since the button was first pressed

int current_2; // Current state of the 2 button long millis_held_2; // How long the button was held (milliseconds) long secs_held_2; // How long the button was held (seconds) long prev_secs_held_2; // How long the button was held in the previous check byte previous_2 = HIGH; unsigned long firstTime_2; // how long since the button was first pressed

void setup() { Serial.begin(9600); // Use serial for debugging digitalWrite(inPin2, HIGH); digitalWrite(inPin4, HIGH); } void displayResult() { long average_sec_total = millis_held_1 + millis_held_2; Serial.print("Average = "); Serial.println(average_sec_total); } void loop() { current_1 = digitalRead(inPin2); current_2 = digitalRead(inPin4); // if the button state changes to pressed, remember the start time if (current_1 == HIGH && previous_1 == LOW && (millis() - firstTime_1) > 200) { firstTime_1 = millis(); } millis_held_1 = (millis() - firstTime_1); secs_held_1 = millis_held_1 / 1000;

// check if the button was released since we last checked if (current_1 == LOW && previous_1 == HIGH) { Serial.print("Seconds held in second: "); Serial.print(secs_held_1); Serial.print(" Milliseconds held: "); Serial.println(millis_held_1); } // if the button state changes to pressed, remember the start time if (current_2 == HIGH && previous_2 == LOW && (millis() - firstTime_2) > 200) { firstTime_2 = millis(); } millis_held_2 = (millis() - firstTime_2); secs_held_2 = millis_held_2 / 1000;

// check if the button was released since we last checked if (current_2 == LOW && previous_2 == HIGH) { Serial.print("Seconds held in second: "); Serial.print(secs_held_2); Serial.print(" Milliseconds held: "); Serial.println(millis_held_2); displayResult(); } previous_1 = current_1; prev_secs_held_1 = secs_held_1; previous_2 = current_2; prev_secs_held_2 = secs_held_2; }

code should be posted this way (within code tags and indented)

int inPin2 = 2;  // the pin number for input (1 push button)
int inPin4 = 4;  // the pin number for input (2 push button)

int current_1;         // Current state of the 1 button
long millis_held_1;    // How long the button was held (milliseconds)
long secs_held_1;      // How long the button was held (seconds)
long prev_secs_held_1; // How long the button was held in the previous check
byte previous_1 = HIGH;
unsigned long firstTime_1; // how long since the button was first pressed

int current_2;         // Current state of the 2 button
long millis_held_2;    // How long the button was held (milliseconds)
long secs_held_2;      // How long the button was held (seconds)
long prev_secs_held_2; // How long the button was held in the previous check
byte previous_2 = HIGH;
unsigned long firstTime_2; // how long since the button was first pressed

void setup() {
  Serial.begin(9600);         // Use serial for debugging
  digitalWrite(inPin2, HIGH);
  digitalWrite(inPin4, HIGH);
}


void displayResult()
{
  long average_sec_total = millis_held_1 + millis_held_2;
  Serial.print("Average = ");
  Serial.println(average_sec_total);
}


void loop() {
  current_1 = digitalRead(inPin2);
  current_2 = digitalRead(inPin4);
  // if the button state changes to pressed, remember the start time
  if (current_1 == HIGH && previous_1 == LOW && (millis() - firstTime_1) > 200) {
    firstTime_1 = millis();
  }
  millis_held_1 = (millis() - firstTime_1);
  secs_held_1 = millis_held_1 / 1000;

  // check if the button was released since we last checked
  if (current_1 == LOW && previous_1 == HIGH) {
    Serial.print("Seconds held in second: ");
    Serial.print(secs_held_1);
    Serial.print("   Milliseconds held: ");
    Serial.println(millis_held_1);
  }
  // if the button state changes to pressed, remember the start time
  if (current_2 == HIGH && previous_2 == LOW && (millis() - firstTime_2) > 200) {
    firstTime_2 = millis();
  }
  millis_held_2 = (millis() - firstTime_2);
  secs_held_2 = millis_held_2 / 1000;

  // check if the button was released since we last checked
  if (current_2 == LOW && previous_2 == HIGH) {
    Serial.print("Seconds held in second: ");
    Serial.print(secs_held_2);
    Serial.print("   Milliseconds held: ");
    Serial.println(millis_held_2);
    displayResult();
  }
  previous_1 = current_1;
  prev_secs_held_1 = secs_held_1;
  previous_2 = current_2;
  prev_secs_held_2 = secs_held_2;
}

your pb is in this function

void displayResult()
{ 
long average_sec_total = millis_held_1 + millis_held_2;
Serial.print("Average = ");
Serial.println(average_sec_total);
}

you are using millis_held_1 and millis_held_2 but millis_held_1 is not correct as it is constantly updated even after your released the button 1. In the if statement

  // check if the button was released since we last checked
  if (current_1 == LOW && previous_1 == HIGH) {

to see if the first button was released, that's where you should put in memory the duration of button1 press that you will use later in display

How do I put it in memory? I am new to programming and I think that it is not being recorded. Do I have to put it in an array? Can you please show me how as I am finding it difficult? Thanks for your help.

For 2 buttons, that is some impressive code. But what exactly are you trying to measure ? The elapsed time between button 1 being pressed (or maybe released) and the button 2 being released ? So a "life cylcle" may be:

button1 pressed at millis= xxxxxx100 button1 released at millis = xxxxxx200 button2 pressed at millis= xxxxxx700 button1 released at millis = xxxxxx800

so you want 800 - 200 = 600mS ?

I am trying to measure how long button1 is being pressed and then measure how long button2 is being pressed and once button2 is released it does the sum of how long button1 was pressed plus how long button2 was pressed and gives me an answer.

macaw77: How do I put it in memory? I am new to programming and I think that it is not being recorded. Do I have to put it in an array? Can you please show me how as I am finding it difficult? Thanks for your help.

you declare a variable (or use the one you already have with prev_secs_held_1) and store the current press duration in this variable. then in your display function this is what you use to calculate the sum

I have done as you said but still not working. The following is the code and where I have done as you suggested has a //add to make it easy for you to find it. I am interested only in milli seconds and the seconds are just to make it easier. Thanks

int inPin2 = 2; // the pin number for input (1 push button)
int inPin4 = 4; // the pin number for input (2 push button)

int current_1; // Current state of the 1 button
long millis_held_1; // How long the button was held (milliseconds)
long secs_held_1; // How long the button was held (seconds)
long prev_secs_held_1;// How long the button was held in the previous check
long prev_millis_held_1;//add
byte previous_1 = HIGH;
unsigned long firstTime_1; // how long since the button was first pressed

int current_2; // Current state of the 2 button
long millis_held_2; // How long the button was held (milliseconds)
long secs_held_2; // How long the button was held (seconds)
long prev_secs_held_2; // How long the button was held in the previous check
byte previous_2 = HIGH;
unsigned long firstTime_2; // how long since the button was first pressed

void setup() {
Serial.begin(9600); // Use serial for debugging
digitalWrite(inPin2, HIGH);
digitalWrite(inPin4, HIGH);
}
void displayResult()
{
long average_sec_total = prev_millis_held_1 + millis_held_2;//add
Serial.print("Average = ");
Serial.println(average_sec_total);
}
void loop() {
current_1 = digitalRead(inPin2);
current_2 = digitalRead(inPin4);
// if the button state changes to pressed, remember the start time
if (current_1 == HIGH && previous_1 == LOW && (millis() - firstTime_1) > 200) {
firstTime_1 = millis();
}
millis_held_1 = (millis() - firstTime_1);
secs_held_1 = millis_held_1 / 1000;

// check if the button was released since we last checked
if (current_1 == LOW && previous_1 == HIGH) {
Serial.print("Seconds held in second: “);
Serial.print(secs_held_1);
Serial.print(” Milliseconds held: ");
Serial.println(millis_held_1);
}
// if the button state changes to pressed, remember the start time
if (current_2 == HIGH && previous_2 == LOW && (millis() - firstTime_2) > 200) {
firstTime_2 = millis();
}
millis_held_2 = (millis() - firstTime_2);
secs_held_2 = millis_held_2 / 1000;

// check if the button was released since we last checked
if (current_2 == LOW && previous_2 == HIGH) {
Serial.print("Seconds held in second: “);
Serial.print(secs_held_2);
Serial.print(” Milliseconds held: ");
Serial.println(millis_held_2);
displayResult();
}
previous_1 = current_1;
prev_secs_held_1 = secs_held_1;
prev_millis_held_1 = millis_held_1;// add
previous_2 = current_2;
prev_secs_held_2 = secs_held_2;
}

macaw77: I have done as you said but still not working. The following is the code and where I have done as you suggested has a //add to make it easy for you to find it. I am interested only in milli seconds and the seconds are just to make it easier. Thanks

int inPin2 = 2; // the pin number for input (1 push button) int inPin4 = 4; // the pin number for input (2 push button)

int current_1; // Current state of the 1 button long millis_held_1; // How long the button was held (milliseconds) long secs_held_1; // How long the button was held (seconds) long prev_secs_held_1;// How long the button was held in the previous check long prev_millis_held_1;//add byte previous_1 = HIGH; unsigned long firstTime_1; // how long since the button was first pressed

int current_2; // Current state of the 2 button long millis_held_2; // How long the button was held (milliseconds) long secs_held_2; // How long the button was held (seconds) long prev_secs_held_2; // How long the button was held in the previous check byte previous_2 = HIGH; unsigned long firstTime_2; // how long since the button was first pressed

void setup() { Serial.begin(9600); // Use serial for debugging digitalWrite(inPin2, HIGH); digitalWrite(inPin4, HIGH); } void displayResult() { long average_sec_total = prev_millis_held_1 + millis_held_2;//add Serial.print("Average = "); Serial.println(average_sec_total); } void loop() { current_1 = digitalRead(inPin2); current_2 = digitalRead(inPin4); // if the button state changes to pressed, remember the start time if (current_1 == HIGH && previous_1 == LOW && (millis() - firstTime_1) > 200) { firstTime_1 = millis(); } millis_held_1 = (millis() - firstTime_1); secs_held_1 = millis_held_1 / 1000;

// check if the button was released since we last checked if (current_1 == LOW && previous_1 == HIGH) { Serial.print("Seconds held in second: "); Serial.print(secs_held_1); Serial.print(" Milliseconds held: "); Serial.println(millis_held_1); } // if the button state changes to pressed, remember the start time if (current_2 == HIGH && previous_2 == LOW && (millis() - firstTime_2) > 200) { firstTime_2 = millis(); } millis_held_2 = (millis() - firstTime_2); secs_held_2 = millis_held_2 / 1000;

// check if the button was released since we last checked if (current_2 == LOW && previous_2 == HIGH) { Serial.print("Seconds held in second: "); Serial.print(secs_held_2); Serial.print(" Milliseconds held: "); Serial.println(millis_held_2); displayResult(); } previous_1 = current_1; prev_secs_held_1 = secs_held_1; prev_millis_held_1 = millis_held_1;// add previous_2 = current_2; prev_secs_held_2 = secs_held_2; }

6v6gt: . . .

button1 pressed at millis= xxxxxx100 button1 released at millis = xxxxxx200 button2 pressed at millis= xxxxxx700 button2 released at millis = xxxxxx800 . . .

macaw77: I am trying to measure how long button1 is being pressed and then measure how long button2 is being pressed and once button2 is released it does the sum of how long button1 was pressed plus how long button2 was pressed and gives me an answer.

So, from my example, the answer would be 200ms (200-100) + (800-700). But, anyway, it looks like you are in good hands with J-M-L and I'm sure you get a good solution.

actually looking a bit more at your code and the part in setup that says

digitalWrite(inPin2, HIGH);  
digitalWrite(inPin4, HIGH);

it seems your buttons are wired as INPUT PULLUP (i.e. the value you read goes to LOW when pressed) isn’t it?

if that is the case then your code afterwards is reversed as you are expecting HIGH when pressed.

try this cleaned up code:

const byte inPin2 = 2;  // the pin number for input (1 push button)
const byte inPin4 = 4;  // the pin number for input (2 push button)

// As we are using INPUT PULLUP the logic is inveresed, button HIGH means not pressed
#define BUTTON_PRESSED LOW
#define BUTTON_NOT_PRESSED HIGH

const unsigned long debouce_delay = 30;

byte current_1;         // Current state of the 1 button
byte previous_1 = HIGH;
unsigned long millis_held_1;    // How long the button was held (milliseconds)
unsigned long firstTime_1; // how long since the button was first pressed

byte current_2;         // Current state of the 2 button
byte previous_2 = HIGH;

unsigned long millis_held_2;    // How long the button was held (milliseconds)
unsigned long firstTime_2; // how long since the button was first pressed

// ----------------------------------------
// some documentation goes here
// ----------------------------------------
void setup()
{
  Serial.begin(9600);         // Use serial for debugging
  pinMode(inPin2, INPUT_PULLUP); //
  pinMode(inPin2, INPUT_PULLUP);
}

// ----------------------------------------
// documentation goes here
// ----------------------------------------
void displayResult()
{
  unsigned long average_sec_total = millis_held_1 + millis_held_2;
  Serial.print("Average = "); // this is not really an average, you should divide by 2 for that
  Serial.println(average_sec_total);
}

// ----------------------------------------
// some documentation goes here
// ----------------------------------------
void loop() {

  // read the buttons' state
  current_1 = digitalRead(inPin2);
  current_2 = digitalRead(inPin4);

  // if the button state changes to pressed, remember the start time
  if (current_1 == BUTTON_PRESSED && previous_1 == BUTTON_NOT_PRESSED && (millis() - firstTime_1) > debouce_delay) { // 30ms enough for debounce
    firstTime_1 = millis();
    previous_1 = BUTTON_PRESSED;
  }

  // check if the button was released since we last checked
  if (current_1 == BUTTON_NOT_PRESSED && previous_1 == BUTTON_PRESSED) {
    millis_held_1 = (millis() - firstTime_1);
    previous_1 = BUTTON_NOT_PRESSED;
    Serial.print("Button1 Milliseconds held: "); Serial.println(millis_held_1);
  }

  // if the button state changes to pressed, remember the start time
  if (current_2 == BUTTON_PRESSED && previous_2 == BUTTON_NOT_PRESSED && (millis() - firstTime_2) > debouce_delay) { // 30ms enough for debounce
    firstTime_2 = millis();
    previous_2 = BUTTON_PRESSED;
  }

  // check if the button was released since we last checked
  if (current_2 == BUTTON_NOT_PRESSED && previous_2 == BUTTON_PRESSED) {
    millis_held_2 = (millis() - firstTime_2);
    previous_2 = BUTTON_NOT_PRESSED;
    Serial.print("Button2 Milliseconds held: "); Serial.println(millis_held_2);
    displayResult();
  }
}

note that your are just calculating the sum, not the average. Also note that I changed the debouncing time to only 30ms

Note that I moved anything related to millis() and timing to unsigned long to not overflow (or overflow properly)

Thanks a million my friend. I have been looking around on the internet for more than 2 days to solve this problem of adding. The plus was only for testing because I need to make a formula instead of the plus which I still need to figure it out. I had to reverse the following as I need to take the reading while they are pressed.

define BUTTON_PRESSED HIGH

define BUTTON_NOT_PRESSED LOW

Looking through the code seems I had a lot of mistakes but I am new to programming especially on arduino. I saw that you have used #define etc... Do you have a link where I can go through some of these codes so maybe I can learn more. Thanks in advance for everything!

I had to reverse the following as I need to take the reading while they are pressed.

define BUTTON_PRESSED HIGH

define BUTTON_NOT_PRESSED LOW

can you explain how the buttons are connected?

If that works for you this way then it means you are not wired as input pullup and you should also change the 2 pinMode lines to not activate the pullup.

have fun!