Creating a stand-up countdown buzzer – Pt 1
For some time now my colleagues and I try to have a more Agile way of working, this includes the traditional stand-ups in the morning. After a few weeks I noticed these were silently turning into full-fledged meetings, sometimes taking over 45 minutes each. As a bit of fun to raise attention to this point I tried to create a way to limit a person’s speaking time. I wanted to have a device which would start an annoying buzzer once a time limit is reached, then beep continuously after a few warning beeps to indicate the overtime. Something like a bomb mechanism I have seen in movies – without the bomb that is.
I wrote this idea down into a small use cases, how would I like to use the device. From here I created some requirements to get an idea of the components needed to make such device: it would need a button to start/stop the device, a buzzer to be able to beep, something to count ‘time passed’ or delay for ‘some time’ to allow the speaking time before beeping. With this written down I started searching for things at home which I could use to create this device.
Since I had a STM32F407G-DISC1 kit lying around, I choose this to work with. On this board I can connect a small speaker retrieved from a kids toy which broke down. By creating a sine wave of some sort (or PWM (pulse width modulation), explained in Pt. 2), the speaker will sound with a beep, which is enough for this purpose. The microcontroller on the discovery kit has some hardware timers available, a button to reset the microcontroller and a spare button I can use for any other purpose. Before starting the project I retrieved the reference manual (the 1500+ pages beast) and a schematic of the board.
I started out by creating a development environment in which I can write and debug C++ code for this microcontroller. (Note: C++ is my preference, could be C or something else as well). There are plenty of installation manuals on the web, I am skipping the installation and configuration here. For my purpose I used the OpenSTM32 IDE, but since ST bought Atollic some time ago this might be a better choice. I decided to make heavy use of the HAL (hardware abstraction layer), stripping out the ‘legacy’ part. This HAL (provided by ST) is useful as it does a lot of low level configuration and provides me with an easier means to use hardware features of the board. I ended up with a ‘main()‘ function, it compiled and from here the application could be created.
Next up was the clock configuration, after that the setup and configuration of the pins of the microcontroller. I typically configure the clock first as usually it runs at its fastest setting, which is overkill for this application. Setting it to a defined, lower value will both lower the power consumption and make the board more stable to use. Since the discovery kit has an 8 MHz (external) crystal, this is what I use for the main clock. The easiest way to configure this is to use the STM32Cube application (now integrated in TrueStudio by ST). I selected the discovery board, did not initialize with defaults, went to the clock settings and configured the clock. Peripherals derive their clock from the main clock – knowing what you use will be essential when using the peripherals. In the reference manual there is a schematic overview of the clocks (Fig 16, Clock tree). For me this meant following the path of the HSE (high speed external clock signal, aka the crystal). Then I used STM32Cube to generate some code and made a function to set the clock in my application.
With the clock set I needed a means to control the GPIO (general purpose input output) pins: be able to toggle some pins high/low to generate a block wave for the buzzer and a way to read the status of the button (did the user press it or not). The reset button cannot be programmed, it resets the microcontroller. Since some indication as to what the board is doing is helpful, I wanted to use the 4 available colored leds – these are controlled by GPIO pins. The pin number of the leds and button I can find in the schematic, search for the name (led, button) and follow the wire until you find a symbol named PA0, PD12 or something.
Free pins to connect the buzzer onto I find by using the STM32Cube where I configured the board with the default options. Some of the pins are not used which allows me to use them to create a block wave by toggling them. At this point I start looking into some examples provided by ST for this specific board, then some specific GPIO examples on the internet. From here I can see that the HAL needs to be initialized and the clock needs to be initialized. After this point the pins can be configured and toggled. For ease of use I made a Pin class, which provides a way to more easily configure a pin. It also provides functionality to deal with an external interrupt: the button press. To figure out how external interrupts work I take a look at the reference manual in the GPIO section, and work my way through a tutorial or 2 from the internet. The only trouble I had was to figure out how an interrupt is handled by this particular microcontroller, something the examples and tutorials from the internet will describe. Creating sample applications to try just a small part of functionality makes it easy to debug and refine – this I used to create the Pin class.
In part 2 the article continues with a means to make the buzzer beep, to keep track of time and combining it all into an application. Stay tuned!