Attempting to program a color matching game, ran into a bit of a block!

Hi there! I’m a new/intermediate programmer and I’m trying my hand at creating a color-matching game, off of my arduino Uno. The game includes 2 NeoPixels, 3 potentiometers, and 1 switch button. The idea of the game is to set one of the Neopixels (dubbed “Simon”) a random color (through method of setting each RGB value a random 0-255), and try to set the color of the other pixel (dubbed “Matcher”) by changing the value of its RGB with the 3 respective potentiometers.

When the button is pressed, if the color is right, Simon will blink white twice, and select a new color. If it is wrong, Simon will blink red twice and retain the color. (this part I haven’t gotten around to coding).

Below is the code that I am currently using:

#include <Adafruit_NeoPixel.h>
#define MATCHER 5
#define SIMON 4
#define NUM_LEDS 1

int redKnobPin = 1; //dial that controls red value
int greenKnobPin = 2; //dial that controls green value
int blueKnobPin = 3; //dial that controls blue value
int button;
int oldButton = 0;
const int buttonPin = 3;
int buttonState = 0;
byte variance = 25; //padding for RGB values to make color matching easier



Adafruit_NeoPixel matcher = Adafruit_NeoPixel(NUM_LEDS, MATCHER, NEO_GRB + NEO_KHZ800); //initiate pixel that will be changing values via dials
Adafruit_NeoPixel simon = Adafruit_NeoPixel(NUM_LEDS, SIMON, NEO_GRB + NEO_KHZ800); //initiate pixel that sets color to try to imitate

void setup() {

  
  // put your setup code here, to run once:
  Serial.begin(9600);
  matcher.begin();
  simon.begin();
  matcher.setBrightness(100);
  simon.setBrightness(100);
  simon.setPixelColor(0,200,0,150); //start off with a certain color for display purposes
  matcher.show();
  simon.show();
  
  pinMode(buttonPin, INPUT);

  

}

void loop() {
  
  // put your main code here, to run repeatedly:
   button =  digitalRead(buttonPin);
    
   int redKnob = analogRead(redKnobPin);
   int greenKnob = analogRead(greenKnobPin);
   int blueKnob = analogRead(blueKnobPin);
   
   byte r= 255, g = 255, b = 255; //set 3 values to pass into Picker function, which get randomized inside

   

   
   redKnob = map(redKnob, 0, 1023, 0, 255);
   greenKnob = map(greenKnob, 0, 1023, 0, 255);
   blueKnob = map(blueKnob, 0, 1023, 0, 255);
      // recalibrate the range of value on the dials to the min/max values of LEDs

int   redKnobP = redKnob + variance;
int   redKnobN = redKnob - variance;  

   matcher.setPixelColor(0, redKnob, greenKnob, blueKnob); //controls color of matcher
   matcher.show();
   
   


  
 if(button == HIGH && oldButton == LOW) //statement to check pushbutton as a triggered press, rather than a press-HIGH release-LOW
 {

  if(buttonState == 0)
  {
    if(redKnobP >= r >= redKnobN)
    {
      
    

     Picker(r,g, b);
      Serial.print("red: "); Serial.print(r); 
      Serial.print(" green: "); Serial.print(g); 
      Serial.print(" blue: "); Serial.println(b);
      Serial.print("red Knob: "); Serial.print(redKnob);Serial.print(" / ");Serial.print(redKnobP); Serial.print(" / "); Serial.println(redKnobN);
      Serial.print(" green Knob: "); Serial.print(greenKnob);
      Serial.print(" blue Knob: "); Serial.println(blueKnob);
      Serial.print("button state: "); Serial.println(buttonState);
      Serial.println();
    }

    
    
    
     buttonState = 1;
 
  }

    else if (buttonState == 1)
    {
     if( redKnobP >= r >= redKnobN){

     Picker(r,g, b);

      Serial.print("red: "); Serial.print(r); 
      Serial.print(" green: "); Serial.print(g); 
      Serial.print(" blue: "); Serial.println(b);
      Serial.print("red Knob: "); Serial.print(redKnob);Serial.print(" / ");Serial.print(redKnobP); Serial.print(" / "); Serial.println(redKnobN);
      Serial.print(" green Knob: "); Serial.print(greenKnob);
      Serial.print(" blue Knob: "); Serial.println(blueKnob);
      Serial.print("button state: "); Serial.println(buttonState);
      Serial.println();

  }
      buttonState = 0;
     
    
    }
 
 oldButton = 1;
 }
 else if(button == LOW && oldButton == HIGH)
 {
  oldButton = 0;
 }
 



}

here is the Picker Function, in another tab:

void Picker(byte &one, byte &two, byte &three ){
  
byte randomNumbers[] = {random(0,255),random(0,255) , random(0,255)};
simon.setPixelColor(0, randomNumbers[0],randomNumbers[1],randomNumbers[2]);
simon.show();


one = randomNumbers[0];
two = randomNumbers[1];
three = randomNumbers[2];
return randomNumbers;

  
}

Here is an example of the data I get in the serial monitor:

red: 116 green: 30 blue: 193
red Knob: 5 / 30 / -20
 green Knob: 5 blue Knob: 16
button state: 1

red: 22 green: 211 blue: 24
red Knob: 0 / 25 / -25
 green Knob: 0 blue Knob: 16
button state: 0

red: 89 green: 251 blue: 223
red Knob: 0 / 25 / -25
 green Knob: 0 blue Knob: 15
button state: 1

red: 42 green: 123 blue: 228
red Knob: 5 / 30 / -20
 green Knob: 5 blue Knob: 20
button state: 0

red: 43 green: 13 blue: 211
red Knob: 0 / 25 / -25
 green Knob: 0 blue Knob: 18
button state: 1

I have the potentiometers working exactly how I want. Currently, when I press the button, I’ll get a random color, and one of the two if statements will run, printing everything I need to debug and get just the red value working. However, since last updating the code, if the redKnob value is at any value besides 0, the button is unresponsive and i get nothing in my monitor. At this point, I fear my method has become too convoluted and will just get messier as i keep trying to fix it and include more features. What is the issue? When I read the code, it’s making sense, but I’m not sure I fully understand what is happening here.

Furthermore, is there an easier way to replicate a trigger button other than writing an if/else statement comparing the two states?

Please let me know if I can provide any more information! Thanks for your time and help!

In your Picker function, you are returning a pointer to a local array. That array may disappear and the pointer may be bad by the time the caller gets it back. You should probably just make that randomNumbers array global for now. Or at least make it static in the Picker function so it doesn't disappear on you.

EDIT: It's worse than that. You have a return statement there, but your function is defined as returning void. If you don't know about returning things from functions, then a good C++ tutorial on functions is in order for you. If you don't want to do that then make randomNumbers global and lose the return altogether.

if(redKnobP >= r >= redKnobN)

That's not going to work. This is programming, not math class.

Go to the top of this page under Learning and click Reference. Scroll down to the bit on boolean operators.

I'll try out your suggestion, and refamiliarize myself with returning values and setting up functions! As for the boolean, I've had it under the correct syntax, (&&) but just made a quick change to see if that made a difference or not. Thanks for your suggestions and advice!

alec5739:
I'll try out your suggestion, and refamiliarize myself with returning values and setting up functions! As for the boolean, I've had it under the correct syntax, (&&) but just made a quick change to see if that made a difference or not. Thanks for your suggestions and advice!

Random changes hardly ever help. Stick with the syntax rules of the language and you can't go wrong.