Rechargeable general/game turn timer with battery monitor
Rechargeable timer with battery level monitor. Countdown display and buzzer to signify time up/end of turn. Set duration stored in EPROM.
Components and supplies
1
Arduino Pro Mini 328 - 3.3V/8MHz
1
330K ohm Resistor
1
1M ohm Resistor
1
Youmile LED Display Module TM1637
3
Tactile Switch, Top Actuated
1
Hook Up wire
1
TP4056 5V 1A TYPE C Micro USB Board Module for 18650 Lithium Battery Charging
1
3.7V 1000mAh Lithium Rechargeable Battery
1
Universal Passive Buzzer,
Apps and platforms
1
Arduino IDE
Project description
Code
Rechargeable countdown timer
arduino
1// General and Game Countdown Timer 2// After turning on, use the UP and DOWN buttons to 3// set the time in minutes and seconds for the time to track or 4// time allowed for the turn, hold button for repeated time changes 5// The set time will remain showing on the display 6// Press start a short tone will sound, "go" will be displayed 7// and the time will start counting down to 0 8// When 0 is reached a longer tone will sound and "End" displayed 9// for 5 seconds before resetting to the allocated time 10// for the next players go. 11// You can terminate the countdown at any time be pressing the 12// start/stop button. 13 14// Include the library driver for display: 15#include <TM1637Display.h> 16// Include the library for managing eprom 17#include <EEPROM.h> 18 19// Define the connections pins for display 20#define CLK 6 21#define DIO 7 22 23// Define other pin connections 24#define UP_BUTTON 2 25#define DOWN_BUTTON 3 26#define START_BUTTON 4 // Also the stop button 27#define BUZZER 9 28#define MONITOR_PIN A0 // Pin used to monitor supply voltage 29const float voltageDivider = 4.0; // Used to calculate the actual voltage from the monitor pin reading 30 // Using 1m and 330k ohm resistors divides the voltage by approx 4 31 // You may want to substitute actual values of resistors in an equation (R1 + R2)/R2 32 // E.g. (1000 + 330)/330 = 4.03 33 // Alternatively take the voltage reading across the battery and from the joint between 34 // the 2 resistors to ground and divide one by the other to get the value. 35 36int epromFlagAddress = 1; // Address used to store flag when duration saved - no relevance to address used 37int durationAddress = 10; // Address where duration is stored - no relevance to address used 38 // EPROM addresses run from 0 to 1,023 on the Pro Mini 39int duration; // Current duration in seconds 40int storedDuration; // Last stored duration 41 42// Create display object of type TM1637Display: 43TM1637Display display = TM1637Display(CLK, DIO); 44 45// Set the individual segments for the word displays: 46const uint8_t seg_end[] = { 47 SEG_A | SEG_D | SEG_E | SEG_F | SEG_G, // E 48 SEG_C | SEG_E | SEG_G, // n 49 SEG_B | SEG_C | SEG_D | SEG_E | SEG_G, // d 50 0x00 // All off 51}; 52 53const uint8_t seg_go[] = { 54 SEG_A | SEG_B | SEG_C | SEG_D | SEG_F | SEG_G, // g 55 SEG_A | SEG_B | SEG_G | SEG_F, // o top of digit 56 0x00, // All off 57 0x00 // All off 58}; 59 60// Full battery 61const uint8_t seg_full[] = { 62 SEG_A | SEG_D | SEG_G, // 3 lines 63 SEG_A | SEG_D | SEG_G, // 3 lines 64 SEG_A | SEG_D | SEG_G, // 3 lines 65 SEG_A | SEG_D | SEG_G // 3 lines 66}; 67 68// Three quatrters 69const uint8_t seg_34[] = { 70 SEG_A | SEG_D | SEG_G, // 3 lines 71 SEG_A | SEG_D | SEG_G, // 3 lines 72 SEG_A | SEG_D | SEG_G, // 3 lines 73 0x00 // All off 74}; 75 76// Half 77const uint8_t seg_half[] = { 78 SEG_A | SEG_D | SEG_G, // 3 lines 79 SEG_A | SEG_D | SEG_G, // 3 lines 80 0x00, // All off 81 0x00 // All off 82}; 83 84// One quarter 85const uint8_t seg_14[] = { 86 SEG_A | SEG_D | SEG_G, // 3 lines 87 0x00, // All off 88 0x00, // All off 89 0x00 // All off 90}; 91 92// Low battery warning 93const uint8_t seg_low[] = { 94 SEG_D | SEG_E | SEG_F, // L 95 SEG_C | SEG_D | SEG_E | SEG_G, // o bottom of segment 96 0x00, // All off 97 0x00 // All off 98}; 99 100 101 102 103void setup() { 104 pinMode(UP_BUTTON, INPUT_PULLUP); // Pullup set so defaults high 105 pinMode(DOWN_BUTTON, INPUT_PULLUP); // Goes low when button pressed 106 pinMode(START_BUTTON, INPUT_PULLUP); 107 pinMode(BUZZER, OUTPUT); 108 analogReference(INTERNAL); // Sets the reference voltage for the analog pins to 1.1v 109 pinMode(MONITOR_PIN, INPUT); // Set input on pin used to monitor the voltage 110 // Check to see if there is a saved duration. If so read it, if not set default 111 if(EEPROM.read(epromFlagAddress) == 1){ 112 storedDuration = EEPROM.read(durationAddress); 113 duration = storedDuration; 114 } 115 else { 116 duration = 30; // Default to 30 seconds 117 storedDuration = duration; 118 EEPROM.write(durationAddress, storedDuration); 119 EEPROM.write(epromFlagAddress, 1); 120 } 121 display.setBrightness(3); // 0 to 7 change if required 122 CheckBattery(); 123 ShowTime(duration); 124} 125 126void loop() { 127 // Function loops checking for time change buttons and only returns 128 // when start button pressed 129 WaitForStart(); 130 // Start the duration timer - returns on completion 131 TimeDuration(); 132} 133 134// Check and display battery level 135void CheckBattery(){ 136 float voltage = BatteryVoltage(); 137 display.clear(); 138 if (voltage > 3.85) // Was 3.6 139 display.setSegments(seg_full); 140 else 141 if (voltage > 3.69) // Was 3.5 142 display.setSegments(seg_34); 143 else 144 if (voltage > 3.59) // Was 3.4 145 display.setSegments(seg_half); 146 else 147 if (voltage > 3.5) // Was 3.3 148 display.setSegments(seg_14); 149 else 150 display.setSegments(seg_low); 151 // If voltage less than 3.4v then sound alarm 152 if (voltage < 3.4){ 153 for (int i = 0; i < 3; i++){ 154 tone(BUZZER, 1500, 500); 155 delay(750); 156 } 157 } 158 else { 159 delay(2250); 160 } 161} 162 163// Read the monitor pin and calculate the voltage 164float BatteryVoltage(){ 165 float reading = analogRead(MONITOR_PIN); 166 // Calculate voltage - reference voltage is 1.1v 167 return 1.1 * (reading/1023) * voltageDivider; 168} 169 170void WaitForStart(){ 171 // Check for button presses every 0.15 seconds 172 while (digitalRead(START_BUTTON) == HIGH){ 173 // Check if up or down has been pressed 174 // If time <= 60 seconds increment by 1 second 175 // If time > 60 then increment by 10 seconds 176 if (digitalRead(UP_BUTTON) == LOW){ 177 if (duration < 60){ 178 duration++; 179 } 180 else{ 181 duration += 10; 182 } 183 ShowTime(duration); 184 } 185 // If time <= 60 seconds increment by 1 second 186 // If time > 60 then reduce by 10 seconds 187 if (digitalRead(DOWN_BUTTON) == LOW){ 188 if (duration > 60){ 189 duration -= 10; 190 } 191 else{ 192 duration--; 193 } 194 ShowTime(duration); 195 } 196 delay(150); 197 } 198 // Start button has been pressed 199 tone(BUZZER, 1500, 100); 200 display.clear(); 201 display.setSegments(seg_go); 202 // Check if duration = storedDuration and if not update stored duration 203 if (storedDuration != duration) { 204 storedDuration = duration; 205 EEPROM.write(durationAddress, storedDuration); 206 } 207} 208 209void TimeDuration(){ 210 // While loop will continue until time up 211 // or start/stop pressed 212 unsigned long startTime = millis(); 213 unsigned long timer = 1000ul * duration; 214 // Repeatedly check if time is up 215 while ((millis() - startTime) <= timer){ 216 // Calculate time elapsed in seconds 217 int elapsed = int((millis() - startTime)/1000); 218 // Only start to display countdown after 3 seconds 219 if ((millis() - startTime) > 3000){ 220 ShowTime(duration - elapsed); 221 // Pressing the start button again will terminate early 222 if (digitalRead(START_BUTTON) == LOW){ 223 break; 224 } 225 } 226 } 227 // Time up 228 tone(BUZZER, 750, 250); 229 display.clear(); 230 display.setSegments(seg_end); 231 // Wait 5 seconds and reset display 232 delay(5000); 233 // Show duration for next player 234 ShowTime(duration); 235} 236 237void ShowTime(int value){ 238 static int lastTime; 239 // Update the display if time has changed 240 if (lastTime != value) { 241 lastTime = value; 242 int iMinutes = value / 60; 243 int iSeconds = value - (iMinutes * 60); 244 // Show on 4 digit display 245 uint16_t number = iMinutes * 100 + iSeconds; 246 display.showNumberDecEx(number, 0b01000000, true, 4, 0); 247 } 248}
Rechargeable countdown timer
arduino
1// General and Game Countdown Timer 2// After turning on, use the UP and DOWN buttons to 3// set the time in minutes and seconds for the time to track or 4// time allowed for the turn, hold button for repeated time changes 5// The set time will remain showing on the display 6// Press start a short tone will sound, "go" will be displayed 7// and the time will start counting down to 0 8// When 0 is reached a longer tone will sound and "End" displayed 9// for 5 seconds before resetting to the allocated time 10// for the next players go. 11// You can terminate the countdown at any time be pressing the 12// start/stop button. 13 14// Include the library driver for display: 15#include <TM1637Display.h> 16// Include the library for managing eprom 17#include <EEPROM.h> 18 19// Define the connections pins for display 20#define CLK 6 21#define DIO 7 22 23// Define other pin connections 24#define UP_BUTTON 2 25#define DOWN_BUTTON 3 26#define START_BUTTON 4 // Also the stop button 27#define BUZZER 9 28#define MONITOR_PIN A0 // Pin used to monitor supply voltage 29const float voltageDivider = 4.0; // Used to calculate the actual voltage from the monitor pin reading 30 // Using 1m and 330k ohm resistors divides the voltage by approx 4 31 // You may want to substitute actual values of resistors in an equation (R1 + R2)/R2 32 // E.g. (1000 + 330)/330 = 4.03 33 // Alternatively take the voltage reading across the battery and from the joint between 34 // the 2 resistors to ground and divide one by the other to get the value. 35 36int epromFlagAddress = 1; // Address used to store flag when duration saved - no relevance to address used 37int durationAddress = 10; // Address where duration is stored - no relevance to address used 38 // EPROM addresses run from 0 to 1,023 on the Pro Mini 39int duration; // Current duration in seconds 40int storedDuration; // Last stored duration 41 42// Create display object of type TM1637Display: 43TM1637Display display = TM1637Display(CLK, DIO); 44 45// Set the individual segments for the word displays: 46const uint8_t seg_end[] = { 47 SEG_A | SEG_D | SEG_E | SEG_F | SEG_G, // E 48 SEG_C | SEG_E | SEG_G, // n 49 SEG_B | SEG_C | SEG_D | SEG_E | SEG_G, // d 50 0x00 // All off 51}; 52 53const uint8_t seg_go[] = { 54 SEG_A | SEG_B | SEG_C | SEG_D | SEG_F | SEG_G, // g 55 SEG_A | SEG_B | SEG_G | SEG_F, // o top of digit 56 0x00, // All off 57 0x00 // All off 58}; 59 60// Full battery 61const uint8_t seg_full[] = { 62 SEG_A | SEG_D | SEG_G, // 3 lines 63 SEG_A | SEG_D | SEG_G, // 3 lines 64 SEG_A | SEG_D | SEG_G, // 3 lines 65 SEG_A | SEG_D | SEG_G // 3 lines 66}; 67 68// Three quatrters 69const uint8_t seg_34[] = { 70 SEG_A | SEG_D | SEG_G, // 3 lines 71 SEG_A | SEG_D | SEG_G, // 3 lines 72 SEG_A | SEG_D | SEG_G, // 3 lines 73 0x00 // All off 74}; 75 76// Half 77const uint8_t seg_half[] = { 78 SEG_A | SEG_D | SEG_G, // 3 lines 79 SEG_A | SEG_D | SEG_G, // 3 lines 80 0x00, // All off 81 0x00 // All off 82}; 83 84// One quarter 85const uint8_t seg_14[] = { 86 SEG_A | SEG_D | SEG_G, // 3 lines 87 0x00, // All off 88 0x00, // All off 89 0x00 // All off 90}; 91 92// Low battery warning 93const uint8_t seg_low[] = { 94 SEG_D | SEG_E | SEG_F, // L 95 SEG_C | SEG_D | SEG_E | SEG_G, // o bottom of segment 96 0x00, // All off 97 0x00 // All off 98}; 99 100 101 102 103void setup() { 104 pinMode(UP_BUTTON, INPUT_PULLUP); // Pullup set so defaults high 105 pinMode(DOWN_BUTTON, INPUT_PULLUP); // Goes low when button pressed 106 pinMode(START_BUTTON, INPUT_PULLUP); 107 pinMode(BUZZER, OUTPUT); 108 analogReference(INTERNAL); // Sets the reference voltage for the analog pins to 1.1v 109 pinMode(MONITOR_PIN, INPUT); // Set input on pin used to monitor the voltage 110 // Check to see if there is a saved duration. If so read it, if not set default 111 if(EEPROM.read(epromFlagAddress) == 1){ 112 storedDuration = EEPROM.read(durationAddress); 113 duration = storedDuration; 114 } 115 else { 116 duration = 30; // Default to 30 seconds 117 storedDuration = duration; 118 EEPROM.write(durationAddress, storedDuration); 119 EEPROM.write(epromFlagAddress, 1); 120 } 121 display.setBrightness(3); // 0 to 7 change if required 122 CheckBattery(); 123 ShowTime(duration); 124} 125 126void loop() { 127 // Function loops checking for time change buttons and only returns 128 // when start button pressed 129 WaitForStart(); 130 // Start the duration timer - returns on completion 131 TimeDuration(); 132} 133 134// Check and display battery level 135void CheckBattery(){ 136 float voltage = BatteryVoltage(); 137 display.clear(); 138 if (voltage > 3.85) // Was 3.6 139 display.setSegments(seg_full); 140 else 141 if (voltage > 3.69) // Was 3.5 142 display.setSegments(seg_34); 143 else 144 if (voltage > 3.59) // Was 3.4 145 display.setSegments(seg_half); 146 else 147 if (voltage > 3.5) // Was 3.3 148 display.setSegments(seg_14); 149 else 150 display.setSegments(seg_low); 151 // If voltage less than 3.4v then sound alarm 152 if (voltage < 3.4){ 153 for (int i = 0; i < 3; i++){ 154 tone(BUZZER, 1500, 500); 155 delay(750); 156 } 157 } 158 else { 159 delay(2250); 160 } 161} 162 163// Read the monitor pin and calculate the voltage 164float BatteryVoltage(){ 165 float reading = analogRead(MONITOR_PIN); 166 // Calculate voltage - reference voltage is 1.1v 167 return 1.1 * (reading/1023) * voltageDivider; 168} 169 170void WaitForStart(){ 171 // Check for button presses every 0.15 seconds 172 while (digitalRead(START_BUTTON) == HIGH){ 173 // Check if up or down has been pressed 174 // If time <= 60 seconds increment by 1 second 175 // If time > 60 then increment by 10 seconds 176 if (digitalRead(UP_BUTTON) == LOW){ 177 if (duration < 60){ 178 duration++; 179 } 180 else{ 181 duration += 10; 182 } 183 ShowTime(duration); 184 } 185 // If time <= 60 seconds increment by 1 second 186 // If time > 60 then reduce by 10 seconds 187 if (digitalRead(DOWN_BUTTON) == LOW){ 188 if (duration > 60){ 189 duration -= 10; 190 } 191 else{ 192 duration--; 193 } 194 ShowTime(duration); 195 } 196 delay(150); 197 } 198 // Start button has been pressed 199 tone(BUZZER, 1500, 100); 200 display.clear(); 201 display.setSegments(seg_go); 202 // Check if duration = storedDuration and if not update stored duration 203 if (storedDuration != duration) { 204 storedDuration = duration; 205 EEPROM.write(durationAddress, storedDuration); 206 } 207} 208 209void TimeDuration(){ 210 // While loop will continue until time up 211 // or start/stop pressed 212 unsigned long startTime = millis(); 213 unsigned long timer = 1000ul * duration; 214 // Repeatedly check if time is up 215 while ((millis() - startTime) <= timer){ 216 // Calculate time elapsed in seconds 217 int elapsed = int((millis() - startTime)/1000); 218 // Only start to display countdown after 3 seconds 219 if ((millis() - startTime) > 3000){ 220 ShowTime(duration - elapsed); 221 // Pressing the start button again will terminate early 222 if (digitalRead(START_BUTTON) == LOW){ 223 break; 224 } 225 } 226 } 227 // Time up 228 tone(BUZZER, 750, 250); 229 display.clear(); 230 display.setSegments(seg_end); 231 // Wait 5 seconds and reset display 232 delay(5000); 233 // Show duration for next player 234 ShowTime(duration); 235} 236 237void ShowTime(int value){ 238 static int lastTime; 239 // Update the display if time has changed 240 if (lastTime != value) { 241 lastTime = value; 242 int iMinutes = value / 60; 243 int iSeconds = value - (iMinutes * 60); 244 // Show on 4 digit display 245 uint16_t number = iMinutes * 100 + iSeconds; 246 display.showNumberDecEx(number, 0b01000000, true, 4, 0); 247 } 248}
Downloadable files
Breadboard
Breadboard

Schematic
Schematic

Breadboard
Breadboard

Comments
Only logged in users can leave comments