Holding button down with only one high and then low

Hello.
I’m trying to make an airsoft gun trigger with arduino.
I’m a little bit new to arduino so go easy on me guys.
Back to the problem. Right now im useing delay to help me out, but then the modes dont work. I want to make it so when i press the button(t) it would only send out one high and if i hold the button down it would send 1 high and go bact to low and when i release it it would be low as well…and when i would oress/hold it again it would repeat the proces.

the code:

const int mode = 2;
const int led1 = 7;
const int led2 = 8;
const int led3 = 9;
const int led4 = 10;
const int t = 4;
const int r = 5;
const int q = 6;

int tStatus = 0;
int rStatus = 0;
int state = 0; //hold curent state
int old = 0; //hold old state
int pul = 0; //hold modestate

void setup() {
  pinMode(mode, INPUT);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(t, INPUT);
  pinMode(r, INPUT);
  pinMode(q, OUTPUT);
  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
  digitalWrite(led3, LOW);
}
//debouncing routine
void loop() {
  pul = digitalRead(mode);
  if (pul == 1) {
    delay(50);
    pul = digitalRead(mode);
    if (pul == 0) {
      state = old + 1;
    }
  }
  else {
    delay(100);
  }
  //mode 1 semi
  switch (state) {
    case 1: //mode 1 semi
      off();
      digitalWrite(led2, HIGH);
      tStatus = digitalRead(t);
      rStatus = digitalRead(r);

      if (tStatus == LOW && rStatus == HIGH)
      {
        digitalWrite(q, LOW);
        delay(500);
      } else {
        digitalWrite(q, HIGH);
      }
      old = state;
      break;

    case 2: //mode 2 2burstshot
      off();
      digitalWrite(led3, HIGH);
      tStatus = digitalRead(t);
      rStatus = digitalRead(r);

      if (tStatus == LOW)
      {
        digitalWrite(q, LOW);
        delay(1000);
      } else {
        for ( int i = 0; i <= 1; i++) {
          digitalWrite(q, HIGH);
          delay(200);
          digitalWrite(q, LOW);
          delay(200);
          digitalWrite(q, HIGH);
          delay(200);
          digitalWrite(q, LOW);
        }
      }
      old = state;
      break;

    case 3: //mode 3 fullauto
      off();
      digitalWrite(led4, HIGH);
      tStatus = digitalRead(t);
      rStatus = digitalRead(r);

      if (tStatus == LOW && rStatus == HIGH)
      {
        digitalWrite(q, LOW);
      } else {
        digitalWrite(q, HIGH);
      }
      old = state;
      break;
    default: // saftey
      old = 0;
      digitalWrite(led1, HIGH);
  }
}

//all leds for modoff
void off() {
  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
  digitalWrite(led3, LOW);
  digitalWrite(led4, LOW);
}

Tnx for the help

Hi,
Is this the same problem?

How have you got your button wired and have you got a pull up or pull down resistor?

Have you built and programmed your code, or are you still simulating?

Tom... :slight_smile:

Hi tom.

I can't open the site...I'm useing a pull down resistor and yes i'm still in simulation. I did try the code on an arduino but it was the same as it was in the simulation.

Hi,
Link fixed..

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Tom.. :slight_smile:

Hi,
No it is not…i fix that problem…a firend toled me to use boolean to fix my button problem…
I will make the pdf today.

If you set the button pin mode to INPUT_PULLUP, the resistor is in the chip and you only need to connect the pin to ground through your button/switch. The logic is that LOW is pressed, HIGH is up.

Any time a contact switch closes or opens there is a brief time of sparks jumping between the contacts, except that to an Arduino not delayed the "bouncing" looks like a few to many ON/OFF switches. Software debouncing involves detecting pin state changes ending in a state that is stable for a certain "debounce time" in milliseconds depending on how you code it.

My latest looks at the pin twice a milli and if the pin was the same for 3.5 ms (7 reads) and different 4 ms (8 reads) ago then -that- is a pin state change detected. The switch may have bounced a long time but the last time was 4 ms ago.
Best part is that the 8-read history fits in 1 byte and the pin # fits in another. I debounce a switch with only 2 bytes of RAM, saves more with multi-button projects.

You can put button-watch code in void loop() that only watches the button and updates a status variable.

Other code in void loop() can run if (status variable means change) { do this; do that }

Then you can change how the button works without getting into the run/process code logic.

Oh PS, some tutorials would have the button status be UP or DOWN and then the sketch keep a variable named previousState or like to compare to for state change detection. Do that in the button handler! Make 4 states, UP, DOWN, RELEASED, PRESSED with the 1st 2 steady states and the 2nd 2 as change states.
In my system the status byte is a 4 ms pin-read history where 128 is press detected and 0 is held down.

Thank you for explaining that to me it realy helped me ou :slight_smile: ...ill do my best and try to fix the code with ur explainations.

alphasniper:
Thank you for explaining that to me it realy helped me ou :slight_smile: ...ill do my best and try to fix the code with ur explainations.

What code you put in loop() runs over and over if only to check for a trigger condition that can happen any time, like button press that 1 piece of code always handles no matter what -- meaning you can't allow delaying code in this void loop(), everything gotta run short, fast steps.

When you first learned to program the whole thing ran start to end, top to bottom? Maybe still work in steps but if there's 256 ints to process then it's for-next loop time? Then time to loosen up. Start to end is a road that may loop, branch, never reach an end and void loop() is the wheel that rolls on it covering a bit more with every cycle. You can write code pieces inside of loop() to run depending on what has been happening, button was pressed causes time to be stored and a watch task sees how long the button is held. A step by step process that is responsive to inputs is easiest to cover using state machine coding.

In my signature space below I put addresses to 3 of Nick Gammon's tutorials, the first teaches using time to do many things at once and the second teaches a simple state machine about halfway down. With those two you can automate.

PS -- once you're code-literate these things are simpler than the names make them sound. What you want is easy, what I want is that you will have that and make more of it.