Friday, August 23, 2013

Enabling USB on Arduino MIDI Keyboard

Considering all modern MIDI controllers have ability to communicate via USB you might think it will be quite nice to connect MIDI keyboard we built directly to USB port on your PC? That’s exactly what we are going to do. Below are the end-to-end steps I took to make it work. It might help someone? May be you?

This instructions were tested on Arduino UNO and should work with Arduino MEGA (not tested, please let me know if you managed to make it work?)
  
To achieve this we are going to use HIDUINO firmware that makes Arduino UNO board to appear as USB HID (MIDI) device.


The important thing to understand is that Arduino has two chipsets ATMEGA8u2 (or 16u2) and main chipset ATMEGA328 (or ATMEGA2560 in case of Arduino MEGA). Purpose of ATMEGA8u2 is to bridge communication between USB port and ATMEGA328. Originally it appears as USB Com port device (or USB modem on the MAC) you might have noticed that while selecting Arduino as device on COM port in Arduino IDE. Flashing HIDUINO firmware on to ATMEGA8u2 will make it act as a USB Midi device. ATMEGA8u2 will effectively turn serial messages from ATMEGA328 chip to MIDI messages sent over USB.

Below are the hardware/software setup and actual steps you need to perform to program the Arduino.

ISP Programmer


One of the cheapest and tested ISP programmers is USBTinyISP available for about $15 from ebay or similar price on the net. There are other options but this one worked well for me…

If you are using MAC you do not have to install drivers - it should work right away.

If you using Win7 / XP there are drivers and resources on the net explaining how to install it. Personally I’ve installed it on Windows 8 and had to do couple of tweaks to make it work. Below is the guide that helped me. The catch with Windows 8 is that you have to installed unsigned drivers and Win8 does not quite like it…

Installing USBTinyISP (UNSIGNED) drivers on Windows 8:


Software


We will as well need a software that will allow ISP programmer to program the chipset. The one I’ve used was AVRDUDE.

Installing AVRDUDE programmer on MAC:
http://www.ladyada.net/learn/avr/setup-mac.html (suggested shortcut option AvrMacPack)


Installing AVRDUDE programmer software on Windows:



Test ISP and Arduino connectivity


Connect USBTinyISP to the Arduino. Please note there are two ISP headers you need to connect exactly to the one displayed below.



Here is the useful link on how to use the USBTinyISP programmer with AVRDUDE and on how to diagnose the connectivity: http://learn.adafruit.com/usbtinyisp/avrdude





Identify the chipset


You will need to take note of the chipset installed on Arduino Uno board as steps/firmware will vary based on the version of the chipset used by the board. As wording on the chipset is quite small the best way to read it is to take a picture. Phone camera worked well… After you took the photo zoom in and it should be clear enough to read (wow I just realised my phone has 8 megapixel camera!).

Below are examples of the chipsets found on two similar boards.

Below is MEGA8U2:



And below is MEGA16U2:







Download the HIDUINO firmware


HIDUINO firmware available from below link:

Access following folder at above location:

HIDUINO/Compiled firmwares/HIDUINO_MIDI.hex

HIDUINO MIDI.hex should work on both 8u2 and 16u2 chipsets.





Program the MIDI Keyboard sketch


Sketches cannot be bootloaded onto an Arduino while a HIDUINO firmware is loaded on the 8u2. That’s why you will have to program the MIDI Keyboard sketch before programming the HIDUINO firmware.

Usually you will have to switch between the default usbserial and HIDUINO firmwares regularly during development in order to program modified sketch onto Arduino. Further we will see how to revert back to original firmware.

 

Programm HIDUINO Firmware


Programming part is quite easy. All you need to do is to make sure you have firmware located in the folder you executing the avrdude from, arduino is connected to ISP and execute below command. While command executed you will observe similar output to what I got during successful programming of my device:

C:\>avrdude -p at90usb82 -F -P usb -c usbtiny -U flash:w:HIDUINO_MIDI.hex -U lfuse:w:0xFF:m -U hfuse:w:0xD9:m -U efuse:w:0xF4:m -U lock:w:0x0F:m

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.02s

avrdude: Device signature = 0x1e9389
avrdude: Expected signature for AT90USB82 is 1E 93 82
avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed

         To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "HIDUINO_MIDI.hex"
avrdude: input file HIDUINO_MIDI.hex auto detected as Intel Hex
avrdude: writing flash (3320 bytes):

Writing | ################################################## | 100% 5.48s



avrdude: 3320 bytes of flash written
avrdude: verifying flash memory against HIDUINO_MIDI.hex:
avrdude: load data flash data from input file HIDUINO_MIDI.hex:
avrdude: input file HIDUINO_MIDI.hex auto detected as Intel Hex
avrdude: input file HIDUINO_MIDI.hex contains 3320 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 3.58s



avrdude: verifying ...
avrdude: 3320 bytes of flash verified
avrdude: reading input file "0xFF"
avrdude: writing lfuse (1 bytes):

Writing | ################################################## | 100% 0.01s

avrdude: 1 bytes of lfuse written
avrdude: verifying lfuse memory against 0xFF:
avrdude: load data lfuse data from input file 0xFF:
avrdude: input file 0xFF contains 1 bytes
avrdude: reading on-chip lfuse data:

Reading | ################################################## | 100% 0.01s

avrdude: verifying ...
avrdude: 1 bytes of lfuse verified
avrdude: reading input file "0xD9"
avrdude: writing hfuse (1 bytes):

Writing | ################################################## | 100% 0.01s

avrdude: 1 bytes of hfuse written
avrdude: verifying hfuse memory against 0xD9:
avrdude: load data hfuse data from input file 0xD9:
avrdude: input file 0xD9 contains 1 bytes
avrdude: reading on-chip hfuse data:

Reading | ################################################## | 100% 0.01s

avrdude: verifying ...
avrdude: 1 bytes of hfuse verified
avrdude: reading input file "0xF4"
avrdude: writing efuse (1 bytes):

Writing | ################################################## | 100% 0.01s

avrdude: 1 bytes of efuse written
avrdude: verifying efuse memory against 0xF4:
avrdude: load data efuse data from input file 0xF4:
avrdude: input file 0xF4 contains 1 bytes
avrdude: reading on-chip efuse data:

Reading | ################################################## | 100% 0.01s

avrdude: verifying ...
avrdude: 1 bytes of efuse verified
avrdude: reading input file "0x0F"
avrdude: writing lock (1 bytes):

Writing | ################################################## | 100% 0.02s

avrdude: 1 bytes of lock written
avrdude: verifying lock memory against 0x0F:
avrdude: load data lock data from input file 0x0F:
avrdude: input file 0x0F contains 1 bytes
avrdude: reading on-chip lock data:

Reading | ################################################## | 100% 0.01s

avrdude: verifying ...
avrdude: 1 bytes of lock verified

avrdude: safemode: Fuses OK

avrdude done.  Thank you.



At this point you can disconnect USBTinyISP ribbon cable and connect USB directly to Arduion board. The device should appear as new USB MIDI device on your computer. All you favourite Musical software should recognize the device as HIDUINO midi. Yay! :) 

Going back to original firmware


If you would like to get back original firmware (could be in order to program new sketch on Arduino) you can program original usbserial firmware by following below steps.

You should be able to find original firmware from Arduino IDE folder: arduino-1.0.5\hardware\arduino\firmwares\atmegaxxu2\UNO-dfu_and_usbserial_combined.hex

Below is the command that you will need to execute and example of the successful on the console.

Please note for 16u2 you will need to use following firmware: Arduino-COMBINED-dfu-usbserial-atmega16u2-Uno-Rev3.hex available from the Arduino IDE folder the command will change to reflect the firmware:

avrdude -p at90usb82 -F -P usb -c usbtiny -U flash:w: Arduino-COMBINED-dfu-usbserial-atmega16u2-Uno-Rev3.hex -U lfuse:w:0xFF:m -U hfuse:w:0xD9:m -U efuse:w:0xF4:m -U lock:w:0x0F:m


Below is command used for 8u2 chipset:

C:\>avrdude -p at90usb82 -F -P usb -c usbtiny -U flash:w:UNO-dfu_and_usbserial_combined.hex -U lfuse:w:0xFF:m -U hfuse:w:0xD9:m -U efuse:w:0xF4:m -U lock:w:0x0F:m

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.01s

avrdude: Device signature = 0x1e9389
avrdude: Expected signature for AT90USB82 is 1E 93 82
avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed

         To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "UNO-dfu_and_usbserial_combined.hex"
avrdude: input file UNO-dfu_and_usbserial_combined.hex auto detected as Intel He
x
avrdude: writing flash (7440 bytes):

Writing | ################################################## | 100% 12.23s



avrdude: 7440 bytes of flash written
avrdude: verifying flash memory against UNO-dfu_and_usbserial_combined.hex:
avrdude: load data flash data from input file UNO-dfu_and_usbserial_combined.hex
:
avrdude: input file UNO-dfu_and_usbserial_combined.hex auto detected as Intel He
x
avrdude: input file UNO-dfu_and_usbserial_combined.hex contains 7440 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 7.37s



avrdude: verifying ...
avrdude: 7440 bytes of flash verified
avrdude: reading input file "0xFF"
avrdude: writing lfuse (1 bytes):

Writing | ################################################## | 100% 0.01s

avrdude: 1 bytes of lfuse written
avrdude: verifying lfuse memory against 0xFF:
avrdude: load data lfuse data from input file 0xFF:
avrdude: input file 0xFF contains 1 bytes
avrdude: reading on-chip lfuse data:

Reading | ################################################## | 100% 0.01s

avrdude: verifying ...
avrdude: 1 bytes of lfuse verified
avrdude: reading input file "0xD9"
avrdude: writing hfuse (1 bytes):

Writing | ################################################## | 100% 0.01s

avrdude: 1 bytes of hfuse written
avrdude: verifying hfuse memory against 0xD9:
avrdude: load data hfuse data from input file 0xD9:
avrdude: input file 0xD9 contains 1 bytes
avrdude: reading on-chip hfuse data:

Reading | ################################################## | 100% 0.01s

avrdude: verifying ...
avrdude: 1 bytes of hfuse verified
avrdude: reading input file "0xF4"
avrdude: writing efuse (1 bytes):

Writing | ################################################## | 100% 0.01s

avrdude: 1 bytes of efuse written
avrdude: verifying efuse memory against 0xF4:
avrdude: load data efuse data from input file 0xF4:
avrdude: input file 0xF4 contains 1 bytes
avrdude: reading on-chip efuse data:

Reading | ################################################## | 100% 0.00s

avrdude: verifying ...
avrdude: 1 bytes of efuse verified
avrdude: reading input file "0x0F"
avrdude: writing lock (1 bytes):

Writing | ################################################## | 100% 0.01s

avrdude: 1 bytes of lock written
avrdude: verifying lock memory against 0x0F:
avrdude: load data lock data from input file 0x0F:
avrdude: input file 0x0F contains 1 bytes
avrdude: reading on-chip lock data:

Reading | ################################################## | 100% 0.00s

avrdude: verifying ...
avrdude: 1 bytes of lock verified

avrdude: safemode: Fuses OK

avrdude done.  Thank you.


At this point you should have original firmware back on Arduino and when connected to USB port Arduino will appear as COM device. You should be able to program the device from Arduino IDE again!

Thats all! Enjoy tinkering!... :)

2 comments:

  1. hi, thanks for this great tutorial. I have a a question, since we are flashing the ATMEGA8u2 chip we are no longer able to upload the sketches via the usb interface. So my question is: would it be posible to use the arduino ICSP to upload the sketches so that we don´t have to be flashing the ATMEGA8u2 everytime we update the sketch?

    ReplyDelete
  2. Anybody tried it with this ATmega328P CH340G UNO R3, this arduino is pretty cheap and I'm gonna try it anyway but if somebody has some feedback on this it'd be great. I'll post my findings.

    ReplyDelete