🍅⏰ Using the Pomodoro Technique to make a Pomodoro Timer (Part 1)

image

first prototype!

Using the Pomodoro Technique to make a Pomodoro Timer (Part 1)

A famous Henry Ford quote goes: “Nothing is particularly hard, if you divide it into small [enough] jobs”. One popular way to practically implement this advice is something called the “Pomodoro Technique”. 1

The Pomodoro Technique aims to divide the day into bite-sized, productive time chunks. The idea is to set some kind of timer for 25 minutes before you start working. Once you start work, (i.e. while the timer is running) you can’t check your email, look at your phone, or otherwise get distracted. Don’t worry! At the end of those 25 minutes, you’ll take a 5 minute break where you can do all of those things. Then it’s time to get started on the next 25 minute chunk.

image

A pictorial explanation of the pomodoro timer. image credit

Intrigued, I wanted to test whether the pomodoro method actually worked. But I still needed a benchmark project to apply this method to. What to do? Then suddenly came a bolt of inspiration. What if I used the pomodoro technique… to make a pomodoro timer?

While this may seem less ambitious than some of my previous embedded projects, I think it may turn out to be harder. For firmware, I wanted to break out of the walled garden of Arduino and use a real microcontroller this time around. More than that, I wanted this to be my first time taking a DIY design from concept all the way to production. 2 This means firmware and prototyping (this article, part 1), but also PCB design and assembly (next article, part 2) I’ve done each of these steps in isolation, but combining them together in one project will be the real challenge!

Finally, since I used a (website-based) pomodoro timer throughout development, I’ll break down how using this technique helped this project move along. Let’s get started!

The Concept

There isn’t much that goes into a pomodoro timer. You just need a way to visualize how much time you have left, and a way to reset the timer once it goes off. For visualization, I decided to use five LEDs to show the status of the timer. Each LED maps to 5 minutes of the timer’s period. So if 10 minutes remain, 2/5 LEDs will be lit. The microcontroller will count down from 25 minutes, turning off each LED in sequence until 25 minutes have passed and all LEDs are off. I made a quick state diagram to clarify below.

image

See the LEDs with the red outline? The LED at the end of the sequence is what I call the “active LED”. I wanted these to slowly pulse to add some extra flair to the project. This ended up having some pretty serious implications on implementation. more on that later…

Finally, how to reset the timer? After kicking around a few ideas (slider with inductive encoding? Adapting a motorized fader from a mixing board?), I settled with the humble button. No need to make more trouble for myself!

What would the timer look like? My original idea was to make it in the same form factor as an expansion card slot on the Framework Laptop. It would be cool to always have access to a pomodoro timer, but I landed on a different idea later in development. But I’m saving that as a secret for part 2 ;)

The Execution

Note: Skip to the conclusion if you don’t care about programming / implementation specifics!

Like I mentioned, one of my goals was to use a real MCU. Picking an MCU is no easy feat. I settled on TI’s MSPM0G3507 - I happened to have a few lying around and wanted to see if CCS’s quirkiness carried over to the new VSCode (technically Theia) CCS IDE.

One of my biggest gripes with previous-gen (eclipse) CCS was the difficulty of git integration. I always seemed to pollute my repositories with half of an SDK that I didn’t need. It looks like this is better in new CCS - following this “list of things to not check in” led to a bloat-less repo. CCS’s shows its VsCode bones in the super helpful source control tab, too. The jury is still out on whether it will survive a git clone, but for now it seems to be working ok.

image

CCS' new, VSCode/Theia coat of paint.

On to the project, where the first thing to implement was the timer logic itself. We set a hardware timer to trigger an interrupt once every second, checking if five minutes have passed. If so, we do a few things:

  1. Check to see if the full 25 minutes have passed. If they have, kill the timer.
  2. Turn off the currently active LED
  3. Make the next LED in the sequence the active LED
  4. Continue

That’s really all there is to it! On the other hand, making the active LED pulsing look pretty was more difficult. Pulse Width Modulation (PWM) is the default way to control LED brightness - but PWM percentage and brightness aren’t a linear relationship. 50% duty cycle on the LED is actually closer to 75% of the LED’s potential brightness, making changes in LED brightness look “one-sided” or “choppy”. As this blog post maintains, LED brightness is closer to a logarithmic curve than a linear one. I used a quick python script to generate a log_10 table from 0 to 256 (my max PWM period value). One lookup table later, and the LEDs pulsed evenly as intended! The video at time 4:06 shows the difference between compensated and non-compensated brightness values.

I was originally going to tie each LED to an individual PWM, but I soon realized there was no need to. The other LEDs don’t have to pulse, so they’re just set high (100% brightness). If I want to add variable brightness this may have to change, but at this point it’s OK. (As a side note, I always seem to forget simple things like enabling interrupts! For this, the M0 academies were really helpful in giving golden reference code and reasoning behind what each line is doing. The SDK documentation itself was super helpful too.)

For the physical prototype, I slapped a few LEDs and resistors onto a breadboard left over from college. (Thanks Dr. Silva!) I was tearing my hair out when two of the LEDs didn’t work, before I realized that PA10/11 were jumpered to the external debug probe rather than the GPIO breakout on the devkit. Some schematics quickly showed me the error of my ways.

Adding the timer reset button was the final step. Annoyingly, I couldn’t find a documented list of interrupt handlers in the SDK. Some kind soul on the e2e forum posted a massive list, but I’d appreciate more insight on where these handler methods come from / are defined.

The Conclusion

It works! I even used the prototype while writing this article! See the video below, (note that the time is set to 5 seconds per period, not 5 minutes as it would in production).

What’s the verdict on the pomodoro method? It’s helpful, but not for the reason you may have guessed. You see, I have a lot of difficulty in not getting distracted. This timer soon became my favorite way of handling distractions while working - whenever I felt distracted, I would look at the timer and remind myself I only had to focus for a few more minutes. Filing those thoughts away until I was done with the pomodoro period made me work way more efficiently!

The pomodoro helped with one other thing, too. Once I focused on a problem, I often went way over the 25 minute period trying to solve it. I see this is a good thing - why interrupt being in “the zone” because of some arbitrary time constraint? I was originally going to add some flashing lights to the end of the timer period, but found I worked a lot better when the timer unobtrusively fades out. So in a way, the timer is useful because it forces you to just start something, regardless of how long it takes you to finish.

Overall, I’m a fan. What a relief - imagine putting in all of this this effort if I ended up hating it! Next article, I’m going to start on my second PCB design ever! You’ll hear more about this in part two (coming hopefully before December). See you back here then!


  1. The guy who popularized this technique originally used tomato shaped timer, and Pomodoro is just Italian for Tomato. The more you know! ↩︎

  2. Brutally honest note: last time I tried this, I gave up. ↩︎