Fixing a bad Arduino UNO clone board
So the Arduino UNO clone board that came with the Chinese kit I bought on Ebay... didn't work. At least, plugging it into my PC's USB port didn't yield the typical "dah dum" sound as the OS recognizes a new USB device being plugged in.
That's vexing...
Skip below if you want the TL;DR version...
Thus began a two week quest to see if I couldn't get the damned thing to work. First I did plenty of research online.There are various techniques to debug and sometimes fix an UNO that refuses to communicate via USB. These latest Revision 3 UNO boards and clones use another microcontroller to handle the USB interface. So in addition to the main ATmega328P microcontroller that you write sketches/programs for, there's a smaller SMD (surface mount device) ATmega16U2 microcontroller on the board. It's tiny -- a 5mm x 5mm square chip soldered onto the board near the USB connector.
If the ATmega16U2 goes bad, you can't use the board with USB.
Phase 1
BUT! Most of these boards have ICSP (In-Circuit Serial Programming) jumpers near both the ATmega16U2 and the ATmega328P microcontrollers. If you have an ICSP (ISP) programmer board/cable/dongle you can plug it into these 3x2 pin connectors and program each microcontroller directly with a "Bit Banging" type of interface.
So I googled and found this page that explains how to make an RS-232 connector ICSP cable. I salvaged some parts from an old boom box I'd torn apart years ago -- so many years ago that it was built with through-hole components that I could desolder and repurpose for my version of that RS-232 ICSP programmer dongle. Note that I used a 3x2 pin connecter (which is the type on an UNO ICSP) instead of the 6x1 type shown in that link. My connecter was actually hacked together by taking a hacksaw to an old wire-wrapping DIP socket I wasn't using, cutting out two 3-pin sections and gluing them together. What can I say, it works. I kind of like this grungy cable made from salvaged parts!
Here it is in all its glory:
I only had one 5.1V zener diode on hand and the circuit requires two -- one each for the SCK and MOSI lines. So I used the one zener on the SCK line and hacked a solution for the MOSI line: I used 3 forward biased red LEDs in parallel with a reverse biased general purpose diode. This roughly mimics the 5.1V zener diode that was called for in the schematic, since the forward biased LEDs drop roughly 1.8V each, so
3 x 1.8V = 5.4V
which is close enough that it works. It also has the benefit of providing visual feedback for when the PC is blasting bits to the microcontroller.
Anyway, I plugged it into the ATmega16U2's ICSP header, fired up avrdude with this command
avrdude.exe -p m16u2 -c ponyser
and... it doesn't work. Here's what avrdude reported:
AVR device not responding.
initialization failed, rc=-1
So I cursed and tried willing it to work, but it was no good. No wonder the UNO won't work on USB!?
But on a whim, I decided to try the ATmega328P's ICSP header. BAM! It works -- avrdude can talk to and program the 328, so at least it's not a total loss. I programmed in the Blink example and it worked! I had a flashing pin 13 LED, on for 1 second, off for 1 second and repeating.
But I still wanted to get USB working since it was a bit inconvenient to compile a program on my main PC, transfer it to an older PC that actually has an RS-232 port, plug in the programmer cable, apply power to the UNO and program the 328 with avrdude or PonyProg.
Phase 2
When my Digi-Key order for "Ayrduino" * parts came in, I got distracted with that. But it turns out the "Ayrduino" and a screw-up on my part ended up playing a role in fixing the UNO clone board.
* NOTE: An "Aydruino" is a DIY stripped down UNO-ish clone designed by Dr. Ayars. One that his students cleverly named the "Ayrduino".
I had already etched the "Ayrduino" PCB using an old kit from Radio Shack. With the parts in hand, I soldered up the board.
I plugged in an ATmega328, ran some jumpers from my RS-232 cable to the correct pins on the Ayrduino headers (RESET, SCK, MISO, +5V, MOSI, GND) and promptly set the lfuse incorrectly so that the board stopped talking to the Ponyprog type serial cable!?!? So I did more googling and found this page about fixing a chip after you've messed up the fuses:
Recovering from a "locked out" AVR
That invaluable thread started by clawson on the AVRFREAKS forum details how to recover from many of these fuse screw-ups. I'd set something like 0xF0 for the lfuse, thinking that external clock (the lower 0x0 nibble) was the appropriate setting. It's not! That's for a proper square wave TTL clean external clock. What I should have set was 0xFF, which is for an oscillator setup like the Ayrduino uses with a 16MHz quartz crystal and two 22pF capacitors.
So I used clawson's tip about using another Arduino to blast out a rough clock signal I could supply to the 328 I'd just messed up. I pulled the chip from the Ayrduino socket, plugged it into a breadboard, programmed the rough clock sketch/program into the Chinese UNO clone's 328 with my Ponyprog serial cable, disconnected it, jumped the output of its digital pin 8 over to the breadboard and the messed up 328's XTAL1 in pin (pin 9 on the 28 pin DIP). I also wired up the Ponyprog cable pins now to the breadboarded 328, supplied power & GND, etc. And BAM, I can talk to the "messed up" 328 again and fix the lfuse.
So now I had fixed the 328 I screwed up and had a working Ayrduino!
Phase 3
But I noticed something interesting after I had screwed up the 328's lfuse. It behaved somewhat similarly to the bad 16U2 from my UNO clone board, in that it started giving out a bogus device signature when connected via ICSP and the Ponyprog serial cable.
I wondered if that meant there might just be a problem with the ATmega16U2's lfuse? Or clock more generally?
So to test that out, I kept the UNO clone's 328 programmed as the rough clock generator and now jumped it over to the XTAL1 pin on the ATmega16U2 on the same board. Wild stuff. And guess what!? It worked! The 16U2 started answering avrdude and giving out the correct device signature.
I could then temporarily set the 16U2's lfuse to 0x62 for the internal clock with divide by 8. In that mode, it was semi-stable and I could get the correct signature and more or less program the chip with the usbserial code or the usbserial-plus-DFU code. I'd then have to set the lfuse back to 0xFF for it to use the external crystal again, since I gather that USB needs that faster, more precise clock speed as opposed to the slow 1Mhz internal clock speed.
But that never worked... If I then plugged the board into USB, it couldn't recognize the chip or communicate properly. If I recall correctly, it was at least now giving the "dah dum" Windows sound for a newly plugged in USB device, but it wasn't yet working properly. And ATmel's FLIP device programming app refused to connect to it via USB.
Phase 4
I began to wonder if the whole thing was a problem with the crystal and associated circuitry. I did some continuity checks on everything and it seemed to check out. I had read one interesting post online where a guy mentioned the crystal package on his clone board was shorting out on a connector. He sent it back and they repaired it by desoldering, raising the crystal slightly to avoid the short, and resoldering it in place.
Could my UNO clone board also have a short underneath the crystal as well?
I was determined to try everything, so I desoldered the crystal on my board (the actual 16MHz crystal the 16U2 uses as opposed to the ceramic resonator the ATmega328 uses). There was nothing underneath it would be shorting to.
But since I had the crystal out, and a spare one from my Ayrduino Digi-Key order (which I'll need to replace -- I wanna make a second Ayrduino) I soldered that one in. Plugged it back into the Ponyprog cable and avrdude recognized it!
Cool!
So I programmed the DFU+usbserial hex file for the 16U2. avrdude seems a bit flaky, reporting errors in the programming. Perhaps I need to tweak the settings and configuration for my cable and the device? Anyway, I plugged the UNO clone into USB on my main computer and it gave the reassuring "dah dum" sound. I shorted the 16U2's RESET and GND ICSP pins to try to get it into DFU mode (which ATmel's FLIP uses to program the device) and it did the "dah dum" sound again and said there was a new unknown device present. So I pointed Windows to the FLIP usb driver directory, installed that driver and then when I brought up FLIP, it could finally, FINALLY connect to the board with USB. Oddly, it complained that the DFU+usbserial hex file was too large for the device!? So I settled for the straight usbserial hex file, which worked. Another odd note was that the device manager never showed the board as "ATmega16U2 DFU" or "Atmel DFU" as I'd read it should. But I'd also found a forum post where a guy said he'd never gotten his Windows 7 machine to report that. But don't despair, the device is actually in DFU mode and FLIP can program it.
That worked. And unplugging and replugging in the board to USB gave the "dah dum" and device manager now saw an "Arduino UNO" under the COM & LPT ports entry! And I could program the board in the normal Arduino IDE manner.
Or actually I couldn't... See, the Arduino IDE setup assumes you have a bootloader installed on the ATmega328, and I still had that rough clock sketch running with no bootloader. So back to the Ponyprog serial cable, programmed in the Blink+Bootloader hex file. Moved back to USB and NOW I could finally program the board with the Arduino IDE in the normal manner.
My "bad" UNO clone board was fixed.
It was a bad crystal for some reason...
But after two weeks of fighting and googling and learning, I'd fixed it and I'm pretty happy about that!
Thanks for reading! Here's a picture of the repaired UNO clone featuring the new crystal and a couple of battle scars:
TL;DR
My UNO clone wouldn't communicate via USB.
I force-fed the ATmega16U2 a rough clock signal from the ATmega328 on the same board so it would talk to avrdude.
Still wouldn't communicate even when bringing the lfuse back to 0xFF from the temporary internal clock lfuse value of 0x62.
I desoldered the 16U2's crystal and replaced it with a new one.
With more serial ICSP programming, then DFU programming using ATmel's FLIP program, I got the board working!