The blog of 2014-09-25T21:37:35+00:00http://t413.comTim O'Brientimo@t413.comUniversal SMS Conversion Tool2014-08-07T00:00:00+00:00http://t413.com/2014/08/sms-conversion<p>Edit: Now available in pip, just <code>pip install smstools</code>.</p>
<p>Working on a project at INQ Mobile I started this tool to convert downloaded
Google Voice messages to native Android smsmms.db sqlite databases. I was doing
local analytics and wanted a big real-world dataset. I built what I called
<em>Android-SMS-DB-importer</em> to import six years of SMS history from two iPhones,
Google Voice, and Android into one Android smsmms.db file. Since then I’ve expanded
the tool’s scope to be a universal SMS translator.</p>
<p>There are lots of real use cases for such a tool. Migrating from/to iPhone from/to
Android? Leaving Google Voice? Want a searchable CSV, JSON, or XML file of
your conversations? Also making a sweet SMS processing app and you want to
run on <em>all</em> your past texts at once? Want to move all your messages from your
past into a new, date-sorted, database? It should be ready to roll.</p>
<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><code class="language-bash" data-lang="bash">1
2</code></pre></div></td><td class="code"><div class="highlight"><pre>pip install smstools
smstools iphone.db androids.xml android.db out.csv
</pre></div>
</td></tr></table>
<p>Imported. Normalized. Sorted. Exported. Easy.</p>
<p>Go clone it at <a href="https://github.com/t413/SMS-Tools">github.com/t413/SMS-Tools</a></p>
<p>Convert your message history between:
- iOS 5, 6, and 7 databases directly (from backup or from your jailbroken phone directly)
- Android mmssms.db database (directly from phone)
- Android XML from the <a href="http://android.riteshsahu.com/apps/sms-backup-restore">SMS Backup & Restore</a> app
- CSV files
- JSON files
- google voice data dump (see more details below)</p>
Talk on Drones at the IFTF2014-07-29T00:00:00+00:00http://t413.com/2014/07/talk-at-itft<div class="icontain"><iframe src="//www.youtube.com/embed/WWPnZ4fqvYE" allowfullscreen=""></iframe></div>
<p>I gave this talk at the <a href="http://plustech.iftf.org/">Institute for the Future</a> back in January. It’s on drones / UAVs / sUAVs, their past and what they can do today. I gave a call-to-build to make these things yourself and understand the whole system.</p>
<p>Full link: <a href="http://youtu.be/WWPnZ4fqvYE">youtu.be/WWPnZ4fqvYE</a> – See the other talks at the <a href="http://plustech.iftf.org/?p=128">IFTF site</a>.</p>
Web Design2014-07-28T00:00:00+00:00http://t413.com/2014/07/web-design<p>Here’s a look at some old web projects I’ve built in the past. Some I’ve built for fun, some freelance, some for family.</p>
<hr />
<p><img src="/res/webdesign/t413v2.png" alt="t413.com" /></p>
<p>The second generation t413.com. Built 2010-2012. Made full use of html5 push/pop-state for a dynamic preloaded javascript experience with static fallback. Dynamic and interactive charts and plots of photo EXIF data to interact with over 30,000 images in real-time. Self designed, developed, and hosted.
<!--more--></p>
<p><a href="http://ncsu.edu/windhover/"><img src="/res/webdesign/windhover.png" alt="ncsu.edu/windhover" /></a></p>
<p><a href="http://ncsu.edu/windhover/">ncsu.edu/windhover</a>, designed for the award winning NC State Literary Magazine, Windhover in 2012.</p>
<p><a href="http://ncsu.edu/sma/"><img src="/res/webdesign/sma.png" alt="ncsu.edu/sma" /></a></p>
<p><a href="http://ncsu.edu/sma/">ncsu.edu/sma</a>, designed for NC State Student Media in 2010 (Site since changed).</p>
<p><a href="http://hammondcarpentry.com"><img src="/res/webdesign/hammond.png" alt="hammondcarpentry.com" /></a></p>
<p><a href="http://hammondcarpentry.com">HammondCarpentry.com</a>, designed for James Hammond of Virginia Beach in 2010.</p>
<p><a href="http://ncsu.edu/agromeck"><img src="/res/webdesign/agromeck.png" alt="ncsu.edu/agromeck" /></a></p>
<p><a href="http://ncsu.edu/agromeck">ncsu.edu/agromeck</a>, designed for NC State Student Media in 2009. (since changed)</p>
<p><a href="/res/webdesign/e115_project/"><img src="/res/webdesign/b-w.png" alt="b&w" /></a></p>
<p><a href="/res/webdesign/e115_project/">B&W photography</a>, designed for my e115 project in 2009. I went a little overboard on the design.</p>
<p><a href="http://wildhairlivingroomtour.com"><img src="/res/webdesign/wild-hair.png" alt="wildhairlivingroomtour.com" /></a></p>
<p><a href="http://wildhairlivingroomtour.com">WildHairLivingRoomTour.com</a>, designed for James Hammond of Virginia Beach.</p>
<p><a href="http://t413.com"><img src="/res/webdesign/t413.png" alt="t413.com" /></a></p>
<p>This site’s previous design, <a href="http://t413.com">t413.com</a>, created to share pictures. Started in 2006.</p>
Starting Over (this site)2014-07-27T00:00:00+00:00http://t413.com/2014/07/starting-over<p>My web site, t413.com, has been down for 6 months. It’s time I fixed it.</p>
<h4 id="what-happened">What happened?</h4>
<p>My server was a intel atom nettop running behind someone’s desk back in North Carolina.</p>
<p>They got a new desk.</p>
<p>My site went down.</p>
<p>My server disappeared.
<!--more--></p>
<h4 id="why-was-i-running-my-site-like-that">Why was I running my site like that?</h4>
<p>Lots of reasons. I was hosting several hundred gigabytes of photos which would have been
prohibitively expensive to host anywhere else. Running my own server was a great
teaching tool and challenge when I was in middle school and I kept the habit
all through college and beyond.</p>
<p>Now-adays I don’t want to pay for rack space for a personal gallery and deal with
the very very real problem of security on my own box. Github pages to the rescue!</p>
<h4 id="wheres-the-gallery">Where’s the gallery?</h4>
<p>Yeah yeah. There were tens of thousands of priceless images, carefully curated,
that told the story of my middle school, high school and college life. They
showed the world around me and highlighted communities I think are great. I put
years of work into developing the style, technology, and photography that went
into it.</p>
<p>Don’t worry, I’ve got a few backups. I’ll do something with them.</p>
<h4 id="whats-next">What’s next?</h4>
<p>Dunno. Haven’t written that far ye</p>
Senior Designing: Robot Arm Style2012-03-13T00:00:00+00:00http://t413.com/2012/03/senior-design-arm<p><img src="https://sites.google.com/a/ncsu.edu/robot-manipulator-arm/_/rsrc/1329116601555/home/arm.png?height=212&width=320" alt="Arm 3D view" />For my ECE senior design project I’m building a robotic arm for the NCSU <a href="http://www.ncsumarsrover.com/">Terrestrial Robotics Club</a> as they take on the <a href="http://urc.marssociety.org/">University Rover Challenge</a>. </p>
<p>Ever wanted a high-strength robotic arm that’s made entirely of 3D prtinted and laser-cut parts and off-the-shelf compodents and electronics? I have, and that’s why I’m building it with my group of 4.</p>
<p>I put together a <a href="https://sites.google.com/a/ncsu.edu/robot-manipulator-arm/home">google site page</a> to keep track of the project’s status and eventually host tutorials, APIs, and other documents you’ll need to build your own! Check it out.</p>
Flying at Dorathea2012-03-13T00:00:00+00:00http://t413.com/2012/03/flying-at-dorathea<p>The <a href="http://www4.ncsu.edu/~aimeriza/">NCSU Aerial Robotics team</a> went out to Dorothea to fly a few weekends ago, and RJ brought his 18 pound 88” wingspan 60cc Extra 300. Add my gopro, some handy ground footage, and a dubstep remix of ‘<a href="http://www.youtube.com/watch?v=KCnaF4KV0L4">fly like an eagle</a>’ and you get this:</p>
<div class="icontain"><iframe src="//www.youtube.com/embed/0ZyVA29MReI" allowfullscreen=""></iframe></div>
New video: slow motion quadcopter flying in EB22011-09-08T00:00:00+00:00http://t413.com/2011/09/new-video-slow-motion-quadcopter-flying-in-eb2<div class="icontain"><iframe src="//www.youtube.com/embed/9zeHYOXod58" allowfullscreen=""></iframe></div>
<p>This was taken on my friend Hardik’s Canon 60D. Music is from the band State Radio and the song: Wicker Plane.</p>
<p><a href="http://itunes.apple.com/us/album/year-of-the-crow/id395632644" title="http://itunes.apple.com/us/album/year-of-the-crow/id395632644">http://itunes.apple.com/us/album/year-of-the-crow/id395632644</a></p>
<p>I used ffmpeg extensively to get the 60fps video to slow-mo 30fps, then ffmpeg again to extract the audio to wav, then Sound Studio (mac app) to resample the audio to the same speed as the video. Next I used Sound Studio to splice, in rythem, the intro, solo, and final few seconds of ‘Wicker Plane’ together, then mix it together with the slow-mo sound of my quad and just imovie to put together the timeline of video.</p>
ARM7 mini quad with xbee remote2011-01-29T00:00:00+00:00http://t413.com/2011/01/arm7-mini-quad-with-xbee-remote<p>Also <a href="http://diydrones.com/profiles/blogs/arm7-mini-quad-with-xbee">take a look</a> at the DIY-drones post I made, (it made it to the front page!).</p>
<div class="icontain"><iframe src="//www.youtube.com/embed/Ng5cj4m8uaw" allowfullscreen=""></iframe></div>
<p>Using an Phillips NXP LPC20148 ARM7 processor, a Nintendo Wii motion+, and some xbees I’ve made a really stable platform for quads. (<a href="http://t413.com/news/rtos-quadcopter-flight-computer">mode details here</a>) It is running FreeRTOS which makes it very expandable in the future. My <a href="http://t413.com/photos_of_projects/#quad3_0-002_MG_4963_2010-12-20.jpg">old</a> frame flew great with it, but I wanted something smaller. Enter my new carbon fiber mini-quad:</p>
<!--more-->
<div class="icontain i4x3"><iframe class="imgur-album" src="//imgur.com/a/x7aOU/embed?background=f2f2f2&text=1a1a1a&link=4e76c9"></iframe></div>
<h3 id="props">Props</h3>
<p>My <a href="http://www.hobbyking.com/hobbyking/store/uh_viewItem.asp?idProduct=11313">props from hobbyking</a> were very unbalanced, but easily fixed with some electrical tape (Last photo in album)</p>
<h3 id="another-video">Another video</h3>
<p>This one is from last week.</p>
<div class="icontain"><iframe src="//www.youtube.com/embed/8gVc9dYw0vM" allowfullscreen=""></iframe></div>
Quadcopter: New photos and video2010-12-23T00:00:00+00:00http://t413.com/2010/12/quadcopter-new-photos-and-video<h3 id="video">Video:</h3>
<div class="icontain"><iframe src="//www.youtube.com/embed/F_cQSrAu5tw" allowfullscreen=""></iframe></div>
<h3 id="photos">Photos:</h3>
<div class="icontain i4x3"><iframe class="imgur-album" src="//imgur.com/a/NCGid/embed?background=f2f2f2&text=1a1a1a&link=4e76c9"></iframe></div>
RTOS quadcopter flight computer2010-12-21T00:00:00+00:00http://t413.com/2010/12/rtos-quadcopter-flight-computer<p>Update: <a href="https://github.com/t413/os_copter">firmware</a>, <a href="https://github.com/t413/remote_xbee">remote</a>,
and <a href="https://github.com/t413/ser_pkt">packet library</a> all now on github.</p>
<p><a href="http://imgur.com/gQg8QG5" style="float:right;width:50%;"><img src="http://i.imgur.com/gQg8QG5l.jpg" alt="" title="Flight controller detail shot. Hosted by imgur.com" /></a></p>
<p>The advent of the modern Chinese manufacturing empire has fueled an explosion of high performance, high quality, reliable, accessible, and low-cost hobby electronics like never before. That, coupled with technological advances, have made electric systems more than just an alternative to nitro fuel powered models. The technology improvements have also enabled, for the first time, hobby-level computer flight control systems and even autopilots. Many commercial and community projects have been developed to perform these tasks and out of them have come low-cost, electric powered, computer controlled planes, cars, conventional helicopters, and helicopters that defy convention. Copters with two, three, four, six, and even eight rotors have taken root in the community as a simple and effective way to lift large payloads, film smooth aerial video, and perform unbelievable acrobatics.</p>
<p>As part of a previous project I built a quadcopter with a laser-cut ABS plastic frame and modified version of the open source AeroQuad project. This semester I built my own open source flight software for quadcopters using the NXP LPC2148 ARM 7 processor on an FreeRTOS system. This allows the inherently unstable quadcopter to fly as a human controllable helicopter with only the addition of a wii motion plus as a gyroscope sensor for rotational acceleration.</p>
<p><a href="http://imgur.com/GOud01P"><img src="http://i.imgur.com/GOud01Pl.jpg" alt="" title="Quadcopter design wide shot. Hosted by imgur.com" /></a></p>
<ul>
<li>Technology breakdown</li>
<li>CPU: Phillips NXP LPC2148 ARM7</li>
<li>FreeRTOS, compiled with arm-elf-gcc</li>
<li>32-bit, 40kB RAM, 60Mh, 512kB Flash</li>
<li>Nintendo Wii Motion+ gyroscope, I<sup>2</sup>C</li>
<li>4xPWM PPM Brushless speed controllers</li>
<li>Packetized XBee communication</li>
<li>Accurate, 10bit remote with backlit LCD
<ul>
<li>Four level menu system</li>
</ul>
</li>
</ul>
<p><a href="http://imgur.com/xHCccO3"><img src="http://i.imgur.com/xHCccO3l.jpg" alt="" title="Remote control. Hosted by imgur.com" /></a></p>
<h3 id="background">Background</h3>
<p>I like remote controlled gadgets a lot. Moving beyond the 2d world of RC cars has long been my dream, but until last year it was just that: a dream. I designed and built a simple rover, controlled by a mint tin that you could simply tilt in the direction you wanted it to drive. After mastering a simple $40 mall-bought helicopter I wanted to move bigger. Rather than shell out several hundred dollars for a regular helicopter I decided to build an AeroQuad quadcopter using parts from hobbyking.com and sparkfun.com. I built my first frame, crashed a lot, and had many issues with my 15 year old FM radio controller. I designed a basic laser-cut acrylic remote and wrote modifications to fly it over a digital XBee connection. I then designed and built a laser-cut ABS plastic frame for the copter.</p>
<p>When I dealt with speed and reliability issues when sending ascii values over serial I decided to design a data packet transfer method similar to UDP. Upon arriving to SJSU I implemented although never finished testing a method for altitude control. I started the year with no idea for how the stabilization with PID control worked, specifically how any of the data busses were implemented, or how the sensor data was processed or used. In the course of this past year of reading, taking apart, fixing, and implementing my own features I’ve learned a great deal. I decided for my open-ended project for CMPE 146 that I’d design and implement my own flight computer program using the real-time operating system FreeRTOS.</p>
<!--more-->
<h3 id="overarching-design">Overarching Design</h3>
<h4 id="rtos">RTOS</h4>
<p>The use of a real-time operating system allows for many advantages in the future that aren’t possible with a timer/scheduling design. Independent tasks can run without inhibiting each-other and with prioritization that will allow things like stabilization and communication to run alongside data acquisition or guidance. The essential tasks for flying were stabilization and communication, and that’s where I started the design process.</p>
<h4 id="control-theory">Control Theory</h4>
<p>Quadcopter stabilization depends on quickly being able to update the motor speed to minimize or zero rotational acceleration. If we used the <em>rotation angle</em> it would be an unstable system; by the time the helicopter has changed position enough to register a proportional response it would be thrown back, past it’s correct location, and in the negative range. The helicopter would oscillate and crash, dramatic and unsuccessful. The rotational acceleration data is acquired by taking the derivative of the absolute tilt angles. To get tilt angles one must integrate the angular acceleration data provided by MEMS gyroscopes and compensate drift using accelerometer data. To simplify this process of integrating then differentiating the same data, I elected to use the gyroscope data directly. Using a fusion of the gyro, accelerometer, and magnetometer data to get a compensated and accurate absolute angle will provide a means of auto-balancing in the future, but for now I can use just the gyroscopes to get a stable and controllable helicopter I can fly.</p>
<h4 id="sensors">Sensors</h4>
<p>For sensors I had many options. For my first quadcopter I used sparkfun’s Razor 6dof board, but it’s analog sensors were not temperature compensated and when I tested them I found they took about an hour to become just marginally consistent. They also had a small ‘full-scale range’ which severely limited their accuracy and required an external analog-to-digital converter which left room for interference and bias. All of these shortcomings made my desire to move to an integrated digital sensor, and there are such sensors, soldered and ready to use, on the market for around $30-40. Instead of buying one of those I decided to use the Nintendo Wii Motion+ which had the advantage of being less than $20, readily available to consumers worldwide, and widely supported by the home-brew community online. The Wii Nunchuck attachment would provide accelerometers in the future.</p>
<h3 id="technology-breakdown">Technology breakdown</h3>
<h4 id="pwm">PWM</h4>
<p>To utilize off-the-shelf components was a major goal of mine. This allows for modularity and low-cost/high-cost options and fast innovation. To interface with brushless motors one must use exactly timed high-current three phase control signals. Easy to use, integrated speed controllers are widely available and all use the same interface: Pulse Position Modulation or PPM. Every 20ms a new signal starts, stays on between 1 and 2ms, then goes low. That time between 1 and 2ms determines the speed controllers’ speed. PPM signals must be precise and reliable, and the best way to ensure both was to use the PWM timer functionality on the LPC board.</p>
<p>There are three steps to generating a PWM signal on the LPC. First setup the general PWM ability, then setup each port you want to use, and finally latch a new duty cycle value. I wrote a header and c library for PWM control and a functionality specifically to set it up to generate a PPM compatible signal, independent of the peripheral clock’s configuration. There are four motors on the helicopter so I needed four separate PWM channels. I used timers 2, 4, 5, and 6 so that UART0 would be still usable.</p>
<h4 id="isup2supc">I<sup>2</sup>C</h4>
<p>The Nintendo Wii Motion+ sensor interfaces with the Wiimote over I<sup>2</sup>C. I<sup>2</sup>C is a useful bus for connecting many low-ish speed digital devices for simple data transfer. It uses 2 wires, SCA and SCL, data and clock respectively. This is a multi-slave bus capable of communicating with many devices without a chip select signal. The addresses are 8 bit with the least significant bit signifying whether to read or write to the device at the address of the other 7 bits. The bus’s single master device initiates commands and reads results, pulling the bus’s wires high with a pull-up resistor. I soldered in 2x4.5kΩ pull-up resistors and made a connector for the Motion+ and was able to read data.</p>
<p>To initialize the sensor I had to send the value 0x04 to register 0xFE at address 0xA6 then 0x05 to register 0xFE to finish the setup. Then the sensor would switch addresses to 0xA4 where it would let you read 6 bytes starting from register 0x00. The data was then decoded from the returned 6 bytes and used in the flight routine.</p>
<h4 id="xbee">XBee</h4>
<p><a href="http://imgur.com/s6m8AqS" style="float:right;
width:35%;"><img src="http://i.imgur.com/s6m8AqSl.jpg" alt="" title="Xbee detail shot. Hosted by imgur.com" /></a></p>
<p>For communication I used the XBee Series 2 wireless modules. For detailed setup information and operation of the modules, see my previous report on the subject at <a href="http://t413.com/news/fast-2-way-xbee-series-2-data">t413.com/news/fast-2-way-xbee-series-2-data</a>. I used UART0 for the XBee because UART1 shares the same pins as the timers for PWM 4 and 6. This required me to switch the UART / FTDI switch each time I want to program the µC, but there doesn’t seem to be a way around this except to design a native USB bootloader so that the FTDI chip can be left off. (future project: DUF bootloader)</p>
<p>The data sent over the XBee is a simple packetized data transfer method with a header, type, length, payload and checksum design. This allows for a means of checking command integrity, something I found to be vitally important. It also reduces the command size and expedites the data processing on both ends. See the library at <a href="https://github.com/t413/ser_pkt">github.com/t413/ser_pkt</a>.</p>
<h3 id="task-breakdown">Task breakdown</h3>
<h4 id="communication-task">Communication Task</h4>
<p>This task simply runs getSerialPacket(), then runs a series of switch()es to decide what to do with each type of received data and do it. When, for example, it gets a kind of USER_CONTROL and type of FULL_REMOTE (#defined as macros on both the transmitter and receiver) it reads all four 16 bit integers it expects, processes it by scaling the pitch/roll/yaw values, and saving it to the flight_settings struct. This flight_settings structure is passed by reference to both the communication task and the flight task and is used directly by the flight task to fly the quadcopter.</p>
<p><a href="http://i.imgur.com/172YcKcl.jpg" title="xbees-together" style="display:block;text-align:center"><img src="http://i.imgur.com/172YcKcl.jpg" alt="xbees-together" style="width:60%;margin:auto;" /></a></p>
<h4 id="flight-task">Flight Task</h4>
<p>The flight task sets up and handles the motors, sensors, and the PID control between the two. On startup it averages and zeroes the gyro sensor data, although this can be done at any time after startup with a signal from the remote. The main loop gets sensor data with update_wii_data(), which passes by reference a struct for the returning values and the calibrated zeroes. This will allow easy modification for other sensors in the future. It then calculates an offset value for the pitch, roll, and yaw based on the target value from the user’s remote and the sensor values, fused using PID control. The PID data settings are passed by reference and stored in the same flight_settings struct described before. If the quadcopter is armed then the offsets are added to the base throttle and sent to the motors using write_motors which is part of the motors.h library.</p>
<h4 id="arming-process">Arming process</h4>
<p>The The arming process is to maintain safe and predictable operation. The first requirement is for the remote to be sending data to the quadcopter. If the quadcopter doesn’t receive new data commands from the remote within 0.5 seconds of the last packet then it will disarm. This is to prevent lost communication or a pulled plug on the remote from sending the quadcopter flying out of control. When I can operate it autonomously I can specify that it not kill all motors as it does now, but rather safely land or fly home. Once data is being regularly sent the throttle must be below 10% and the yaw must be within 10% of its maximum, just as a precaution and an explicit way to say ‘start flying.’ Then the motors will spin slowly and throttle can be applied to lift off and fly.</p>
<h3 id="downloads">Downloads</h3>
<p>This is an open source project under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 license. See this page for details: <a href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/">http://creativecommons.org/licenses/by-nc-sa/3.0/us/</a></p>
<p>OS-copter project, now on GitHub: <a href="https://github.com/t413/os_copter">github.com/t413/os_copter</a></p>
<p>Remote project on GitHub: <a href="https://github.com/t413/remote_xbee">github.com/t413/remote_xbee</a></p>
<p>Packet communications project on GitHub: <a href="https://github.com/t413/ser_pkt">github.com/t413/ser_pkt</a></p>
mp3 player design2010-11-19T00:00:00+00:00http://t413.com/2010/11/mp3-player-design<p>Recent edit: The project <a href="https://github.com/t413/mp3_player_v2">is now on github!</a> with all the original svn commit history included.</p>
<h3 id="background">Background</h3>
<p><a href="http://imgur.com/huV73nN" style="float:right;width:40%;"><img src="http://i.imgur.com/huV73nNl.jpg" alt="" title="Hosted by imgur.com" /></a></p>
<p>I’m participating in a national student exchange this semester at San Jose State University in Silicon Valley California. One of my classes is CMPE 146, Embedded Microprocessor System Design. For one of our projects we were told to make an mp3 player on the <a href="https://sjvalley.com/shop/index.php?page=shop.product_details&flypage=flypage.tpl&product_id=27&category_id=1&option=com_virtuemart&Itemid=63&vmcchk=1&Itemid=63">dev board</a> we had to buy for the class. Since the final goal was the same for each person the design was especially important. Here’s my design:</p>
<p>There is also a handy <a href="/uploaded/mp3_player_design2.pdf">PDF version</a>.</p>
<h3 id="technology-breakdown">Technology breakdown:</h3>
<ul>
<li>CPU: <a href="https://sjvalley.com/shop/index.php?page=shop.product_details&flypage=flypage.tpl&product_id=27&category_id=1&option=com_virtuemart&Itemid=63&vmcchk=1&Itemid=63">Phillips NXP LPC2148 ARM7</a></li>
<li>FreeRTOS, compiled with arm-elf-gcc</li>
<li>32-bit, 40kB RAM, 60Mh, 512kB Flash</li>
<li>512Kbyte SPI based Flash memory</li>
<li>SD Card with <a href="http://elm-chan.org/fsw/ff/00index_e.html">elm-chan.org FAT-FS</a></li>
<li>TI PCM1774 DAC & Amplifier</li>
<li>Phillips PCA9535 I2C Port expander</li>
<li>ST STA013 SPI MP3 Decoder</li>
</ul>
<h3 id="downloads">Downloads</h3>
<p>This project is open source. My hope is that it helps others get started on their ARM without breaking their legs. If you’re taking CMPE 146 want to bum off my code then be warned: my style is pretty distinctive and the TA knows my site.</p>
<p>The project <a href="https://github.com/t413/mp3_player_v2">is now on github!</a> with all the original svn commit history included.</p>
<h3 id="overarching-design-process">Overarching Design Process</h3>
<p>I was adamant to have a fully functional audio player that I could use on a regular basis. The button control must be straightforward and the song selection must be dynamic. Using the serial terminal to change settings, select songs, or to do anything at all necessary for playing music was off the table. The interface must be usable by anyone who’s used an iPod despite not having an lcd.
<!--more--></p>
<p>I decided to structure the task communication and song handling around playlists. Sending the mp3 player task a single file using xQueue to queue up songs doesn’t allow for a previous track button, is resource heavy with many songs, and would be limited in playlist length. Therefore I devised a way (see section on mp3_task) to recursively scan the SD card and dynamically create playlists of tracks separated by artist. I dedicated two buttons, + -, to navigate through the found artists and start that artist’s playlist. The mp3 playing task now just takes a pointer to a playlist that already exists and can simply navigate forward and reverse through it. I also added the variable behavior of the previous button to jump to the beginning of the track when just a few seconds into the song (exactly as most modern players do). This also leaves room for playlists based on album, genera, or user-generated playlists (however, with only buttons and no LCD that would be far far to complex of a UI).</p>
<p><a href="http://imgur.com/6rHjSGP"><img src="http://i.imgur.com/6rHjSGPl.jpg" alt="" title="Hosted by imgur.com" /></a></p>
<p>Now playlists of songs can be selected, that playlist can be navigated, and it can be paused (see mp3_task section). This takes five buttons. I dedicated two buttons to adjust the output volume, leaving 1 button remaining. The last feature I could feasibly add would be track seek. Instead of using two more buttons for seek forward and seek back (I didn’t have the buttons anyway) I changed the behavior of the next/previous buttons to be more dynamic. If one presses the next button momentarily then it skips to the next track. If one holds it down then it seeks forward until it’s released. This is intuitive for anyone who has used an digital audio player in the past decade, adds very useful and sometimes needed functionality, uses not a button more, and only added a dozen lines of code.</p>
<p>The thoughtfulness in the design process lends to the final product an intuitive and useful interface, something unheard of for a prototype class project.</p>
<p><a href="http://imgur.com/W8tdXpn"><img src="http://i.imgur.com/W8tdXpnl.png" alt="" title="Hosted by imgur.com" /></a></p>
<h3 id="hardware-enclosure">Hardware Enclosure</h3>
<p>Most students carry their PCB around in a antistatic bag or a cardboard box. Because I enjoy actually using my project as a functional audio player and I don’t feel complete without a complete product, I decided to design an enclosure. Adobe Illustrator is my preferred vector editor (I am accustom to adobe’s products from my photography background) and I designed it entirely using that program. I used a caliper to measure dimensions, acrylic from TAP plastics, and an Epilog Helix 60 watt laser cutter for cutting. The enclosure uses no glue and is held together entirely by friction from the interlocking pieces. I chose to design it this way since we’re using a development board that can (and will) be used for other purposes. It also reduces the bill of materials and minimizes cost by forgoing screws or glues.</p>
<h3 id="task-breakdown">Task Breakdown</h3>
<h3 id="void-portexpandertaskvoid-pvparameters">void port_expander_task(void *pvParameters);</h3>
<p>This is the simplest of the two main tasks. It has one public function, port_expander_task(), and controls the I2C port expander which has the 8 pushbuttons and 8 blue LEDs. Before it starts an endless for loop it initializes the led port as output. During the loop, which happens every 100ms, it polls the button port on the port expander and sends queue commands to the MP3 task based on which button was pressed and the duration held. One of the unique decisions in my design was to keep a variable with the previously polled port expander’s button port result. This allows for leading edge triggered and trailing edge triggered button behaviors. For example: when pressed momentarily then released, the NEXT button advances the playlist. However, when held for longer than 500ms it sends the seek command and when it’s released it resumes normal speed playback. This advanced button behavior is just 20 lines of code and allows for much more intuitive user operation.</p>
<p>The artist +- buttons send the MP3 task a playlist of an artist. This artists are stored on a linked list, and the nth member, n being advanced by the +- buttons, has a linked list of tracks which is sent to the MP3 task. This data structure and the playlist idea is covered in the mp3_task breakdown.</p>
<p>Finally, the last function of this task is to control the LEDs. There is a global data structure which contains the mp3_task status. When it is not playing an mp3 the LEDs only turn on with a button press, but when an mp3 is playing it animates the LEDs with a left-to-right back and forth pattern. This is accomplished using the variable i which is incremented with ever iteration of the for loop.</p>
<h3 id="void-mp3taskvoid-pvparameters">void mp3_task(void *pvParameters);</h3>
<p>The mp3_task is a beast of a task, with 8k of RAM allocated to it. It has many public functions, but the main one is the mp3_task.</p>
<p>Before the infinite for loop the task starts scan_root() which starts a recursive scan for every file on the card. When it finds a file that ends with .MP3 it reads the artist ID3 tag using the read_ID3_info() function I wrote (see writeup at tinyurl.com/t4-id3). It searches the artist_list for one with that title then prepends the track structure to it’s tracks list. With hundreds of songs and dozens of artists in many subfolders this function still only takes a fraction of a second.</p>
<p>The for loop starts next and the first thing it does is wait for xQueueReceive to get a playlist. Why playlist? When one chooses an artist and chooses a track they may navigate between any track, before or after the starting track. This also allows for album playlists, genera playlists, and random playlists in the future. The playlist is just a Track pointer that points to a linked list of tracks.</p>
<p>To play a received playlist the task then loads the first item on the playlist, checks to see if it’s an mp3, and opens the file. It starts a while loop which reads a 4KB chunk of MP3 data from the file to a buffer then sends that chunk over SPI to the decoder. If, when reading to the 4KB file buffer, it reads fewer then 4096 bytes it ends this while loop, advances the playlist position counter, and it opens the file and repeats.</p>
<p>To pause playback the data transfer while loop is simply stopped by waiting for the RESUME status to be sent. If NEXT is sent then it will break; then advance the playlist. If PREV is sent then it does the same but decrements the playlist position counter. To fast forward and rewind the mp3 the f_lseek() function is used. It skips eight 4KB data chunks then plays one, making it an 8x seek.</p>
<h3 id="void-sdcarddetectvoid-pvparameters">void sd_card_detect(void *pvParameters);</h3>
<p>To handle the plugging-in and unplugging of the SD card without the need to restart, I’ve created a task that keeps notices plugging and mounts and unmounts it accordingly. It does this every 100 ms.</p>
<h3 id="void-uartuivoid-pvparameters">void uartUI(void *pvParameters);</h3>
<p>This task is massive and has lots of functionality. However, I will be brief since this is only a means to an end. The useful interface is the button task and in the future an LCD task or something similar. Tethering a device to a computer just to change tracks etc. defeats the purpose of having a mobile device in the first place. For development however it’s very handy.</p>
<p>This task provides a bash-like interface to administer the mp3 player. I’ve coded in bash-like cd, ls, and pwd commands that let one navigate the filesystem with relative pathnames, absolute pathnames, and optional arguments. One can also test crash the system, check the memory usage, check cpu utilization, and administer the spi flash memory module. I’ve made functions to load a file to a location in this spi flash module, to erase it, to scan it, to read from it, and to play an mp3 from it.</p>
<p>Before the endless for loop this task also plays a welcome mp3 from the spi serial flash memory. I think this is silly and counter-productive, but had to incorporate it to satisfy the requirement.</p>
<h3 id="por-fin">Por Fin</h3>
<p>This player is a great success. It’s something I’m proud of and have learned quite a bit creating. I’d like to take it further, creating an LCD interface, games, and album-art support. It would be great practice to port this to an STM32 ARM board which is more mainstream and slightly more powerful. One thing I wish we did would be design a PCB and fab our own board so we could make a marketable product. That would be a real top-down process of industry creation.</p>
<h3 id="pictures">Pictures</h3>
<div class="icontain i4x3"><iframe class="imgur-album" src="//imgur.com/a/I3DH2/embed?background=f2f2f2&text=1a1a1a&link=4e76c9"></iframe></div>
Lightweight C MP3 ID3v2 Reader2010-10-29T00:00:00+00:00http://t413.com/2010/10/lightweight-mp3-id3-metadata-tag-reader<p>Super lightweight MP3 ID3 metadata tag reader made for embedded systems.</p>
<p>Now <a href="https://github.com/t413/read_ID3_info">on GitHub!</a></p>
<h3 id="background">Background</h3>
<p>I’m writing a full-featured mp3 player for the SJSU class CMPE 146, Embedded Microprocessor System Design, that runs on the <a href="https://www.sjvalley.com/shop/index.php?page=shop.product_details&flypage=flypage.tpl&product_id=27&category_id=1&option=com_virtuemart&Itemid=63&vmcchk=1&Itemid=63">LPC2148 ARM7 Board</a> from sjvalley. The project is running RTOS and has reads files from a SD card streams them through an MP3 decoder to a DAC and finally your headphones.</p>
<p>The project is coming along nicely but I wanted a way to read ID3 tags so read_ID3_info() was born.
<!--more--></p>
<h3 id="alternatives">Alternatives</h3>
<p>The implementations for c/c++, according to <a href="http://www.id3.org/">http://www.id3.org/</a> are thus:</p>
<ul>
<li><a href="http://www.id3.org/TagLib">TagLib</a> Audio Meta-Data Library - modern implementation with C, C++, Perl, Python and Ruby bindings. <a href="http://developer.kde.org/~wheeler/taglib.html">http://developer.kde.org/~wheeler/taglib.html</a></li>
<li><a href="http://id3lib.sourceforge.net/">ID3Lib</a> on Sourceforge. The source code is coordinated by Scott Haug and was initially written by Dirk Mahoney and Andreas Sigfridsson.</li>
<li><a href="http://www.underbit.com/products/mad/">libid3tag</a></li>
</ul>
<p>Each of these libraries were too large and complicated to run on an embedded system although they offered many cool features. The library I’ve written is just one function, read_ID3_info(). It works well on my desktop and on my LPC2148 ARM7 board using <a href="http://elm-chan.org/fsw/ff/00index_e.html">FatFs</a> from <a href="http://elm-chan.org/">elm-chan.org</a>.</p>
<h3 id="implementation">Implementation</h3>
<p>Here’s an example for running on the LPC2148 ARM7 board using FatFs functions:</p>
<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><code class="language-c" data-lang="c">1
2
3
4
5
6</code></pre></div></td><td class="code"><div class="highlight"><pre><span class="n">FIL</span> <span class="n">file</span><span class="p">;</span>
<span class="n">f_open</span><span class="p">(</span><span class="o">&</span><span class="n">file</span><span class="p">,</span> <span class="n">file_name</span><span class="p">,</span> <span class="p">(</span><span class="n">FA_READ</span> <span class="o">|</span> <span class="n">FA_OPEN_EXISTING</span><span class="p">));</span>
<span class="kt">char</span> <span class="n">str</span><span class="p">[</span><span class="mi">40</span><span class="p">];</span>
<span class="n">read_ID3_info</span><span class="p">(</span><span class="n">TITLE_ID3</span><span class="p">,</span><span class="n">str</span><span class="p">,</span><span class="k">sizeof</span><span class="p">(</span><span class="n">str</span><span class="p">),</span><span class="o">&</span><span class="n">file</span><span class="p">);</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"Title: %s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span><span class="n">str</span><span class="p">);</span>
<span class="n">f_close</span><span class="p">(</span><span class="o">&</span><span class="n">file</span><span class="p">);</span>
</pre></div>
</td></tr></table>
<p>For running on a desktop I made a demo program which is now also in the github project.</p>
<p>You can run the test program, read_id3, with a mp3 file as an argument. You may also run it with a directory as an argument and the program will scan that directory for any .mp3 files and list the info on them.</p>
<h3 id="feedback">Feedback</h3>
<p>I’ve spend many a night on a <a href="http://ridiculousfish.com/hexfiend/">hex editor</a> and <a href="http://www.id3.org/id3v2.4.0-structure">id3.org</a> writing this and I hope it helps out at least someone. If anyone has any suggestions, finds any bugs, or comes up with an especially cool use for it I’d like to hear about it (yes, even the bugs). File a bug <a href="https://github.com/t413/read_ID3_info">on GitHub</a> and/or <a href="mailto:timo@t413.com">send an email</a>.</p>
<h3 id="license--copyright">License / Copyright</h3>
<p>This work is licensed under the Creative Commons Attribution-ShareAlike 3.0. See source code comments for details. I’m flexible if this is incompatible with your needs, just email me and ask.</p>
Fast 2-way XBEE series 2 data2010-03-18T00:00:00+00:00http://t413.com/2010/03/fast-2-way-xbee-series-2-data<p><a href="http://imgur.com/s6m8AqS" style="float:right;
width:40%;"><img src="http://i.imgur.com/s6m8AqSl.jpg" alt="" title="Hosted by imgur.com" /></a></p>
<p>Say that title out loud. It’s a mouthful– any yet it’s not enough. There are so many names for these modules and a better title would be <em>Fast two way Xbee ZigBee Series 2 Znet 2.5 Serial AT Communication.</em> In my trials and tribulations building my quadcopter remote (soon I’ll post about it) I’ve run across problems getting two way, full speed, and reliable communication between <a href="http://www.sparkfun.com/commerce/product_info.php?products_id=8691">my modules</a>. Here’s what I discovered after a lot of manual reading:</p>
<h3 id="fast-two-way-xbee-zigbee-series-2-znet-25-serial-at">Fast two way Xbee ZigBee Series 2 Znet 2.5 Serial AT</h3>
<p>The heart of the issue is that Xbee 2.5 modules are not designed (spesificlly) to be point-to-point direct communicators. Whereas Series 1 modules can communicate directly with zero configuration, these series 2 ZNET modules need some work. <a href="http://www.dudek.org/blog/180">Here’s</a> a great article on the difference. There’s a few great articles on how to setup these znet modules, however they’re really hard to find. (I can’t even find which ones I’ve already manged to run across). Here’s the basic setup:</p>
<!--more-->
<h3 id="basic-series-25-setup">Basic Series 2.5 Setup</h3>
<ol>
<li>First get <a href="http://www.digi.com/support/kbase/kbaseresultdetl.jsp?kb=125">X-CTU</a>from digi. It’s windows only, however:
<ul>
<li><a href="http://www.winehq.org/">Wine</a> on (<em>apt-get install wine</em> for debian) <strong>linux</strong> will let it install and run perfectly.</li>
<li>Wine also runs on <strong>Macs</strong>, try <a href="http://winebottler.kronenberg.org/">this</a>.</li>
<li>To get it to work correctly in wine, follow <a href="http://lizard43.blogspot.com/2008/10/x-ctu-with-linux.html">this tutorial</a>.</li>
</ul>
</li>
<li>Open X-CTU, select your COM port, (see that tutorial if you’re running linux or os x) set the serial baud rate, and click on the <em>Modem Configuration</em> tab.
<a href="http://i.imgur.com/cdtCwZkl.png"><img src="http://i.imgur.com/cdtCwZkl.png" alt="selecting com port" title="selecting com port" /></a></li>
<li>Read the current information from your xbee.
<ul>
<li>Note: if x-ctu complains, it’s likely missing the latest firmware. Try the _Download new version _button to automatically get them, but I’ve never had that work. Go to the digi <a href="http://www.digi.com/support/productdetl.jsp?pid=3261&osvid=0&s=269&tp=2">download page</a> and download the .zip file then give that to x-ctu.</li>
</ul>
</li>
<li>Change the _Function Set _dropdown menu to ZNET 2.5 COORDINATOR AT. One and only one coordinator xbee is required for each series 2.5 network. <a href="http://i.imgur.com/MQTJVc0l.png"><img src="http://i.imgur.com/MQTJVc0l.png" alt="selecting firmware" title="selecting firmware" /></a></li>
<li>Check the <em>Always update firmware _box then click _write.</em></li>
<li>Optional configuration:
<ul>
<li>You can change the **PAN ID **to something unique if you’d like, but you’ll also need to change the other module to match it exactly.</li>
<li>Change your **serial baud rate **if you want to communicate faster then 9600 bps. Scroll down to _serial interfacing _to find that option.</li>
</ul>
</li>
</ol>
<p>Sweet, it’s all set for automatically packetized, full-speed serial communication.</p>
<p><a href="http://i.imgur.com/172YcKcl.jpg" title="xbees-together"><img src="http://i.imgur.com/172YcKcl.jpg" alt="xbees-together" /></a></p>
<h3 id="fast-reliable-two-way-data-not-what-you-get">Fast, reliable two-way data: not what you get</h3>
<p>The problem you may soon discover is that the communication from the coordinator to the <em>ZNET 2.5 ROUTER/END DEVICE AT</em> (I call this on the node) slows to a halt after a few dozen bytes and never catches up when there’s regularly sent data. Data coming from the node to the coordinator is fine.</p>
<h3 id="the-fix">The Fix</h3>
<p>Taking with the idea from <a href="http://forums.digi.com/support/forum/viewthread_thread,683_lastpage,yes#2528">this forum</a> posting and mixing in lots of reading of <a href="http://docs.google.com/viewer?url=http://www.sparkfun.com/datasheets/Wireless/Zigbee/XBee-2.5-Manual.pdf">the manual</a>, I discovered that if the coordinator is told to only send to your one node it works flawlessly. I came up with this process after reading into the configuration options further.</p>
<ol>
<li>Go back into X-CTU configuration and name <em>each module</em> (I called mine PICARD and RIKER) using the <strong>NI</strong>, or Node Identifier, option (+++ATNI PICARD WR if you know what you’re doing).</li>
<li>Write the changes.</li>
<li>Power-on both modules, with the <em>coordinator</em> connected to the computer.</li>
<li>Click on the _Terminal _tab.</li>
<li>Type <strong>+++</strong> to go into command mode, don’t hit return. Be sure it outputs <em>OK</em>.</li>
<li>Type <strong>ATND</strong> (and return) to show connected modules, to be sure your NODE and all it’s address information is there. All the commands start with AT, and the ND is <em>Node Discover</em>.</li>
<li>Type <strong>ATDN <your node’s NI></strong> (and return). That’s the command for <em>Destination Node</em>, space, and the <em>Node Identifier</em> you created earlier and just confirmed in the previous step. <em>It should return _OK_</em>.This sets the DH and DL values to the SH and SL values from the node. This means the destination address (both High and Low halves) are automatically set to the serial number from the node. All communication will now only go to the node when coming from the coordinator.
<a href="http://i.imgur.com/A0fXHmfl.png"><img src="http://i.imgur.com/A0fXHmfl.png" alt="writing addresses" /></a></li>
<li>Type +++ again to enter command mode then type WR (and return) to save settings. If it returns <em>OK</em> then You’re done!</li>
</ol>
<h3 id="por-fin">Por fin</h3>
<p>Here’s what JordanH <a href="http://forums.digi.com/support/forum/viewthread_thread,683_lastpage,yes#2528">said</a> on the digi discussion boards:</p>
<blockquote>
<p>[Not setting a destination address] will transmit each and every packet from the XBee module as a broadcast packet. Broadcast data is unreliable and unacknowledged so that may explain the behavior you are seeing.</p>
</blockquote>
<p>Now that we’ve got the address set, go send some data!</p>
Wireless Wii Robot2009-12-23T00:00:00+00:00http://t413.com/2009/12/wireless-wii-robot<p><a href="http://imgur.com/C9QO3CJ"><img src="http://i.imgur.com/C9QO3CJl.jpg" alt="" title="Hosted by imgur.com" /></a></p>
<p>Physical computing -> wireless two-way data -> physical control. This is a intuitive, durable, and fun way to control almost anything. Here I’ve built a transmitter which reads data from the Wii nunchuck and sends it over xbee. The rover receives the xbee broadcast, decodes it, maps it to drive the tank-like dual motor setup, and controls the motor driver IC. To achieve my goal of a small mint-tin fitted remote I used a lithium polymer (LiPo) battery, and to make them safer I included a voltage monitoring subroutine. The result is modular, easily incorporated into future projects, or disassembled for different use. Here are more details:</p>
<div class="icontain"><iframe src="//www.youtube.com/embed/b9O7bzlCbT0" allowfullscreen=""></iframe></div>
<h3 id="transmitter">Transmitter</h3>
<p>Arduino pro mini (3.3V version), xbee series 2.5, used wii nunchuck, lipo battery, old off-brand mint tin.</p>
<h3 id="receiver">Receiver</h3>
<p>9V battery, Xbee, ATmega168, SN754410 H-Bridge motor IC, lego motors</p>
<h2 id="pictures">Pictures!</h2>
<div class="icontain i4x3"><iframe class="imgur-album" src="//imgur.com/a/VHjZg/embed?background=f2f2f2&text=1a1a1a&link=4e76c9"></iframe></div>
<h2 id="source-files">Source Files</h2>
<p><a href="https://gist.github.com/t413/36974b8490b5e53683e5">View and download on GitHub</a></p>
<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><code class="language-cpp" data-lang="cpp"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19</code></pre></div></td><td class="code"><div class="highlight"><pre><span class="kt">int</span> <span class="n">ledPin</span> <span class="o">=</span> <span class="mi">13</span><span class="p">;</span>
<span class="kt">void</span> <span class="nf">setup</span><span class="p">(){</span>
<span class="n">Serial</span><span class="p">.</span><span class="n">begin</span><span class="p">(</span><span class="mi">115200</span><span class="p">);</span>
<span class="n">nunchuck_init</span><span class="p">();</span>
<span class="n">pinMode</span><span class="p">(</span><span class="n">ledPin</span><span class="p">,</span> <span class="n">OUTPUT</span><span class="p">);</span>
<span class="c1">//print inital battery charge</span>
<span class="n">Serial</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s">"b="</span><span class="p">);</span>
<span class="n">Serial</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="n">update_batt_status</span><span class="p">());</span>
<span class="n">Serial</span><span class="p">.</span><span class="n">println</span><span class="p">(</span><span class="s">"%"</span><span class="p">);</span>
<span class="p">}</span>
<span class="kt">void</span> <span class="nf">loop</span><span class="p">()</span> <span class="p">{</span>
<span class="n">nunchuck_get_data</span><span class="p">();</span>
<span class="k">if</span> <span class="p">(((</span><span class="n">nunchuck_buf</span><span class="p">[</span><span class="mi">5</span><span class="p">]</span> <span class="o">>></span> <span class="mi">0</span><span class="p">)</span> <span class="o">&</span> <span class="mi">1</span><span class="p">)</span> <span class="o">?</span> <span class="mi">0</span> <span class="o">:</span> <span class="mi">1</span><span class="p">){</span>
<span class="n">digitalWrite</span><span class="p">(</span><span class="n">ledPin</span><span class="p">,</span> <span class="n">HIGH</span><span class="p">);</span>
<span class="n">send_packet</span><span class="p">();</span>
<span class="p">}</span>
<span class="k">else</span> <span class="n">digitalWrite</span><span class="p">(</span><span class="n">ledPin</span><span class="p">,</span> <span class="n">LOW</span><span class="p">);</span>
</pre></div>
</td></tr></table>
<p>These are provided under the same licence as my photos: <a href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/">Creative Commons Attribution-Noncommercial-Share Alike 3.0</a>. Click on either image to download the one of the sketches.</p>
<h2 id="software-requirements">Software Requirements</h2>
<ul>
<li>Arduino IDE 017 or later (for the new Wire library)</li>
<li>That’s it.</li>
</ul>
<h2 id="helpful-linksresources">Helpful links/Resources</h2>
<ul>
<li>Here’s a great tutorial on how to understand/control this H-bridge motor IC: <a href="http://itp.nyu.edu/physcomp/Labs/DCMotorControl">DC Motor Control Using an H-Bridge</a></li>
<li><a href="http://www.sparkfun.com/commerce/tutorial_info.php?tutorials_id=57">Background and Power Supply</a>, a SparkFun lecture on how to make a regulated power supply.</li>
<li><a href="http://blog.makezine.com">Make Blog</a> and <a href="http://makezine.com">Make Magizine</a> - Great community with unparalleled creativity and originality. Notice the make magazines my bot crawls over?</li>
<li>Did you like my <a href="http://todbot.com/blog/2009/05/23/arduino-chip-sticker-label/">Arduino AVR sticker label</a>? it’s from todbot blog.</li>
</ul>
<h2 id="future-directions">Future Directions:</h2>
<ul>
<li>Packetized data transfer</li>
<li>Bigger bot: (I have a wheelchair I can’t wait to get running..)</li>
<li>Put in an on/off switch and status leds.</li>
<li>Miniaturize the receiver into it’s own mint tin once I have a more permanent (not lego) rover.</li>
<li>Force feedback by measuring of current draw on the motors, rumbling the nunchuck (or something).</li>
<li>Generally more two-way communication.</li>
</ul>