0

i have a need to use 3 buttons a a simple option/variable selector at sketch start up ...

Pretty much at startup , script must wait for button press ( one of 3 ) , when button is pressed , use that buttons predefined string value as a variable for the loop script further down .. if wanting to change the "variable" then a reboot is required ..

i know how to digital read in the buttons , but not sure how to

1) wait for one of the buttons to be pressed to then jump to main loop 2) Associate a "string" variable to each button

thinking about it i suppose a If/Else loop will be required for the Input 'wait" and then just if the digital input (button) is pushed then continue .. am i correct ?

Ideas or better way to do it ?

Thx Greg

2

When I am searching for something inside a loop, I find that the simplest thing to do is to just break out of the loop once I found it. This was frowned upon in the days when structured programming was a hot thing, but as long as it makes things simpler, you should not be ashamed to break:

const int button_pins[] = {2, 3, 4};
const char * const urls[] = {"foo.com", "bar.org", "baz.net"};
const char * url;  // the selected URL

void setup()
{
    Serial.begin(9600);

    // Configure input pins.
    for (int i = 0; i < 3; i++)
        pinMode(button_pins[i], INPUT_PULLUP);

    // Find first button pressed.
    int i;  // button index
    for (i = 0; ; i = i==2 ? 0 : i+1) {
        if (digitalRead(button_pins[i]) == LOW)
            break;
    }

    // The button index selects the URL.
    url = urls[i];

    Serial.print("Selected URL: ");
    Serial.println(url);
}

void loop() {}

The for loop above is written as an endless loop (no end condition). The expression i = i==2 ? 0 : i+1 means: “if i is 2, make it 0, otherwise make it i+1”. In other words, we are endlessly looping i over 0, 1 and 2.

Now, it may well happen that you actually do not care about which button was pressed once you have selected the proper URL. In this case, you can use the URL pointer as a “flag” that tells you when you can end the loop:

// First button pressed selects the URL.
for (int i = 0; !url; i = i==2 ? 0 : i+1) {
    if (digitalRead(button_pins[i]) == LOW)
        url = urls[i];
}

Where !url means “the URL has not been found”. This works because the C runtime initializes url to zero, which is interpreted as false in boolean context.

Addendum: If you are likely to add new button/URL pairs, you can make this easier by structuring the list as an array of structs:

const struct {
    int pin;          // pin number
    const char *url;  // associated URL
} buttons[] = {
    {2, "foo.com"},
    {3, "bar.org"},
    {4, "baz.net"}
    // etc. just add to this list as needed.
};
const size_t button_count = sizeof buttons / sizeof buttons[0];

Then the search becomes:

for (int i = 0; !url; i = i==button_count-1 ? 0 : i+1) {
    if (digitalRead(buttons[i].pin) == LOW)
        url = buttons[i].url;
}
1

1) One solution is to create a function that loops repeatedly, eg while(1), until one of the buttons is pressed. It then returns the button "number", eg 0,1 or 2.

2) In C you would usually remember the index into a string table. So one solution is to store the button number in a global variable and use it to index a "string array", something like char * buttonStrings["B1","B2","B3"]; and to get the string for a button use buttonStrings[buttonNumber];

-1

You can try this. The comments in the program explain quite well.

const int buttons[3] = {2,3,4}; // buttons pins

int butStatus = 0;

void setup() {
  pinMode(buttons[0], INPUT); // declaring pins as inputs
  pinMode(buttons[1], INPUT);
  pinMode(buttons[2], INPUT);

  while(butStatus<=0) //waiting for a button to be pressed
  {
    for(int i=0; i<3; i++) //running trough the 3 buttons
    {
      if(digitalRead(buttons[i]) == HIGH)
      {
        butStatus = i+1; //set variable to the button that has been turned on
      }

      else
      {
        butStatus = 0; //if there is no button press, keep the variable at 0
      }
    }
  }
}

void loop() {
  //variable butStatus is now equal to the button that has been pressed
}
  • Thanks , this looks good .. one question , for the variable .. i require the variables to be URL strings (example www.google.com) , how can i map this ?? so something like button 1 = www.google.com , button 2 - www.yahoo.com , button 3 = somesite.com – Greg Griessel Oct 31 '16 at 12:14
  • use string urls[3] = {"www.google.com", "www.yahoo.com","www.somesite.com"}. Then you can call string something = urls[butStatus];. – Dat Ha Oct 31 '16 at 12:24
  • perfect :-) let me go play :-) – Greg Griessel Oct 31 '16 at 12:25
  • Better make that string something = urls[butStatus-1]; butStatus is 0 for no button or 1-3 for a button pressed, you need to subtract one to get back to a zero based array index. – Andrew Oct 31 '16 at 12:45
  • 1
    If button 2 is not pressed, you butStatus = 0; and stay in the loop. – Edgar Bonet Oct 31 '16 at 21:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.