So, I enjoy working out and have turned half of my garage into a home gym. One thing that I don’t have and would like in my gym is a big stopwatch for doing a cross fit work out, so I looked around to see what was on amazon and was shocked at how expensive they were. I mean $150 for a stopwatch with a large display is a bit excessive. So, I decided that I would build one using a raspberry pi, an old computer monitor that I had laying around, and some python code.
At the end of writing my last blog post, I got the idea about writing a maze game using pygame on the raspberry pi. After doing a little more research, it looked like a great way to quickly write a graphics program, so I decided to give it a shot. Since, I don’t have much experience with python, I decided to start small and just draw a rectangle on the screen. Here’s the code to make that happen:
import pygame
import os
import time
red = pygame.Color(255, 0, 0)
def main():
# Initialize the screen
pygame.init()
screen = pygame.display.set_mode((750, 350))
pygame.display.set_caption('Timer')
# Draw a rectangle
pygame.draw.rect(screen, red, pygame.Rect(10,10, 50, 50))
pygame.display.flip()
# Exit when a key is pressed or the X is clicked
while(1):
for event in pygame.event.get():
if event.type == pygame.KEYUP or event.type == pygame.QUIT:
return
time.sleep(0.1)
if __name__ == '__main__': main()
That creates a window with a red rectangle in it that looks like this:
After I got a rectangle on the screen, I decided to draw out the 7 segments of a typical clock display. The code to put in the place of the draw rectangle section looks something like this:
# Draw a seven segment led
led_height = 10
led_width = 75
offset = 4 * led_height / 3
# Top Center
pygame.draw.rect(screen, red, pygame.Rect(offset, 0, led_width, led_height))
# Top Left
pygame.draw.rect(screen, red, pygame.Rect(0, offset, led_height, led_width))
# Top Right
pygame.draw.rect(screen, red, pygame.Rect(2*offset + led_width - led_height, offset, led_height, led_width))
# Middle Center
pygame.draw.rect(screen, red, pygame.Rect(offset, 2*offset + led_width - led_height, led_width, led_height))
# Bottom Left
pygame.draw.rect(screen, red, pygame.Rect(0, 3*offset + led_width - led_height, led_height, led_width))
# Bottom Right
pygame.draw.rect(screen, red, pygame.Rect(2*offset + led_width - led_height, 3*offset + led_width - led_height, led_height,led_width))
# Bottom Center
pygame.draw.rect(screen, red, pygame.Rect(offset, 4*offset + 2*led_width - 2*led_height, led_width, led_height))
pygame.display.flip()
That creates a window with a seven segment LED that looks like this:
The last part of the puzzle is to take in a number and then determine which segments to light up. To do this I used a pretty sneaky trick (well at least I think it is sneaky), I created a hash table where the key was the numbers 0-9 and the value was a bit mask that contained which segments should be on for that particular number. So, the hash table looks like this:
digit_hash = {}
digit_hash[0] = int('1110111', 2)
digit_hash[1] = int('0100100', 2)
digit_hash[2] = int('1011101', 2)
digit_hash[3] = int('1101101', 2)
digit_hash[4] = int('0101110', 2)
digit_hash[5] = int('1101011', 2)
digit_hash[6] = int('1111011', 2)
digit_hash[7] = int('0100101', 2)
digit_hash[8] = int('1111111', 2)
digit_hash[9] = int('0101111', 2)
And the least significant bit is the top center LED segment, and the next bit is the top left LED segment, and so on, in the order that the segments were given in the previous code sample. Now, all I can light up the LED segment based on whether or not the corresponding bit is set. Something like this:
mask = digit_hash[digit]
# Top Center
if(mask & int('0000001', 2)):
pygame.draw.rect(canvas, color, pygame.Rect(offset, 0, led_width, led_height))
# Top Left
if(mask & int('0000010', 2)):
pygame.draw.rect(canvas, color, pygame.Rect(0, offset, led_height, led_width))
And so on for the rest of the LED segments.
That’s all of the tricky parts of the code, the rest is just combining the pieces and updating the time every second. The complete code is in the attached zip file.
Finally, here’s a video of the code running on my raspberry pi: