Ever since Ms Geek introduced me to the Arduino last April, I’ve been having a blast tinkering with them and building things. I’ve bought quite a few Arduino boards now, most of which are clones or third-party boards. A couple of them have been duds out of the package, but when I can buy four cheap boards for the cost of one “real” board, it’s tough to rationalize paying the extra money. Plus, a bit of time with a magnifier and a soldering iron fixed all but one of the boards that were DOA.
Up until two days ago, I’ve used the Arduino IDE exclusively under Windows and things have been working well. Two days ago, I installed the IDE (1.18.10) on a Raspberry Pi 4 running Raspbian Linux (Buster), and had no problems connecting to and uploading programs to MEGA328p boards like the Nano and Pro Mini.
A nice thing about Arduinos is that from a programming perspective, they’re pretty tough to permanently kill. As always, though, I make no guarantees that any of the following (or anything on this site, for that matter) will work for you. It’s worked for me so far, but it may not work for you. Who knows – it may not even work for me tomorrow. Anyway…
When I tried to do anything with a board that had the MEGA32U4 chip, though, the IDE couldn’t find it. There were no serial ports listed that pointed to the board:
The same thing happened with every single Pro Micro clone I tested (four of them from two different orders months apart) and a Keyestudio Leonardo clone. After hours of research and tinkering, I wasn’t any closer to fixing the problem, although I did disable modemmanager, which is something I discovered you should do if you want to do Arduino stuff under Linux anyway.
Just before I gave up, I extricated an authentic Leonardo from the project it was wired to and plugged it in. Immediately, a new serial port (ttyACM0) appeared in the IDE and showed a device connected to it:
Finally, I had a starting point. Here’s an assortment of my 32U4-based Arduino boards (the Pro Micro is basically a little Leonardo):
An easy thing to check was the 32U4 chip. They all looked pretty much the same, other than the authentic Leonardo being quite a bit older than the other boards:
Since the boards all worked under Windows, I was pretty sure that despite some different components (regulators, crystals, etc) on the clone boards, all were electrically sound. So, I took a look at what the Pi said when I plugged the boards in. It turned out that Linux was seeing the clones when I plugged them in but they disconnected almost immediately:
Then I plugged the genuine Leonardo in. It showed up in dmesg and stayed connected:
Aside from not disconnecting, the genuine Leonardo showed up a little different in dmesg. Take a look at the “New USB device found” and “New USB device strings” lines.
On the genuine Arduino: idVendor=2341, idProduct=8036, bcdDevice=1.00, Mfr=1, Product=2, SerialNumber=3
On the clones: idVendor=2341, idProduct=0036, bcdDevice=0.01, Mfr=2, Product=1, SerialNumber=0
Everything except the idVendor is different. According to the USB ID Repository, the vendor ID of 2341 belongs to Arduino. The Product ID of 8036 is associated with the Leonardo, while the Product ID of 0036 is associated with… a blank spot:
I still remember going through USB hell when the original Raspberry Pi came out, so to make sure the Pi or Raspbian weren’t causing the problem, I connected the boards to an Ubuntu VM. I got the exact same results, which took the Pi off the list of suspects. I did some more research and discovered that the vendor, product, and other information presented by the MEGA32U4 isn’t hard-coded in the chip or selected by OTP fuses – it’s firmware. As in, the bootloader. Which can be replaced.
I found some instructions for replacing the bootloader on an Arduino here and used a Nano (which works fine in Linux) as the programmer. I hooked one of the 32U4-based clones to the Nano, set the IDE to use the Nano as a programmer (Tools -> Programmer -> ArduinoISP), then burned the new bootloader (Tools -> Board -> Arduino Leonardo, then Tools -> Burn Bootloader).
I hooked the clone Leonardo up to the Raspberry Pi and took a look at the output of dmesg:
After burning the new bootloader, all of the clones showed the same values as the genuine Leonardo for idVendor, idProduct, bcdDevice, Mfr, Product, and SerialNumber… and all of the clones now show up as /dev/ttyACM0 or /dev/ttyACM1, and they are all visible and programmable in the Arduino IDE on a Pi 4 running Raspbian.
So, to sum up… if you can’t program a 32U4-based board with the Arduino IDE in Linux but it works fine in Windows, you can try the following:
- Check dmesg and confirm that the board is connecting and disconnecting. If so, then…
- Disable modemmanager (good idea to do this anyway), then…
- Check dmesg and see if the board has idVendor=2341 and idProduct=0036. If so, then…
- Buy or build an Arduino ISP. Once you’ve got it, then…
- Hook up the board in question to the ISP and burn the correct bootloader to the board. Once that’s done, you can…
- Check dmesg again and see if the board now has idProduct=8036. If it does, then…
- Give it a try (don’t forget to change the IDE settings (i.e. Tools -> Programmer -> AVRISP mkII) back to program your board directly instead of using the IDE!)