momentary pushbutton as toggle switch

i need to use a momentary pushbutton as a toggleswitch to toggle a pin on or off each time its pressed. could someone help me with code im confused how to do this. thanks in advance

You need to keep track of whether a switch press should turn the pin on or off.

bool pinOn = true;

Then, each time the switch is pressed, toggle the state of that variable:

pinOn = !pinOn;

Finally, if pinOn is true, set the pin LOW. Otherwise, set the pin HIGH.

if(pinOn)
  digitalWrite(pin, LOW);
else
   digitalWrite(pin, HIGH);

im having trouble with the button part of code could someone help

For help with code, you have to post your code.

The stock answer would be to look at the button tutorials. They will explain how to connect a button and make it work.

Connect one side of the pushbutton to ground,. the other to a 10K resistor that goes to VCC. This resistor is called a “pull up resistor”.

Connect the end of the button that goes to the resistor to Digital Input 4 as well.
before setup() add:

// Variable for the button's current state.
// button_mode = 1 when the button is up, and 0 when the button is pressed.
// This variable is 'static' and persists because it is declared outside of a function.
int button_mode = 1;

In setup() add:

// Initialize the Serial port at 9600 baud.
Serial.begin(9600);
// Set Digital pin 4 to an input so it can monitor the button.
pinMode(4,INPUT);

In loop() add:

// Check Digital pin 4 to see if it's pressed.
if ((digitalRead(4) == LOW) && (button_mode == 1))
  {
  // Button was up before, but is pressed now. Set the button to pressed
  // and report that to the serial monitor.
  button_mode = 0; // Button is pressed.
  Serial.println("Button has been pressed.");
  {

else if ((digitalRead(4) == HIGH) && (button_mode == 0))
  {
  // Button was down before, but is released now. Set the button to
  // released and report that to the serial monitor.
  button_mode = 1; // Button is released.
  Serial.println("Button has been released");
  }

delay(100); small delay to account for button bounce.

Note: I did not compile or test this. There may be bugs. Notice also that I commented virtually EVERY line of code.

If you are new, do that. Comment the crud out of your code. These comments server to explain to the you in 20 minutes what the you now was thinking. I cannot BEGIN to tell you how many bugs I have found because I comment the heck out of my code. Bugs happen when what you THINK is happening is not what IS happening. Comments always say what you THINK is happening. Looking and thinking tells you what IS happening. When the two don’t match… you found the bug.

Have a look at this:

int Button = 0; //This is the default "Button Off" and 1 is "Button On"
int OldButton = 0; //I'll explain later

void setup() {
  pinMode(2, INPUT); //Pin 2 is an Input
}

void loop() {
  if(digitalRead(2) == HIGH) { //If Pin 2 is high (At 5 Volts)
    Button = 1 - Button; //If Button is set as 0 then Button = 1 - 0 (=1) and if Button is 1 then Button=1 - 1 (=0)
  }
  
  if(Button == 1 && OldButton == 0) { //If Button is 1 and OldButton is 0 (This means basically means "If the button was just pressed"
      //Put what you want to happen when the "Switch" is on here
     delay(500); //Delay for half a second
  }
  
  if(Button == 0 && OldButton == 1) {
    //Put what you want to happen when the "Switch" is off here
    delay(500); //Delay for half a second
  }

  OldButton = Button; //The data is now old
}

So basically, what happens is that when the button is just pressed something will happen. I have put the “OldButton” in there because the Arduino is very fast (microseconds fast) and it would think that there is a whole new button press, even if you haven’t had the opportunity to take your finger off the button.

TeslaFan:
Comment the crud out of your code. These comments server to explain to the you in 20 minutes what the you now was thinking. I cannot BEGIN to tell you how many bugs I have found because I comment the heck out of my code. Bugs happen when what you THINK is happening is not what IS happening. Comments always say what you THINK is happening. Looking and thinking tells you what IS happening. When the two don’t match… you found the bug.

Ugh… I am SO glad that they hammered that into my head in college. I can’t tell you how much code I’ve been able to use and recycle at my job because of my fastidious commenting. :stuck_out_tongue: I comment virtually every line, and I put preformatted comment blocks over every file, function, class, what have you. Here’s a classic example (of mine):

/**************************** Dragon Radar ************************************/
/* Turns on 7 LEDs for .6s, and simultaneously makes a dragon radar beep.     */
/* Modified Blink function and Beep function.                                 */
/******************************************************************************/

/* Global Variables */
// PinArray - An array of integers. A value of 0 denotes an unused pin;
//            A value of 1 denotes an LED;
//            A value of 2 denotes a buzzer.
//            A value of 3 denotes a button.
int PinArray[] = {0, 0, 2, 0, 0, 1, 0, 3, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0};

// SpeakerPin - An integer denoting the pin number of the buzzer/speaker.
int SpeakerPin = 3;

// switchPin - an integer denoting the pin number of the button
int switchPin = 8;

// switchValue - an integer for storing the current state of the button
int switchValue;

// radarState - an integer for storing the current state of the dragon radar
int radarState;

/*********************************** Setup() **********************************/
/* Initializing function for the LilyPad's pins. Sets LED pins and buzzer     */
/* pins to output, and all others to input.                                   */
/*                                                                            */
/* Input Parameters: none                                                     */
/* Return Type: void                                                          */
/******************************************************************************/
void setup() 
{ 
  /* Local Variables */
  // i - Integer loop counter variable.
  int i;  

  // for: Loop through PinArray, setting output/input status to pins 
  for (i = 0; i < 20; i++)
  { // begin for
    // switch: determine which value is set for current pin.
    switch(PinArray[i])
    { // begin switch
      // if the value is 0, set pin to INPUT. This pin is not being used.
      case 0:
        pinMode(i + 1, INPUT);
        break;
        
      // if the value is 1, set pin to OUTPUT. An LED is using this pin.
      case 1:
        pinMode(i + 1, OUTPUT);
        break;
        
      // if the value is 2, set pin to OUTPUT. A buzzer is using this pin.
      case 2:
        pinMode(i + 1, OUTPUT);
        break;
        
      // if the value is 3, set pin to INTPUT. A button is using this pin.
      case 3:
        pinMode(i + 1, INPUT);
        
        // Set up serial communication at 9600bps
        Serial.begin(9600);
        
        // sets the default (unpressed) state of switchPin to HIGH
        digitalWrite(switchPin, HIGH);
        
        // initialize radar to "off".
        radarState = 0;
        
        break;
    } // end switch
  } // end for
} // end setup()

I know it seems like overkill, but it really helps. With my comments, I usually don’t have to explain much at all to people what my code is “trying” to do. :stuck_out_tongue:

Yes, very nice. Very wise.

If I may suggest, you can remove the "magic numbers" to make sure that later on you don't mistake a 2 for a 3 or something like this:

// PinArray - An array of integers. A value of 0 denotes an pinUnused pin;
//            A value of 1 denotes an pinLed;
//            A value of 2 denotes a pinBuzzer.
//            A value of 3 denotes a pinButton.

typedef enum { pinUnused, pinLed, pinBuzzer, pinButton };

int PinArray[] = {
       pinUnused, pinUnused,  pinBuzzer, pinUnused, pinUnused,   // pins 0 to 4
       pinLed,    pinUnused,  pinButton, pinUnused, pinLed,      // pins 5 to 9
       pinUnused, pinLed,     pinUnused, pinLed,    pinUnused,   // pins 10 to 14
       pinLed,    pinLed,     pinLed,    pinUnused, pinUnused};  // pins 15 to 19

Then later on, it becomes more self-documenting:

switch(PinArray[i])
    { // begin switch
      // if the value is 0, set pin to INPUT. This pin is not being used.
      case pinUnused:
        pinMode(i + 1, INPUT);
        break;
        
      // if the value is 1, set pin to OUTPUT. An LED is using this pin.
      case pinLed:
        pinMode(i + 1, OUTPUT);
        break;
        
      // if the value is 2, set pin to OUTPUT. A buzzer is using this pin.
      case pinBuzzer:
        pinMode(i + 1, OUTPUT);
        break;

Although I do have to wonder, if pinArray [2] is something, why do you set the pinMode for pinArray [3]? Looks confusing.

Indeed, if you assign a type to the enum, it prevents you accidentally using the wrong value:

typedef enum { pinUnused, pinLed, pinBuzzer, pinButton } pinTypes;

pinTypes PinArray[] = {
       pinUnused, pinUnused,  pinBuzzer, pinUnused, pinUnused,   // pins 0 to 4
       pinLed,    pinUnused,  pinButton, pinUnused, pinLed,      // pins 5 to 9
       pinUnused, pinLed,     pinUnused, pinLed,    pinUnused,   // pins 10 to 14
       pinLed,    pinLed,     pinLed,    pinUnused, pinUnused};  // pins 15 to 19

Then:

  PinArray [5] = 4;

Gives an error (which you want):

sketch_apr16b.cpp: In function 'void setup()':
sketch_apr16b:15: error: invalid conversion from 'int' to 'pinTypes'

Now you don't accidentally use the wrong types in your pin array.

[quote author=Nick Gammon link=topic=58284.msg421713#msg421713 date=1302931837]
Yes, very nice. Very wise.

If I may suggest, you can remove the “magic numbers” to make sure that later on you don’t mistake a 2 for a 3 or something like this:

// PinArray - An array of integers. A value of 0 denotes an pinUnused pin;
//            A value of 1 denotes an pinLed;
//            A value of 2 denotes a pinBuzzer.
//            A value of 3 denotes a pinButton.

typedef enum { pinUnused, pinLed, pinBuzzer, pinButton };

int PinArray[] = {
       pinUnused, pinUnused,  pinBuzzer, pinUnused, pinUnused,   // pins 0 to 4
       pinLed,    pinUnused,  pinButton, pinUnused, pinLed,      // pins 5 to 9
       pinUnused, pinLed,     pinUnused, pinLed,    pinUnused,   // pins 10 to 14
       pinLed,    pinLed,     pinLed,    pinUnused, pinUnused};  // pins 15 to 19

Then later on, it becomes more self-documenting:

switch(PinArray[i])
    { // begin switch
      // if the value is 0, set pin to INPUT. This pin is not being used.
      case pinUnused:
        pinMode(i + 1, INPUT);
        break;
        
      // if the value is 1, set pin to OUTPUT. An LED is using this pin.
      case pinLed:
        pinMode(i + 1, OUTPUT);
        break;
        
      // if the value is 2, set pin to OUTPUT. A buzzer is using this pin.
      case pinBuzzer:
        pinMode(i + 1, OUTPUT);
        break;

Although I do have to wonder, if pinArray [2] is something, why do you set the pinMode for pinArray [3]? Looks confusing.
[/quote]Yes, an enum list is probably much smarter, since there’s so little room for confusion. :stuck_out_tongue: I’m ashamed to say that I didn’t think of that.

As for why pinArray[2] is something, and i set pinMode on 3, it’s very simple. An array begins its index at 0, while the pins begin their indices at 1. So to switch from my array index to my pin index, I have to add 1. :slight_smile: