So far, the Ardunio environment seems to be the easiest way for me to get real and practical things done with hardware, most of which has to do with there being a decent open-source library for most of the things that I could write but don’t want to.
I’ve never actually purchased a real Arduino, however. When given a choice between making a PCB that has a footprint where I could plug in an Arduino of some sort and just making a PCB that contains the bits I want out of an Arduino without the plug-in Arduino, I’ve tended towards just making my own board.
There are two existing tutorials that cover a bunch of the issues. The first one is the Arduino From Scratch series, which goes into fairly heavy detail on the making of a Uno R3 clone, bit-by-bit, complete with a lot of explanation. The second one, a bit shorter, is the DIY Arduino Schematic Checklist.
A lot of this applies. The clock circuit, the RESET line, and capacitors, same. The USB interface is a bit of unfamiliar ground, however.
I thought, after the QMK Keyboard write-up, I’d cover more of the story about how to get a working module. I wanted to be able to test making a USB keyboard and fit it into a 5mm x 5mm board size for DirtyPCBs but I also wanted to be able to recycle the other 9-ish boards I was going to receive as regular Arduino boards.
The USB connection
Most of what you need to know is in Chapter 21 of the datasheet. Folks have just soldered the chip to a breakout board and made this work on a breadboard.
Mostly, what you need is a pair of 22 ohm termination resistors, and a 1uF capacitor on the UCAP line. You also probably want to use a crystal instead of a resonator for the system clock.
If you want to do it right, however, you probably want to add ESD Protection diodes, a 10 uF capacitor between VBUS and GND, a fuse, and maybe decouple the shield from ground.
Also, if you are making a PCB, you want to make sure that the length of the traces is identical.
ESD Protection Diodes for USB
If I look at the schematics for most USB development boards, there’s no diodes to be found, but it does feel like a good idea to have some protection past what’s built into the chip.
There’s an entirely reasonable ESD protection diode array available in a SOT-143 package: the PRTR5V0U2X by Nexperia. It’s in an eminently hand-solderable package with a reasonable pinout.
I’ve come to realize that putting in PTC fuses on my devices is saving me from troubles. Especially considering where the device is getting plugged into, it’s really a bad idea to skip out on this.
Thus, I put a little 0805 PTC fuse between the VUSB pin on the USB connector and the rest of the board.
Shield and ground decoupling
This is… hard. If you are making a real device, you would want to do a proper ESD test regime.
Basically, the USB connector has a shield line and a ground line. The ground line is the real ground that serves as an electrical return line, the shield line is the braided shield that shields the connector. It’s intended that the shield line be connected to the metal chassis for the computer and the board and not directly connected to ground, however, there are a LOT of differing opinions and stories about the right way to do this.
My impression is that the answer if you ask a trained expert electrical engineer, they will tell you to run some tests because anything you might do could break things.
Atmel AVR1017 suggests that you create a RC filter between the ground signal and the shield using a 1MΩ resistor and a 4.7nF capacitor. That, at the very least, doesn’t cause USB to stop working.
The ATMega32u4 comes with a factory bootloader that doesn’t work with the Arduino environment
When you get a ATMega32u4 from a supplier, it’s already got a bootloader on it: the default DFU firmware.
This will work for some things. QMK is able to burn to it right out of the box, for example. AVRDude is able to burn to it, if you want to construct your own toolchain.
The problem is that the DFU bootloader isn’t compatible with the Arduino way of working.
Thus, if you want to actually use it as an Arduino, you need to replace it with an Arduino bootloader.
The only “Better” bootloader is the bootloader on a Teensy and that’s not open-source. Otherwise, everything else takes up a 4k block of flash.
You need to use a programmer to install a new bootloader
The DFU bootloader doesn’t allow you to install another bootloader. Thus, you need to use one of the programming protocols, probably by connecting up the I/O pins to a standard 6 pin ISP connector.
The pin mapping looks something like this:
|1 (MISO) → PB3 (11)||2 (Vcc) → Vcc|
|3 (SCK) → PB1 (9)||4 (MOSI) → PB2 (10)|
|5 (RESET) → RESET (13)||6 (GND) → GND|
In my case, I ended up just connecting it to the AVR-STK500 that I’ve had for years and years and used the “Burn Bootloader” option inside of the Arduino application to burn the bootloader.
Also: If you get an error message something like this:
atmega32u4 Failed to enter programming mode. ispEnterProgMode: Error status received: Got 0xc0, expected 0x00 (Command has failed to execute on the tool)
That’s probably a ratty connection on the RESET line.
There is no general-purpose Arduino board file for the 32u4 but it worked if I called it an Arduino Micro
There is the ATTinyCore for ATTiny devices, the MightyCore for the 40/44 pin ATMega devices, the MegaCore for the giant 64+ pin ATMegas, and the MiniCore for the 28/32 pin ATMega devices. The MiniCore, in particular, is kinda the same thing as the Uno, but more flexible.
In an ideal world, somebody would have a similar general-purpose core for these devices, but I also understand that whoever did that sits at the end of a stream of issues, bugs, support requests, and so on. I am not creating it because I know what goes into it. 😉
In lieu of making my own custom Arduino board file, what I found is that my design works just fine if I call it an Arduino Micro. If I tried to call it an Adafruit ATMega32u4 breakout the bootloader would act up.
The longer explanation:
The Arduino environment tends to want to treat the ATMega32u4 as just another Arduino with a serial port. Now, I really really like devices that don’t require an external programmer because I deeply hate the industry that bundles up a relatively cheap device that charges a lot of money for something that’s basically a USB to serial converter… or maybe a USB to SPI connector or some GPIO pins.
The way that the Arduino environment made USB work for the ATMega32u4 was to create a “fake” serial port that the Arduino serial library considers to be a real one, which is run in software. This means that debugging over the serial port still works, as before.
To program the device, the Arduino app connects to the fake serial port with a set of specific connection parameters (1200 baud). The Arduino uses this as a cue to do a software reset. The device will then sit in programmer mode for a pre-configured amount of time before starting the actual execution of the Arduino sketch.
For some reason, this works when I call it an Arduino Micro but not when I call it an Adafruit ATMega32u4 breakout and I am declining to debug that one further.
This also shows why the DFU firmware won’t work: It doesn’t let you treat it as an Arduino-like thing.