Functions pointers and arrays

Hi Everyone,

I’m trying to learn about function pointers and going through them with an array using a button press.

I have three functions, each will turn on the LED that is allocated to that function when a button is pressed and turn off when it’s let go. I’ve put those functions into an array so I can use the button press count to go through each function.

I just can’t get this to work, though. Does anyone have any ideas or advice.

// this constant won't change:
const int buttonPin = 2;    // the pin that the pushbutton is attached to
const int redLED = 13;       // the pin that the LED is attached to
const int yellowLED = 12;       // the pin that the LED is attached to
const int greenLED = 11;       // the pin that the LED is attached to
 
// Variables will change:
int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button

//---------------------------------------------------
// LED FUNCTIONS
//---------------------------------------------------

void redFunction(){
  digitalWrite(redLED, HIGH);
}

void yellowFunction(){
  digitalWrite(yellowLED, HIGH);
}

void greenFunction(){
  digitalWrite(greenLED, HIGH);
}

//---------------------------------------------------
// LED FUNCTIONS ARRAY
//---------------------------------------------------

typedef void (*GeneralFunction)();

GeneralFunction LEDFunctionsArray[]=
{
  redFunction,
  yellowFunction,
  greenFunction
};

//---------------------------------------------------
// SETUP FUNCTION
//---------------------------------------------------

void setup() {
  // put your setup code here, to run once:
    // initialize the button pin as a input:
  pinMode(buttonPin, INPUT_PULLUP);
  // initialize the LEDs as outputs:
  pinMode(redLED, OUTPUT);
  pinMode(yellowLED, OUTPUT);
  pinMode(greenLED, OUTPUT);
}

//---------------------------------------------------
// LOOP FUNCTIONS
//---------------------------------------------------

void loop() {
buttonState = digitalRead(buttonPin);
 
  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == HIGH) {
        if(buttonPushCounter < 4){
       // if the current state is HIGH then the button
       // wend from off to on:
          buttonPushCounter++;
          LEDFunctionsArray[buttonPushCounter]();
      }
    }
    // Delay a little bit to avoid bouncing
    delay(50);
  }
  // save the current state as the last state,
  //for next time through the loop
  lastButtonState = buttonState;
 
}

Cody_Makes_Things: I just can't get this to work, though.

  • ? -

First question, this is to learn about function pointer? Otherwise this is a terrible way of doing it ;) But to learn it's fine.

Cody_Makes_Things: I just can't get this to work, though. Does anyone have any ideas or advice.

But that is the worst type of problem description ;) WHAT is the problem? Compiler error? Or doesn't do what you want? What does it do then?

Cody_Makes_Things: and turn off when it's let go

Why would it do that? I don't see you writing LOW ever ;)

an array of three elements (zero through two):

GeneralFunction LEDFunctionsArray[]=
{
  redFunction,
  yellowFunction,
  greenFunction
};

an index incremented from zero to four:

        if(buttonPushCounter < 4){
       // if the current state is HIGH then the button
       // wend from off to on:
          buttonPushCounter++;
          LEDFunctionsArray[buttonPushCounter]();

Thanks guys!

Sorry for not being specific. Nothing happens at all when I press the button.

Oh crap, I can't believe I screwed that up. Thank you for pointing that out, BulldogLowell! I've fixed that but still no luck.

How would you guys go about doing this?

Cody_Makes_Things: How would you guys go about doing this?

I would at least start with answering all questions ;)

Sorry about that.

The code compiles with no errors and uploads without any issues. When I press the button the LED don’t turn on at all.

I want to be able to press the button and the redFunction gets executed, the red LED comes on and when I let go of the button it turns off; when I press the button again the yellowFunction gets executed and the yellow LED comes on and so one.

I thought that if the button state was LOW the condition of the If statement would be false and the LED would turn off.

Cody_Makes_Things: Sorry about that.

And still... Like I asked, is this just a test? Otherwise this is a poor way of doing it.

Cody_Makes_Things: The code compiles with no errors and uploads without any issues. When I press the button the LED don’t turn on at all.

But BulldogLowell already pointed out a major flaw. Did you correct that? If you did, please repost the code.

Cody_Makes_Things: I thought that if the button state was LOW the condition of the If statement would be false and the LED would turn off.

Why would it? There is no else to that statement. So all it does is only run the function when the switch becomes HIGH. (So I assume external pull up resistors?) Otherwise it will simple do nothing. The inverse is luckily not automatically applied. Also you never write anything else then HIGH to the pins. That will not automagically turn off the led.

Since you're using input_pullup on your button, the test to see if it's pressed should be against LOW. Your wiring needs to reflect that too.

Assuming you've replaced the 4 in your if with a 3, you are still calling an undefined function because you increment buttonPushCounter before you use it. Also, you need something to set buttonPushCounter back to zero.

wildbill:
Since you’re using input_pullup on your button, the test to see if it’s pressed should be against LOW. Your wiring needs to reflect that too.

Assuming you’ve replaced the 4 in your if with a 3, you are still calling an undefined function because you increment buttonPushCounter before you use it. Also, you need something to set buttonPushCounter back to zero.

+1

so, if you are not using function pointers, why use function pointers?

just call the function from the button press like this:

void setup() 
{
  Serial.begin(9600);
  pinMode(buttonPin, INPUT_PULLUP);
  //... etcetera

}

void loop() 
{
  if(buttonPressed())
  {
    counter++;
    counter %= 3;
    switch(counter)
    {
      case 0:
        redFunction();
        break;
      case 1:
        yellowFunction();
        break;
      case 2:
        greenFunction();
        break;
    }
  }
}

sense a button press like this:

bool buttonPressed(void)
{
  static unsigned long lastMillis = 0;
  static byte lastPress = HIGH;
  byte currentPress = digitalRead(buttonPin);
  if(currentPress != lastPress)
  {
    if(millis() - lastMillis < 200) return false;
    lastPress = currentPress;
    if(currentPress == LOW)
    {
      Serial.println("Button press detected!");
      lastMillis = millis();
      return true;
    }
  }
  return false;
}

are you still working on the Psychedelic Flail?