With a little research and some USB tracing, I wrote a Windows program — and an Android app — that turns my Fretlight guitar into a BCD mode binary clock!
(Update: I now also have a Raspberry Pi version.)
What Is a Fretlight Guitar?
A Fretlight guitar is a teaching aid for guitarists. It has LEDs embedded in the fretboard. The LEDs are controlled by software on a computer, which is connected to the guitar through a USB cable. The software lights the LEDs to show scales, chords, and songs. Check out this demo if you want to learn more about it.
Why Did I Turn It Into a Binary Clock?
I wanted to know the guitar’s API because I thought it would be cool to control it (not that I knew what I wanted to do with it). When searching I found demos of unconventional uses of the Fretlight: the LED Fretboard Light Show and Conway’s Game of Life on FretLight Guitar. I immediately thought of a binary clock, realizing the six columns of LEDs were a perfect match.
Researching The Fretlight Interface
Optek Music Systems has a Fretlight SDK that’s available by application, but I found open source software that implemented interfaces: Fretlight Animator (the code behind “Conway’s Game of Life”) and TuxGuitar Light Plugin. Fretlight Animator is written in C#, but I wanted something in C++. Nonetheless, the code was well documented, so I had all that I needed to write my own implementation. TuxGuitar Light Plugin, written in Java, was also a good reference, confirming what I learned from Fretlight Animator.
To verify everything, I decided to “sniff” the USB traffic to my guitar. I wrote a “song” in Guitar Pro 6 to play all 132 notes on the guitar in sequence; here is a screenshot of the first few lines:
(If you are not familiar with guitar tablature, the lines correspond to the six guitar strings, with the thick string at the bottom and thin string at the top. The numbers are the frets, with fret 0 meaning the open string.)
The USB traffic confirmed what was encoded in Fretlight Animator and TuxGuitar.
The Fretlight Interface
The Fretlight is a simple USB HID. The host controls the status of the LEDs by sending reports to the guitar’s interrupt OUT endpoint. Each report is 8 bytes, with a one-byte report ID (0) and a 7-byte packet. Each packet contains a one-byte packet ID and 6 bytes of LED data. Each LED is specified by one bit: a 1 turns the LED on, and a 0 turns the LED off. With 48 bits per packet, you need three packets to specify the status of all 132 LEDs.
Packet ID 1 controls the LEDs in frets 0 through 7, packet ID 2 controls the LEDs in frets 8 through 15, and packet ID 3 controls the LEDs in frets 16 through 21. Each bit in each packet corresponds to a unique combination of fret and string. Fret numbers range from 0-21, and string numbers range from 1-6, with 1 being the high E (thinnest string). Here is the layout of the LEDs, with ‘f’ standing for fret, and ‘s’ standing for string:
Byte | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
---|---|---|---|---|---|---|---|---|
0 | f6s5 | f6s6 | f7s1 | f7s2 | f7s3 | f7s4 | f7s5 | f7s6 |
1 | f5s3 | f5s4 | f5s5 | f5s6 | f6s1 | f6s2 | f6s3 | f6s4 |
2 | f4s1 | f4s2 | f4s3 | f4s4 | f4s5 | f4s6 | f5s1 | f5s2 |
3 | f2s5 | f2s6 | f3s1 | f3s2 | f3s3 | f3s4 | f3s5 | f3s6 |
4 | f1s3 | f1s4 | f1s5 | f1s6 | f2s1 | f2s2 | f2s3 | f2s4 |
5 | f0s1 | f0s2 | f0s3 | f0s4 | f0s5 | f0s6 | f1s1 | f1s2 |
6 | (0x01) |
Byte | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
---|---|---|---|---|---|---|---|---|
0 | f14s5 | f14s6 | f15s1 | f15s2 | f15s3 | f15s4 | f15s5 | f15s6 |
1 | f13s3 | f13s4 | f13s5 | f13s6 | f14s1 | f14s2 | f14s3 | f14s4 |
2 | f12s1 | f12s2 | f12s3 | f12s4 | f12s5 | f12s6 | f13s1 | f13s2 |
3 | f10s5 | f10s6 | f11s1 | f11s2 | f11s3 | f11s4 | f11s5 | f11s6 |
4 | f9s3 | f9s4 | f9s5 | f9s6 | f10s1 | f10s2 | f10s3 | f10s4 |
5 | f8s1 | f8s2 | f8s3 | f8s4 | f8s5 | f8s6 | f9s1 | f9s2 |
6 | (0x02) |
Byte | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
---|---|---|---|---|---|---|---|---|
0 | xxxxx | xxxxx | xxxxx | xxxxx | xxxxx | xxxxx | xxxxx | xxxxx |
1 | f21s3 | f21s4 | f21s5 | f21s6 | xxxxx | xxxxx | xxxxx | xxxxx |
2 | f20s1 | f20s2 | f20s3 | f20s4 | f20s5 | f20s6 | f21s1 | f21s2 |
3 | f18s5 | f18s6 | f19s1 | f19s2 | f19s3 | f19s4 | f19s5 | f19s6 |
4 | f17s3 | f17s4 | f17s5 | f17s6 | f18s1 | f18s2 | f18s3 | f18s4 |
5 | f16s1 | f16s2 | f16s3 | f16s4 | f16s5 | f16s6 | f17s1 | f17s2 |
6 | (0x03) |
(The unused bits in packet ID 3 are marked with ‘x’s.)
Overview of My Windows Code
I wrote my program in Visual C++ (Visual Studio 2013). I used hidapi as my USB API because it was extremely simple (I turned to it after trying to wade through Microsoft’s HID examples.) I created a project, included files hidapi.h and hid.c, and changed a few compile and link options.
I used calls hid_init(), hid_open(), hid_write(), hid_close(), and hid_exit(). I used hid_open() to open the Fretlight HID, using its vendor ID (0x0925) and product ID (0x2000). (I don’t know why the vendor ID is 0x0925 — that is assigned to Lakeview Research!). I used hid_write() to send packets to the guitar (hid_write() automatically knew to send to the guitar’s interrupt OUT endpoint).
I initialized local variables to represent the current time on my computer, and then set a one second timer. Each time the timer popped I incremented the time, created the packet (packet ID 3), and sent it to the guitar. I used 19 LEDs: f21s6, f18s5, f19s5, f20s5, f21s5, f19s4, f20s4, f21s4, f18s3, f19s3, f20s3, f21s3, f19s2, f20s2, f21s2, f18s1, f19s1, f20s1, and f21s1.
I picked those frets for several reasons:
- The LEDs are spaced about as closely as on my real binary clock.
- The clock is easier to read being up against the last fret (there can’t be any hidden “off” LEDs below it).
- The LEDs are all in the same packet.
I only implemented BCD mode, and only for 12-hour time.
Overview of My Android Code
After writing and debugging my Windows program I wrote an equivalent Android app to run the Fretlight as a binary clock. I wrote it in Java, using Android Studio. I used the Android USB Host API, classes UsbManager, UsbDevice, UsbInterface, UsbEndpoint, and UsbDeviceConnection. I used the bulkTransfer() method of the UsbDeviceConnection class to send HID packets to the guitar. (I modeled my USB code on the USB HID Terminal app.)
To use an Android device as a USB host, it must support USB OTG; this support is in Android 3.1 and higher. You also need a female USB to male micro USB adapter to connect the Fretlight cable to the device. When writing the app, I enabled wireless debugging, since the device’s USB slot was connected to the guitar.
On Reflective Fret Markers
The Fretlight has reflective, circular, LED-sized fret markers, which is a poor design; sometimes they look like a lit LED! See how that plays out in my binary clock by watching the last few seconds of my video (watch when the time turns 10:30:00).
Update 12/2/14: Added section describing my Android app.
Great Job Rick! Very unique….
Keep Rockin’
Rusty Shaffer
Inventor of the Fretlight Guitar