Press vs Hold Time Button Function

I need help with calculating the amount of time a button remains held down. My current program in which I received from online only calculates from the point in time when the button was first pressed. Rather Then being able to press the button and then pause for a couple seconds and pick up from where it last left off. My setup just continues to count. Are there any suggestions? I am using a touch surface so before doing so I calculated where the button is being pressed with a certain amount of pressure.

It sort of works but it is still running in the background of the program without the button being pressed after the first time. Are there any solutions for this??

whileloopcap.pde (3.56 KB)

It sort of works but it is still running in the background of the program

The Arduino is a single-threaded system. It doesn't have a "background" where stuff can "still run". It really isn't clear what your problem is.

Sorry, for the misunderstanding. But when I run the program. The moment I hold down even press down on the touchpad surface. it starts the timer. So if I let go of the button it still continues to run if I'm still pressing down, though it doesn't show the results on the screen. For example, lets say I start my program and hold down on the surface for 10 secs. and let go and wait 20secs before I press down again. It should show it continuing from the 10secs where I left off, but instead it is still running continuing from 30secs.

Here is a picture of it. I paused for like 10secs in between the gaps that are off. So you can have a better idea of what I'm talking about.

Put all the { on lines by themselves. Use Tools + Auto Format to fix your crappy indenting.

There is no excuse for stuff like this:

  pressTime1
  = millis()- startTime1;

Pay some attention to what you are doing. Consistent use of spaces helps immensely. All of a statement goes on one line, if at all possible. (Yes, I have some code that calls a function with a bunch or arguments, and compares the response to that of another function call that takes a bunch of arguments, and the statement is spread over 20 lines, but that is NOT the case here.)

  if(firsttime == true){

firsttime is not a boolean. The value in it should not be compared to true.

   firsttime=0;
  firsttime = true;

See my earlier note about paying attention and consistency. If you are going to use true and false, use the right kind of variable and use true and false consistently.

/*
while(digitalRead(button) == LOW){}
while(digitalRead(button) == HIGH){
delay(2000);
if(digitalRead(button) == HIGH){
Do something
}}*/

Does this have anything to do with your problem? Of course not. It's commented out. We do NOT need to see this. Delete it!

I'm being a bit harsh, I know, but I can't read your code well enough to see what the problem is, because of it's poor layout (and the fact that notepad++ sees the file as read-only and won't let me edit it to fix the indenting issues and split lines, and to remove commented out code).

I suspect that if the code was laid out logically, the variables types and values were consistent, and there was no useless "code", the problem would be quite obvious.

There is one thing, though, that strikes me as just plain wrong:

  if (readCapacitivePin(capSensePin1) > touchedCutoff) {
   // digitalWrite(LEDPin, HIGH);
   delay(10);
 if(digitalRead(capSensePin1) == LOW){

What, exactly, is connected to capSensePin1? Is it a capacitive sensor that needs readCapacitivePin() to read it? Or, is it a digital sensor that requires digitalRead() to read it? I can't imagine any kind of sensor that can be read either way.

If it IS a capacitive sensor, you really should be using the CapSense library:
http://playground.arduino.cc//Main/CapacitiveSensor?from=Main.CapSense

Sorry about the formatting issues, I was working on a code on a smaller scale which is why I forgot to format it correctly. I'm still very new to Arduinos so please bare with me. But I appreciate the criticism as being constructive comments which will only help me, so I thank you. But coming from a programming background and food for thought, most compilers (c++, java, c, etc. ) do not recognize indentations or the the amount of spaces that you use. For example if I decide to do this:

int var1=


5;

rather than ,

int var1=5;

It is still the same thing to the compiler.
It may affect the human aesthetics of looking at it, but nonetheless it will still run the same way.

But I still reformatted it for readability purposes, and especially programming for a couple years I should know better.

Next issue, I was testing out maybe if the it would recognize it better as a Boolean value, but on the documentation, it says that it recognizes numbers > 0 as true and 0 == false. So that is not the issue and plus it runs the same way.
Referred to....constants - Arduino Reference.

Third issue, I apologize again for not taking out irrelevant comments, such as the while loop comment. I can see it is very much misleading to the readers. I was just testing out different alternatives I saw online, but it didn't work. I didn't pay much attention to the way the program looked to the viewers because this is just a small scale on how my program looks. But I apologize again.

Fourth issue, the function readCapacitivePin() is converting the value of the pressure you press on to the touch pad surface into a number, and if the number is over a certain amount then I nested another if statement within it, so it can then signify this as being a digitalRead(). It shows the change in the button's state from HIGH to LOW. I've alleviated the use of the libraries by putting it in function form and plus this is what the person who gave me the assignment wants me to do they wanted me to calculate the amount pressure placed on the button so we can later modify it for the sensitivity of the touch pad surface, smh.

But nevertheless, it functions properly, the only thing is that after the first time a button is pressed and at the point of release it calculates the elapsed time. But even though, the button has been released it is still running. Also, I have to make 5 more buttons that can do the same thing, and calculate each of the elasped time that the buttons were pressed.

t is still the same thing to the compiler.
It may affect the human aesthetics of looking at it, but nonetheless it will still run the same way.

No argument there. It doesn't matter to the compiler, but it wasn't the compiler that you were asking to review your code. It was us humans, to which it does matter.

So that is not the issue and plus it runs the same way.

It is my expectation that if you use an int, it is because you want to store values other than true or false, and that if you want to store true or false, then boolean is the correct type. There is nothing that the compiler will complain about with a statement like:

boolean isItRaining = 137;

but, do not expect ME to like that. And, do not expect me to help you with code that contains stuff like that.

I don't understand not using a library that has been fully tested and peer reviewed. But, if you have reasons to not use them, that's fine.

I don't understand the part about the extra if statement making it so that digitalRead() can read the capacitive sensor. But, I'm willing to accept that that is true.

Now that you have made some changes, and formatted the code, do you want to post it again? I promise not to be so picky about the style.

Here is the better formatted code:

int touchedCutoff = 60;
int firsttime1,firsttime2,firsttime3,firsttime4,firsttime5,firsttime6=1;
unsigned long startTime1,startTime2;
unsigned long pressTime1,pressTime2;
int capSensePin1 = 2;
int capSensePin2 = 3;
float h, m, s, ms;
unsigned long over;

void setup()
{
Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
pinMode(capSensePin1, INPUT);
pinMode(capSensePin2, INPUT);
digitalWrite(capSensePin1, HIGH);
digitalWrite(capSensePin2, HIGH);

Serial.println("Press and Hold: 1,2 for there corresponding stopwatch function");

}

void displayResult(unsigned long a, unsigned long b)
{
  ms = a % 1000;
  a = a/1000;
  s = a % 60;
  a = a / 60;
  m = a % 60;
  h  = a / 60;
 
 Serial.print("Formatted Press 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(); 
}

void loop(){
  // If the capacitive sensor reads above a certain threshold,
//then proceed with the code
  if (readCapacitivePin(capSensePin1) > touchedCutoff) {
  //this will result in the capSensePin1 being analyzed as a button, if taken out it will automatic go to else if since there is no button //to determine if it was pressed
 if(digitalRead(capSensePin1) == LOW){
  if(firsttime1 == 1){
    startTime1 = millis();

   firsttime1=0;
  }
      pressTime1 = millis()- startTime1;

  if(pressTime1 >= 1){
   Serial.print("Pin2 Runtime: ");
   Serial.print(int(pressTime1/1000));
   Serial.print(" secs ");
   Serial.print(pressTime1);
   Serial.println(" msecs");

 displayResult(pressTime1,startTime1); 

         }
   }
 
 else if(firsttime1 == 0){
  firsttime1 = 1;
  delay(5);
  Serial.println("Time: 0 milleseconds; 0 seconds");

 }
  }

  if (readCapacitivePin(capSensePin2) > touchedCutoff) {

   delay(10);
 if(digitalRead(capSensePin2) == LOW){
  if(firsttime2 == 1){
    startTime2 = millis();
   firsttime2=0;
  }
     
   pressTime2 = millis()- startTime2;
  if(pressTime2 >= 1){
   Serial.print("Pin3 Runtime: ");
   Serial.print(int(pressTime2/1000));
   Serial.print(" secs ");
   Serial.print(pressTime2);
   Serial.println(" msecs");

 displayResult(pressTime2,startTime2); 

}
   }
 
 else if(firsttime2 == 0){
  firsttime2 = 1;
  
  Serial.println("Time: 0 milleseconds; 0 seconds");

 }
  }  
  
}

 
// readCapacitivePin
//  Input: Arduino pin number
//  Output: A number, from 0 to 17 expressing
//          how much capacitance is on the pin
//  When you touch the pin, or whatever you have
//  attached to it, the number will get higher
//  In order for this to work now,
// The pin should have a 1+Megaohm resistor pulling
//  it up to +5v.
uint8_t readCapacitivePin(int pinToMeasure){
  // This is how you declare a variable which
  //  will hold the PORT, PIN, and DDR registers
  //  on an AVR
  volatile uint8_t* port;
  volatile uint8_t* ddr;
  volatile uint8_t* pin;
  // Here we translate the input pin number from
  //  Arduino pin number to the AVR PORT, PIN, DDR,
  //  and which bit of those registers we care about.
  byte bitmask;
  if ((pinToMeasure >= 0) && (pinToMeasure <= 7)){
    port = &PORTD;
    ddr = &DDRD;
    bitmask = 1 << pinToMeasure;
    pin = &PIND;
  }
  if ((pinToMeasure > 7) && (pinToMeasure <= 13)){
    port = &PORTB;
    ddr = &DDRB;
    bitmask = 1 << (pinToMeasure - 8);
    pin = &PINB;
  }
  if ((pinToMeasure > 13) && (pinToMeasure <= 19)){
    port = &PORTC;
    ddr = &DDRC;
    bitmask = 1 << (pinToMeasure - 13);
    pin = &PINC;
  }
  // Discharge the pin first by setting it low and output
  *port &= ~(bitmask);
  *ddr  |= bitmask;
  delay(1);
  // Make the pin an input WITHOUT the internal pull-up on
  *ddr &= ~(bitmask);
  // Now see how long the pin to get pulled up
  int cycles = 16000;
  for(int i = 0; i < cycles; i++){
    if (*pin & bitmask){
      cycles = i;
      break;
    }
  }
  // Discharge the pin again by setting it low and output
  //  It's important to leave the pins low if you want to 
  //  be able to touch more than 1 sensor at a time - if
  //  the sensor is left pulled high, when you touch
  //  two sensors, your body will transfer the charge between
  //  sensors.
  *port &= ~(bitmask);
  *ddr  |= bitmask;
  
  return cycles;
}

Now the format of the code is not relevant to me, nor to my superiors...they just want it to work correctly. I appreciate it, but it the functionality of the program is most prevalent to me.

I copied and paste the code into the IDE, and used Tools + Auto Format. My code looks nothing like yours.

There are a number of conditions that should result in serial output. Looking at the output you posted earlier, I do not see that all of them actually do produce output. Therefore, I have to question your assertion that digitalRead() works correctly on the sensors you have.

Regardless, I don't see anything in the code that accumulates time. I can't understand what firsttimeN is supposed to be telling me. I can't picture what readCapacitivePin() and digitalRead() are supposed to be telling me. I can't see how you detect when a switch is released. I can't see what should reset the accumulated time.

I think that you need to test each part of the code separately, for one switch. Determine that readCapacitivePin() produces correct output. Verify that where and how hard are actually reflected in the output.

Then, verify that digitalRead() actually works with the sensors, and can correctly detect pressing and releasing.

Then, verify that pressing on the sensor and releasing causes the amount of time actually pressed to be measured correctly.

Next, you need to develop some method of resetting the time.

Finally, you can add the pressed time, on release, to the previously accumulated time. To do that, you need to accurately detect pressed (enough) and released. That is the part that I can't see happening.

check out my code

byte setBtnValue;
long setBtnTime;

void checkSetBtnPress() {
setBtnValue = digitalRead(setBtn);
if (setBtnValue == HIGH && (millis() - setBtnTime) >= 2000) { //check if button is pressing and press time more than 2 second
tone(audioPin, 5000, 1000); //make some noise
} else if (setBtnValue == LOW)
setBtnTime = millis(); //if button isn't pressing, set check time to present
}