This is the second post in a series doing a deep dive into Internet of Things implementation. If you didn’t read the first post, Our Plants Need Watering Part I, then you should read that first.
This post talks about one of the most important decisions you’ll make in an IoT project: which microcontroller to use. There are lots of factors and some of them are quite fractal – but that said I think I can make some concrete recommendations based on what I’ve learned so far on this project, that might help you in your next IoT project.
This post gets really technical I am afraid – there’s no way of comparing microprocessors without getting into the weeds.
There are thousands of different microcontrollers on the market, and they are all different. How you choose the one you want depends on a whole range of factors – there is no one-size-fits all answer.
Inside a microcontroller
A microcontroller is a single chip that provides all the parts you require to connect software and hardware together. You can think of it as a tiny, complete, computer with CPU, RAM, storage and IO. That is where the resemblance ends though, because each of these parts is quite different from the computers you might be used to.
The Central Processing Unit (CPU) takes software instructions and executes them. This is the bit that controls the rest of the microcontroller, and runs your software.
Microcontroller CPUs come in all shapes and sizes all of which governs the performance and capabilities of the complete package. Mostly the impact of your CPU choice is smaller than you might think – toolchains and libraries protect you from most of the differences between CPU platforms.
Really it is price and performance that matter most, unless you need very specific capabilities. If you want to do floating point calculations or do high-speed video or image processing then you’re going to select a platform with those specific capabilities.
The kind of computers we are used to dealing with have hard disks to hold permanent storage. Microcontrollers generally do not have access to hard disks. Instead they have what is called “flash” memory. This is permanent – it persists even if power is disconnected. The name “flash” comes from the way the memory is erased “like a camera flash”. It’s colloquially known as just “flash”.
You need enough flash to store your code. The amount of flash available varies tremendously. For example the Atmel ATtiny25 has a whole 2KB of flash whereas the Atmel ATSAM4SD32 has 2MB.
Determining how big your code will be is an important consideration, and often depends on the libraries you need to use. Some quotidian things we take for granted in the macro world, like C’s venerable printf function are too big to fit onto many microcontrollers in its normal form.
Static RAM (SRAM)
Flash is not appropriate for storing data that changes. This means your working data needs somewhere else to go. This is generally SRAM. You will need enough SRAM to hold your all changeable data.
The amount of SRAM available varies widely. The ATtiny25 has a whole 128 bytes (far less than the first computer I ever programmed, the ZX81, and that was 35 years ago!). At the other end of the scale the ATSAM4SD32 has 160K, and can support separate RAM chips if you need them.
Microcontrollers need to talk to the outside world, and they do this via their I/O pins. You are going to need to count the pins you need, which will depend on the devices you plan to connect your microcontroller to.
Simple things like buttons, switches, LEDs and so forth can use I/O pins on an individual basis in software, and this is a common use case. Rarely do you build anything that doesn’t use a switch, button or an LED.
If you are going to talk digital protocols however you might well want hardware support for those protocols. This means you might consider things like I²C, RS232 or ISP.
A good example of this is plain old serial. Serial is a super-simple protocol that dates back to the dark ages of computing. One bit at a time is sent over a single pin, and these are assembled together into characters. Serial support needs a bit of buffering, some timing control and possibly some flow control, but that’s it.
The ATtiny range of microprocessors have no hardware support for serial, so if you want to even print text out to your computer’s serial port you will need to do that in software on the microprocessor. This is slow, unreliable and takes up valuable flash. It does work though, at slow speeds – timing gets unreliable pretty quickly when doing things in software.
At the other end you have things like the SAM3X8E based on the ARM Cortex M3 which have a UART and 3 USARTs – hardware support for high speed (well 115200 baud) connections to several devices simultaneously and reliably.
There are loads of different packaging formats for integrated circuits. Just check out the list on Wikipedia. Note that when you are developing your product you are likely to use a “development board”, where the microcontroller is already mounted on something that makes it easy to work with.
Here is a dev board for the STM32 ARM microprocessor:
(screwdriver shown for scale).
You can see the actual microprocessor here on the board:
Everything else on the board is to make it easier to work with that CPU – for example adding protection (so you don’t accidentally fry it), making the pins easier to connect, adding debug headers and also a USB interface with a programmer unit, so it is easy to program the chip from a PC.
For small-scale production use, “through hole” packages like DIP can be worked with easily on a breadboard, or soldered by hand. For example, here is a complete microcontroller, the LPC1114FN28:
Some, others, like “chip carriers” can fit into mounts that you can use relatively easily, and finally there are “flat packages”, which you would struggle to solder by hand:
It is all very well choosing a microcontroller that will work in production – but you need to get your software written first. This means you want a “dev board” that comes with the microcontroller helpfully wired up so you can use it easily.
There are dev boards available for every major platform, and mostly they are really quite cheap.
Here are some examples I’ve collected over the last few years:
The board at the bottom there is an Arduino Due, which I’ve found really useful. The white box connected to it is an ATMEL debug device, which gives you complete IDE control of the code running on the CPU, including features like breakpoints, watchpoints, stepping and so forth.
Personally I think you should find a dev board that fits your needs first, then you need to choose a microcontroller that is sufficiently similar. A workable development environment is absolutely your number one goal!
Frameworks, toolchains and libraries
This is another important consideration – you want it to be as easy as possible to write your code, whilst getting full access to the capabilities of the equipment you’ve chosen.
Arduino deserves a special mention here, as a spectacularly accessible way into programming microprocessors. There is a huge range of Arduino, and Arduino compatible, devices starting at only a few pounds and going right up to some pretty high powered equipment.
Most Arduino boards have a standard layout allowing “shields” to be easily attached to them, giving easy standardised access to additional equipment.
The great advantage of Arduino is that you can get started very easily. The disadvantage is that you aren’t using equipment you could go into production with directly. It is very much a hobbyist solution (although I would love to hear of production devices using Arduino code).
Other vendors have their own IDEs and toolchains – many of which are quite expensive. Of the ones I have tried Atmel Studio is the best by far. First it is free – which is pretty important. Second it uses the gcc toolchain, which makes debugging a lot easier for the general programmer. Finally the IDE itself is really quite good.
Next time I’ll walk through building some simple projects on a couple of platforms and talk about using the Wifi module in earnest.
I’ve enjoyed reading these articles about the plant waterer, and look forward to the next installment.
These days, since the advent of the ESP8266, I generally find that there’s very little need to involve any other processors in an IoT project – there’s sufficient processing power and storage on the ESP8266 for most needs, and it has some great development environments – Arduino IDE and LUA support being the main two.
The ESP-01 modules usually have enough I/O (a couple of pins of GPIO) for most simple purposes, and are sufficiently tiny that battery-powered nodes are usually dominated by the battery size, rather than the rest of the circuit. Finally, you really can’t argue with the price – usually cheaper even than the ubiquitous Arduino Micro knock-offs.
Personally, I love ’em and they’ve revolutionised most embedded device development for me.
I’d recommend digging into crypto support on the ESP8266 – there are definitely TLS implementations kicking around. Possibly not up to the requirements for AWS, but you could happily have TLS from the sensor nodes directly to a base station (e.g. RasPi or spare cycles on an existing office infrastructure server) which could then relay messages over heftier crypto to AWS. That would gain you a lot in terms of simpler sensor nodes.