February 28, 2012

Arduino Uno serial port

I finally bought an "original" Arduino Uno. It costs far more than the Arduino Mega local clone that I've been using, but the main reason is because I want to see how the ATmega16U2's COM port emulation works in Windows. (I have the Uno R3, older revisions of the Uno has the ATmega8U2.) Of course, I want to support the Arduino project.

Older Arduino's and most of the Arduino clones use the FTDI FT232R chip for the USB UART. FT232R works great with Windows, and has the ability to change COM ports, which is really important for supporting older programs that have fixed COM ports. In fact, after discovering how good the FT232R works from using my Arduino Mega clone, I started buying USB to RS232 adapters that use this chipset, and they work with everything I've thrown at them, including DOS applications running in Windows.

One feature the FT232R chip has is that if the COM port is fixed to a particular adapter or Arduino board, Windows will remember the setting and it will continue to be that COM port, unless manually changed. This is important if I have multiple serial port devices all connected to the same computer. They all remember what COM ports they're supposed to be, and everything just works.

You might think this is the standard USB behavior for Windows, but NOOOOOOOO. Recently we got some industrial barcode printers from Argox. While they're decent barcode printers, whoever designed the idiotic USB interface needs to have infinite barcode printers stuffed up their behinds. The problem is that every single Argox printer looks like the same printer to Windows. So whichever printer I turn on first is always "Printer 1". This might be fine for people with just one printer, but I need to have multiple different sized labels printed simultaneously. So my users have to remember to always turn on their printers in a particular order.


Anyway, I discovered both the FTDI driver and the standard Windows driver lets you change the COM ports without any limitation. But the FTDI has an additional option that's really useful: the ability to disable the serial port enumerator. The serial port enumerator is a left-over thing from when mice were plugged into the serial port. If Windows sees incoming data over the serial port when booting up or configuring hardware devices, it will automatically configure the serial port device as a mouse. This is problematic if you have an Arduino or other serial port device connected, and your mouse pointer goes crazy, this is what's happening.


Unfortunately, Arduino Uno's ATmega16U2 emulates a standard COM port so perfectly, it still uses Windows' own driver. Fortunately, the ability to change the COM port number is still there, but sadly there's no built-in way to disable the serial port enumerator.

Before Windows 7, Microsoft had a COMDisable Tool that does the job. With Windows 7, it looks like you're outta luck. Either go back to Windows XP, or use an FTDI based adapter with the serial port enumerator disabling option. But wait, what about the Arduino Uno? Well, don't let it send data over the serial port in a mouse-like manner, and all should be fine.

... Speaking of serial port mouse. You think Apple invented shiny white products? Nope, Microsoft did with the 9-pin serial mouse, also known as the soap mouse at the time. It was shiny and white, and five minutes after you start using it it's covered with fingerprints and scratches, and people loved it. I had one and I hated it.

Image courtesy: The MCA Mafia

February 22, 2012

Arduino Mega Optiboot

I wrote a little sketch on my Arduino Mega clone coupled with an Ethernet Shield clone to reboot my remote desktop servers in case they lockup. The question is, what monitors the monitor? Of course, being a microcontroller, I figured the AVR surely must have some kind of watchdog function to reboot itself.

Unfortunately, the watchdog function didn't seem to work correctly. I simulated lockup conditions by using a long delay(). The watchdog happily triggered a reboot, but then the Mega gets into some kind of infinite reboot loop that could only be exited by uploading another sketch. (Just pressing reset or power recycle didn't work.) Upon further research, I discovered the watchdog doesn't function correctly on the Arduino Mega. The fix apparently is either to use Optiboot, or use a bootloader that has this bug fixed.

Optiboot comes by default for the Arduino Uno, and is actually available for the Arduino Mega, it's just not distributed in the Arduino IDE by default. I could either compile it by myself, or download it from the Optiboot repository. I would need to use an AVR programmer to flash the bootloader. Fortunately, my Arduino clone, the ET-EASY MEGA1280 is self-programmable by setting onboard jumpers.

So I flashed the Optiboot bootloader onto my Arduino Mega. But after the flashing was completed I discovered I could no longer upload sketches to it. It didn't feel completely "bricked" though, as I could re-flash the regular bootloader back to it and it worked again, but with Optiboot loaded, it didn't accept sketches any more. It kept giving me this error: sync avrdude: stk500_getsync(): not in sync: resp=0x00

It occured to me that because the board now contains Optiboot, I should be uploading at 115,200 kbps, and I should probably choose Uno as the board type. This is similar to how older boards such as the Arduino Duemilanove, when upgraded with Optiboot, effectively become the Uno and should be treated as an Uno in the Arduino IDE.

So I tried choosing Arduino Uno from the board type menu. It now complained that I don't actually have an Arduino Uno or a board based on the ATmega328P. The exact error was: avrdude: Expected signature for ATMEGA328P is 1E 95 0F  Double check chip, or use -F to override this check. I probably shouldn't override the check, since my ATmega1280 chip has much larger flash space, so I should probably just edit boards.txt instead.

Modifying the Arduino Mega section in boards.txt and changing the mega.upload.speed to 115200 fixed the upload problem. Even though Optiboot takes less space, I didn't modify the mega.upload.maximum_size value since I had no idea how much flash space Optiboot saved and what the maximum value should be, and 128K is enough for everyone. But since I have both regular Arduino Mega and Mega with the Optiboot, I decided to create a new section called Arduino Mega Uno.

The only issue I have with Optiboot is that once in a while, after upoading sketches or after plugging in the USB cable for USB power, the board doesn't start itself correctly. I need to push the reset button to run the sketch. The problem seems to be related to the serial port, since if I disable auto-reset (I have a jumper for that too.) it always works correctly. It also always starts correctly if I power up using an external power supply. Strangely enough, it seems to always start correctly too if I have shields installed, but I haven't tested this completely.

And yes, after installing Optiboot, watchdog works correctly now.

Edit: I noticed that the Optiboot repository actually contains a special boards.txt for Optiboot. However, the entry for Arduino Mega isn't quite correct, but it does contain a different maximum_size value. This is what I eventually put into my boards.txt.

megao.name=Arduino Mega Optiboot
megao.upload.protocol=arduino
megao.upload.maximum_size=130048
megao.upload.speed=115200
megao.bootloader.low_fuses=0xff
megao.bootloader.high_fuses=0xda
megao.bootloader.extended_fuses=0xf5
megao.bootloader.path=optiboot
megao.bootloader.file=optiboot_atmega1280.hex
megao.bootloader.unlock_bits=0x3F
megao.bootloader.lock_bits=0x0F
megao.build.mcu=atmega1280
megao.build.f_cpu=16000000L
megao.build.core=arduino
megao.build.variant=mega