Every programmer worth his salt has written a raytracer of some sort. It’s one of the classic “recursion exercises”, with a fair amount of math to wrap your head around. I’m not interested in writing one to run on the PC – there are already far more capable ones that can run on pretty much any hardware, complete with optimizations and features I couldn’t hope to implement in my lifetime.
Instead, I decided to write a raytracer which targets the Atmega 328 microcontroller in my Arduino! In the end, I succeeded in banging one together that calculates ray-triangle intersection, and each triangle can have a material attached with ambient / diffuse / transparent / reflective values and an RGB color. The scene is compiled in with a .h file (stored in PROGMEM), and outputs a PPM image pixel-by-pixel over the serial port.
The same engine can be used on the PC with a few modifications, so I was able to benchmark the performance of the Arduino in comparison with a modern laptop. The “detailed scene” rendered a 640×640 image in 263 seconds on the laptop. The same scene, scaled to only 64×64, still took 4008.471 seconds… in other words, the PC outperformed the Arduino by a factor of ~1500.
I posted the code, and further write-up, on the Arduino.cc message board at this link: http://forum.arduino.cc/index.php?topic=281076.0. There are a lot of features that COULD be added here, but none that I actually intend to do. If I need a raytracer in the future, I’m just downloading POVRay : )
Previously I had run pfSense as my firewall / router on a discarded Celeron 700mhz machine, with a lot of spare NICs in the PCI slots. Browsing around the local Goodwill and I stumbled upon this Watchguard Firebox X500 for $10. Finally, real rackmount gear for my 2×4 server rack!
I’m sure whatever software comes on this thing is great and wonderful, but I didn’t even try to use it. First step if you have one of these – hop on over to the pfSense Firebox wiki page and do some research. Popped open the case, swapped in a 2gb CF card with the pfSense no-VGA embedded image, and set to configuring it. The most difficult part of all this was getting a USB to Serial cable that worked… and then a Null Modem cable… and then having to do the configuration in a virtualized Windows XP machine because there are no OSX drivers for the WCH341 chip in my cheap eBay usb-serial converter.
Now that it’s all set up I can easily access via ssh or http, so serial access isn’t as important. The hardware in this is just a 1.2ghz Celeron, with 10/100 Ethernet ports and some 256mb RAM. Obsolete, yes, but that red paint job never goes out of style.
Six or so years ago, I picked up a Wacom ArtPad II digitizer from Freecycle. It came with serial cable and power brick, but no pen. These devices aren’t like an iPad or whatever (which use a capacitative touchscreen) where you can use your finger or a cheap stylus. Wacom pens have built-in smarts to communicate with the tablet and relay pressure information, pen/eraser mode, button click, etc. Without the pen, it’s downright useless. A few eBay searches revealed that pens were crazy expensive to replace at the time. Into the spare bin it went.
Recently I had an interest in getting this working again. I did more research and found that Wacom pens are actually somewhat interchangeable – in this case I can use any “Penabled” pen on it, and it’ll probably work. The new Samsung Galaxy Note S tablet uses Wacom styluses and the replacements are cheap – $8 on eBay, so I ordered one. Holding the pen over the tablet causes the LED to switch from orange to green, which was good enough for me to figure it’s working.
New problem – I have no machines with a serial port any more, and even if I did, Wacom drivers don’t support serial tablets any more. The solution comes from the WaxBee project, which uses a Teensy 2.0 to sniff old-protocol tablet packets and re-encode them to emulate an Intuos2 (a modern USB tablet with driver support). Great! Ordered a Teensy and cracked open the tablet to set to work.
First, I knocked off the serial connector and voltage regulator (soldered across that instead), as the USB will provide the +5V needed to drive the tablet. Next step is removing the ADM202 TTL-to-RS232 chip, where things took a disastrous turn: my overeager Dremel application removed the chip as well as the pads it sat on, and gouged out some of the PCB to boot. Crud, now I have to follow traces to figure out where it was supposed to go. Took a couple high res photos and gave up for the night. (If you need more info – circuit board photos, etc – check out this series of posts: http://forum.bongofish.co.uk/index.php?topic=2088.msg20757#msg20757)
The actual solution turned out not so bad: had to lift three pins on the Motorola chip and solder those to the Teensy. The hid_debug tool from pjrc (and associated WaxBee firmware) was invaluable in figuring out when I had the wires going the right way. Once that was done, superglue secured the wires and electrical tape held the Teensy. I cut a chunk off the side of the enclosure for the USB micro-port to fit, and drilled a hole for the Teensy button if I ever need to reprogram it. Covered with electrical tape, plugged it, and miraculously it all worked!
Here is a project I’d been talking about for years, but never actually pulled it off until recently. It’s a voice set for a Garmin GPS, which replaces the default “narrator” with the obnoxious announcer from Crazy Taxi. All voice clips were pulled from the PC version of the game, which had them in convenient .wav format already. Some trim / normalize with Audacity and import into Garmin Voice Studio to assemble together. I wanted to do more than just the announcer, but didn’t have any luck with that… there just weren’t enough clips to make it happen.
cfg_parse, that tiny config parser I wrote a few months back, has now been moved to Sourceforge. I also took the time to make some Doxygen comments and generate a manual for it. No major bugs were found but a couple minor tweaks help tighten up the release.
The easiest, easiest way to use this is to add it as a subversion externals for your project – that way it will automatically get checked out with the rest of your code, and you can build it right in! The syntax would be something like… svn:externals svn://svn.code.sf.net/p/cfg-parse/code/trunk cfg_parse .