Am making a toy for my kid and need some help with the coding for it.
A few members here have already helped in parts of the code for this project but I still need some guidance if I am doing it right .
Working : - So its basically like this, the status strip is divided into 2 halves (4 leds each) each half shows a different color , the user is supposed to guess the resultant color which we get when mixing the colors shown in the 2 halves, this is done using the 3 buttons and 3 leds on the front which is called the buttons strip. the 3 leds show 3 possible answers and the user is supposed to select the right one of the 3.
The right answer advances the user to the next level and he gets a new set of colors on the status strip and the game moves on and on like this. Each level gives the user 30 secs to give his input after which the game will fail and start over. If game will reduce the time given for answering after every 5 levels by 10 seconds .
My implementation :-
I am using an Arduino Pro Mini and 3 AAA batteries to power this toy.
I have 2 LED strips , one for the buttons which is 3 LED's long and will be called buttons strip here on and another LED strip around the toy which is 9 LED's long but I will need to use only 8 LEDS of it (am leaving the centermost led of this strip which I dont need to use here (marked in grey in the picture above).
I am using the Fastled library and created 3 arrays of type CRGB to hold values for the buttons strip , status strip and the correct answer.
I also cannot use the delay function as the function that controls the leds and the function that checks for the button press have to run simultaneously , i also plan to include a function to generate sounds via a speaker to indicate the different actions in the game later on .
My programming skill is quite basic and I still have a lot to learn from the brilliant people on this forum, so please bear with me if I seem to ask silly questions in the discussions .
The below is my code I have written till now. Please suggest if any issues in my code and any improvements that i can make . the code compiles fine by the way
#include <FastLED.h>
//configure the buttons and variables to record the button state
const int buttonPin1 = 1;
const int buttonPin2 = 2;
const int buttonPin3 = 3;
int button1State = 0;
int button2State = 0;
int button3State = 0;
//configure the 2 led strips
#define BUTTONS_LED_PIN 9
#define STATUS_LED_PIN 7
#define NUMOFLEDS_BUTTON 3
#define NUMOFLEDS_STATUS 9
#define BRIGHTNESS 50
//#define LED_TYPE WS2811
//#define COLOR_ORDER GRB
// Define the array of leds for both the button strip and status strip
CRGB leds_buttons[NUMOFLEDS_BUTTON];
CRGB leds_status[NUMOFLEDS_STATUS];
//Assign time varibales to use with millis()
unsigned long time;
unsigned long currentTime;
unsigned long previousTime = 0;
long levelTimeout = 30000;
long levelFailedDuration = 2000;
long levelFailedBlink = 100;
//gameSpeed is a work in rogress variable and is currently not being used
int gameSpeed;
int gameLevel;
//create arrays for the different levels
//colorsOnButtons defines the colors that will be displayed on any given level
CRGB colorsOnButtons[3][3] = {
{{ 255, 0, 0}, {0, 255, 0}, {0, 0, 255}},
{{0, 255, 0}, {0, 0, 255}, { 255, 0, 0}},
{{0, 0, 255}, { 255, 0, 0}, {0, 255, 0}}
};
//checkCorrectColor holds the combination of colors with which we need to compare in order to find if a level was won or not.
CRGB checkCorrectColor[3][3] = {
{{ 255, 0, 0}, {0, 200, 0}, {0, 0, 255}},
{{0, 255, 0}, {0, 0, 255}, { 255, 0, 0}},
{{0, 0, 255}, { 255, 0, 0}, {0, 255, 0}}
};
//colorsOnStatus defines what colors are shown on the status led strip, this strip will be devided into 2 halves 0-3 LED and 5-8 LED , the LED number 4 will not be used here
CRGB colorsOnStatus[3][2] = {
{{ 255, 0, 0}, {0, 255, 0}},
{{0, 255, 0}, {0, 0, 255}},
{{0, 0, 255}, { 255, 0, 0}}
};
void(* resetFunc) (void) = 0;//declare reset function at address 0
void setup() {
// Uncomment/edit one of the following lines for your leds arrangement.
delay( 500 );
gameSpeed = 1;
gameLevel = 0;
//Initialize the buttons as Input
pinMode(buttonPin1, INPUT);
pinMode(buttonPin2, INPUT);
pinMode(buttonPin3, INPUT);
FastLED.addLeds<NEOPIXEL, BUTTONS_LED_PIN>(leds_buttons, NUMOFLEDS_BUTTON); // GRB ordering is assumed
FastLED.addLeds<NEOPIXEL, STATUS_LED_PIN>(leds_status, NUMOFLEDS_STATUS);
FastLED.setBrightness( BRIGHTNESS );
//start();
//cycling through the led's on the strip and buttons on start of the game just for fun
for ( int i = 0; i < NUMOFLEDS_STATUS; i++) {
leds_status[i] = ColorFromPalette( RainbowColors_p, 1, BRIGHTNESS, LINEARBLEND);
}
for ( int i = 0; i < NUMOFLEDS_BUTTON; i++) {
leds_buttons[i] = ColorFromPalette( RainbowColors_p, 1, BRIGHTNESS, LINEARBLEND);
}
FastLED.show();
delay(3000);
fill_solid(leds_buttons, NUMOFLEDS_BUTTON, CRGB::Black);
fill_solid(leds_status, NUMOFLEDS_STATUS, CRGB::Black);
FastLED.show();
}
void loop() {
currentTime = millis();
//if(currentTime <= levelTimeout)
showColors(gameSpeed, gameLevel);
checkButtonPressed(gameLevel);
}
//this function checks all 3 buttons and then checks if the right answer was given by comparing the led corresponding to the button with the checkAnswer array
void checkButtonPressed(int x) {
if (currentTime <= levelTimeout) {
button1State = digitalRead(buttonPin1);
button2State = digitalRead(buttonPin2);
button3State = digitalRead(buttonPin3);
if (button1State == HIGH) {
if (colorsOnButtons[x, 0] == checkCorrectColor[x, 0]) {
levelWin();
return;
}
else
levelLose();
}
else if (button2State == HIGH) {
if (colorsOnButtons[x, 1] == checkCorrectColor[x, 1]) {
levelWin();
return;
}
else
levelLose();
}
else if (button3State == HIGH) {
if (colorsOnButtons[x, 2] == checkCorrectColor[x, 2]) {
levelWin();
return;
}
else
levelLose();
}
}
else levelLose();
}
//this function generates the colors which are being shown on the 2 led strips
void showColors(int x, int y) {
int count = 1;
//to show colors on the buttons and selecting the colors for the buttons from the array defined
for (int i = 0; i < 3; i++) {
leds_buttons[i] = colorsOnButtons[y, i];
}
FastLED.show();
// the below code was written to make sure the last 5 seconds of the game time both halves of the status strip alternate between ON and OFF state to indicate that time is running out.
if (currentTime - previousTime >= levelTimeout - 5000) {
long timeDiff = currentTime - previousTime;
//to show the colors for the strip and selecting the colors from the array defined
if (timeDiff >= 500 && timeDiff <= 1000) {
for (int i = 0; i < 4; i++) {
leds_buttons[i] = colorsOnButtons[y, 0];
}
for (int i = 5 ; i < 9; i++) {
leds_buttons[i] = CRGB::Black;
}
FastLED.show();
}
else {
for (int i = 0; i < 4; i++) {
leds_buttons[i] = CRGB::Black;
}
for (int i = 5 ; i < 9; i++) {
leds_buttons[i] = colorsOnButtons[y, 1];
}
FastLED.show();
}
}
else {
for (int i = 0; i < 4; i++) {
leds_buttons[i] = colorsOnButtons[y, 0];
}
for (int i = 5 ; i < 9; i++) {
leds_buttons[i] = colorsOnButtons[y, 1];
}
FastLED.show();
}
}
void levelWin() {
gameLevel++;
if (gameLevel >= 6) {
gameSpeed++;
levelTimeout = 20000;
}
else if (gameLevel >= 10) {
gameSpeed++;
levelTimeout = 10000;
}
FastLED.clear();
for (int i = 0; i < NUMOFLEDS_STATUS; i++) {
leds_status[i] = CRGB::Green;
}
FastLED.show();
for (int i = 0; i < NUMOFLEDS_STATUS; i++) {
leds_status[i] = CRGB::Black;
delay(100);
FastLED.show();
}
}
// when the game is lost the the arduino is reset and the game starts from beginning again
void levelLose() {
FastLED.clear();
for (int i = 0; i < NUMOFLEDS_STATUS; i++) {
leds_status[i] = CRGB::Red;
}
FastLED.show();
for (int i = 0; i < NUMOFLEDS_STATUS; i++) {
leds_status[i] = CRGB::Black;
delay(100);
FastLED.show();
}
resetFunc();
}
