For this weeks assignment I wanted to really challenge myself. I feel really comfortable with coding so I decided not to code at all and depend only on the physical components of our Arduino sets!
When I think about LEDs they always reminds of simple colors. And what could be simpler than a color in RGB representation. With that idea in mind I decided to create a form of button steered RGB representation.
I discovered that in our kits we have an actually RGB LED. Having read about it on the internet I plugged it accordingly. I wanted to have 3 separate buttons, which would control the amount of Red, Green and Blue in the final LED.
I plugged regular buttons in corresponding colors as well as check up LEDs next to them. Then I connected everything with the separate pins of the RGB LED.
I struggled to think of any creative ideas at first and just started working. After a while, my initial idea was to have 4 buttons and 4 bulbs, where clicking on a button triggers a temporary lighting of the bulbs in the order 1234, the second triggers them in the same order with the last bulb off (123), third lights 2 bulbs (12), and the fourth lights 1. If you click two times, the order changes to 4123, and the same logic applies to buttons, 2, 3, and 4. Then if three clicks it is 3412, and if 4 clicks it is 2341, basically shifting every number to fit in all four possible positions.
Major Struggles
This assignment was actually very challenging for me for several reasons. Firstaly, I was not able to get buttons until Sunday night which made me very stressed while working during the tight time. I was not able to find big colorful buttons like the ones which my peers have in their kits; I found much smaller ones instead which are all just black. This in itself made it very hard to try them out properly and I would sometimes cause the buttons to fall off from the circuit if I simply press a bit hard. In order to resolve the color issue, I actually used nail polish to color the small surfaces of the buttons.
I kept working for hours and a recurring issue kept happening; anything I use in the lower half of the board simply did not work, even if I copy the literal code for it and corresponding electrical wiring from above. After hours of extreme frustration, I realized that half of my breadboard doesn’t work properly.
In order to resolve the issue, I actually extended my power and ground wires to the right side too, and added a button and bulb on the right side. Even though I wanted to have more than three items at the start, that was not feasible at this point.
Idea and implementation
After getting acquainted with my board and with playing with electrical tools in general, I started to dive right into my idea. I realized that lighting the bulbs one after the other might be too much work that is not very necessary so I decided to just dismiss that idea. I decided pressing certain buttons would trigger certain bulbs and that pressing several buttons together would yield another result.
I was able to achieve this goal after several trials and errors where the following applies to my final project:
Pressing the blue button on the left turns the 3 bulbs on
Pressing it again right after turning them on turns them all off
Pressing the purple button in the middle turns the last 2 (yellow and white) bulbs on
Pressing it again right after turning them on turns them off
Pressing the dark red button on the left turns the 1st and 3rd (red and white) bulbs on
Pressing it again right after turning them on turns them off
Pressing/holding the first and second buttons together turns only the red (1st) one on
Pressing/holding the second and third buttons together turns only the yellow (2nd) one on
Pressing/holding the third and first buttons together turns only the white (3rd) one on
Pressing/holding the 3 buttons simply turns them all off
It should be noted that I made sure that if you already had some lights on and click a certain button, it adapts the bulbs to fit the appropriate output without having to turn off all of them and resetting then turning the appropriate ones on, which is so much aesthetically pleasing.
Below, I show how clicking on two buttons lights one bulb up (red in this case).
Below is the final assignment:
I learned so much from this assignment as the experience of coding and building such circuits is quite new me, and my pace is not as fast as with Processing which will require some extra effort from my end.
Here is the code I used for the circuit:
int ledRed = 5; //pin of the red bulb
int ledYellow = 9; //pin of yellow bulb
int ledWhite = 11; //pin of white bulb
int prevButtonState1= LOW; //previous state of blue button
int prevButtonState2= LOW; //previous state of purple button
int prevButtonState3= LOW; //previous state of red button
int ledState1; //state of red bulb
int ledState2; //state of yellow bulb
int ledState3; //state of white bulb
int buttonBlue = 4; //pin of blue button
int buttonPurple = 8; //pin of purple button
int buttonRed = 10; //pin of red button
void setup() {
ledState1 = LOW; //initializing blue button state to not clicked
ledState2 = LOW; //initializing purple button state to not clicked
ledState3 = LOW; //initializing red button state to not clicked
pinMode(ledRed, OUTPUT); //declaring red led as output variable
pinMode(buttonBlue, INPUT); //declaring blue button as intput variable
pinMode(ledYellow, OUTPUT); //declaring yellow led as output variable
pinMode(buttonPurple, INPUT); //declaring purple button as intput variable
pinMode(ledWhite, OUTPUT); //declaring white led as output variable
pinMode(buttonRed, INPUT); //declaring red button as intput variable
Serial.begin(9600);
}
void loop() {
int currentButtonState1 = digitalRead(buttonBlue); //setting variable to digital reading of state of blue button
int currentButtonState2 = digitalRead(buttonPurple); //setting variable to digital reading of state of purple button
int currentButtonState3 = digitalRead(buttonRed); //setting variable to digital reading of state of red button
if ((currentButtonState1 == HIGH) && (currentButtonState2 == HIGH) && (currentButtonState3 == HIGH)) { //if all buttons are pressed, turn all bulbs off
ledState1 = LOW;
ledState2 = LOW;
ledState3 = LOW;
}
else if ((currentButtonState1 == HIGH) && (currentButtonState2 == HIGH)) { //if both the blue and purple buttons are pressed/held together
if (ledState1 == HIGH) { //if red bulb was lighting turn it off
ledState1 = LOW;
}
else if (ledState1 == LOW) { //if red bulb was not on, turn it on
ledState1 = HIGH;
}
ledState2 = LOW; //ensure the yellow bulb is off
ledState3 = LOW; //ensure the white bulb is off
}
else if ((currentButtonState2 == HIGH) && (currentButtonState3 == HIGH)) { //if both the purple and red buttons are pressed/held together
if (ledState2 == HIGH) { //if yellow bulb was on, turn off
ledState2 = LOW;
}
else if (ledState2 == LOW) { //if yellow bulb was off, turn on
ledState2 = HIGH;
}
ledState1 = LOW; //ensure red bulb is off
ledState3 = LOW; //ensure white bulb is off
}
else if ((currentButtonState1 == HIGH) && (currentButtonState3 == HIGH)) { //if both the blue and red buttons are pressed/held together
if (ledState3 == HIGH) { //if white bulb is on, turn off
ledState3 = LOW;
}
else if (ledState3 == LOW) { //if white bulb is off, turn on
ledState3 = HIGH;
}
ledState1 = LOW; //ensure red bulb is off
ledState2 = LOW; //ensure yellow bulb is off
}
else if (currentButtonState1 == HIGH && prevButtonState1 == LOW) { //if blue button is pressed
if (ledState1 == HIGH && ledState2 == HIGH && ledState3 == HIGH) { //if this was the last button previously pressed, turn off all bulbs
ledState1 = LOW;
ledState2 = LOW;
ledState3 = LOW;
}
else { //otherwise, turn them all on
ledState1 = HIGH;
ledState2 = HIGH;
ledState3 = HIGH;
}
}
else if (currentButtonState2 == HIGH && prevButtonState2 == LOW) { //if the purple button is pressed
if (ledState2 == HIGH && ledState3 == HIGH && ledState1 == LOW) { //if this was the last pressed button, turn the lit ones off
ledState2 = LOW;
ledState3 = LOW;
}
else { //otherwise, turn the yellow and white bulbs only on
ledState2 = HIGH;
ledState3 = HIGH;
ledState1 = LOW;
}
}
else if (currentButtonState3 == HIGH && prevButtonState3 == LOW) { //if the red button is pressed
if (ledState1 == HIGH && ledState3 == HIGH && ledState2 == LOW) { //if it was teh last pressed button, turn lit ones off
ledState1 = LOW;
ledState3 = LOW;
}
else { //otherwise, turn the red and white bulbs on
ledState3 = HIGH;
ledState1 = HIGH;
ledState2 = LOW;
}
}
digitalWrite(ledRed, ledState1);
digitalWrite(ledYellow, ledState2);
digitalWrite(ledWhite, ledState3); //update the bulbs accordingly
prevButtonState1 = currentButtonState1;
prevButtonState2 = currentButtonState2;
prevButtonState3 = currentButtonState3; //update the current states of the buttons for evaluation in the next frame
}
This week, I decided to do an LED puzzle that is similar to Simon Says, where the instructions are given in the form of a melody. I didn’t want to use a song too long or else it’d be too hard, so I used the beginning of the sound of music theme song. The melody goes: 1 2 3 1 3 1 3 2 3 4 4 3 2 4.
There are four buttons on the breadboard, with four corresponding LEDs. They are Green(1), Yellow(2), Blue(3), and Red(4). When the program starts up, the lights will play (show) the melody in full. Then, it’s up to the player to recognize or memorize what the melody is. Then, the player has to press the four buttons in the order that the melody is. If they succeed in the end, all four lights will light up and flash.
In the process of doing this project, I encounter a lot of problems that were great learning experiences for Arduino. For one, when I put the condition where a button is pressed down, Arduino cycles through the execution many times, even though I just pressed it briefly. To solve this problem, I borrowed the method in class notes, where I made a “previous button” value that holds whether a button was just pressed.
There is one part of this project that I really wanted to improve on but couldn’t, which is making a database of melodies and giving them out randomly. There are a few problems that I’ll face if I want to do this. Currently, I have two arrays, one is the original melody array that is recorded when the lights are shown, and the other is the entry array of the player. I then go through a for loop the length of the original melody, and in each loop, I check whether that index is the same between the original and entry. If I wanted to do a database of melodies, I would have to find a way to make the length of the arrays dynamic and make the length of it a variable for the for-loop.
Another improvement I wanted to do was to make my code more optimized, specifically the part where the lights are showing the melody. Right now, I hardcoded the order and delay that each note should be played. What I want to do is to simply enter a dictionary of numbers, the first being the note and the second being the delay, and the code would automatically sort the dictionary into the flashing order for the lights. I ran out of time to do it this time, but I’m confident this is do-able. Getting the code to do this would also help the database idea by making it easier to code in a melody.
Here is my full code:
//buttons and lights initialization:
int greenB = 12;
int greenL = 13;
int yellowB = 9;
int yellowL = 10;
int blueB = 6;
int blueL = 7;
int redB = 3;
int redL = 4;
int prevB = LOW;
int prevYB = LOW;
int prevBB = LOW;
int prevRB = LOW;
boolean play = true;
boolean yay = false;
int song[14];
int entry[14];
int value;
int count = 0;
void setup() {
// put your setup code here, to run once:
pinMode(greenL, OUTPUT);
pinMode(greenB, INPUT);
pinMode(yellowL, OUTPUT);
pinMode(yellowB, INPUT);
pinMode(blueL, OUTPUT);
pinMode(blueB, INPUT);
pinMode(redL, OUTPUT);
pinMode(redB, INPUT);
}
void loop() {
// put your main code here, to run repeatedly:
int Gstate = digitalRead(greenB);
int Ystate = digitalRead(yellowB);
int Bstate = digitalRead(blueB);
int Rstate = digitalRead(redB);
//instructions
if (play == true){
digitalWrite(greenL, HIGH);
delay(650);
digitalWrite(greenL, LOW);
song[0] = 1;
digitalWrite(yellowL, HIGH);
delay(250);
digitalWrite(yellowL, LOW);
song[1] = 2;
digitalWrite(blueL, HIGH);
delay(250);
digitalWrite(blueL, LOW);
song[2] = 3;
delay(500);
digitalWrite(greenL, HIGH);
delay(400);
digitalWrite(greenL, LOW);
song[3] = 1;
digitalWrite(blueL, HIGH);
delay(400);
digitalWrite(blueL, LOW);
song[4] = 3;
digitalWrite(greenL, HIGH);
delay(400);
digitalWrite(greenL, LOW);
song[5] = 1;
digitalWrite(blueL, HIGH);
delay(400);
digitalWrite(blueL, LOW);
song[6] = 3;
delay(500);
digitalWrite(yellowL, HIGH);
delay(600);
digitalWrite(yellowL, LOW);
song[7] = 2;
digitalWrite(blueL, HIGH);
delay(250);
digitalWrite(blueL, LOW);
song[8] = 3;
digitalWrite(redL, HIGH);
delay(200);
digitalWrite(redL, LOW);
delay(100);
song[9] = 4;
digitalWrite(redL, HIGH);
delay(200);
digitalWrite(redL, LOW);
song[10] = 4;
delay(100);
digitalWrite(blueL, HIGH);
delay(250);
digitalWrite(blueL, LOW);
song[11] = 3;
digitalWrite(yellowL, HIGH);
delay(250);
digitalWrite(yellowL, LOW);
song[12] = 2;
digitalWrite(redL, LOW);
song[13] = 4;
digitalWrite(redL, HIGH);
delay(650);
play = false;
}
//game
if (play == false){
//button lighting when pressed
//green
if (Gstate == HIGH) {
digitalWrite(greenL, HIGH);
if (prevB == LOW){
value = 1;
count = count + 1;
entry[count - 1] = value;
prevB = Gstate;
}
}
if (Gstate == LOW) {
digitalWrite(greenL, LOW);
prevB = Gstate;
}
//yellow
if (Ystate == HIGH) {
digitalWrite(yellowL, HIGH);
if (prevYB == LOW){
value = 1;
count = count + 1;
entry[count - 1] = value;
prevYB = Ystate;
}
}
if (Ystate == LOW) {
digitalWrite(yellowL, LOW);
prevYB = Ystate;
}
//blue
if (Bstate == HIGH) {
digitalWrite(blueL, HIGH);
if (prevBB == LOW){
value = 1;
count = count + 1;
entry[count - 1] = value;
prevBB = Bstate;
}
}
if (Bstate == LOW) {
digitalWrite(blueL, LOW);
prevBB = Bstate;
}
//red
if (Rstate == HIGH) {
digitalWrite(redL, HIGH);
if (prevRB == LOW){
value = 1;
count = count + 1;
entry[count - 1] = value;
prevRB = Rstate;
}
}
if (Rstate == LOW) {
digitalWrite(redL, LOW);
prevRB = Rstate;
}
if (count >= 14){
for (int i = 0; i <= 14; i++){
if (song[i] == entry[i]){
yay = true;
}
}
}
}
//win celebration:
if (yay == true){
for (int i = 1; i <= 5; i++){
delay(500);
digitalWrite(greenL, HIGH);
digitalWrite(yellowL, HIGH);
digitalWrite(blueL, HIGH);
digitalWrite(redL, HIGH);
delay(500);
digitalWrite(greenL, LOW);
digitalWrite(yellowL, LOW);
digitalWrite(blueL, LOW);
digitalWrite(redL, LOW);
delay(500);
}
yay = false;
}
}
The LED puzzle I am made is a sort of game where 3 different LED lights randomly turn on at different times and speed. There will come a point when all 3 lights are on at the same time, and this is when a player should press the button. If a player has pressed the button at this exact time of alignment, then all the lights will blink 7 times, signifying the win of the game.
I wanted to make this a game of speed and simplicity. I am personally very happy with what I have produced because it looks neat to me. One thing a player would have to be aware of is the pressing of the button because sometimes the button does not come in full contact with the board and so it leads to misses. Would love to learn to incorporate music to this game later in the future.
INITIAL CODE (didn’t work):
int ledPin = 2;
int ledPin2 = 4;
int buttonPin2 = 5;
int ledPin3 = 6;
int buttonState2 = 0;
void setup() {
// put your setup code here, to run once:
pinMode(ledPin, OUTPUT);
pinMode(ledPin2, OUTPUT);
pinMode(buttonPin2, INPUT);
pinMode(ledPin3, OUTPUT);
}
void loop() {
// put your main code here, to run repeatedly:
int buttonState2 = digitalRead(buttonPin2);
if (buttonState2 == HIGH) {
Serial.println("button");
digitalWrite(ledPin2, HIGH);
digitalWrite(ledPin, HIGH);
} else {
// turn LED off:
while (buttonState2 != HIGH){
int n = 2*random(1,4);
int m = 2*random(1,4);
int p = 2*random(1,4);
//Serial.begin(9600);
//Serial.println(n);
digitalWrite(n, HIGH);
delay(random(1,500));
digitalWrite(m, HIGH);
delay(random(1,500));
digitalWrite(p, HIGH);
delay(random(1,500));
digitalWrite(n, LOW);
delay(random(1,500));
digitalWrite(m, LOW);
delay(random(1,500));
digitalWrite(p, LOW);
delay(random(1,500));
if (buttonState2 == HIGH) {
Serial.println("BUTTON");
break;
}
}
digitalWrite(ledPin2, LOW);
digitalWrite(ledPin, LOW);
}
delay(100);
}
You can actually tell from the video below that the lights do turn on, but the buttons do not carry out any functionalities… Not good!
FINAL CODE:
I wanted to make my code as simple and straightforward as possible. Here is what it looks like.
This is to let everyone know that – thanks to Aaron’s help last week – I managed to fix the scoring glitch that I had in my game!
My game logic was missing a lot of elements here and there, which resulted in a massive bug that crashed the whole game.
Fixing a few functions inside the main class and adding id tracking variables and array in mousePressed() helped to resolve this issue.
void mousePressed() {
// play sound
click.play();
for (int i=0; i<cards.length; i++) {
// only flip cards over if there are less than 2 flipped
if (amountFlipped<2) {
// only flip if the card hasn't been flipped
// and also hasn't been matched (just to be safe)
if (!cards[i].flipped && !cards[i].matched) {
// check which card got clicked
if (cards[i].checkClicked()) {
// we've flipped it now so increase the amount that have been flipped
amountFlipped++;
}
}
}
}
}
// check the IDs of the flipped cards
void checkIDs() {
// make sure we have two flipped
// (already checked in mousePressed to make sure we're not counting matched cards)
if (amountFlipped == 2) {
// we need to keep track to make sure we check two cards
// this index does that (we already made sure it's only two just above)
int thisIndex = 0;
for (int i=0; i<cards.length; i++) {
// if the card is flipped, AND is NOT matched
if (cards[i].flipped && !cards[i].matched) {
// get that card's ID and its index
ids[thisIndex] = cards[i].id;
whichCard[thisIndex] = cards[i].index;
// increment our local index
thisIndex++;
}
}
// if we have something for both cards (otherwise one would be -1)
if (whichCard[0]>=0 && whichCard[1]>=0) {
// if they match set to matched and increase score
if (ids[0] == ids[1]) {
cards[whichCard[0]].matched = true;
cards[whichCard[1]].matched = true;
score++;
if (score == numCards/2){
scene = 2;
}
} else { // otherwise trigger the timer and reset things back to -1
cards[whichCard[0]].triggerTimer();
cards[whichCard[1]].triggerTimer();
ids = new int[]{-1, -1};
whichCard = new int[]{-1, -1};
}
// always reset the amountflipped back to 0 so we can start again
amountFlipped = 0;
}
}
}
Starting something new is always scary. Ever since class on Wednesday, I had this assignment on my mind and I kept questioning how fast I could be able to get accustomed to working with the Arduino Uno. After going through our class recording and playing around with the elements a bit, I felt nostalgic for the days I did Lego robotics in high school and realized that it’s a lot of fun exploring the possibilities that this kit has. Also, I felt like getting feedback from something you’re doing with your hands when you’re trying to debug your code is so helpful! It helped me understand better how what I write is translating into reality.
Idea
So, my first instinct was to create a puzzle based on color theory. Maybe that the user needs to press the yellow and blue buttons to turn on an LED? So I went down that path and decided to make a puzzle that’s inspired by the colors of the rainbow.
Game Play
A player has 4 buttons and 4 LEDs in front of them, and the goal is to get all four LEDs flashing simultaneously. Before starting they get a few instructions or pointers:
You need six steps to achieve the task
These steps have a specific order/sequence
You can press a maximum of two buttons at the same time
Here’s a riddle to give you a hint:
“You see me in the air
But I am not a kite
I am what’s created
When water refracts light”
(I found this on a children’s riddle website)
Solution
The solution is inspired by the colors of the rainbow which I considered to be (Red, Orange, Yellow, Green, Blue, Violet) ((Sorry, Indigo)). So here are the steps to the solution:
Press Red Button
Press Red + Yellow Buttons
Press Yellow Button
Press Green Button
Press Blue Button
Press Blue + Red Buttons
It has to be in that specific sequence, or else the LEDs won’t flash!
Video Examples
(Just realized I should’ve filmed horizontal videos!)
My solution is highly dependent on the sequence, so if the Red button is pressed in step one, the Red LED turns on to signify the completion of the step. Otherwise, it wouldn’t trigger anything. Here’s an example of me pressing some buttons at the wrong time
Finally, I thought it would be fun if I got someone to test it so my suitemate volunteered! She almost got it from the first time! 🙂
Logic
To transition between steps, I used Switch() and created a variable number called step number to move between the steps of my solution sequence. So, when step number = 0, the puzzle only responds to the play pressing the red button.
Improvement
One point of improvement could be adding another LED that flashes when a wrong button is pressed, to add more feedback for the user. I pointed out where that would be included in my code in the comments.
Also, if I had an extra button, I would make a reset button since the user has to get through the puzzle for it to restart or I have to re-upload the program.
Code
Here’s my commented code!
//introduce LED pin variables
int blueLedPin = 10;
int greenLedPin = 11;
int yellowLedPin = 12;
int redLedPin = 13;
//introduce Button pin variables
int redButtonPin = 7;
int yellowButtonPin = 6;
int greenButtonPin = 5;
int blueButtonPin = 4;
//introduce variable to keep track of steps
int stepNo = 0;
void setup() {
//set pin modes
pinMode(redLedPin, OUTPUT);
pinMode(yellowLedPin, OUTPUT);
pinMode(greenLedPin, OUTPUT);
pinMode(blueLedPin,OUTPUT);
pinMode(redButtonPin, INPUT);
pinMode(yellowButtonPin, INPUT);
pinMode(greenButtonPin, INPUT);
pinMode(blueButtonPin, INPUT);
Serial.begin(9600);
}
void loop() {
//creating variables for all button states, to read if button is pressed
int redButtonState = digitalRead(redButtonPin);
int yellowButtonState = digitalRead(yellowButtonPin);
int greenButtonState = digitalRead(greenButtonPin);
int blueButtonState = digitalRead(blueButtonPin);
//using a switch function to move between steps, this makes the sequence aspect of the puzzle possible.
switch (stepNo) {
// 1st color is red, move must be red button
case 0:
// checks if red button is pressed, and turns it on then off accordingly
if (redButtonState == HIGH) {
digitalWrite(redLedPin, HIGH);
delay(700);
digitalWrite(redLedPin, LOW);
//if the step is performed correctly, it moves on to the next step of the puzzle
stepNo += 1;
//here, there's a possibility to add an else if statement, where if any of the other buttons are pressed an
//additional "error" LED light would flash, indicating a mistake
}
break;
case 1:
//2nd color is orange, move must be red + yellow buttons
if (yellowButtonState == HIGH && redButtonState == HIGH) {
digitalWrite(redLedPin, HIGH);
digitalWrite(yellowLedPin, HIGH);
delay(700);
digitalWrite(redLedPin, LOW);
digitalWrite(yellowLedPin, LOW);
stepNo += 1;
}
break;
case 2:
//3rd color is yellow, move must be yellow button
if (yellowButtonState == HIGH) {
digitalWrite(yellowLedPin, HIGH);
delay(700);
digitalWrite(yellowLedPin, LOW);
stepNo += 1;
}
break;
case 3:
//4th color is green, move must be green button
if (greenButtonState == HIGH) {
digitalWrite(greenLedPin, HIGH);
delay(700);
digitalWrite(greenLedPin, LOW);
stepNo += 1;
}
break;
case 4:
//5th color is blue, move must be blue button
if (blueButtonState == HIGH) {
digitalWrite(blueLedPin, HIGH);
delay(700);
digitalWrite(blueLedPin, LOW);
stepNo += 1;
}
break;
case 5:
//6th color is violet, move must be blue + red buttons
if (blueButtonState == HIGH && redButtonState == HIGH) {
//introducing a variable for number of times that all the lights will flash, will use in a while loop
int flashes = 0;
//10 flashes when the user finishes the pattern
while(flashes < 10){
//flashing technique from class, all LEDs on, delay, LEDs off, delay
digitalWrite(blueLedPin, HIGH);
digitalWrite(redLedPin, HIGH);
digitalWrite(yellowLedPin, HIGH);
digitalWrite(greenLedPin, HIGH);
delay(400);
digitalWrite(blueLedPin, LOW);
digitalWrite(redLedPin, LOW);
digitalWrite(yellowLedPin, LOW);
digitalWrite(greenLedPin, LOW);
delay(400);
//adding flashes to eventually exit the while loop
flashes+=1;}
//restarts the puzzle
stepNo = 0;
}
break;
}
}
For this week’s assignment, I decided to create a small reaction game where the user will have to press the button corresponding to the color of the LED light that will be lightened up in a random order within a small interval, which is 3 seconds. When the right button is pressed, it will turn off that LED light and another one will light up again.
Sketch of original idea
SETTING IT UP
When it came to setting up the hardware part on the breadboard and microcontroller, surprisingly I did not encounter any difficulties as my setup was overall not that complex or confusing. However, it is after a couple days that I realized I had misplaced one of my pins for the red button one row lower than it should be and this caused me to spend hours figuring out why that one button wouldn’t work.
Also, as seen in the first picture above of my original idea, I originally wanted to place the buttons that are the same color as the LED lights in the same row. But later, I decided it would be more interesting and kind of more difficult for the user if the buttons were not in the same row as the LED lights that were the same color.
CODING
This was where I had the most difficulties in mainly because I was not able to code in this new environment aside from Processing, as we’ve been coding on that for so long now.
Coding for randomly lighting up LED lights
For this section of code for the LED lights to light up randomly, I struggled with it originally as I just simply just told it to choose a random number and turn on that random number in correspondence to the LED light, have a little delay, then light up another random one. But, later, I realized that there was so much more needed in it for it to work, such as the fact that during the delay, it won’t do anything so that means that my buttons will not be able to work, therefore I could not use the delay function.
Luckily, I found the “Blink without Delay” example in Arduino and I incorporated that into my own code while configuring it to include the random element.
Coding for Button Press
When coding for the buttons to turn off the corresponding LED lights, I had the most difficulty in understanding the concept about previous and current button states, where after the button is pressed and released in the current frame, I have to set LOW to the previous button state so that the next time it can fit the condition to be a new button press again. (Not sure if I explained it clearly, but that’s the gist.)
My Code
const int GreenLed = 2;
const int RedLed = 3;
const int YellowLed = 4;
int GreenLedState = LOW;
int RedLedState = LOW;
int YellowLedState = LOW;
const int Redbutton = 10;
const int Yellowbutton = 9;
const int Greenbutton = 8;
int prevGreenButtonState = LOW;
int prevRedButtonState = LOW;
int prevYellowButtonState = LOW;
int randomNum; //pick random light to turn on (from pin 2 to pin 4)
unsigned long previousMillis = 0; // will store last time LED was updated
const long interval = 3000; //interval at which to blink (milliseconds)
void setup() {
// setup all LED pins as outputs
for (int i = 2; i < 5; i++) {
pinMode(i, OUTPUT);
}
Serial.begin(9600);
Serial.println(randomNum);
//setup all button pins as inputs
for (int i = 8; i < 11; i++) {
pinMode(i, INPUT);
}
}
void loop() {
LEDLightSequence();
Greenbuttonpress();
Redbuttonpress();
Yellowbuttonpress();
}
void LEDLightSequence() {//code to light up random LED light
randomNum = random(2, 5);//pick random light to turn on (from pin 2 to pin 4)
Serial.println(randomNum);
unsigned long currentMillis = millis();
// check to see if it's time to blink the LED; that is,
//save the last time you blinked the LED
//if the difference between the current time and last time you blinked the LED is bigger than
//the interval at which you want to blink the LED.
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
//if the LED is off turn it on and vice versa
if (randomNum == GreenLed && GreenLedState == LOW) {
GreenLedState = HIGH;
} else {
GreenLedState = LOW;
}
// set the LED with the ledState of the variable:
digitalWrite(GreenLed, GreenLedState);
if (randomNum == RedLed && RedLedState == LOW) {
RedLedState = HIGH;
} else {
RedLedState = LOW;
}
digitalWrite(RedLed, RedLedState);
if (randomNum == YellowLed && YellowLedState == LOW) {
YellowLedState = HIGH;
} else {
YellowLedState = LOW;
}
digitalWrite(YellowLed, YellowLedState);
}
}
void Greenbuttonpress() {
int currentGreenbutton = digitalRead(Greenbutton); // check if green button is pressed
if (currentGreenbutton == HIGH && prevGreenButtonState == LOW) { //if the randm number chosen is 2, the Green LED light is lit and the greenbutton was pressed, turn off the green led light
if (GreenLedState == HIGH) {
GreenLedState = LOW;
}
}
digitalWrite(GreenLed, GreenLedState);
prevGreenButtonState = currentGreenbutton;
}
void Redbuttonpress() {
int currentRedButton = digitalRead(Redbutton); // check if green button is pressed
if (currentRedButton == HIGH && prevRedButtonState == LOW) { //if current red button is pressed and the previous red button in the last frame wasn't pressed (wasn't pressed before)
if (RedLedState == HIGH) { //if the red led light is on
RedLedState = LOW; //turn the red led light off
}
}
digitalWrite(RedLed, RedLedState);
prevRedButtonState = currentRedButton; //after button is pressed (HIGH) and released (LOW) in current frame, set LOW to prevButtonstate so next time it can be newly pressed again
}
void Yellowbuttonpress() {
int currentYellowButton = digitalRead(Yellowbutton); // check if green button is pressed
if (currentYellowButton == HIGH && prevYellowButtonState == LOW) { //if current red button is pressed and the previous red button in the last frame wasn't pressed (wasn't pressed before)
if (YellowLedState == HIGH) { //if the red led light is on
YellowLedState = LOW; //turn the red led light off
}
}
digitalWrite(YellowLed, YellowLedState);
prevYellowButtonState = currentYellowButton; //after button is pressed (HIGH) and released (LOW) in current frame, set LOW to prevButtonstate so next time it can be newly pressed again
}
For this week’s assignment, I decided to make some sort of game where you have to press a button before the light reaches the bottom.
The light goes through three colored LEDs before it does reaches the bottom (which is a common yellow LED).
As I said, you have to press the corresponding colored button to “stop” the light from falling. If the light does reach the bottom/yellow LED, all the other colored LEDs will light up at once signaling you lost.
I only did this with 2 buttons, 6 LEDs (3 for each button) + an extra common LED, because including 3 buttons made it way too messy and it wouldn’t fit. However, I do include a version with 3 buttons made on an online simulator at the end.
This is what the circuit looks like for the 2-button version:
code
I define all the pins before setup, including 2 arrays for the LED pins.
In setup(), I set the pins to OUTPUT for the LEDs, and INPUT for the buttons.
I then have two functions right before loop(). One is RED(), the other is BLUE(). They do the exact same thing, except that RED operates on the array of red LEDs, while BLUE operates on the array of blue LEDs.
Inside loop(), I just call these functions based on an if-statement.
int rowN;
int l1 = 2;
int l2 = 3;
int l3 = 4;
int l4 = 5;
int l5 = 6;
int l6 = 7;
int b1 = 8;
int b2 = 9;
int common = 10;
int checkCommon =0; //to check if the common LED is on
int lost = 0; //to check if you lost
int pressed1 = 0; //to check if red button is pressed
int pressed2 = 0; //to check if blue button is pressed
int row1[4] = {l1,l2,l3,common}; //array of red LEDs
int row2[4] = {l4,l5,l6,common}; //array of blue LEDs
void setup() {
// put your setup code here, to run once:
for (int i= 0; i<3; i++)
{
pinMode(row1[i],OUTPUT);
}
for (int i= 0; i<3; i++)
{
pinMode(row2[i],OUTPUT);
}
pinMode(b1,INPUT);
pinMode(b2,INPUT);
pinMode(common,OUTPUT);
randomSeed(digitalRead(0));
rowN = int(random(1,3));
}
void RED()
{
if(pressed1 == 0)
{
for (int i= 0; i<4; i++)
{
checkCommon=0;
if (digitalRead(b1) == HIGH)
{
pressed1 = 1;
digitalWrite(row1[i],LOW);
delay(500);
break;
}
else
{
checkCommon =1;
}
delay(200);
digitalWrite(row1[i],HIGH);
delay(100);
digitalWrite(row1[i],LOW);
if (i==3 && checkCommon ==1)
{
delay(200);
digitalWrite(common, LOW);
lost = 1;
}
}
}
if (lost == 1)
{
for (int i= 0; i<3; i++)
{
digitalWrite(row1[i],HIGH);
digitalWrite(row2[i],HIGH);
}
delay(500);
for (int i= 0; i<3; i++)
{
digitalWrite(row1[i],LOW);
digitalWrite(row2[i],LOW);
}
lost = 0;
}
if (pressed1 == 1)
{
pressed1 = 0;
}
}
void BLUE()
{
if(pressed2 ==0)
{
for (int i= 0; i<4; i++)
{
checkCommon=0;
if (digitalRead(b2) == HIGH)
{
pressed2 = 1;
digitalWrite(row2[i],LOW);
delay(500);
break;
}
else
{
checkCommon =1;
}
delay(200);
digitalWrite(row2[i],HIGH);
delay(100);
digitalWrite(row2[i],LOW);
if (i==3 && checkCommon ==1)
{
delay(200);
digitalWrite(common, LOW);
lost = 1;
}
}
}
if (lost == 1)
{
for (int i= 0; i<3; i++)
{
digitalWrite(row1[i],HIGH);
digitalWrite(row2[i],HIGH);
}
delay(500);
for (int i= 0; i<3; i++)
{
digitalWrite(row1[i],LOW);
digitalWrite(row2[i],LOW);
}
lost = 0;
}
if (pressed2 == 1)
{
pressed2 = 0;
}
}
void loop() {
// put your main code here, to run repeatedly:
//red case
if (rowN == 1)
{
RED();
rowN = int(random(1,3));
}
//blue case
if (rowN == 2)
{
BLUE();
rowN = int(random(1,3));
}
}
Steps
First, I started out by making the LED arrays and randomly switching between them.
Then, I added the common yellow LED, and made all the other colored LEDs light up at once if the light reaches this common LED. This will mean you lost.
final outcome
Adding the push-buttons and their functionalities gave this final result:
3 buttons version
The assignment asked for at least 3 buttons and at least 3 LEDs, but since three buttons were too hard to fit on the breadboard in my case, I made a version with three buttons on an online simulator.
This is what the circuit looks like
For my project this week, I decided to make a communication system using a series of LEDs and buttons and the ability for you to record your own message in
…
wait for it
….
MORSE CODE
and then play it back as many times as you’d like.
When the Arduino first starts up, the Arduino will flash SOS denoted by:
…—…
and then will wait for actions.
You can record your own message by pressing the blue button. When red led lights up it means that it will record a message when you push buttons. When you push the red button it will flash two green leds and will record a dash, when you push the yellow button it will flash one green led and will record a dot.
You can stop the recording by pushing the blue button, the red led will turn off.
You can play back the message that you just recorded pushing the green button. This will turn on the blue led indicating that you are now in playback mode and will flash the message you just recorded.
You can push the green button as many times as you want to playback the record message.
// use static array to store the recorded codes
int message[500];
int messageSize = 0;
int sos[9] = {0, 0, 0, 1, 1, 1, 0, 0, 0};
int playSos = true;
//pins
int dashPin = 12;
int dotPin = 11;
int recordStopPin = 10;
int playPin = 9;
//one led is dot
//two leds are dash
int led1Pin = 3;
int led2Pin = 2;
int recordPin = 4;
int playingLedPin = 5;
//flags
bool record = false;
bool isPlaying = false;
void setup() {
Serial.begin(9600);
pinMode(dashPin, INPUT);
pinMode(dotPin, INPUT);
pinMode(recordStopPin, INPUT);
pinMode(playPin, INPUT);
pinMode(led1Pin, OUTPUT);
pinMode(led2Pin, OUTPUT);
pinMode(recordPin, OUTPUT);
pinMode(playingLedPin, OUTPUT);
// play(sos, 9);/
}
void loop() {
readPin();
if (record) {
digitalWrite(recordPin, HIGH);
} else {
digitalWrite(recordPin, LOW);
}
if (isPlaying) {
digitalWrite(playingLedPin, HIGH);
play(message, messageSize);
} else {
digitalWrite(playingLedPin, LOW);
}
if (playSos) {
play(sos, 9);
playSos = false;
}
}
// register a dash
void registerDash() {
addDigit(1);
}
// register a dot
void registerDot() {
addDigit(0);
}
// add the digit to the array
void addDigit(int add) {
message[messageSize] = add;
Serial.println(message[messageSize]);
messageSize++;
}
//
void readPin() {
if (digitalRead(dashPin) == HIGH && !isPlaying) {
if (record) {
registerDash();
}
digitalWrite(led1Pin, HIGH);
digitalWrite(led2Pin, HIGH);
delay(500);
digitalWrite(led1Pin, LOW);
digitalWrite(led2Pin, LOW);
}
if (digitalRead(dotPin) == HIGH && !isPlaying) {
if (record) {
registerDot();
}
digitalWrite(led1Pin, HIGH);
delay(500);
digitalWrite(led1Pin, LOW);
}
if (digitalRead(recordStopPin) == HIGH && !isPlaying) { //set recording state
Serial.println("record/stop");
record = !record;
delay(500);
}
if (digitalRead(playPin) == HIGH && !record) {
Serial.println("play");
isPlaying = !isPlaying;
delay(500);
}
}
int play(int arr[], int arrSize) {
for (int i = 0; i < arrSize; i++) {
if (arr[i] == 1) {
digitalWrite(led1Pin, HIGH);
digitalWrite(led2Pin, HIGH);
delay(500);
digitalWrite(led1Pin, LOW);
digitalWrite(led2Pin, LOW);
}
if (arr[i] == 0) {
digitalWrite(led1Pin, HIGH);
delay(500);
digitalWrite(led1Pin, LOW);
}
delay(500);
}
isPlaying = false;
return 0;
}
//notes
// -1 is invalid
// 0 is a dot
// 1 is a dash
// first button is for registering a dash
// second button is for registering a dot
// third button is to record
// forth button is to play the saved recording
My first idea for this assignment was to create a sort of pattern game where the lights show a pattern, and you are required to mimic that pattern to unlock the fourth (blue light). Unfortunately, I wasn’t entirely sure how to accomplish that, so decided to experiment with other ideas. Here is what my code does:
Red button: turns on each led one at a time, consecutively, then all off.
Blue button: turns all LEDs on at the same time, for 3 seconds then turns them off.
Green button: usually just turns green like a regular switch, but when pushed after the red button, will turn on both green and red
Yellow button: does a pattern where two lights are turned on at once.
This assignment was particularly interesting because when I faced an issue, I was unsure whether I should debug from the code or from the physical board. At some points, even though I was sure that everything in the circuit was working fine, my green button never turned off and I began considering a fault in the circuit. (ultimately it was my code). I also faced a lot of problems getting the initial circuit to work, because of the number of wires and resistors, and small breadboard. Eventually what worked for me was colour coordinating the wires to the colors (i used white for power, instead of red just this time so that I could colour coordinate).
int greenButton = 2;
int greenLed = 3;
int yellowButton = 4;
int yellowLed = 5;
int redButton = 6;
int redLed = 7;
int blueButton = 8;
int blueLed = 9;
int redState = LOW;
int redButtonState = LOW;
void setup() {
// set pin modes
pinMode(redLed, OUTPUT);
pinMode(redButton, INPUT);
Serial.begin(9600);
pinMode(greenLed, OUTPUT);
pinMode(greenButton, INPUT);
Serial.begin(9600);
pinMode(yellowLed, OUTPUT);
pinMode(yellowButton, INPUT);
Serial.begin(9600);
pinMode(blueLed, OUTPUT);
pinMode(blueButton, INPUT);
Serial.begin(9600);
}
void loop() {
//green button that lights green regularly, but if pushed after the red button, the red lights up too
int greenState = digitalRead(greenButton);
Serial.println(greenLed);
digitalWrite(greenLed, greenState);
if (greenState == HIGH && redButtonState == HIGH){
digitalWrite(redLed, greenState);
delay(1000);
redButtonState = LOW;
}
int redState = digitalRead(redButton);
Serial.println(redLed);
digitalWrite(redLed, redState);
//yellow makes a pattern appear- two leds at a time
int yellowState = digitalRead(yellowButton);
Serial.println(yellowLed);
digitalWrite(yellowLed, yellowState);
if (yellowState == HIGH){
digitalWrite(blueLed, yellowState);
digitalWrite(yellowLed, yellowState);
delay(500);
digitalWrite(greenLed, yellowState);
digitalWrite(redLed, yellowState);
delay(500);
}
// turns all the leds at once, for 3 seconds
int blueState = digitalRead(blueButton);
Serial.println(blueLed);
digitalWrite(blueLed, blueState);
if (blueState == HIGH ) {
digitalWrite(redLed, blueState);
digitalWrite(greenLed, blueState);
digitalWrite(yellowLed, blueState);
delay(3000);
}
// turns each led one at a time with a one second delay
if (redState == HIGH) {
delay(1000);
digitalWrite(blueLed, redState);
delay(1000);
digitalWrite(greenLed, redState);
delay(1000);
digitalWrite(yellowLed, redState);
delay(1000);
digitalWrite(redLed, redState);
delay(1000);
redButtonState = HIGH;
}
}