(Article still under construction)

Programming An Uno Under Windows 2000

Before I purchased an Arduino Uno board, I first downloaded the software and made sure that it would run under Windows 2000, the operating system I'm using on my machine, knowing that a lot of software developers just don't seem to grasp the concept of backwards-compatibility. The Arduino integrated development environment seemed to run with no problems under Win2k (revision 0022 did, anyway). However, once I had my Uno in hand, I found out I couldn't get it to take an upload. With a little research I found out that there's a problem with the Windows 2000 driver that's supposed to allow a USB port to be treated like a virtual serial COM port. The result is that the USB port does something that the ATmega8U2 chip that acts as an Uno board's serial input controller doesn't like, and it won't accept an uploaded sketch. You end up getting weird, cryptic error messages like, "avrdude: stk500_getparm(): (a) protocol error, expect=0x14, resp=0x41".

Grrrrrrrrrrrrr...

I decided that there had to be a way to get an Uno to take a program from a Win2k system, and I set out to find it. In fact, there are a number of possible options to deal with this problem. I've seen several methods alluded to on the internet, but none were actually described in detail and I had to experiment for myself. To date, I've found two methods that did the job for me, and I describe them below along with several other possible options that I've not yet tried.


Option 1: Upgrade to XP

Okay, let's get this out of the way first. The first idea that probably comes to mind for many is to upgrade to Windows XP or later. Presumably, if this were practical for you, you'd have done it by now and wouldn't be reading this article. Perhaps you're under budget constraints and can't afford new hardware able to run more recent versions of Windows or, like me, are a stubborn creature of habit and refuse to unnecessarily upgrade to a newer operating system simply because Bill Gates wants more money from us. This issue is the only one I've ever found where Win2K won't do what I need, so why should I have to "upgrade"? If anybody out there wants me to use their programs, they should make sure they're backwards compatible with the OS I'm using, in my not-so-humble opinion. And now that I've found out how to make Win2K do what I need in this issue, I still don't have a reason to "upgrade"... unless it be to Linux.


Option 2: Updating the Windows 2000 Driver by itself

This is the one trick that I've used that seems to work with every combination of board and chip I've tried so far. Unfortunately, it requires some tinkering with your computer's system files. If you're not intimidated by Windows' "Touch me there again and I shall scream!" attitude, read on.

Hypothetically, I'd think there ought to be a way to tell Windows to use a different driver rather than upgrading its default USB driver. I've tried editing the Arduino .inf files to make it use a different driver, but nothing seems to work. Windows either insists on using the same faulty driver that came with it, or it stomps off in a snit and refuses to install a driver at all. Maybe some Windows expert who may read this article can explain to us why this happens and how to force Windows to use an alternate driver.

About the only other way, then, is to update the Windows 2000 USB driver in question itself. This is harder than it sounds, but it CAN be done. The big obstacle is that Windows uses an active protection scheme that continually monitors critical system files like drivers and DLLs for "unauthorized" changes. (Meaning, any change that Windows itself doesn't make.) If it detects a change, it copies the original file from a backup copy or, failing that, from an obscure archive. This is valuable protection against your system getting accidentally corrupted or attacked by malicious software, but it's a damned nuisance if you actually do need to update a file on your own. The trick is to find that resident archive and hide it from Windows so that it has no choice but to use the new file.

Here's how to do it:

Step 1.

Just for good measure, you might want to first uninstall whatever driver you've been using. (I suspect that this isn't necessary, but it can't hurt to cover all your bases.) Plug your Uno into the USB port, open up the Windows Settings command, doubleclick on System, click on the Hardware tab, then click on the Device Manager button. Once you've got the driver tree listed, click on the "+" in front of "Ports (COM & LPT)". In the expanded branch, you should see an entry for your Arduino board if you've tried using it previously. (Your Arduino must be plugged in or this line won't be displayed even if a driver is installed.) Right click on it, pick "Uninstall" from the menu, then confirm that you really do want to remove the Arduino driver. When you're done, unplug your Arduino.

Step 2.

Next, you'll need get a new driver. The driver file in question is named "usbser.sys", which resides in my system at "\WINNT\system32\drivers\usbser.sys". (On my multi-boot computer, the Windows system directory is called "\WINNT\...", but it may be called "\WINDOWS\..." on yours. Make the appropriate modifications to the path names I give below.) With my Win2K SP4 installation, I've got version 5.00.2195.6655, which is 22768 bytes long. (You can easily find the version number by using FileAlyzer, a useful utility available from the same fine fellow who brought us the popular SpyBot anti-spyware program.)

I got onto an XP computer and found the XP version of the usbser.sys driver at "\WINDOWS\ServicePackFiles\i386\usbser.sys". (Note that using Windows Explorer's search function found several other apparent copies, but in several cases they were not the actual file but rather listings for the file in various installation archives.) The file is 26112 bytes long (the file lengths are noteworthy in that I use them to identify at a glance which copy of the file is which version) and is labeled as being version 5.1.2600.5512.

I can say from experience that this particular driver is capable of interfacing to an Arduino Uno, but with only one example I can't swear that other XP revisions of the driver will work, and I've no idea about the drivers from Vista or later. If you don't have access of an XP machine, I'm afraid I don't know of any trustworthy sources you can download it from. Perhaps you can find a friend, relative, or online contact who's using XP and who may be able to get you a copy. Maybe if it doesn't violate the Arduino Playground's usage policies, I'll try to upload the one I'm using and link it to this article. But whatever you use, whatever the source, be sure to check it yourself for viruses before trying to use it!

Step 3.

Once you've got a more recent driver, you need to block Windows from overwriting it when you try to put it where it needs to be. On my system there's a folder called \WINNT\Driver Cache\i386" that appears to hold the compressed archive for drivers. We've got to hide it from Windows. What I did was to create another folder that I called "WINNT\Driver Cache Backup\i386\". Then I moved everything from the first folder into the second. Not copied but moved, so that the first folder is now empty. Yeah, you COULD just delete them, but it's better to back them up somewhere in case you need them again in the future. It's perhaps safer to do this in two steps: copy all the files first and verify that they did get copied, and then delete the contents of the original folder.

Step 4.

Windows also keeps a folder of uncompressed backup copies of drivers etc. On my system, they're in "\WINNT\system32\dllcache\". Similar to what I did in Step 2, I created a folder I called "\WINNT\system32\dllcache-backup\" and moved all the files in the first folder into the new folder.

Step 5.

Okay, now we're ready to pull off the gauntlet and smack Windows' face with it. Change the name of "\WINNT\system32\drivers\usbser.sys" to, say, "usbser-old.sys", or whatever suits you. Again, you COULD just delete it, but I have a morbid fear of deleting files I may need again some day. Yup, "Digital Packrat", that's me.

Step 6.

Within a few seconds, Windows File Protection should pop up with notice that "Files that are required for Windows to run properly have been replaced by unrecognized versions." On my system, it then asks the user to insert the Service Pack 4 disk. It gives you three button choices: Retry, More Information, and Cancel. Click on Cancel. It then warns you that not letting it fix the "problem" could affect Windows stability and asks if you're sure you want to keep the "unrecognized file". Click on Yes.

Step 7.

Copy your newer version of "usbser.sys" into "...\system32\drivers\".

Step 8.

Again, Windows detects an "unrecognized" file. Repeat Step 6.

Step 9.

The new driver should now be ready for action, though you may want to reboot first just for good measure. Plug your Arduino in to the USB port and let the system install the driver. The system may want you to insert an installation disk in another attempt to restore the old driver. Tell it to Cancel this action. Instead, tell it to search for the driver in a specific location, then Browse to the folder where the new version of "usbser.sys" is located, i.e. "\WINNT\system32\drivers\".

Step 10.

Start up the Device Manager and expand the "Ports" branch. You should see your Arduino driver in place without the yellow question mark that denotes a driver problem. Make note of which Com port it's configured as. You'll have to give that info to the Arduino IDE.

Step 11.

Start the Arduino IDE. In the Tools pull-down menu, click on Serial Port and make sure the appropriate port is selected. Also in the Tools pull-down menu, click on the choice for Board and select the Arduino Uno, same as you would for the USB interface.

Step 12.

If everything has gone well, you should now be able to upload your sketch. Don't panic if it doesn't work the first time; it didn't for me, either. Hit your Uno's reset button and try again. On the second try, my unit worked like a champ. It's been my observation that upload failures typically happen the first time I try to upload a sketch after plugging the Uno into the port, so it might be a good idea to get into the habit of always pressing the reset button after powering up your unit.

This procedure has worked for me on two different Windows 2000 machines. Unfortunately, while this lets you hide the old version of "usbser.sys" and replace it with the newer one, it also hides the other archived critical files as well. On the other hand, should one of them become corrupted at some point in the future, Windows will still detect it and let you know, at which time you can copy your backups back into the appropriate folders so that Windows can perform the needed repairs. But I don't know if the system will also "repair" usbser.sys as well at the same time and require you to perform this process all over again.

As an experiment, I tried putting the all the moved files back into the archive folders and rebooting my machine, and Windows allowed the new driver to stay in place. It might be that the active protection scheme is only triggered by the act of modifying a file and the system will leave an updated file alone as long as you don't draw attention to it by deleting or modifying it again.

Note 1 - By Lee Brand.

I had exactly the same issue and based on the above took the Windows 7 (Starter) USBSER.SYS and copied it over (after saving) the one in ..\drivers\.. on my Win2000 machine. Uninstalled the UNo, installed again and presto - problem solved. This has got to be the easiest option!

Note 2 - By Jose S. Augusto

I have 2 Win2K machines. In one of them, I managed to replace usbser.sys using this recipe. But in the other machine the system kept replacing the XP usbser.sys with the older one, even after the recommended "backup" measures were taken. I think the driver usbser.sys was being loaded by the USB keyboard, or some other device.

Finally I've done the following: after uninstalling Arduino UNO R3, I rebooted the PC in "safe mode" (and used an old PS2 keyboard and PS2 mouse, just in case the usbser.sys would eventually be loaded), and then with a DOS command window I deleted the original usbser.sys and replaced it with the usbserxp.sys (by renaming it). After this, the system didn't try to recover the old file. Then I reinstalled the Arduino and now it works fine.


Option 3: Using the COM1 Serial Port

Another option is to try using the 9-pin RS232 serial port that most older Win2K machines are equipped with, bypassing the ATmega8U2-based USB interface on the Uno and connecting directly to the main chip. You can also use this technique to load sketches into ATmega328 chips that are wired into circuits on a prototyping breadboard.

The problem with this method is that the bootloader that comes preloaded into some Uno boards' ATmega328 chips expect a different timing arrangement than the one generated by the circuit I describe below. If I can figure out how to modify the timing of the circuit to match what the chip expects, I'll post the info here. Failing that, ATmega328 chips that use the Optiboot bootloader work just fine with this method. If you are not using an Uno with surface-mounted chips but rather have one with a 28-pin DIP socket for the microcontroller, you can buy an ATmega328 preloaded with Optiboot from Sparkfun Electronics for less than $6 plus shipping. The part number is DEV-10524.

You can't simply plug raw RS232 signals into your Uno. An Uno is designed to interface with signals only within the voltage range of TTL chips, zero to +5VDC. A standard RS232 signal swings back-and-forth between +12VDC and -12VDC and could fry the chips on your Uno. In addition, the RS232 signal is inverted: the "rest state" when there's no data or a "logical 0" is coming through is +12V, and the signal drops to -12V for a "logic 1" bit. You need an interface circuit that will not only change the voltage levels to an acceptable range but also invert the signal so that a "logic 0" is at 0VDC and a "logic 1" is at +5VDC.

RS232-vs-TTLFig.1: Comparison of standard RS232 signal versus the TTL-level serial format accepted by the Optiboot boot loader. Note that there are also a number of other serial formats, such as I2C and SPI, both of which can be used by the ATmega328.

There are a number of different ways of doing this. A web search of "rs232 ttl converter" or "rs232 ttl shifter" will produce hundreds of thousands of links both for commercial products as well as do-it-yourself plans. I used a module available from Sparkfun Electronics, part number PRT-00449. This unit will convert the two data signals TxD and RxD, but by themselves they're not quite enough. There's still one more thing you need.

The Optiboot boot loader is set up so that immediately after a power-up or reset, it spends a moment listening for incoming data from a programmer (a sequence of binary zeroes, apparently). If it doesn't hear anything within a certain time period, it stops listening and starts running whatever sketch is already loaded into it. So if you're going to send a new sketch into your Uno via your RS232 port, you need to somehow either hit the reset button at EXACTLY the right instant, or come up with a way to signal the chip automatically.

I don't know as of this writing whether it's by accident or design, but one of the RS232 control signals, known as DTR ("data terminal ready"), changes state at just the right time that it can be used for this function. Again, it's a +/-12V signal you can't just tie directly into your Uno board without having to worry about damaging the chip. But a usable interface for this signal is simpler than for the data lines: just send it through a 0.1uF capacitor. This allows a quick pulse through that triggers the ATmega328's reset line and gets it to pay attention to the incoming sketch at the right time. I tied into the DTR signal by soldering a wire to pin #4 of the DB9 connector on the PRT-00449 shifter's board.

RS232 to TTL ShifterFig 2: Sparkfun Electronics PRT-00449 RS232 Shifter board, modified to provide access to the DTR signal from Pin 4 of the DB-9 connector.

Once you've got your converter wired up, the following 5 connections are needed:

  • VCC - Assuming your converter is powered from your Uno or your breadboard (unlike USB, there is no 5V supply available on your computer's COM port!), you'll need to apply power to it. Connect the +5V power lead on your converter to your breadboard's +5V bus or the 5V terminal on your Uno's 6-pin power header.
  • GND - Connect the GND lead on your converter to your breadboard's ground bus or the GND terminal on your Uno's 6-pin power header. You need this connection even if your board has it's own on-board power source. Digital signals from two different devices need a common frame of reference, or the devices won't understand each other. It's like trying to read the fine print on a legal contract while the person holding it for you is bouncing up-and-down on a pogo stick. Tying the grounds together makes the units "hold still" relative to each other so they can read each other's signals.
  • RxD (pin #2 on the host's DB-9 connector) goes through the signal converter to the pin labeled "TX->1" on the Uno's Digital I/O 16-pin header, or directly to a breadboarded ATmega328's pin #3. "RxD" stands for "received data" and "TxD" for "transmitted data. Think about it: your computer is listening on the signal line that the ATmega is talking on and vice versa. Makes sense, doesn't it?
  • Likewise, TxD (pin #3 on the host's DB-9) goes through the signal converter to "RX<-0" on Uno's I/O header or to a breadboarded ATmega328's pin #2.
  • RESET - The DTR signal from the host computer goes through a 0.1uF capacitor, then to the RESET terminal on the Uno's power header or to an ATmega328's pin #1.

Uno RS232 ConnectionFig 3: The circuit I use for loading sketches into an ATmega32, whether in an Uno or on a breadboard. Note the crystal. It's okay to set up an ATmega328 to use its onboard oscillator in some situations, but while you're loading sketches into the chip, the onboard oscillator isn't accurate enough to stay reliably in sync with the host system. You really need that crystal if you're working with a breadboarded chip. The Uno uses a crystal; no problem there.

Uno Connected via RS232Fig4: My Uno connected up for RS232 uploads. Note the little 0.1uF capacitor soldered to the end of the DTR/Reset line. The "pins" inserted into the header sockets are 22 ga. solid copper wires soldered to the ends of the stranded conductors of the cable, with heat shrink tubing insulating the joints.

As I said above, not all Uno's might be able to use this method with the chips supplied with them. I have, as of this writing, two different ATmega328 chips: the one that came installed in my Uno and another I bought by itself pre-loaded with the Optiboot boot loader. The individual chip works fine with this method, both in the Uno and on a breadboard. However, the chip that came on my Uno won't take a sketch via the RS232 port in either setup unless I get REALLY lucky and manually hit the reset button at EXACTLY the right instant, which I've only managed once. If you can't get a replacement chip with Optiboot or have an Uno with surface-mount chips that aren't replaceable, you can try Option 5 below and replace the bootloader.

UPDATE Sept 6, 2011: Okay, I seem to have found the right timing to get the Uno board with its original ATmega328 with the older bootloader to take a sketch via the COM1 port and the modified RS232 shifter board. The trick seems to be to hit the Uno's reset button at exactly the right instant, and it has to be a really quick tap.

When you start the upload process, hold down one of your keyboard's shift keys at the same time you click on the upload button in order to tell it to use the "verbose" output. What you'll see is something like this:

 Binary sketch size: 1578 bytes (of a 32256 byte maximum)
 C:\U\ArduinoIDE\hardware/tools/avr/bin/avrdude -CC:\U\ArduinoIDE\hardware/tools/avr/etc/avrdude.conf -v -v -v -v -patmega328p -cstk500v1 -P\\.\COM6 -b115200 -D -Uflash:w:C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\build349272376178497284.tmp\Blink3b.cpp.hex:i 

 avrdude: Version 5.4-arduino, compiled on Oct 11 2007 at 19:12:32
          Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/

          System wide configuration file is "C:\U\ArduinoIDE\hardware/tools/avr/etc/avrdude.conf"

          Using Port            : \\.\COM6
          Using Programmer      : stk500v1
          Overriding Baud Rate  : 115200
 avrdude: ser_open(): setting dtr
 avrdude: Send: 0 [30]   [20] 
 avrdude: Send: 0 [30]   [20] 
 avrdude: Send: 0 [30]   [20] 
 avrdude: Recv: 
 avrdude: Recv: 

Those first few lines, in white-colored text, are the output report of the compiler followed by the command line that invokes "avrdude", the program that actually does the communication with your Uno. Avrdude's output text is in red.

Do you see those three lines generated by avrdude that all read "Send: 0 [30] [20]"? That seems to be our target. They print out one after the other, with a slight time delay between them. As soon as you see the first of those three lines, you need to very quickly hit the reset button, during the gap between the first and second printings of that line. Alternately, if you're using a Sparkfun shifter like the one I'm using, you can watch the green "TX" LED; you see a quick flash, a pause, then another quick flash. As soon as you see that second flash, that's when you need to hit the reset.

Rather than using my fingertip, I found it helpful to use a pen with a bit of a dimple at one end to press the button. (I can't say for sure that it let me hit the button faster, but it feels faster!) But you've got to be quick; a nice short tap, holding the button down for as short a time as you can manage and still make contact, seems to do the job. With a little practice, I was getting better than a 50% success rate. With further practice, I may be able to improve that. Ultimately, I'd like to see if I can somehow filter the reset signal or add a timer chip to it to get the right timing automatically.

The thought occurred to me to try this trick while the Uno is plugged into the USB port and using Windows 2000's original driver. It seemed to work, up to a point. The upload would start, but then it would hang up somewhere in the middle. Apparently there's still something in that faulty version of usbser.sys that's causing a problem. I've not yet had time to try this with the new XP version of the driver, but that would seem to be largely irrelevant; if you've got the XP driver, just install it as described above in Option 2 and use it.

In summary, if you're not able to get a copy of the newer XP version of the driver, at least there IS a way to load a sketch into an off-the-shelf Uno by using the COM1 port and conditioning the high-voltage RS232 signals through a shifter board.


Option 4: Try a Different USB Interface

I've not yet tried this method yet. It seems to me that one might be able to use a USB interface based on the FTDI chip to generate the uninverted TTL-level RS232 signals and then apply the technique described above in Option 3 (with the simplification that the FTDI unit supplies the DTR signal). It might be that the DTR signal generated this way might have the right timing to work with non-Optiboot chips. I'll let you know if I try it out.

UPDATE Sept 6, 2011: I tried using a cheap USB-to-RS232 interface I bought at a local computer store, running the output through my modified Sparkfun shifter board. It didn't work by itself. It did, however, work if used in conjunction with the reset button trick I describe in the Sept 6, 2011 update to Option 3.


Option 5: Use an In-System Programmer

I've not tried this method yet either. Whether or not it works will likely be controlled by the Win2k compatibility of the drivers provided by the device's manufacturer. Check before buying! If I find one that works, I'll post the info here and a detailed description of what I did, both for loading the Optiboot boot loader into the chip and uploading sketches.


Hopefully, at least one of the methods I've described above for getting around the Windows 2000 USB driver incompatibility issue will help you to get your Uno to load correctly. If you have feedback about this article or other tricks you wish to suggest, please send it to adamsm1@fuse.net.

Good luck!

DISCLAIMER: I believe the information I present here is factual and accurate, and I'll correct any mistakes as promptly as I can. But computers are complicated gadgets with a lot of things that can go wrong, even if you know what you're doing. Ask any technician: If you tinker around with your computer long enough, eventually you will screw something up. It's virtually a law of nature. If you damage your host computer, it's software, your Arduino, your fingernails, or your significant other's plans for the evening in following the information I present here, feel free to blame it on the gods, but I deny any and all responsibility for any inconvenience, damages, or stiff necks caused by being forced to sleep on the couch.

Article posted Sept 5, 2011


Share