1

So. I would like to cycle through an array using a button. My current code goes through if statements when the button is pushed. In each if statement I have a loop to print out a list of strings. I am curious if there is anyway to directly cycle through an array using buttons instead of this indirect route I have taken.

Last question - Is there a way to set the indents in the Arduino IDE to make formatting easier here?

//------------------------------------------------------------------------------------------------
// Displays information when a push button is pressed. Also turns on and off a corresponding led.
// 5/3/2016
//------------------------------------------------------------------------------------------------

// declare variables

char* titles[] = {
  "RELATION",
  "FIRST NAME",
  "LAST NAME",
  "LOCATION",
  "PHONE NUMBER"
};
char* user_info[] = {
  "SELF",
  "JOHN",
  "SMITH",
  "FLORIDA",
  "999-888-6666"
};
char* econ_one[] = {
  "BROTHER",
  "MICHAEL",
  "SMITH",
  "FLORIDA",
  "999-888-5555"
};
char* econ_two[] = {
  "WIFE",
  "EMILY",
  "SMITH",
  "FLORIDA",
  "999-888-4444"
};
char* econ_three[] = {
  "SISTER",
  "SOPHIA",
  "ADAMS",
  "NEW YORK",
  "888-777-3333"
};

int ledPinOne = 2;
int ledPinTwo = 3;
int ledPinThree = 4;
int ledPinFour = 5;
int buttonPin = 6;
int state = 0;
// setup - set pins

void setup() {
  Serial.begin(9600);
  pinMode(ledPinOne, OUTPUT);
  pinMode(ledPinTwo, OUTPUT);
  pinMode(ledPinThree, OUTPUT);
  pinMode(ledPinFour, OUTPUT);
  pinMode(buttonPin, INPUT);
  Serial.println("Emergency Contact");
}

// main
void loop() {
  if (digitalRead(buttonPin)) {
    if (state == 0) {
      int x;
      for (x = 0; x <= 4; x++) {
        Serial.println(" ");
        Serial.print(titles[x]);
        Serial.print(" ");
        Serial.print(user_info[x]);
      }
      Serial.println(" ");
      setLights(HIGH, LOW, LOW, LOW);
      state = 1;
    } else if (state == 1) {
      int y;
      for (y = 0; y <= 4; y++) {
        Serial.println(" ");
        Serial.print(titles[y]);
        Serial.print(" ");
        Serial.print(econ_one[y]);
      }
      Serial.println(" ");
      setLights(LOW, HIGH, LOW, LOW);
      state = 2;
    } else if (state == 2) {
      int z;
      for (z = 0; z <= 4; z++) {
        Serial.println(" ");
        Serial.print(titles[z]);
        Serial.print(" ");
        Serial.print(econ_two[z]);
      }
      Serial.println(" ");
      setLights(LOW, LOW, HIGH, LOW);
      state = 3;
    } else if (state == 3) {
      int q;
      for (q = 0; q <= 4; q++) {
        Serial.println(" ");
        Serial.print(titles[q]);
        Serial.print(" ");
        Serial.print(econ_three[q]);
      }
      Serial.println(" ");
      setLights(LOW, LOW, LOW, HIGH);
      state = 0;
    }
    delay(1000);
  }
}

// function to turn LEDs on/off

void setLights(int one, int two, int three, int four) {
  digitalWrite(ledPinOne, one);
  digitalWrite(ledPinTwo, two);
  digitalWrite(ledPinThree, three);
  digitalWrite(ledPinFour, four);
}

output image

https://www.dropbox.com/sc/fwll0qe7cyye1mt/AAD5vI9buU_X0bl04KXFAQyja

2
  • The question is how do you want to cycle through the array? Also its Ctrl+T in the IDE to format the code.
    – RSM
    Commented May 4, 2016 at 7:39
  • Since the question is pretty old and it has some answers, if some of them fits your needs please accept it; otherwise the question will periodically show up in the homepage making possible answerer's lose a lot of time for matters you don't care anymore...
    – frarugi87
    Commented Sep 26, 2017 at 12:11

2 Answers 2

1

I would recommend using multidemnsional arrays for both your contacts and your light states.

//------------------------------------------------ declare variables

char* titles[] = {"RELATION", "FIRST NAME", "LAST NAME", "LOCATION", "PHONE NUMBER"};

char* econs[][5] = {
  {"SELF", "JOHN", "SMITH", "FLORIDA", "999-888-6666"},
  {"BROTHER", "MICHAEL", "SMITH", "FLORIDA", "999-888-5555"},
  {"WIFE", "EMILY", "SMITH", "FLORIDA", "999-888-4444"},
  {"SISTER", "SOPHIA", "ADAMS", "NEW YORK", "888-777-3333"}
};

uint8_t lights[][4] {   {HIGH, LOW, LOW, LOW},
  {LOW, HIGH, LOW, LOW},
  {LOW, LOW, HIGH, LOW},
  {LOW, LOW, LOW, HIGH},
};

int ledPinOne = 2;
int ledPinTwo = 3;
int ledPinThree = 4;
int ledPinFour = 5;
int buttonPin = 6;
int state = 0;

//------------------------------------------------ setup - set pins
void setup() {
  Serial.begin(9600);

  pinMode(ledPinOne, OUTPUT);
  pinMode(ledPinTwo, OUTPUT);
  pinMode(ledPinThree, OUTPUT);
  pinMode(ledPinFour, OUTPUT);
  pinMode(buttonPin, INPUT);

  Serial.println("Emergency Contact");
}

//------------------------------------------------ main
void loop() {


  if (digitalRead(buttonPin))
  {
    if (state > 3)
      state = 0;

    {
      for (int y = 0; y <= 4; y++)
      {
        Serial.println(" ");
        Serial.print(titles[y]);
        Serial.print(" ");
        Serial.print(econs[state][y]);
      }

      Serial.println(" ");
      setLights(lights[state][0], lights[state][1], lights[state][2], lights[state][3]);
    }

    delay(1000);
    state++;

  }

}


//------------------------------------------------ function to turn LEDs on/off

void setLights(int one, int two, int three, int four)
{
  digitalWrite(ledPinOne, one);
  digitalWrite(ledPinTwo, two);
  digitalWrite(ledPinThree, three);
  digitalWrite(ledPinFour, four);
}

I haven't tested the above, but it should provide the same result.

As for the second part of your question, there is an autoformat tool in the Tools menu that will auto-indent your code. Ctrl-T will do the same.

5
  • The multidimensional array is a good idea. I haven't used one before. The code you provided cycles through the array entirely with one button push. I was trying to see if I could cycle through the elements one at a time with each button press. I might try a switch-case. Thank you again for your help I really appreciate it. Commented May 5, 2016 at 3:20
  • I guess i misunderstood yohrnask. You could accomplish what you want to do with a counter, but stil, store the data as shown above. Instead of having the nested for loops (for x, for y), you could replace the for x with a counter that increments with each button press until it reaches 4, the cycles back to zero. It would be a simple change to the code above. When I get a chance, I can show you how to change it.
    – Prdufresne
    Commented May 5, 2016 at 3:40
  • I updated the code in the answer above to cycle through the contacts with each button push.
    – Prdufresne
    Commented May 5, 2016 at 12:55
  • @Prdufresne if you keep the button pressed it will cycle through all the values; moreover if you press it twice within 1 second it will not cycle twice. I'd use the bounce library to detect just the rising edge and avoid that delay; for more info see my answer
    – frarugi87
    Commented May 5, 2016 at 13:14
  • @frarugi87, I think you're right on the point of debounce. I was focused on giving him a cleaner way to cycle the records.
    – Prdufresne
    Commented May 6, 2016 at 17:55
0

As for your question, your way is (kind of) the best way.

I just saw a problem: when you keep the button pressed you will go on showing. Moreover I really don't like the delay at the end, and if its purpose is just to avoid bounces, well, use the Bounce2 class.

As for the repeated ifs, I prefer a switch-case statement.

I highly suggest you to use the Bounce2 class, though. Here is an example of its usage:

Bounce debouncer = Bounce(); 

void setup()
{
    ...
    pinMode(buttonPin, INPUT);
    debouncer.attach(buttonPin);
    debouncer.interval(5); // interval in ms
}

void loop()
{
    debouncer.update();
    if (debouncer.rose())
    {
        switch (state)
        {
        case 0:
            {
                int x;
                for (x=0; x <= 4; x++)
                {
                    Serial.println(" ");
                    Serial.print(titles[x]);
                    Serial.print(" ");
                    Serial.print(user_info[x]);
                }
                Serial.println(" ");
                setLights(HIGH, LOW, LOW, LOW);
                state = 1;
            }
            break;
        case 1:
        ...
        }
    }
}

As you can see the class has a rose member, which tells you if the button was just pressed (only on the rising edge).

Now, your particular problem can be solved in another way. Since you are repeating the same code for all the cases, you can cycle through two arrays; one stating which is the second array you need to use, the other the lights.

This is an example. Please note that I haven't tested it, so there might be some errors

char ** second_array[] = { user_info, econ_one, econ_two, econ_three }
uint8_t lights[][4] {   {HIGH, LOW, LOW, LOW},
                        {LOW, HIGH, LOW, LOW},
                        {LOW, LOW, HIGH, LOW},
                        {LOW, LOW, LOW, HIGH},
                    }

void loop()
{
    debouncer.update();
    if (debouncer.rose())
    {
        int x;
        for (x=0; x <= 4; x++)
        {
            Serial.println(" ");
            Serial.print(titles[x]);
            Serial.print(" ");
            Serial.print(second_array[state][x]);
        }
        Serial.println(" ");
        setLights(lights[state][0], lights[state][1], lights[state][2], lights[state][3]);
        state++;
        if (state >= 4)
            state = 0;
    }
}

Try to use it and then report back if there is some issue ;)

1
  • thank you very much, I will look at this this evening after work. Commented May 4, 2016 at 17:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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