Wednesday, September 11, 2013

Fun with USB

So I wanted to get rid of the USB-MIDI cable needed to run my Tesla coils and save 5 bucks...

Actually, I wanted to save as much as possible, and keep things through-hole. Fortunately, there exists a library called V-USB that implements a software USB stack on Atmel microcontrollers.

As usual, it starts with a board. Fortunately the actual hardware design was pretty trivial - the board consists of an ATTiny85, a micro-USB jack (mini-USB is so 2005), an output connector, and a couple of passives. The design is mostly based on this fellow's work here. I didn't want the diodes dropping the voltage down to 3.6V, so I left them out in the initial design. The boards were sent out to OSH Park since I was feeling cheap and didn't want to send out for a $100 Myro order, and a couple weeks later I had them on hand.

After putting a board together and plugging it in, I was immediately greeted with a very warm, very sad microcontroller. Hmmm...
So it turned out I had entered the micro-USB jack backwards into Eagle...sadly the fix was not as simple as making a reversed cable since D- had been connected to NC on the board, and naturally, NC was not connected in the cable.
After some fiddling around, I gave up and soldered a cable to the bottom of the board.
Next up was putting some firmware on the board. I flashed this demo using Atmel studio, upon which Windows angrily told me that the USB device had failed. Turns out those diodes were necessary.
A couple of 1N4007's later (the next revision of the board clamps D+ and D- with 3.3V zeners), I had a device which properly identified itself as a MIDI device. I felt extremely accomplished until I realized my MIDI device did absolutely nothing. So ended the first day's work.

The next day...
The next step was compiling the source provided in the demo. Sadly this was easier said than done. For starters, Atmel studio threw a bunch of syntax errors trying to compile V-USB in its stock state. Inserting 'const' into the appropriate places remedied that, and produced output that was neither the same size as the original binary, nor functional.
Next up was Eclipse, which didn't throw syntax errors, but produced similarly dysfunctional binaries.
Finally, I gave up and switched to a Makefile and Vim. This still didn't work, until I realized that V-USB depended on having an accurate value defined for F_CPU (which in this case is 16500000). At this point I was able to compile the demo file, flash it, and have the device show up as a MIDI device that did nothing.

Next: implement MIDI handling. Fortunately, USB-MIDI is not as complex as normal MIDI (for one thing, there is no running status). This document describes the packet structure nicely. A dozen lines of code and an ISR later, I had the board buzzing at 400Hz on every note.

From here it was presumably a matter of calculating 220*2^((n-57)/12) for each note received and setting some prescalers, right? Nope, including math.h to get a pow() function caused the microcontroller to run out of memory. The workaround was to precompute 2^((n-57)/12) for n=36, 37,...,47 and then use the fact that f(n+12)=2*f(n) to find the actual frequencies (so this way our LUT is only 12 entries instead of 128 entries long).

Finally I had the thing producing different tones. Unfortunately they were the wrong tones, and even more alarmingly, the interrupter would sometimes cause Windows to crash. The latter was attributed to the blocking nature of my ISR (adding ISR_NOBLOCK fixed it), but the former was trickier to track down.
After finally pulling out the scope (scopes are better test equipment than ears!) I realized all of my on-times were 600uS, which threw off the frequencies of the high notes pretty spectacularly. It turns out that _delay_us() and _delay_ms() only take constant values as arguments, so I switched to _delay_loop_2() and it worked just fine.

The last bits to implement were master volume control (control change 0x07) for power control, limiting the notes played to channel 1, and STOP messages (which are harder to implement than you'd think; there are six ways to stop a MIDI track and it's easy to forget one...). The results are still a bit too unstable to post (I need to work out some host-side issues involving driver installation) but at this point I'm pretty sure I have (what might be the first?) direct-USB interrupter. It's not really good for DRSSTC use (for one thing it's copper out, not fiber out) and is pretty limited in what it can do (no hardware knobs, only one note at a time though this might change tomorrow) but it's dirt cheap (the total cost of hardware is something like $3) and should work acceptably for a small SSTC.

Speaking of which...well, hopefully that project will come together in the next day or two.

Tuesday, August 6, 2013

So I found this camera on eBay...

A thousand FPS of goodness
A Redlake MotionXtra HG-SE, to be precise. This camera does 1280x1024 24-bit color at 500FPS, and doubles in framerate every time the vertical resolution is halved, up to 32000FPS at 1280x16. It records to 1.3GB of internal SDRAM, giving 2 seconds of record time. While this may seem low, 2 seconds of footage at 500FPS translates into nearly a minute at 24FPS, and most fast events don't take all that long to happen anyway.

I'm pretty sure (though not certain) that the camera uses a Photobit PB-MV13 as its image sensor (the same sensor is found in cameras such as the Weisscam HS-1) and was made by AOS. The camera is identical to the AOS VITCam, and in fact, Redlake Imaging Studio is a rebranded version of AOS Imaging Studio.

The first step was to find a reasonable control computer for the camera. Unfortunately, the drivers were never updated for Windows 7, which means the control machine has to be a dedicated Windows XP system. Furthermore, most ExpressCard/PCMCIA Firewire adapters don't have 12V power lines, which means the the camera needed to be tethered to an external adapter as well.
Fortunately, it turns out that Apple was obsessed with Firewire until recent years, so the first generation (2006) Macbooks have full-sized Firewire ports, complete with 12V power. Plus, they were x86 (Core/Core 2 Duo), so they run Windows XP quite nicely.

The trickiest part of using this camera is lighting. At 500FPS, the camera is constrained to shutter speeds of 1/500 or faster. Furthermore, the 2005-era CMOS sensor it uses doesn't have the greatest sensitivity, and there is no option to turn up the sensor gain.
Initial tests with room lighting proved to be a dismal failure. I switched to a 300W halogen bulb, which at least gave usable results:

Sadly, the sensor really wants high color-temperature (bluer) lighting, so there was no way to make the image look decent with a halogen.
Fortunately, the home hydroponics market has spawned a bunch of semi-legit electronic metal halide ballasts. These are functionally equivalent to what the film industry calls "HMI" lights, and are good for around 25000 lumens at a color temperature of 5000K.
In addition, the camera is natively a C-mount camera. Unfortunately, most C-mount lenses don't go above 16mm format, which means the edges of the image degrade in quality. The solution to this is to use SLR lenses and an adapter; I'm a Nikon guy, so I chose F-mount as my mount of choice. Nikon F also happens to have the most lenses out of any mount (since the mount has not changed since the early 60's!)
Because the camera uses a sensor with a diagonal of 20mm, and not a full-frame 35mm sensor, the crop factor is approximately 2. This means that a 50mm normal lens behaves like a 100mm telephoto, and a 24mm wide-angle behaves like a normal lens.
Putting the metal halide lighting, a 50mm f/1.8 Nikkor lens, and some Jello together gave the following video:

If you look closely at the video, you'll notice numerous color and motion artifacts. These are not actual camera artifacts, but rather a consequence of the shitty early-90's AVI codec Imaging Studio uses. The solution was to export the frames as uncompressed BMP's first, then use FFMPEG to convert the sequence of BMP's into a high-quality video.
At this point, I also discovered that by default, Imaging Studio does not apply gamma correction, leading to some washed-out looking images. Applying a gamma of 1.5 and turning up the contrast resulted in much prettier, contrastier videos:

This past weekend, we (oneTesla) was at MuseCon in Chicago. One of the featured shows was Masters of Lightning (Terry Blake and Jeff Larson, with a pair of 12KW DRSSTC's). The sparks from the big coils were just bright enough to show up decently on the camera.


1000FPS (quick 'n dirty export with pretty bad artifacting):

Jeff also brought his wire exploder, so we filmed that as well. Both videos at 1000FPS.

The exploding wire produces some interesting stills: