RGB LED Randomization when button clicked

Hello,
I want to create a program that controls 10 RGB LEDs. When a start button is pressed, 5 random LEDs should light up blue. The user then has to select the correct buttons (10 buttons total and each corresponds to an LED) corresponding to those LEDs, turning them green when clicked. After all five LEDS turn green, pressing the 'start' button should initiate a new set of random LEDs.

Hi @kadiiiiiiii ,

a nice project ...

Is there anything stopping you from just programming it?
ec2021

I have started to program it but I'm unsure on how to make it so that each LED corresponds to a button.

@kadiiiiiiii - Please, delete your other topic with the same subject.

To start your program, search for "arduino button press" and find an example you can use. Here is one:

https://docs.arduino.cc/built-in-examples/digital/Button/

BE SURE to follow the wiring diagram in the example. Then, copy the program so you have something like this:

/*
  Button

  Turns on and off a light emitting diode(LED) connected to digital pin 13,
  when pressing a pushbutton attached to pin 2.

  The circuit:
  - LED attached from pin 13 to ground through 220 ohm resistor
  - pushbutton attached to pin 2 from +5V
  - 10K resistor attached to pin 2 from ground

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/Button
*/

// constants won't change. They're used here to set pin numbers:
const int buttonPin = 2;  // the number of the pushbutton pin
const int ledPin = 13;    // the number of the LED pin

// variables will change:
int buttonState = 0;  // variable for reading the pushbutton status

void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT); // the drawing shows the button tied LOW with a resistor
}

void loop() {
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);

  // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
  if (buttonState == HIGH) {
    // turn LED on:
    digitalWrite(ledPin, HIGH);
  } else {
    // turn LED off:
    digitalWrite(ledPin, LOW);
  }
}

Compile and upload the code to your Arduino. You should see a blinking LED.

if you need 10 buttons and 10 RGB LEDs, that is a lot of pins (10 + 3*10). You might want to look into NeoPixels (aka W2812 led strips). These take power, ground and 1 input pin and you chain them all together so only 1 digital pin for all 10 LEDs. That way, you only need 11 pins so a small Arduino could do the trick (Uno, nano, etc.)

Cross-post removed.

Here is a version that uses a Neopixel ring with 15 RGB leds and a key matrix for 16 buttons, the red starts the game, the buttons are numbered from top left == 1 to bottom right == 16 (the red button):

image

To be tested on Wokwi: https://wokwi.com/projects/393342544046703617

Sketch:

/*
   Forum: https://forum.arduino.cc/t/rgb-led-randomization-when-button-clicked/1239702
   Wokwi: https://wokwi.com/projects/393342544046703617

   Matrix keyboard for 4 rows x 4 columns = 16 keys
   requires one Pin per row and one per column = 8 pins in this case
   And a 15 pixel Neopixel ring

   Press the red key to start a game
   Press the button that corresponds to the blue pixel (changes the color to green)
   If a "black pixel" button was pressed the black pixel changes to red
   If all blue pixels have been changed to green the game ends and
   can be restarted with the red button

   2024/03/25 by ec2021

*/

#include <Adafruit_NeoPixel.h>
#define PIN_NEO_PIXEL 8  // Arduino pin that connects to NeoPixel
#define NUM_PIXELS 15    // The number of LEDs (pixels) on NeoPixel

Adafruit_NeoPixel NeoPixel(NUM_PIXELS, PIN_NEO_PIXEL, NEO_GRB + NEO_KHZ800);
byte pixelColReference[NUM_PIXELS];
const byte clBlack = 0;
const byte clBlue  = 1;
const byte clGreen = 2;
const byte clRed   = 3;
const byte NUM_BLUE = 8;

// key matrix
int row[] = {2, 3, 4, 5};
int column[] = {13, 12, 11, 10};
int col_scan;
int last_scan = -1;

constexpr int noOfRows  = sizeof(row) / sizeof(row[0]);
constexpr int noOfColumns = sizeof(column) / sizeof(column[0]);

boolean blueModus = false;
int greenPixels = 0;
int redPixels   = 0;


void setup()
{
  Serial.begin(115200);
  NeoPixel.begin();
  NeoPixel.clear();
  for (int i = 0; i < noOfRows; i++)
  {
    //Initialization of row pins
    pinMode(row[i], OUTPUT);
  }
  for (int i = 0; i < noOfColumns; i++)
  {
    //Initialization of column pins
    pinMode(column[i], INPUT);
    digitalWrite(column[i], HIGH);
  }
  setAllTo(clBlue);
  delay(1000);
  setAllTo(clGreen);
  delay(1000);
  setAllTo(clBlack);
}

int aRow;
int aColumn;

void loop()
{
  if (buttonPressed(aRow, aColumn)) {
    action(aRow, aColumn);
  }
}

void setAllTo(byte aColor) {
  for (int i = 0; i < NUM_PIXELS; i++) {
    pixelColReference[i] = aColor;
  }
  updateNeoPixels();
}


void updateNeoPixels() {
  for (int pixel = 0; pixel < NUM_PIXELS; pixel++) {
    switch (pixelColReference[pixel]) {
      case clBlack: NeoPixel.setPixelColor(pixel, NeoPixel.Color(0, 0, 0));
        break;
      case clBlue: NeoPixel.setPixelColor(pixel, NeoPixel.Color(0, 0, 255));
        break;
      case clGreen : NeoPixel.setPixelColor(pixel, NeoPixel.Color(0, 255, 0));
        break;
      case clRed:   NeoPixel.setPixelColor(pixel, NeoPixel.Color(255, 0, 0));
        break;
    }
  }
  NeoPixel.show();
}

void randomBlue() {
  randomSeed(millis());
  setAllTo(clBlack);
  int i = 0;
  while (i < NUM_BLUE) {
    int index = random(NUM_PIXELS);
    if (pixelColReference[index] == clBlack) {
      pixelColReference[index] = clBlue;
      i++;
    }
  }
  updateNeoPixels();
  blueModus = true;
  greenPixels = 0;
  redPixels   = 0;
}

boolean buttonPressed(int &aRow, int &aColumn) {
  //Check for pressed buttons
  static boolean pressed = false;
  static unsigned long lastPressTime = 0;
  if (pressed && millis() - lastPressTime < 300) { // The 300 ms avoid bouncing and
    // quick key repetitions
    return false;
  }
  pressed = false;
  for (int i = 0; i < noOfRows; i++)
  {
    if (pressed) break;
    for (int j = 0; j < noOfRows; j++) {
      digitalWrite(row[j], HIGH);
    }
    digitalWrite(row[i], LOW);
    for (int j = 0; j < noOfColumns; j++)
    {
      col_scan = digitalRead(column[j]);
      if (col_scan == LOW)
      {
        lastPressTime = millis();
        pressed = true;
        aRow  = i;
        aColumn = j;
        break;
      }
    }
  }
  return pressed;
}


void action(int i, int j)
{
  int keyNo = i * noOfColumns + j + 1;
  switch (keyNo) {
    case 1 ... NUM_PIXELS :
      changeColor(keyNo - 1);
      break;
    case 16 : // Action for key 16
      randomBlue();
      break;
    default: // and all others here ...
      Serial.println("No action implemented yet ....");
  }
}

void changeColor(byte pixel) {
  if (!blueModus) {
    return;
  }
  byte color = pixelColReference[pixel];
  switch(color){
     case clBlue: color = clGreen;
          greenPixels++;
       break;
     case clBlack: color = clRed;
          redPixels++;
       break;
  }
  pixelColReference[pixel] = color;
  updateNeoPixels();
  if (greenPixels == NUM_BLUE){
    blueDone();
  }
}

void blueDone(){
    blueModus = false;
    Serial.print("Wrong Keys ");
    Serial.println(redPixels);
    delay(2000);
    setAllTo(clGreen);
    delay(1000);
    setAllTo(clBlue);
    delay(1000);
    setAllTo(clRed);
    delay(1000);
    setAllTo(clBlack);

}

It may provide some ideas for your sketch ...
ec2021

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