A multiFunction button

hi im trying to find out how to code a button and a potentiometer . i don't know how to code it as im quite new to it. all I know is i want the button to cycle colors for my neopixles RBG value and the potentiometer to change the valure of R G or B .

What have you achieved so far? Can we see your code and hardware setup? If you really haven't written any code, have you at least tried example sketches? If so can you tell us about that?

In order to avoid wasting time telling you things you already know, we need to know what stage you are at, exactly.

The Arduino is a learning platform and so there are numerous online guides and tutorials for common functions such as those that you mention. Have you explored any of those?

1 Like

Think of the button as a single function: “change” that some multifunction code uses to change its state.

1 Like

I think a potentiometer is not the right device. For example, if you press the button to select a color, then adjust that potentiometer for the color to be "100", then store that color value, then press press the button to select another color, the potentiometer will not start at "0" value, the new color will start at "100"... so my suggestion for the intensity selector is a rotary encoder, which can be set to any value you stored at any rotary locations.

But start with your potentiometer idea... Here is an Arduino document showing how to use a potentiometer to fade LEDs.

Maybe instead of adding a button, add two more potentiometers to something like:

Here is an example showing how to use a pushbutton switch to cycle thru colors. See my state change detection for active low inputs tutorial for more information on state change detection and schematics of the wiring. Tested with real hardware.

// by groundfungus
const byte  buttonPin = 7;    // the pin that the pushbutton is attached to
                              // switch wired to ground and input

// Variables will change:
int buttonPushCounter = 0;   // counter for the number of button presses

void setup()
{
   // initialize the button pin as a input, enable the internal pullup resistor:
   pinMode(buttonPin, INPUT_PULLUP);
  
   // initialize serial communication:
   Serial.begin(9600);
   Serial.println("Use momentary switch to cycle through 4 color choices");
}

void loop()
{
   static bool lastButtonState = 0;     // previous state of the button
   static unsigned long timer = 0;
   unsigned long interval = 50;
   if (millis() - timer >= interval)
   {
      timer = millis();
      // read the pushbutton input pin:
      bool buttonState = digitalRead(buttonPin);

      // compare the buttonState to its previous state
      if (buttonState != lastButtonState)
      {
         if (buttonState == LOW)
         {
            // if the current state is LOW then the button
            // went from off to on:
            buttonPushCounter++;  // add one to counter
            if (buttonPushCounter > 3) // if couter over 3 reset the counter to 0 all off
            {
               buttonPushCounter = 0;
            }

            Serial.print("Button Push Counter = ");
            Serial.println(buttonPushCounter);
            Serial.print("color = ");
            switch (buttonPushCounter)
            {
               case 0:
                  Serial.println("Black");
                  break;
               case 1:
                  Serial.println("Red");
                  break;
               case 2:
                  Serial.println("Green");
                  break;
               case 3:
                  Serial.println("Blue");
                  break;                  
            }
         }
      }
      // save the current state as the last state,
      //for next time through the loop
      lastButtonState = buttonState;
   }
}
1 Like

Here's an adaptation of @groundFungus's code to detect changes in an analog potentiometer reading:

// by groundfungus in https://forum.arduino.cc/t/a-multifunction-button/1131935/6
// DaveX modified to demonstrate using similar logic on change in an analog signal
// Simulation demo at https://wokwi.com/projects/365991099114946561
const byte potentiometerPin = A0;    // the pin that the potentiometer is attached to
// switch wired to ground and input

// Variables will change:
int buttonPushCounter = 0;   // counter for the number of zeros detected presses

void setup()
{
  // initialize the button pin as a input, enable the internal pullup resistor:
  pinMode(potentiometerPin, INPUT);

  // initialize serial communication:
  Serial.begin(9600);
  Serial.println("Use analog potentiometer as switch to cycle through 4 color choices");
}

void loop()
{
  static int lastPotentiometerState = 0;     // previous state of the button
  static unsigned long timer = 0;
  unsigned long interval = 50;
  if (millis() - timer >= interval)
  {
    timer = millis();
    // read the potentiometer input pin:
    int potentiometerState = analogRead(potentiometerPin);

    // compare the buttonState to its previous state
    if (potentiometerState != lastPotentiometerState)
    {
      // On potentiometer change:
      Serial.print("Pot:");
      Serial.print(potentiometerState);
      Serial.print(' ');

      if (potentiometerState == 0) // treat as button push
      {
        // if the current state is LOW then the button
        // went from off to on:
        buttonPushCounter++;  // add one to counter
        if (buttonPushCounter > 3) // if couter over 3 reset the counter to 0 all off
        {
          buttonPushCounter = 0;
        }

        Serial.print("Button Push Counter = ");
        Serial.println(buttonPushCounter);
        Serial.print("color = ");
        switch (buttonPushCounter)
        {
          case 0:
            Serial.println("Black");
            break;
          case 1:
            Serial.println("Red");
            break;
          case 2:
            Serial.println("Green");
            break;
          case 3:
            Serial.println("Blue");
            break;
        }
      }

    }
    // save the current state as the last state,
    //for next time through the loop
    lastPotentiometerState = potentiometerState;
  }
}

Tested only in simulation:

I left @groundfungus's counting and color-switching code, and tied to analogRead(A0) == 0 to demonstrate parallels between analog state change detection and digital state change detection.

Your problem could use a bit of both:

  • when the button changes, change the adjustment color like @groundFungus's code,
  • when the potentiometer changes, change the color of the LED based on the potentiometerState and the color.

Maybe with something like this completely untested snippet:

switch(buttonState){
  case 0:
       // set to black
    redComponent = 0;
    greenComponent = 0;
    blueComponent = 0;
   break;
case 1:
    redComponent = potentiometerState/4;
   break;
case 2:
    greenComponent = potentiometerState/4;
   break;
case 3:
    blueComponent = potentiometerState/4;
   break;
}

//update the strip color to match
for(int a=0;a<LED_COUNT;a++){
    strip.setPixelColor(a,redComponent,greenComponent,blueComponent);
}
strip.show();
2 Likes

this is a bit of my code i did watch a video on how to do the neo pixel.
ive changed my idea instead of 1 button i will have 2 so i can use the "if" function and the "else" .e.g. butt1 butt2 , butt1 > butt2 do Red. if butt1 < butt2 do G and if butt1 = butt2 while both is held down it will do B.

Neo pixel

#include <Adafruit_NeoPixel.h> // plugin for the Neopixel library

int dataPin = 6; //what pin dose the LED data cable connect to on the board eg.D6
int PotValue = 0;
//buttons
int Button1 = 2;
int Button2 = 3;

#define numberOfPixels 100 //how meny NeoPixels are on the Led strip

#define maximumBrightness 60 //the maximum brightness of the pixel is 255
//any higher you will damagethem, lower the brightness to increase batttry life

Adafruit_NeoPixel ledStrip = Adafruit_NeoPixel(numberOfPixels, dataPin); //over here we are telling the controller that we have a "ledStrip"
//that has amount of pixels "numberOfPixels" eg 255
//connected to pin "dataPin" on the board eg 6

void setup() {
  ledStrip.begin(); // This tells the led strip to wakeup becouse its going to do things now.
  pinMode(A0, INPUT);
}

void loop() {
  customLight(); //this calls the "customLight" method
  PotValue = analogRead(A0);
}

void customLight() // this is the "customLight" method, think of it as some type of box that groups tasks together
{
  setLightsToColour(PotValue, 44, 155); // this is calling the "SetLightsToColour" method,it needs to know how much Red ,Blue and Green Light
  // to add to each pixel this is known as RGB colour so we are sending it.(255 red,200 green,0 blue)
}

void setLightsToColour(int red, int green, int blue) //this is the "setLightsToColour" method, it needs 3 values for (red,green,blue) so it knows how much to add to each one
{
  for (uint8_t i = 0; i < numberOfPixels; i++) // this makes sure that every pixel gets its colour changed from 0 to "numberOfPixels"
  {
    ledStrip.setPixelColor(i, ledStrip.Color(red, green, blue)); // this is telling the led pixel to change its red green blue to what you have given "setLightToColour()" method
  }

  ledStrip.show(); // this tells the ledStrip to show the changes
}

mapping on the button is needed but i think that will be simple

ill make a wiring diagram on tikercad as it looks like a mess to others .

Please post code properly.

The button switches are not wired right. Remove the connection to Vcc.
image

And set the pinModes for the 2 switch inputs to INPUT_PULLUP. The switch inputs will read HIGH when the switch is open (not pressed) and reads LOW when closed (pressed).

2 Likes
#include <Adafruit_NeoPixel.h>  // plugin for the Neopixel library

int dataPin = 6;  //what pin dose the LED data cable connect to on the board eg.D6
int PotVal = 0; //potimneter value

int butt1 = 2; // button one connected to digital 2
int butt2 = 3; // button two connected to digital 3

int RGBR = 0; // to controll the Red of the RGB
int RGBG = 0;// to controll the Green of the RGB
int RGBB = 0;// to controll the blue of the RGB

#define numberOfPixels 100  //how meny NeoPixels are on the Led strip

#define maximumBrightness 60  //the maximum brightness of the pixel is 255 \
                              //any higher you will damagethem, lower the brightness to increase batttry life

Adafruit_NeoPixel ledStrip = Adafruit_NeoPixel(numberOfPixels, dataPin);  //over here we are telling the controller that we have a "ledStrip"
                                                                          //that has amount of pixels "numberOfPixels" eg 255
                                                                          //connected to pin "dataPin" on the board eg 6

void setup() {
  ledStrip.begin();  // This tells the led strip to wakeup becouse its going to do things now.
  pinMode(A0, INPUT); // to declear what Potval is.
  pinMode(2, INPUT); // to declear what butt 2 is using
  pinMode(3, INPUT); // to declear what butt 3 is using
}


void loop() {
  customLight();  //this calls the "customLight" method
  PotVal = analogRead(A0);
  PotVal = map(PotVal, 0, 1024, 0, 255); //mapping the PotVal
  if (butt1 > butt2) {
    (RGBR = PotVal);                                                  //trying to find a way to make if butt1 has a higher value than butt2 if so the PotVal controlls the RGBR after that it wil save the colour untill changed
  }
}


void customLight()  // this is the "customLight" method, think of it as some type of box that groups tasks together
{
  setLightsToColour(RGBR, 44, 155);  // this is calling the "SetLightsToColour" method,it needs to know how much Red ,Blue and Green Light
                                    // to add to each pixel this is known as RGB colour so we are sending it.(255 red,200 green,0 blue)
}




void setLightsToColour(int red, int green, int blue)  //this is the "setLightsToColour" method, it needs 3 values for (red,green,blue) so it knows how much to add to each one
{
  for (uint8_t i = 0; i < numberOfPixels; i++)  // this makes sure that every pixel gets its colour changed from 0 to "numberOfPixels"
  {
    ledStrip.setPixelColor(i, ledStrip.Color(red, green, blue));  // this is telling the led pixel to change its red green blue to what you have given "setLightToColour()" method
  }

  ledStrip.show();  // this tells the ledStrip to show the changes
}

Did you change those to
pinMode(pin, INPUT_PULLUP);
and adjust the logic in the code to suit?

Yeah .

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.