Button Pressed Timer written to variable

Hello everyone.
I made a remote shutter release for my Nikon camera that works by sending a certain IR signal through an IR LED to trigger the camera (take a picture). I want this remote to have 2 modes (for now at least) with the first being a single shot mode where the camera just takes a picture every time the button on my remote is pressed and the second mode being a time lapse mode, where the camera takes a picture every x amount of seconds or milliseconds.

With the code I have now the remote can work in both modes as intended, but the delay in the time lapse mode can only be changed in the code (it is 5 seconds now) , but I want to be able to change it while out taking time lapses and pictures.

So what I want to do is if the remote is set to Time Lapse Mode, I want the shutter button to control that delay value that determines the interval between the shots. I want it to monitor the button, and if I press the button, the arduino should start timing and if I release the button it should stop timing and then take that time to use it as an interval. I don’t know much about the millis function but I think that is the correct one to use, so I would read the time when the button is pressed, and then when it is released and then subtract those 2 values from each other to get the wanted delay or interval between shots.

I did read a lot on how to time the button, but every time their main intent is to distinguish between a long press and a short press, and not just read the time and insert it to a value. And if the sources’ code could work, I’m not sure how to implement it into my scenario.
Thanks.

// Nikon Remote Emulator
// A1 = IR +
// A0 = IR -

int count=0;
const int buttonPin = 8;  //shutter release button
const int modePin = 12;   //toggle switch to switch between single shot mode (uses button to release shutter) and time lapse mode (automatically releases the shutter every x seconds)

int buttonState = 1;  //reads if the shutter button is pressed
int modeState = 1;   //reads in what mode the remote is set (single shutter release/time lapse)

void setup() {
  pinMode(A0,OUTPUT);  //negative output to IR led 
  digitalWrite(A0,LOW);
  pinMode(A1,OUTPUT);  //positive outuput to IR led
  digitalWrite(A1,LOW);
  pinMode(buttonPin, INPUT_PULLUP); 
  pinMode(modePin, INPUT_PULLUP);
}

void loop() {
  // Send code three times, as the clone remote does
  // Delays are tuned to account for overhead of library code.
  modeState = digitalRead(modePin);
  buttonState = digitalRead(buttonPin);

  if(modeState == 0) {  //Single shot mode
  while(buttonState == 0) {  //Checks if shutter button is pressed
  while(count<3) {     //the following lines are just the one signal to trigger a Nikon camera 
    tone(A1,38000);
    delay(2);
    noTone(A1);
    delay(28);
    tone(A1,38000);
    delayMicroseconds(200);
    noTone(A1);
    delayMicroseconds(1500);
    tone(A1,38000);
    delayMicroseconds(200);
    noTone(A1);
    delayMicroseconds(3300);
    tone(A1,38000);
    delayMicroseconds(200);
    noTone(A1);
    delayMicroseconds(100);    
    delay(63);   
    count++;  
   }
   buttonState = digitalRead(buttonPin);
   count = 0;
  }
  }
  if(modeState == 1) {    //set to time lapse mode
     while(count<3) {

    tone(A1,38000);
    delay(2);
    noTone(A1);
    delay(28);
    tone(A1,38000);
    delayMicroseconds(200);
    noTone(A1);
    delayMicroseconds(1500);
    tone(A1,38000);
    delayMicroseconds(200);
    noTone(A1);
    delayMicroseconds(3300);
    tone(A1,38000);
    delayMicroseconds(200);
    noTone(A1);
    delayMicroseconds(100);    
    delay(63); 
    delay(5000);   //I want this time value to be a variable and therefore easily controlled
    count++;
  }
  count = 0;
 }
}

johansmituser:
So what I want to do is if the remote is set to Time Lapse Mode, I want the shutter button to control that delay value that determines the interval between the shots. I want it to monitor the button, and if I press the button, the arduino should start timing and if I release the button it should stop timing and then take that time to use it as an interval.

When the shutter button *becomes *pressed reset a timer then allow the timer to run as long as the button is held pressed. When the button *becomes *unpressed move the milliseconds the timer has accumulated over to the delay() statement.

If you haven't already, look at the first five in IDE -> file/examples/digital.

Don't try to shoehorn this function into the existing code, build a separate sketch just for developing/testing this feature. Once it's working you can merge it with the main code.

Thank you!

I went to those examples, I didn’t think I’ll get anything there, but looking at the examples, especially the Blink without delay and funny enough the Debounce example, and then combining it from what I saw on YouTube, I could put together something that almost works like I planned.

Because of the delays in the code after the button monitor part of the sketch, the Arduino sometimes only look at the button every 30 seconds in time lapse mode, which is definitely not what I wanted, so I googled around on interrupts, but I think if I have that code I struggled with, put into an interrupt with the press of the button (or a change in state) “activating” the interrupt, the Arduino senses a change in state, triggers the interrupt, and then goes back to where it was busy, which is not what I wanted because it should time, so the Interrupt doesn’t work.

Now I simply defaulted that interval variable to 1 second, so now the loop runs about every second, making the button press timer accurate within one second, which is perfectly fine. With a five second default, I could only set the interval to multiples of 5, because the code makes it check only every about 5 seconds, so now I just set the default interval to 1 second so now it “refreshes” every one second making it just right. It could be one second off but that’s fine. For some reason it doesn’t take more than the one interval change after a power on. But that is also perfectly fine as my power switch is literately just a toggle switch that I can switch off and on in a second. So that’s fine. So if I want to change the interval I can just power the Arduino off and then on again and then set the new interval.

So I think I’m satisfied with what it can do for now.

// Nikon Remote Emulator
// A1 = IR +
// A0 = IR -

int count=0;
const int buttonPin = 2;  //shutter release button
const int modePin = 12;   //toggle switch to switch between single shot mode (uses button to release shutter) and time lapse mode (automatically releases the shutter every x seconds)

int buttonState = 1;  //reads if the shutter button is pressed
int modeState = 1;   //reads in what mode the remote is set (single shutter release/time lapse)
int tlinterval = 1000;
//////////////////////////////
int lastButtonState = 1;
unsigned long startMillis = 0;
unsigned long endMillis = 0;



void setup() {
  pinMode(A0,OUTPUT);  //negative output to IR led 
  digitalWrite(A0,LOW);
  pinMode(A1,OUTPUT);  //positive outuput to IR led
  digitalWrite(A1,LOW);
  pinMode(buttonPin, INPUT_PULLUP); 
  pinMode(modePin, INPUT_PULLUP);
  Serial.begin(9600);
  //attachInterrupt(digitalPinToInterrupt(buttonPin), ISR_button, CHANGE);
 
}

void loop() {
  // Send code three times, as the clone remote does
  // Delays are tuned to account for overhead of library code.
  modeState = digitalRead(modePin);
  buttonState = digitalRead(buttonPin);

  //////////////////////////////////////////////////////////////////////////////////////////////
 if (buttonState != lastButtonState && modeState == 1) {
          if (buttonState == LOW) {
             startMillis = millis();
             //Serial.print("Button Pressed");
             
             Serial.print(buttonState);
          }
          else {    
            endMillis = millis();
            //Serial.print("Button Depressed");
            tlinterval = endMillis - startMillis;
           //Serial.print(tlinterval);
          }
          lastButtonState = buttonState;
 }
/////////////////////////////////////////////////////////////////////////////////////////////////

  if(modeState == 0) {  //Single shot mode
  while(buttonState == 0) {  //Checks if shutter button is pressed
  //while(count<3) {     //the following lines are just the one signal to trigger a Nikon camera 
    tone(A1,38000);
    delay(2);
    noTone(A1);
    delay(28);
    tone(A1,38000);
    delayMicroseconds(200);
    noTone(A1);
    delayMicroseconds(1500);
    tone(A1,38000);
    delayMicroseconds(200);
    noTone(A1);
    delayMicroseconds(3300);
    tone(A1,38000);
    delayMicroseconds(200);
    noTone(A1);
    delayMicroseconds(100);    
    delay(63);   
    count++;  
   //}
   buttonState = digitalRead(buttonPin);
   count = 0;
  }
  }
  if (modeState == 1) {    //set to time lapse mode

    //while(count<3) {

    tone(A1,38000);
    delay(2);
    noTone(A1);
    delay(28);
    tone(A1,38000);
    delayMicroseconds(200);
    noTone(A1);
    delayMicroseconds(1500);
    tone(A1,38000);
    delayMicroseconds(200);
    noTone(A1);
    delayMicroseconds(3300);
    tone(A1,38000);
    delayMicroseconds(200);
    noTone(A1);
    delayMicroseconds(100);    
    delay(63); 
    delay(tlinterval);   //I want this time value to be a variable and therefore easily controlled
    count++;
  //}
  count = 0;
  
 }
}