Super easy and fun board game turn timer
building DIY Turn Timer
Arduino Code:
#include <FastLED.h>
//pins
const byte BUTTON_PIN = 3;
const byte DATA_PIN = 6;
// LED array
const byte NUM_LEDS = 16;
CRGB leds[NUM_LEDS];
// Colors used when setting time. Color ref: https://github.com/FastLED/FastLED/wiki/FastLED-HSV-Colors
const CHSV UNCOUNTED_COLOR = CHSV(0, 255, 255); //Red
const CHSV SECONDS_COUNTED_COLOR = CHSV(160, 255, 255); //Blue
const CHSV MINUTES_COUNTED_COLOR = CHSV(96, 255, 255); // Green
const CHSV HOURS_COUNTED_COLOR = CHSV(64, 255, 255); // Yellow
// Colors / "Hue" used durring each turn (0-255)
const int START_HUE = 85; //Green(ish) MUST be a number < END_HUE
const int END_HUE = 255; //Red
const int HUE_INCREMENT = END_HUE - START_HUE; // Used to change color based on selcted turn time
// Timing settings
const unsigned long HOLD_TO_FINISH_INTERVAL = 2 * 1000; // How long to hold button when making final selection for time
long turnTime = 0; // Manages the turnTime - determined in setup(), used in loop()
// Flag set in ISR to indicate a button press
volatile boolean buttonPressed = false;
/************************************************************
ISR: Actions to take on button press
***********************************************************/
void buttonPress() {
buttonPressed = true; //flag that button was pressed
}
/************************************************************
LED Effect: Set all LEDs same color
***********************************************************/
void changeAllColorTo(int h, int s = 255, int v = 255) {
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = CHSV(h, s, v);
}
}
/************************************************************
LED Effect: Blink Red
***********************************************************/
void blinkRed() {
changeAllColorTo(255);
FastLED.show();
delay(300);
changeAllColorTo(0, 0, 0);
FastLED.show();
delay(300);
}
/************************************************************
LED Effect: Fade All
***********************************************************/
void fadeall() {
for (int i = 0; i < NUM_LEDS; i++) {
leds[i].nscale8(100);
}
}
/************************************************************
LED Effect: Half Cyclon
***********************************************************/
void halfCylon(CHSV color) {
static uint8_t hue = 0;
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = color;
FastLED.show();
fadeall();
delay(10);
}
}
/************************************************************
Signal a time unit has been selected
***********************************************************/
void signalTimeSelected(CHSV color) {
for (int i = 0; i < 10; i++) {
halfCylon(color);
}
}
/************************************************************
Select Turn Time Routine
***********************************************************/
int selectTime(CHSV uncountedColor, CHSV countedColor) {
int timeCounter = 0; // This tracks the button presses, each button press is a time unit
unsigned long previousButtonHoldTime = 0; // Used for determining long button hold time
boolean update = true;
while (true) {
if (update) {
// Set color of each LED based on counted or uncounted
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = i < timeCounter
? countedColor
: uncountedColor;
}
FastLED.show();
update = false;
}
// Increment count when button pressed
if (buttonPressed) {
// Debounce button press
delay(50);
if(digitalRead(BUTTON_PIN)) {
buttonPressed = false; // Reset ISR button flag
timeCounter++;
update = true;
//Rollover timeCounter if max reached
if (timeCounter >= NUM_LEDS) {
timeCounter = 0;
}
}
}
// Check if button held
if (!digitalRead(BUTTON_PIN)) {
// Exit while if button has been held "long" time
if (millis() - previousButtonHoldTime > HOLD_TO_FINISH_INTERVAL) {
signalTimeSelected(countedColor); //Display cylon effect to show selection has been made
buttonPressed = false; // reset ISR button flag
break;
}
} else {
previousButtonHoldTime = millis();
}
}
return timeCounter; //Returns the number of times the button was pressed (less the long hold)
}
/************************************************************
Compute Turn Time
***********************************************************/
long computeTurnTime(long s = 0, long m = 0, long h = 0) {
s = s * 5 * 1000; // 5 seconds for every count
if ( m <= 11 ) {
m = m * 60 * 1000; // 1 minute for every count <= 10
} else {
m = m * 5 * 60 * 1000; // 5 min for every count over 10
}
h = h * 60 * 60 * 1000; // 1 hour for every count
return s + m + h; // in milliseconds
}
void setup() {
Serial.begin(115200);
FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS); //adds the
FastLED.setBrightness(84);
pinMode(BUTTON_PIN, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), buttonPress, RISING);
// Set turn time. Select seconds, then minutes.
long secondsCount = selectTime(UNCOUNTED_COLOR, SECONDS_COUNTED_COLOR);
long minutesCount = selectTime(UNCOUNTED_COLOR, MINUTES_COUNTED_COLOR);
//long hoursCount = selectTime(UNCOUNTED_COLOR, HOURS_COUNTED_COLOR); //Add this is you have REALLY long turns
turnTime = computeTurnTime(secondsCount, minutesCount);
}
void loop() {
boolean overTime = false;
// As turn time elapses, show a fade from Green to Blue to Red
for (int hue = START_HUE; hue <= END_HUE; hue++) {
changeAllColorTo(hue);
FastLED.show();
delay(turnTime / HUE_INCREMENT);
// If button flag was set in ISR then exit
if (buttonPressed) {
buttonPressed = false; // Reset button flag
break;
}
// If button is not pressed before turn ends, LEDs go into "overtime" mode
if (hue == END_HUE) {
overTime = true;
}
}
// Over Time Mode, All LEDs blink
while (overTime) {
blinkRed();
// If button flag was set in ISR then exit
if (buttonPressed) {
buttonPressed = false;
break;
}
}
} // End loop()
Video Transcript:
I don’t know about you, but I really enjoy playing board games with friends. I like talking, eating good snacks, and just having some friendly competition. But it seems like every time I play a board game with a group of friends, there’s always that one person who takes forever on their turn. Everybody’s like, dude, the world’s not gonna blow up if you take your turn too fast. But it’s like they’re just staring at the board and thinking and thinking, and I don’t have anything against thinking, but think on other people’s turn, then take your turn. And I feel like every group of friends has that person. It’s like the deep thinker who just takes really long turns. Maybe that’s you. Maybe that’s all of us sometimes. Anyway, in the group of guys I play board games with, this guy’s name is Ted. And one of my other friends was like, “Mike, let’s make a turn timer for Ted “so the board game doesn’t take like three hours to play.” So that was like two years ago, and I finally got around to building a turn timer. I am calling this the Ted Turn Timer because it was inspired by Ted.
It’s super simple. Really, it’s just like any old timer. And if you like playing games with friends, then I have a feeling, you know somebody just like Ted. In this video, I’m gonna walk through how to build a turn timer just like this. I’ll go over the design, the parts I got, the 3D printed model, all that stuff will be in the comments. Really, you can put this together pretty quick. And I have a feeling, if you like playing games with friends, then you probably know somebody like Ted so this thing could be really helpful for you.
I just wanted to have some LEDs that change color through a spectrum of color. So, like, over the course of a turn, right? And you, you’d be able to set the length of each turn with the timer, right? So I’m thinking there’s gonna be a single button on this timer, and then, like, you can set the time so it will have like a set time mode, and then once you’ve set the time, then it goes into play mode, and then let’s say you set the turn for one minute, basically the LEDs in the turn timer will change from, like, I don’t know, I’m thinking green, go through a, a spectrum of colors, end up at red, and then when the turn is over, it starts, like, blinking red or something like that.
That’s kind of what I have in mind. So anytime I’ve got a project in mind like this, usually what I do is I try to run through just this quick prototyping process. It’s somewhat formalized, but I don’t necessarily hold myself to it super strictly, but this is what I like to do. So first what I do is I draw a picture of what it is I wanna build. This is like no holds barred, whatever I wanna draw, I just draw it out there, even if it sounds crazy. Then I list out in words all the stuff that is in the picture, so if I drew a button, I’m gonna list the word button underneath the picture somewhere. Then what I try to do is I try to add some specifications to my list of words.
Like, what kind of button is it or what type of microcontroller am I gonna use? So specifications, and then what I do is I start to prune off the ideas that are not immediately required. Once I’ve kind of done that, again, drawn pictures, I list out the words, add some specifications, prune off that list, once I’ve kind of done that, that’s when actually start building something out, start researching the components more, and I just really try to do things as incremental as possible.
Now me, I am not an artist, and I’ve kind of like, just become okay with that. I do love other people’s beautiful lines, great artwork, and like great precision to detail, but I’ve kind of just grown okay with my own style because I can interpret it, and for my purposes, that’s good. And usually when I’m drawing these things out, I’m trying to get my ideas on paper as fast as my hands will work. So what I want, like, I’m imagining the aesthetic of this thing is like this smallish hockey puck looking thing.
It’s gonna have some cool LEDs on it, you know that kind of thing. So I’m just gonna draw like a box for the case, you know, like the enclosure that this thing is, and it’s gonna need a big old button in there, and I’m gonna want some LEDs. I’m gonna need some type of microcontroller to be the brains of this thing. I’m gonna use a switch to turn it on and off. It’s gonna need a battery. And it would be neat if I could, like, set the timing of it maybe with a phone app, I don’t know.
That might be kind of cool. And that’s really about it. Like I said, I’m trying to keep this thing pretty simple. Now at this stage, I really do just allow myself to draw anything. I just let myself live in the clouds while I’m drawing, I say goodbye to reality for a little bit, and I just pretend like anything’s possible, even if I know it’s total BS, and it isn’t gonna happen. I’ll still draw it out if I think about it. Because for me this whole thing’s, it’s an, a creative endeavor, and sometimes I feel like my outlandish ideas end up spawning something that’s actually really practical. So the outlandish thing goes away, but then something practical might kind of like bounce off of that that wouldn’t have come unless I gave myself to be a little bit unrealistic. So once I’ve drawn out the picture, then I just list out in words what I’ve drawn.
So here I’ve got LEDs, got a button, got a microcontroller, got a switch, got a battery, got the case, a.k.a. the enclosure, and then, you know, I’m thinking about, like, that phone app Wi-Fi. Now, once I’ve got the words down, now what I do is I start adding some specifications. Like, what are these things actually gonna be? So for the LEDs, I’ve been wanting to play around with those individually addressable LED strips. I think the popular name is NeoPixel. For the button, I want like a cool game controller button, like a arcade game button, and it’d be cool if it was, if it had its own LED, like it was internally lit.
For the microcontroller, I’m definitely gonna use something that is Arduino compatible. Now, if you don’t know what an Arduino is, maybe you think it’s a sub sandwich, make sure to check out our video about what is Arduino, and it’ll get you up to speed really quick. So for the microcontroller, I need something that’s gonna be Wi-Fi enabled if I wanna connect to the internet, so I think I’m just gonna use an ESP32. And I just want a simple on-off switch. That’s pretty straightforward for the switch. And I think I can use a lithium polymer battery. I know those are like 3.7 volts. I’m pretty sure the ESP32, that’s what that runs off of, but I have heard that NeoPixels are kinda power hungry, and I’m not sure what the voltage and like the, the stuff is for that, but for now I think I’m just gonna say lithium polymer.
Now, for the phone app, honestly, I’m kind of drawing a blank, and that leads me to the next phase of this process, which is pruning away stuff that is not essential for getting the project off the ground. Now I could definitely add some neat Wi-Fi feature to this project in the future, but for just building like this minimum turn timer, it’s just not necessary, and I just don’t want anything that’s gonna hold me up ’cause I love to build momentum. I feel like if I can get some momentum going, like actually get some stuff working, then it helps me that much more get a project actually done. So I’m just gonna scratch this off my list for now. Again, doesn’t mean I won’t add it later, but for now, just don’t need it.
All right, so I’ve kind of drawn everything out here, got some basic specs. Now what I wanna do is start looking around online and trying to find stuff. And it’s at this point that I usually make myself a simple spreadsheet, right? And I start looking a lot closer at the specs of each of the components to make sure that they can do what I want ’em to do. So I ended up getting like a cool NeoPixel LED ring, cool arcade game-style button. I’m using an Unexpected Maker ESP32 FeatherS2 for the microcontroller. I also got a protoboard to solder stuff to and a lithium polymer battery. Had a simple switch layin’ around, so everything’s pretty set. I was thinking I might need, like, a boost converter to boost up the voltage to five volts or maybe, like, use a logic level shifter or something like that, but it looks like I won’t have to do that to do this. So that, that simplifies it quite a bit. So here is a very imperfect circuit diagram here. I’m using Fritzing to show this and there were some components that didn’t match up, so I’m just doing my best.
For example, I used an ESP32. Here I’m showing a Nano. It’s, you know, you can still use a Nano for this project for sure, but I had the ESP32, and then for the NeoPixels, I didn’t, couldn’t find any good NeoPixels examples so I’m just using this part right here, but let me just try to walk through it as best I can. So with the NeoPixel strip, there’s a data line that comes in, and then there’s just a power in ground. In the data line, I’m just connecting up to a GPIO. I ended up using digital pin six. And then I have that arcade button attached. Now my arcade button has an internal LED, so I show a button and an LED, but it’s actually one, just one thing. There’s four leads off the end of the button though so one of the leads just goes to a digital pin. I’m using digital pin three. It is important that that digital pin be connected to an interrupt, so depending on the boards you use, you wanna make sure that there is an interrupt attached there. The other side of the button’s just going to ground and then with the LED, it’s got an internal resistor on that LED so you’re able to just hook it up to power and ground, and that’s really it for the circuit. The only I’m not showing here is the on-off switch, and on the ESP32 I’m using, there’s an enable pin that you can connect an on-off switch to, and it basically can turn on and off power which is really pretty handy when you’ve got it connected to the battery, so.
So I soldered up the ESP32, and I had that NeoPixel ring that I soldered up. Did some checking on the button to make sure I was connecting the right pins where, and I soldered up the button. And then at first, I had it running on a breadboard but you know what? I ended up soldering everything together on a ProtoShield and just sticking it in the enclosure. Now for the enclosure, please feel free to make fun of me because, man, I’m just not a 3D CAD guy quite yet. So I made a little design in Tinkercad. I feel I made every error possible but just wanted a place to put my on-off switch, a place where I could hook in the USB cable. It made me feel like, man that’s a big hole for the USB cable. I did that because I figured this would just be the first run. You know, basically this is the space where the button’ll go through, where I’ll fit in that ring and then the lid.
And yeah, I don’t know, I, I basically kind of like just put the rough sizes of each of the components in here, made some empty space, and I don’t know, like I said, I’m no pro at this stuff, and you know, but it, for the first run, I, it didn’t turn out too bad. I mean, if I only did stuff that I was good at, I really wouldn’t do get much done. So you just gotta try, so that’s what I did. All right, so once I had everything together, you know, again like this is the box, right, I just, so here’s that button, comes through, there, this roughly fits into the top, the NeoPixel’s there, here’s the protoboard that I had. I just soldered everything up, the ESP32 battery connector, there’s my LiPo battery down there, the connector which actually, of all the things, that fit in there pretty nice, and you just close it like this. All right, and then this is how this thing works, right? So it does fit on there.
I know it’s pretty, pretty hokey looking, but give me a break here. Anyway, so you turn the thing on, it powers up, okay? And when you first turn it on, it goes into the mode where you’re gonna set the time, right? And there was a lot of ways to set the time. I’ve got 16 LEDs to work with, and I was like, “Well, how do I wanna do this?” So this is how I’ve got it set up. There is, so every time you press the button and release it, it counts one, like one LED will turn on, right? So, and that counts for 10 seconds in the first phase, right? So this is, I pressed it, you can see that LED came on. So that would be 10 seconds. This would be 20 seconds, 30 seconds, and then if you press and hold, it goes to the next setting, right? So you see the LEDs kinda flash, and now it’s in the next, so now we can set minutes. So we have 30 seconds, let’s say I wanted 30 seconds in one minute, right?
Then we could have two minutes. And then, let’s say, I just want two minutes and 30 seconds, and then I release. And so then it goes into gameplay mode, and immediately, in gameplay mode, what it does is it starts at the color green. So all the LEDs are green, and then it fades through a spectrum, and then when it gets to red, it starts to flash. Now, since, you know, we, we set it for like, what, two minutes and 30 seconds, it’s gonna take a while. So what I’m gonna do is I’ll just shut it off, go ahead and turn it back on, and let’s just do, like, I don’t know, 20 seconds, okay? So I’m just gonna hold this all the way through. So there, now we’re gonna set minutes. I’ll just, now I’ll release it.
Here we go, so here it’s going, it’s fading through the green, goes to like blue, then I think purple. And then eventually it’s gonna turn to that red color, and I kinda like how it, it looks, but then you can see, now it’s flashing red. You know, if it’s somebody else’s turn or, you know their turn would be over, right? Now, you, you would pass it off to the next person. They just hit the button, and it starts over. Now it’s green. It goes through the spectrum. I mean, this is just like straight-up simple. So the software is doing the math. It’s, you know, determining how long that term is, turn, turn is, based on what your input is in the, in the gameplay, and again, you just press that, and, and it just counts through that spectrum and adjusts it. So I don’t know, that’s the turn timer. Again, first iteration. Now I sent this over to my friend, Chad, at HackMakeMod, and this is what he thought. I think he, I think he liked it.
– [Chad] Hey, Mike, I got your idea, and I’m really inspired by it. I think it’s a, I think it’s a pretty cool idea. Here’s my spin on it. See if you like it. So instead of using the ring, let’s just use like a, a regular, like this kind right here, and just wrap it in a circle. Use 10 lights, and then we put a button through the center, which I haven’t quite, you know, designed it all yet but some kind of button, and then you have the body around it and the electronics can be in the base of this. And this has like a nice little, let me get rid of the button. It’s hard to see here, but it has like a nice little curve here, so the light will gradiate out, and then I tried to do a rendering so it would look like this. And then when the lights came on, they would come on like that. That’s kinda my, my thought process. I wanted to see what you thought.
– [Mike] So, yeah, I, I really like that 3D design that Chad’s got going on; I think that’s awesome. We might try to put a little kit together just to put all these components in one little package that we’ll make available, not available yet, but you know, check in, maybe, maybe it’ll be, eventually be available, who knows? We’ll see what happens, but anyway, it’s just so fun to collaborate and see something cool like this kinda come together, and I would love to get your thoughts. What, what do you think would be neat on a button like this? Love to get your input and see what we could do to just kinda play around, but I just, I love collaborating with people ’cause just leaning into other people’s skills and abilities is pretty exciting to see what can kinda come out, so. One last thing, I know I didn’t really go over the code here. It’s not too complicated, but there are some fun things in it. If you’re interested in me kind of walking through this code for this project, let me know in the comments, and I can make a video that goes step-by-step through the code. We could talk about it. Do use a really cool library for those NeoPixels. It’s called the FastLED Library, and they have a fantastic Reddit, a community around using that library, so it’s really, it’s really nice to kinda get up and started with it. It’s pretty fun. Some interesting code examples to kinda get you started. Anyway, if you wanna learn more about the code in this project, definitely let me know in the comments, and I will go, you know, we can just go step-by-step through the code if, if you thought that was interesting, so thanks a ton.
Awesome project!
I’ve also made a number of board game timers using microcontrollers, but coding in Circuit Python. And, they all make use of the Bluetooth or MQTT API of the Shared Game Timer. I’ve written up guides for how to make those and the code that runs them here: https://sharedgametimer.com/remote-control/bluetooth / https://sharedgametimer.com/remote-control/mqtt)
If you want to collaborate on a remote, or hook up the one you made here to the Shared Game Timer, let me know.