I’ve written a few basic tutorials about bare-metal STM32 development in the past, and even though I’m still learning as I write them, I think that there’s enough groundwork to start covering some ‘real world’ scenarios now. I’d like to start with a very important technique for designing efficient applications: the Direct Memory Access (DMA) peripheral. DMA is important because it lets you move data from one area of memory to another without using CPU time. After you start a DMA transfer, your program will continue to run normally while the data is moved around ‘in the background’.
That’s the basic idea, but the devil is always in the details. So in this post, we’re going to review how the three main types of STM32 DMA peripherals work. Different STM32 chips can have similar peripherals which behave slightly differently, and usually more expensive / newer chips have more fully-featured peripherals. I think that this is how the peripherals are grouped, but I didn’t test every type of STM32 chip and corrections are always appreciated:
- ‘Type 1’ Simple DMA:
- ‘Type 2’ Double-buffered DMA:
- ‘Type 3’ DMA + DMA multiplexer:
Once we’ve reviewed the basics of how DMA works, I’ll go over how to use it in a few example applications to show how it works with different peripherals and devices. The required hardware for each example will be discussed later, but I’ll present code to:
- Generate an audio tone by sending a sine wave to the DAC peripheral at a specific frequency.
- Map an array of colors to a strip of
- Map a small region of on-chip RAM to a monochrome
- Map a a region of RAM to an
The key to these examples is that the communication with an external device will happen ‘in the background’ while your microcontroller’s CPU is doing other things. Most of the examples won’t even use interrupts; the data transmission is automatic once you start it. But be aware that DMA is not magic. Every DMA ‘channel’ or ‘stream’ shares a single data bus which is also used by the CPU for memory transfers, so there is a limit to how much data you can actually send at once. In practice this probably won’t be a problem unless you have multiple high-priority / high-speed DMA transfers with tight timing requirements, but it’s something to be aware of.
So let’s get started!
It’s good to know what time it is, and once you work out how to use a RealTime Clock module, making a clock display seems like a natural next step. 7-segment LED displays used to be the go-to way to display time digitally before LCD and OLED screens got so cheap, and I thought it would be fun to make a more modern take on them with diffused multicolor LEDs for the actual lighting. I would like to write a post about drawing to traditional 7-segment digits using shift registers, but this project uses the easy-to-wire ‘Neopixels’ that we all know and love.
You’ll need a few materials for this project if you want to follow along:
- Access to a laser cutter and a 3D printer.
- About 6 x 12″ of 1/8″-thick ‘frosted’ acrylic, to diffuse the LEDs. (About 150 x 300mm, 3mm thick)
- Enough plywood to make a clock face for the front and back; I wound up using about 500 x 200mm each.
- 58 individually-addressable RGB LEDs. (28 sets of 2 for each segment of the 4 digits, and 2 more for the colon dots.)
- A DS3231 or similar realtime clock module.
- A microcontroller to run everything; I used an ATMega328 on an “Arduino” nano board to keep the code simple.
- Craft supplies: solder, soldering iron, glue, hot glue gun, wire, etc.
For the LEDs, I cut lengths off of a reel of LED strip that I ordered off Amazon; I think it used SK6812 LEDs and had 30 LEDs / meter. For the two dots of the colon, you can also buy small single-LED boards that are about 10mm in diameter and usually have WS2812B LEDs. I didn’t run into any problems stringing SK6812 and WS2812B LEDs together with Adafruit’s “Neopixel” library, but caveat emptor.
Over the past month or two, I’ve been learning about plastic recycling with a friend at a local makerspace. We decided to start out with HDPE as a nice beginner’s material, because it melts at less than 200C and tends to be fairly nontoxic. We’ve tried a few different techniques now, and we’ve learned a lot about what doesn’t work.
This is an exciting field and we hope to make a decent press for forming 3mm and 6mm-thick HDPE sheets soon, but our early designs have shown us some key difficulties to be aware of if you are planning to start recycling plastics on your own. And I’ll mention this later, but please research what you plan to recycle ahead of time and avoid plastics which might release hazardous fumes. As you will see, I am not an expert.
Our first instinct was to imitate an injection-molding press, and we started by scavenging some large heating elements from a Goodwill-sourced griddle. It consisted of four ~13-Ohm coils arranged as two parallel banks, each consisting of two elements in series. That meant an effective resistance of 13 Ohms, or a bit over 9 amps at the mains 120V which it was more or less directly connected to.
We wound up clipping the heating coils out and scavenging some of the crimped and heat-insulated wiring, strapping them to a smooth-bore metal pipe, and then soldering or spot-welding the four coils back together in their original 2×2 arrangement. Temperature monitoring is all well and good, but this was a first attempt; we just wired the coils across a 2-prong plug, and flipped a surge suppressor on and off to control the heat. A handheld infrared thermometer gave us a rough indication of the tube’s temperature, and we aimed for 350-400F to melt the HDPE.
Among the cheap gadgetry that constantly spews forth from the spawning pits of consumer electronics, sometimes you can find a gem. The W1209 is an interesting board which is designed to act as a thermostat which can also switch a relay when certain temperatures are reached. It is used in everything from rice cookers to yogurt machines to people who want their A/C to only turn on when it’s hot out. Originally they shipped with a fairly powerful STM8S003F3 microcontroller, and they cost less than $1.50 each.
Even so, their popularity has inspired the usual imperfect cloning process, so chances are that a board you buy from ebay, Aliexpress, Taobao, or Amazon today will need some touching up before you will be able to reprogram it. In this tutorial, we will replace the microcontroller and add a few missing capacitor/resistors. Then we’ll upload a simple test program to test that the microcontroller and board both work. So here is an example of what is probably the worst possible knock-off that you could fear to get, with missing or faulty parts highlighted:
Well, that’s life. You try your best, and then someone comes along and kicks you in the teeth. But let’s make some lemonade and take the opportunity to learn about fixing cheap-o knock-off circuit boards!
It’s great to be able to write programs for a chip’s evaluation boards, but the real strength of microcontrollers is their ability to act as a low-cost, low-power “brain” for larger designs or products. And along those lines, I’ve been writing a few tutorials about bootstrapping some basic ‘bare metal’ STM32 projects using an
STM32F031K6 “Nucleo” board sold by ST.
That’s a great way to get started and test ideas out, but what if you want to try your hand at building a robot, or a home automation widget, or some other sort of complex machine? It’s nice to avoid huge messes of breadboards and wires once you have a basic prototype working, and these days it only costs a few dollars to get a small custom circuit board manufactured. The catch is, they usually take a few weeks to arrive and you need to provide the design. Still, the boards that we design in this tutorial will cost less than $2 each.
In this tutorial, we will use a suite of free software called KiCAD to produce a small example board using the same basic
STM32F031K6 chip that I’ve been writing programming examples for. Our board won’t be quite as nice as ST’s, and it will require an external USB device for programming and debugging. But on the other hand, our board will be smaller and cheaper, and you will be able to put the same design onto more holistic boards with other parts for your kickass robot or electronic vehicle or <insert dream here>:
The design files described in this post are all available in a Github repository, if you want a reference to follow along with.
OLED displays are excellent solutions for low-power, high-visibility UIs that don’t need to depict much detail and can be smaller than a square-inch or two. These days, they are cheap and available enough to be viable options for the hobbyist:
These are two small display panels which you can find on Taobao, Alibaba, or eBay in small quantities for roughly $2-4 each. The one on the left is a 96×64-pixel
SSD1331 16-bit color display. The one on the right is a 128×64-pixel
SSD1306 monochrome display where each pixel is either ‘off’ or ‘on’ – typically ‘on’ is a white or blue color. Some of them have a row of 16px along the top set to yellow, but each pixel is still only one color.
In this post, we will walk through the circuitry (although not the code) required to control these displays using a microcontroller, including circuit schematics for laying out a ‘breakout board’ in your preferred EDA program – I used KiCAD, and I’ll also provide a link to those projects if you don’t want to design a new board.