Arduino Twister Spinner
Twister is the classic game from your childhood! The referee gives the spinner a whirl and the other players follow the steps on the mat... until one of them falls down. The last remaining wins!
Wouldn't it be more fun to have a modernized version of the Twister spinner? On this Arduino Twister Spinner, the arrow is replaced by LED lights, with a buffer that moves automatically. By pressing the button, the referee can decide when the buffer stops. The light will either show green, yellow, red or blue next to the decided position (for example: a blue light next to "right foot"). By turning the Potentiometer, the referee can adjust the buffer speed!
In this instructable I will share my work process with you. Let's get started!
Supplies
- 1x Arduino Uno R3
- 1x Breadboard 400 points
- 1x Perfboard
- 1x USB cable
- 20 Jumper wires M/M 20cm (it's better to have too many than too little)
- 20 Jumper wires M/F 10cm
- 1x Potentiometer 10k ohm
- 2x 9 Volt batteries (just in case)
- LEDS (to practice)
- 10k ohm resistors (to practice)
- 1x 9 Volt battery clip
- 1x Pushbutton
- 1x NeoPixel Digital RGB LED Strip black 30 LEDs
- Cardboard
- Coloured paper
- Knee stockings
- Tape
- Glue
- Popsicle sticks
- Magnets
- Scissors
- Solder kit
- Tin
- Arduino IDE
- FastLED (Open Arduino IDE -> Sketch -> Include Library -> Manage Libraries -> Type in "FastLED" and Install)
Experimenting With the LED Strip
After collecting your supplies, start with experimenting. Practice with the button, the LED strip or the Potentiometer individually so that you have a better understanding of how each tool works.
Connect the LED strip to the Arduino Uno R3. The LED strip has 4 rows of connections with 4 cables. The rows exist of: GND, BO/BI, DO/DI and 5V. Connect the GND cable from the LED strip to a jumper cable (preferably from the same colour). Connect the jumper cable to the Arduino Uno R3's GND.
Now connect the 5V cable from the LED strip and the jumper cable to the 5V on the Arduino, and the cable from DO/DI to pin 6. Save your code! It's very important to make backups.
Here's the code I used to test the LED strip:
#include <FastLED.h>
// LED variables
#define LED_PIN 6 // pin used for the led strip DIN
#define NUM_LEDS 30 // amount of leds the strip has
CRGB leds[NUM_LEDS];
// used to keep track of led that is essentially highlighted
int valLed = 0;
void setup()
{
FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);
}
void loop()
{
// without a delay the update will happen too fast, later on we will make this adjustable
delay(50);
LedAnimation();
// each led will have the color blue, yellow, green, or red
leds[1] = CHSV(0, 255, 255);
leds[2] = CHSV(0, 255, 255);
leds[3] = CHSV(95, 255, 255);
leds[4] = CHSV(95, 255, 255);
leds[5] = CHSV(45, 255, 255);
leds[6] = CHSV(45, 255, 255);
leds[7] = CHSV(160, 255, 255);
leds[8] = CHSV(160, 255, 255);
leds[9] = CHSV(0, 255, 255);
leds[10] = CHSV(0, 255, 255);
leds[11] = CHSV(95, 255, 255);
leds[12] = CHSV(95, 255, 255);
leds[13] = CHSV(45, 255, 255);
leds[14] = CHSV(45, 255, 255);
leds[15] = CHSV(160, 255, 255);
leds[16] = CHSV(160, 255, 255);
leds[17] = CHSV(0, 255, 255);
leds[18] = CHSV(0, 255, 255);
leds[19] = CHSV(95, 255, 255);
leds[20] = CHSV(95, 255, 255);
leds[21] = CHSV(45, 255, 255);
leds[22] = CHSV(45, 255, 255);
leds[23] = CHSV(160, 255, 255);
leds[24] = CHSV(160, 255, 255);
leds[25] = CHSV(0, 255, 255);
leds[26] = CHSV(0, 255, 255);
leds[27] = CHSV(95, 255, 255);
leds[28] = CHSV(45, 255, 255);
leds[29] = CHSV(160, 255, 255);
}
void LedAnimation()
{
valLed++;
if (valLed > 29)
{
valLed = 0;
}
if (valLed == 0)
{
leds[valLed] = CHSV(200, 255, 255);
}
if (valLed != 0)
{
leds[valLed] = CHSV(200, 255, 255);
leds[valLed-1] = CHSV(0, 0, 0);
}
FastLED.show();
}
Practicing With the Button
Take photos of the LED strip set up so that you can rebuild it later. Keep in mind that when you change cables, take the USB cable out of the laptop/PC. This will avoid any potential damage to your laptop/PC.
To make the button functionable, it's best to test it out individually to avoid complications. For this little exercise I used a small LED and a 10k ohm resistor. Connect the wires to the Arduino Uno R3 as displayed on the image.
Here's the code I used for the button:
bool pressedbtn;
int PIN_BUTTON = 3;
int PIN_LED = 6;
void setup()
{
Serial.begin(9600);
pinMode(PIN_BUTTON, INPUT_PULLUP);
}
void loop()
{
if(digitalRead(PIN_BUTTON) == LOW){ // if the button is pressed
pressedbtn = true;
}
else
{
pressedbtn = false;
}
// we are using a boolean due to the implementation that we will need in the final code
if (pressedbtn)
{
Serial.println("I'm Pressed!");
}
}
Practicing With the Potentiometer
To make the Potentiometer functionable, it's best to test it out individually to avoid complications. For this little exercise I used a small LED and a 10k ohm resistor. Connect the wires to the Arduino Uno R3 as displayed on the image.
Here's the code I used for the Potentiometer:
#define SPEEDPIN A0
// the stored value will be used to determine the led animation speed
int speed = 0; // 0 to 340
int speedMin = 10;
int speedMax = 300;
void setup()
{
Serial.begin(9600);
}
void loop()
{
speed = analogRead(SPEEDPIN);
if (speed < speedMin)
{
speed = speedMin;
}
if (speed > speedMax)
{
speed = speedMax;
}
// we just want to make sure that it can store and print the value
Serial.println(speed);
delay(100);
}
Combining the Codes
Now that you've tested each tool, it's time to combine these elements together to make the Arduino Twister Spinner. First add your button code to the Potentiometer code.
After combining these two codes, you're prepared to add these to the LED strip code. Make sure you adjust your cables suitable for the code. If the GND or the 5V is occupied, you can use the + and - on the breadboard (- for GND and + for 5V).
Here's the code I used to combine:
///// libraries used
#include <FastLED.h>
///// arduino settings
#define LED_PIN 6
#define BUTTON 3
#define NUM_LEDS 30
#define NUM_COLS 26
///// speed potmeter settings
#define SPEEDPIN A0
int speedMin = 10;
int speedMax = 300;
///// editable settings
// used for gameplay
int speed = 25; // lower is faster
#define PAUSE 2000 // higher is longer
// used for blinking based on HSV colors
int hueVal = 0;
int satVal = 0;
int valVal = 0;
///// non editable settings
CRGB leds[NUM_LEDS];
CRGB ledColors[NUM_LEDS];
CRGB breathColors[NUM_COLS];
bool pressedButton = false;
int selectedLight = 0;
int currentColor = 0;
void setup() {
Serial.begin(9600);
pinMode(BUTTON, INPUT_PULLUP);
FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);
SetColors();
}
void SetColors()
{
// these colors are creating the breathing animation
breathColors[0] = CHSV(hueVal, satVal, 30 + valVal);
breathColors[1] = CHSV(hueVal, satVal, 30 + valVal);
breathColors[2] = CHSV(hueVal, satVal, 35 + valVal);
breathColors[3] = CHSV(hueVal, satVal, 35 + valVal);
breathColors[4] = CHSV(hueVal, satVal, 40 + valVal);
breathColors[5] = CHSV(hueVal, satVal, 40 + valVal);
breathColors[6] = CHSV(hueVal, satVal, 45 + valVal);
breathColors[7] = CHSV(hueVal, satVal, 45 + valVal);
breathColors[8] = CHSV(hueVal, satVal, 50 + valVal);
breathColors[9] = CHSV(hueVal, satVal, 50 + valVal);
breathColors[10] = CHSV(hueVal, satVal, 55 + valVal);
breathColors[11] = CHSV(hueVal, satVal, 55 + valVal);
breathColors[12] = CHSV(hueVal, satVal, 60 + valVal);
breathColors[13] = CHSV(hueVal, satVal, 60 + valVal);
breathColors[14] = CHSV(hueVal, satVal, 60 + valVal);
breathColors[15] = CHSV(hueVal, satVal, 55 + valVal);
breathColors[16] = CHSV(hueVal, satVal, 55 + valVal);
breathColors[17] = CHSV(hueVal, satVal, 50 + valVal);
breathColors[18] = CHSV(hueVal, satVal, 50 + valVal);
breathColors[19] = CHSV(hueVal, satVal, 45 + valVal);
breathColors[20] = CHSV(hueVal, satVal, 45 + valVal);
breathColors[21] = CHSV(hueVal, satVal, 40 + valVal);
breathColors[22] = CHSV(hueVal, satVal, 40 + valVal);
breathColors[23] = CHSV(hueVal, satVal, 35 + valVal);
breathColors[24] = CHSV(hueVal, satVal, 35 + valVal);
breathColors[25] = CHSV(hueVal, satVal, 30 + valVal);
// these colors are creating for the individual leds with the twister colors
ledColors[0] = CHSV(160, 255, 255);
ledColors[1] = CHSV(0, 255, 255);
ledColors[2] = CHSV(0, 255, 255);
ledColors[3] = CHSV(95, 255, 255);
ledColors[4] = CHSV(95, 255, 255);
ledColors[5] = CHSV(45, 255, 255);
ledColors[6] = CHSV(45, 255, 255);
ledColors[7] = CHSV(160, 255, 255);
ledColors[8] = CHSV(160, 255, 255);
ledColors[9] = CHSV(0, 255, 255);
ledColors[10] = CHSV(0, 255, 255);
ledColors[11] = CHSV(95, 255, 255);
ledColors[12] = CHSV(95, 255, 255);
ledColors[13] = CHSV(45, 255, 255);
ledColors[14] = CHSV(45, 255, 255);
ledColors[15] = CHSV(160, 255, 255);
ledColors[16] = CHSV(160, 255, 255);
ledColors[17] = CHSV(0, 255, 255);
ledColors[18] = CHSV(0, 255, 255);
ledColors[19] = CHSV(95, 255, 255);
ledColors[20] = CHSV(95, 255, 255);
ledColors[21] = CHSV(45, 255, 255);
ledColors[22] = CHSV(45, 255, 255);
ledColors[23] = CHSV(160, 255, 255);
ledColors[24] = CHSV(160, 255, 255);
ledColors[25] = CHSV(0, 255, 255);
ledColors[26] = CHSV(0, 255, 255);
ledColors[27] = CHSV(95, 255, 255);
ledColors[28] = CHSV(45, 255, 255);
ledColors[29] = CHSV(160, 255, 255);
}
void loop() {
if(digitalRead(BUTTON) == LOW)
{
pressedButton = true;
}
else
{
pressedButton = false;
}
if (!pressedButton)
{
// play the animation when the button isn't pressed
LedAnimation();
}
if (pressedButton)
{
// give the user some time after pressing to perform move and to see what was pressed
delay(PAUSE);
}
delay(speed / 5);
speed = analogRead(SPEEDPIN);
if (speed < speedMin)
{
speed = speedMin;
}
if (speed > speedMax)
{
speed = speedMax;
}
}
void LedAnimation()
{
// the index for loop animation
selectedLight++;
if (selectedLight >= NUM_LEDS)
{
selectedLight = 0;
}
// the index for breath animation
currentColor++;
if (currentColor >= NUM_COLS)
{
currentColor = 0;
}
for (int i = 0; i < NUM_LEDS; i++)
{
if (i == selectedLight)
{
// color for selected lights
leds[i] = ledColors[i];
}
else
{
// default color for not selected lights
leds[i] = breathColors[currentColor];
}
}
FastLED.show();
}
Solder the Arduino Twister Spinner
Your Arduino Twister Spinner works! Now you can start soldering. Preheat the solder machine. Now copy the wires from the breadboard onto the perfboard. You can shorten the wires to make them fit perfectly into the spinner. Solder the wires onto the perfboard with the tin and let it dry for a few seconds. Feel free to cut in the perfboard around the wires, so you can tape the pieces onto the Arduino Twister Spinner box later on.
Place the Arduino Inside the Twister Spinner Box
First I cut out the pieces from a cardboard box that I will use for the spinner. I taped the edges so that it will look smooth and even. Make sure you measure every part of your cut-outs precisely, as you will be needing that to implement the Arduino set-up.
Take the popsicle sticks (in my case I used skewers and broke them in half) and tape them onto the inner edges of the spinner box. Tape magnets on the bottom and the top of the inside of the box, so that you can open and close it to reach the Arduino set-up.
Take the soldered Arduino and place it on the inside of the spinner box. Make two holes for the button and the Potentiometer. Place the Arduino as sufficient as possible, so that it is easy to access in case you need to adjust something. Don't place the wires too close to each other to avoid unneccessary chaos.
Creating the Aesthetics of the Twister Spinner Box
As for the aesthetics of this project, you can let your inner creative spirit run wild! I will show you how I made the aesthetics for my Arduino Twister Spinner. I used the thin fabric of the knee stockings to cover up the LED strip without losing sight of the colours. Then, I cut out pieces from coloured paper to create the childlike Twister vibe and tape it gently onto the box. I printed off the hands and feet and glued them onto the coloured paper. The LED colours green, yellow, red and blue, were equally divided between the hands and feet. I covered the button and Potentiometer with the fabric of the knee stockings and placed a piece of red paper onto the button.
Enjoy!
You now have your very own Arduino Twister Spinner! Congratulations and enjoy!
Reflection
Before I started this project, I didn't have any experience with Arduino. It was quite a challenge. The biggest challenge was connecting all the wires to the right spots. I was overwhelmed by all the little numbers and abbreviations on the Arduino Uno R3 and organizing all the tools. But with a little help I was able to get through it with enjoyment.
Coding is also something I struggle with but taking baby steps has helped me understanding it a little better. For example, I practiced with a simple button code before I jumped right into the whole project. And by experimenting I found out that two Potentiometers were too much to ask (I smelled something burning) from the Arduino and that some of my buttons didn't work.
Making the aesthetics was by far my favourite step. But I've learned the most from the technical aspect of this Arduino project.