tag:blogger.com,1999:blog-42894528950580707462024-03-13T23:02:06.105+02:00Microcontrollers, Electronics & RoboticsProjects, techniques and thoughts involving microcontrollers, electronics & robotics for the hobbyist.Ytaihttp://www.blogger.com/profile/05373159288627167940noreply@blogger.comBlogger19125tag:blogger.com,1999:blog-4289452895058070746.post-86647627117502513302015-11-04T07:54:00.000+02:002015-11-05T01:01:29.983+02:00Pixie - Bright Things Come in Small Packages<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-cmQxtgkl1zM/VjqNfv5iQmI/AAAAAAABBvo/BdXzYg15JmU/s1600/2741-01.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="240" src="http://2.bp.blogspot.com/-cmQxtgkl1zM/VjqNfv5iQmI/AAAAAAABBvo/BdXzYg15JmU/s320/2741-01.jpg" width="320" /></a></div>
<br />
Exciting! A new product of my design just hit the market last week! World, meet <a href="https://www.adafruit.com/products/2741" target="_blank"><b>Pixie</b> - a 3W chainable smart LED Pixel.</a> Kind of a long title... what does it mean?<br />
<b><br /></b>
<b>LED Pixel</b>: The Pixie is a color LED module, allowing an external controller to change its color and brightness dynamically.<br />
<b>Chainable</b>: The module is designed so that you can chain many of them and control each one individually. If you know NeoPixels, this concept should be clear, but in case you don't, imagine you want to build a project that requires 50 LEDs to be individually controlled. Naively, you would need to power each on of them individually, then connect each one of them individually to a controller. This would require tons of wiring, many pins on the controller, each one possibly driven by a specialized peripheral, such as UART or PWM. In short, this is not practical. With the Pixie, being chainable, you connect the first LED's input pins to power and a single control pin (serial TX) on the controller. Then you connect the first LED's output pins (power, ground, data) to the input of the second LED, and so on. Each Pixie in the chain consumes its own data, then relays the rest of the data down the chain, so the controller can control each Pixie individually, without being connected to each one.<br />
<b>3W</b>: 3 Watts of power drive the LED, or 1 Watt for each Red, Green, Blue. This is a VERY bright LED. Compare to typical NeoPixels, which are around 0.2W.<br />
<b>Smart</b>: Some really high-end features are available on each Pixie, such as Gamma correction (8-bit to 16-bit) for super-smooth color gradients, over-heating protection (these things do get hot if left on at full blast for too long), communication loss protection.<br />
<span style="text-align: center;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-g-fP1YgbMjw/VjqNhlssulI/AAAAAAABBvw/HMm-uj-ZTCE/s1600/2741-06.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="240" src="http://3.bp.blogspot.com/-g-fP1YgbMjw/VjqNhlssulI/AAAAAAABBvw/HMm-uj-ZTCE/s320/2741-06.jpg" width="320" /></a></div>
<span style="text-align: center;">The idea was born about a year back, when I started designing </span><a href="http://ytai-mer.blogspot.com/2014/09/fairydust.html" style="text-align: center;" target="_blank">my Burning Man LED jacket</a><span style="text-align: center;">. The jacket required 50 x 3W RGB LED and I couldn't find any off-the-shelf ones that include the required drive circuitry and are chainable. So I decided to make one myself. It was only a couple of month later that I recognized that this might actually be useful for other people, so I decided to try to turn it into a product. It took a couple of iterations to get it right, fixing some issues that I'll describe in detail below.</span><br />
<br />
I chose to collaborate with <a href="https://www.adafruit.com/" target="_blank">Adafruit</a> on this project, partly because I've already worked with SparkFun and SeeedStudio in the past, and partly because Adafruit really have a great selection of LED-related products and have a great reputation in this field (and in general). I think I chose well, they were great to work with!<br />
<br />
So... before this thing starts sounding too much like a sales pitch, let me share with you some of the design insights I've had while working on this module. As you'll see, sometimes the devil is in the details and what might appear to be a simple product initially may turn out to be quite a challenge. I've shared the same information as a <a href="https://learn.adafruit.com/pixie-3-watt-smart-chainable-led-pixels/design" target="_blank">Design Notes page on Adafruit</a>. Keep in mind that as with my previous products, this one is also fully open-source software and hardware for maximum hackability and fun.<br />
<h2>
Microcontroller</h2>
Fairly early down the design path, it became clear that implementing all the features we wanted is a task most suited for a small microcontroller. We chose the 8-bit Microchip PIC12F1571, which had just about everything we could hope for in this application. It is small and cheap, works on 5V, has exactly 5 I/O pins (used for R, G, B, Din, Dout), an internal oscillator, a 16-bit, 3 channel PWM module, on-die temperature sensor and more. Pretty amazing!<br />
Programming the PIC12 is done through exposed pads featured on the circuit for that purpose (labeled rst/pgd/pgc). A cheap PIC programmer can be used, but the programming protocol is so simple that we’ve implemented an Arduino library that can do that for our testbed.<br />
The possibilities with having an on-board microcontroller are endless! The Pixie can be reprogrammed for standalone operation, and the Din/Dout pins can be repurposed to support different protocols or to directly connect to buttons, etc. The Dout pin can even be used for analog input!<br />
The exiting firmware can be found in <a href="https://github.com/ytai/pixie" target="_blank">Pixie's Github repository</a>.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://learn.adafruit.com/system/assets/assets/000/028/083/medium800/adafruit_products_pixie-pic.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="125" src="https://learn.adafruit.com/system/assets/assets/000/028/083/medium800/adafruit_products_pixie-pic.png" width="320" /></a></div>
<br />
<h2>
Constant Current Driver</h2>
In order to provide a consistent level of illumination each of the R, G, B LEDs needs a constant current supply of about 350mA. We opted for linear regulation for its simplicity and low-cost, despite it being less efficient (and as such, dissipating more heat) than switching regulation.<br />
The constant current circuit is pretty cool. Let’s explain it by first considering the path of the current through the LED. The current comes from the 5V supply, through the LED, then through a nFET (Q1/3/5) then through a 1.74[Ohm] shunt resistor. The more resistive the FET becomes between its drain and source, the smaller the current flowing through this path. Now let’s see how we can use this to our advantage.<br />
The NPN transistors Q2/4/6 have a specified 0.6V drop between base and emitter when on. This means the voltage across their respective shunt resistors R1/3/5 will always be 0.6V. According to Ohm’s law, this means that the current through them will be 0.6[V]/1.74[Ohm], or about 344mA. Close enough. If the current were to decrease, the base voltage would decrease proportionally, resulting in the NPN having more resistance between its collector and emitter, thus causing a higher voltage on the collector (recognize the voltage divider formed between the NPNs and their R2/4/6 pull-ups?). But this would result in a higher voltage on the FET gate, causing it to become less resistive between source and drain and as a result, higher current through the LED. The same logic can be applied in the opposite direction. The conclusion is that this circuit is self-regulating the LED current.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://learn.adafruit.com/system/assets/assets/000/028/084/medium800/adafruit_products_pixie-led-driver.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="301" src="https://learn.adafruit.com/system/assets/assets/000/028/084/medium800/adafruit_products_pixie-led-driver.png" width="320" /></a></div>
<br />
<h2>
Color and Brightness Control</h2>
Different colors are achieved via Pulse Width Modulation (PWM) on each of the R, G, B LED. The PIC has a built-in 3-channel, 16-bit PWM peripheral. This allows us to be fancy and do Gamma correction, which means we are doing a non-linear mapping of the 8-bit color value we are commanded with to a high resolution 16-bit color, resulting in a much more natural color gradient compared to a straight linear mapping. The PWM peripheral runs at about 500Hz. The generated signals switch the constant-current circuit described above.<br />
<h2>
Daisy-Chaining</h2>
Originally, we have designed the Pixie to support the same serial protocol as the WS28x family (aka NeoPixel). It worked. However, this compatibility, which was originally considered a feature has been eventually deemed a drawback: the WS28x protocol doesn’t easily lend itself to common micro controller peripherals, and in most cases ends up being bit-banged by the controller, requiring a relative high CPU usage, making it hard to do other timing-sensitive operations at the same time, not to mention driving another chain on a different pin… Our solution: stick to the good ol’ 115k.2 asynchronous serial. Almost every microcontroller has a UART peripheral capable of easily generating this protocol without much CPU intervention. Many have more than one. Even a PC with a simple USB-serial dongle can do that fairly easily. Seems like a win! The only drawback we could see what with the data rate being relatively low, we run into frame-rate / chain length limitations (about 60-long chain @ 50 frames/sec). However, at about 1[A] per Pixie, we concluded that typical chains would not be super-long.<br />
The resulting serial protocol is very simple: the controllers sends a byte-string containing a color value for each LED in the chain as follows:<br />
<span style="font-family: "courier new" , "courier" , monospace;"><r1>, <g1>, <b1>, <r2>, <g2>, <b2>, <r3>, <g3>, <b3>, …, <rn>, <gn>, <bn>, <at 1ms="" least="" of="" silence=""></at></bn></gn></rn></b3></g3></r3></b2></g2></r2></b1></g1></r1></span><br />
Each of <span style="font-family: "courier new" , "courier" , monospace;"><xi></xi></span> is a byte representing the brightness of a single color of a single Pixie, where 0 is off, 255 is fully on, and everything is between is, er, everything in between. <span style="font-family: "courier new" , "courier" , monospace;"><r1>, <g1>, <b1></b1></g1></r1></span> will determine the color of the Pixie that is the first in the chain, counting from the controller end. <span style="font-family: "courier new" , "courier" , monospace;"><r2>, <g2>, <b2></b2></g2></r2></span> is the next one, etc.<br />
Each Pixie listens on it Din pin for serial data. It will consume the first 3 bytes it sees and store them. It will then echo any subsequent bytes to its Dout pin (with less than a microsecond latency). It will keep doing so until it detects a 1ms-long silence on Din. Then, it will immediately apply (latch) the color values it got and go back to listening for a new color. This yield a very effective mechanism for addressing LEDs individually and making sure they all latch at the same time.<br />
<h2>
Dealing With Supply Noise</h2>
Having a chain with multiple nodes constantly switching 1[A] loads is no small feat! Even an otherwise negligible wire resistance would result in noticeable voltage glitches. Not to mention wire inductance, which likes sudden current changes even less, and reacts with furious voltage surges unless dealt with. To make things worse, being a chain-oriented product, we’re expecting people to use rather long (several meters) wires, which inevitably have more resistance and inductance. And worse still, the on-chip temperature indicator that we really really wanted to use is extremely sensitive to the slightest of noise on the supply. Did we get your attention?<br />
We took several measure to mitigate those issues. First, we made sure the holes for the supply wires are large enough to fit a 16AWG wire. Thicker wires = less resistive = good. The PCB traces connecting the input and output supply are super wide for the same reason.<br />
Then, bulk capacitance! A large 22uF ceramic (hence, low ESR) capacitor across the supply on every node is used to absorb voltage transients, especially those caused by wire inductance. Then, that supply gets further filtered using an R/C circuit comprising R7, R9 and C1, the latter being yet another 22uF ceramic and the relatively high resistor values ensure that the C1 reacts very slowly to any change in the supply voltage. One thing to notice is that we’ve used to resistors and we let the capacitor “float” in the middle. Why? Assuming fairly equal wires for 5V and GND, this setup would result in the supply rails for all microcontrollers in the chain to always have the same Vcc/2 potential, even if their Vcc voltage is different as result of wire resistance x high current. This makes it easier to discern the 0’s from the 1’s between consecutive nodes and thus get a reliable communication channel despite the supply noise. Otherwise, since the detection threshold is relative to the supply rails, we would have smaller error margins.<br />
That simple circuit took a lot of tweaking to get right, but the result is very satisfactory noise-immunity characteristics.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://learn.adafruit.com/system/assets/assets/000/028/086/medium800/adafruit_products_pixie-supply.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://learn.adafruit.com/system/assets/assets/000/028/086/medium800/adafruit_products_pixie-supply.png" /></a></div>
<br />
<h2>
Power Dissipation and Over-Temperature Protection</h2>
Despite LEDs being relatively efficient light sources, they still convert the vast majority of their consumed power into heat. Furthermore, our linear constant current circuit uses resistance (across the FET) to limit the current, resulting in the extra power being converted to heat. In total, at full steam (driving all 3 LEDs at 100% duty cycle) our little circuit dissipates around 5W! Keeping it from over-heating in this condition is unfeasible. We’ve allocated largish thermal places on the PCB to improve cooling efficiency, but really, the intention is to not leave the LED full-on for more than a couple of seconds. Rather, working continuously at lower brightness is perfectly fine as well as generating fast, bright pulses periodically.<br />
But we wanted to make sure that the LEDs would not get dangerously hot even by accident. For that reason, the Pixie firmware uses the PIC’s on-chip temperature indicator to estimate the board’s temperature and would shut-down the LED when it gets too hot (above about 70 degrees celsius). It will automatically resume operation when it cools down. Getting this temperature indicator to work with reasonable precision was a challenge. First, the PIC’s supply voltage needed to be extra-clean (as described above) and second, to account for variability between different instances of the PIC, each and every unit goes through an automated calibration process during manufacturing and the temperature calibration data gets written to the PIC’s flash memory.<br />
<h2>
Loss of Communication</h2>
Have you ever noticed how NeoPixels retain their color if their controller goes away? While this can be considered a convenient feature in some cases, it is an absolute no-go in a 3W LED case. Losing communications with the controller for any reason during a high-brightness pulse, that was otherwise intended to be very short, could potentially result in LEDs being left on for extended periods, consuming a lot of power and dissipating a lot of heat (limited by the over-temperature feature described above). Even more, what if we have a firmware bug (not that we ever have bugs, but just for the sake of the discussion ;D) causing the PIC to hang while its LED is on? That would be unacceptable.<br />
Watchdog to the rescue! Remember we told you how awesome the PIC12 is? Another feature that is useful for us is the watchdog. It will reset the PIC if it doesn’t hear from our firmware that everything is fine for about 2 seconds. In turn, our firmware will only pet the watchdog every time it gets a valid color and successfully latches it. So unless we hear from our controller at least every 2 seconds (and in practice, better leave a little margin), the Pixie resets, causing the LED to turn off until told otherwise.<br />
So unlike NeoPixels, if you want your Pixies to stay on for extended periods, even with no color change, you need to constantly remind them that you’re alive by sending them their favorite string.<br />
<h2>
Conclusion</h2>
Who would have guessed that designing a circuit having only about 20 simple parts could get so complicated? Certainly not us! We have done our best to provide a high quality, useful product and learned a lot along the way. We’re hoping you’ll like the result and enjoyed reading about some of the reasoning behind it.<br />
<br />
I have some cool ideas for projects now that this is done. Stay tuned :)<br />
<br />Ytaihttp://www.blogger.com/profile/05373159288627167940noreply@blogger.com15tag:blogger.com,1999:blog-4289452895058070746.post-6327891209118685852015-05-19T21:03:00.000+03:002015-05-20T18:45:35.427+03:00Electro-LegosMy oldest son is almost seven years old. Seven is right about when I got my first Atari 800XL and learned to program. Today's kids have much cooler choices for computers. Personally, I think that the ability for programs to interact with the physical world makes a huge difference in motivation.<br />
<a href="http://1.bp.blogspot.com/-WytLf8ws1Eo/VVtvc8HB9_I/AAAAAAAA-Yk/86CovrN5DGU/s1600/IMG_20150519_092202380_HDR.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="320" src="http://1.bp.blogspot.com/-WytLf8ws1Eo/VVtvc8HB9_I/AAAAAAAA-Yk/86CovrN5DGU/s320/IMG_20150519_092202380_HDR.jpg" width="260" /></a>I recently backed up a Kickstarter campaign for the <a href="http://www.espruino.com/Pico" target="_blank">Espruino Pico</a>. While being "yet another" small microcontroller-based board, this one has quite a neat software stack: it runs a JavaScript interpreter and exposes a very extensive JavaScript API for controlling its I/O. I was thinking this would make a great tool for super-quick hacks that I sometimes need for testing purposes / one-off tooling. But quickly it dawned on me that this would be a perfect way to get my son into programming! The Espruino has an IDE that is a Chrome extension with <a href="https://code.google.com/p/blockly/" target="_blank">Blockly</a> support, allowing us to code without having to do much typing and without risking syntax errors (which is often a big source of frustration for beginners). I also found that it was fairly easy to add new blocks, so I quickly made a couple of useful ones (for example, there wasn't a stock block for controlling a servo).<br />
And so we've been playing for a while, controlling the on-board LEDs with the on-board button, and later adding a servo motor. But blinking LEDs and moving a servo for their own sake gets boring after a while. Luckily, the tooth-fairy has kindly provided us with a kit of accessories which greatly extends the possibilities! Since my son loves Legos (who doesn't?), my idea was to allow him to embed the I/O devices in his creations. Not a new concept, but mine was totally DYI, taking only a few hours of work in my garage and costing next to nothing.<br />
The kit I made (shhhhh, don't tell it was me!) contains:<br />
<br />
<ul><a href="http://4.bp.blogspot.com/-vaEoz0tL6PA/VVtvhOhZaMI/AAAAAAAA-Ys/eTC1EctrTdk/s1600/IMG_20150519_092407358.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="180" src="http://4.bp.blogspot.com/-vaEoz0tL6PA/VVtvhOhZaMI/AAAAAAAA-Ys/eTC1EctrTdk/s320/IMG_20150519_092407358.jpg" width="320" /></a>
<li><b>A micro servo</b>, fitted with 2x2 Lego bricks on the top and bottom with correct alignment and a 1x4 brick on the arm. I used Gorilla glue for attaching the bricks to the servo, then "cast" the thing in hot glue for extra strength and cleaner shape. For alignment, I built a Lego fixture that held everything in place while the glue dries. For the casting, I found a cool trick you can do with hot glue: I pressed the workpiece with the molten glue against a piece of parchment paper placed on the desk. Once cool, the hot glue easily separates from the parchment paper, resulting in a really clean, flat surface.</li>
<li><b>A selection of LEDs</b>. I found that the "technic" lego pieces have holes that are the perfect size for a 5mm LED. With a bit pressure it goes all the way in and will never come out. I made a set including: a double-LED (red, green) piece, an auto-color-changing LED piece and an RGB LED piece. I soldered the appropriate (for 3.3V) current-limiting resistors to the back of all LEDs to make hook-up simpler for my son.</li>
<li><b>Two push-buttons</b>. It turns out those through-hole push-buttons fit perfectly between the bumps of a 2x2 piece, when placed diagonally. A dab of Gorilla glue, and we're done.</li>
</ul>
<div>
I'm really happy with the result and if it works out well I can easily add more pieces.</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: left;">
Here's what happens when you let dad play with the kids' toys...</div>
<div style="text-align: center;">
<div class="separator" style="clear: both; text-align: center;">
<iframe width="320" height="266" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/wURZfpP-wxE/0.jpg" src="https://www.youtube.com/embed/wURZfpP-wxE?feature=player_embedded" frameborder="0" allowfullscreen></iframe></div>
<br /></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div>
<br /></div>
Ytaihttp://www.blogger.com/profile/05373159288627167940noreply@blogger.com6tag:blogger.com,1999:blog-4289452895058070746.post-80715249103475926662014-09-16T08:04:00.000+03:002015-07-15T00:19:12.419+03:00Fairydust<style>
table.tr-caption-container {
display: inline-table !important;
}
</style>
<br />
<h2>
The Story of My Obnoxiously Bright LED Jacket</h2>
<div>
Burning Man. The most awesome experience ever. My story begins last year, which was the first time I went. Long story short, having been a little unprepared, I was just about the darkest creature on the playa (one of the most typical things about Burning Man is that at night everybody and everything is lit up beautifully). I had a head lamp to keep cyclists from running me over. Me of all people! So for this year I decided to over-compensate. Inspired by a super-bright LED that I saw at work, I decided I'm going to make an LED jacket that would be seen from a distance and will blind anyone that's standing close. Mission accomplished :)<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/W0b854OpM2U/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/W0b854OpM2U?feature=player_embedded" width="320"></iframe></div>
<br />
This jacket has 48 super-high-brightness (150 lumen) variable-color LEDs integrated in it. The LED color are created by a controller that is installed on the wrist. The controller has a little graphic display and a rotary push-button that allow selection from different available patterns. Some of those patterns react to sound in real-time. The jacket is powered by two integrated battery packs weighing a total of about 1kg and lasting for over 12 hours of typical usage.<br />
I've designed and hand-made all the electronics and software and sewed the actual jacket over a few months in my not-so-spare time.<br />
<h3>
The Attire</h3>
</div>
<div>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-pu9W_oYAyzM/U7DR_XLEawI/AAAAAAAA294/ZesP3iO-nBU/s1600/IMG_20140623_225439475_HDR.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="200" src="http://3.bp.blogspot.com/-pu9W_oYAyzM/U7DR_XLEawI/AAAAAAAA294/ZesP3iO-nBU/s1600/IMG_20140623_225439475_HDR.jpg" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Extracting the pattern from an existing jacket</td></tr>
</tbody></table>
This is by far the most advanced sewing project I've ever done. It includes a 5-piece pattern (that I had reverse-engineered from an existing jacket) times two layers. The outer layer is black felt with fine glitter. The inner layer is black fleece. All the electronics go in between, so the jacket looks clean and feels smooth from both the outside and the inside. The jacket features a hoodie and a separating zipper. In order to allow washing of the jacket as well as easy repair of the electronics, everything can be detached and re-attached: the connection between the two layer as well as between the electronics and the fabric are all implemented using hook-and-loop fasteners (Velcro). Each LED is mounted on a small PCB that is attached to the inside of the outer fabric layer. Only the LED itself is visible from the outside, through a 5mm hole. The hole is reinforced (on the inside) with a fusible (iron-on) female Velcro, also serving for mounting the PCB, which has a male Velcro glued to it. The controller is attached in a similar fashion, with the display and control knob picking through matching holes. Two battery packs are carried inside specialized flame-proof inner pockets that are attached near the waist.</div>
<div style="text-align: center;">
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-J3oc9J27CHU/U-PLB4ARwkI/AAAAAAAA5rw/Uw96IGtu_Kg/s1600/IMG_20140805_210604581_HDR.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="200" src="http://1.bp.blogspot.com/-J3oc9J27CHU/U-PLB4ARwkI/AAAAAAAA5rw/Uw96IGtu_Kg/s1600/IMG_20140805_210604581_HDR.jpg" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Marking the fabric with a chalk</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-4StIwxqSygg/U-PLB-HJ_II/AAAAAAAA5rw/aGQvYnw5PTE/s1600/IMG_20140804_223747579_HDR.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="200" src="http://4.bp.blogspot.com/-4StIwxqSygg/U-PLB-HJ_II/AAAAAAAA5rw/aGQvYnw5PTE/s1600/IMG_20140804_223747579_HDR.jpg" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The cut pieces for one of the layers</td></tr>
</tbody></table>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-ElJo-ecozCI/U-PLBzkQj_I/AAAAAAAA5rw/_naERgSY5xk/s1600/IMG_20140806_015328287.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="200" src="http://1.bp.blogspot.com/-ElJo-ecozCI/U-PLBzkQj_I/AAAAAAAA5rw/_naERgSY5xk/s1600/IMG_20140806_015328287.jpg" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Complete jacket, prior to mounting electronics</td></tr>
</tbody></table>
</div>
<div>
All in all, it was an amazing experience to design the jacket and make it. I'm very pleased with the result too. To my untrained eye it looks not much different in quality than a jacket that you might see in a store.</div>
<h3>
LED Modules</h3>
<div>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-cW0KCar0L34/U5f8KUvTa2I/AAAAAAAA3BA/_aZNkb-41No/s1600/IMG_20140610_242441591_HDR.jpg" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="200" src="http://2.bp.blogspot.com/-cW0KCar0L34/U5f8KUvTa2I/AAAAAAAA3BA/_aZNkb-41No/s1600/IMG_20140610_242441591_HDR.jpg" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">LED modules, top and bottom</td></tr>
</tbody></table>
It started with finding these amazing 3W RGB LEDs on eBay that cost $30 / 50 pieces. Sold! My idea was to make modules around them that allow them to be daisy-chained. Controlling a large number of LEDs would require a hell-of-a-lot wiring if had to run 4 wires (R, G, B, GND) from the controller to each LED! So the standard solution is to daisy-chain them. In other words, each LED is connected to the next until the last one is connected to the controller. Particularly popular with the Maker crowd are the WS281x series LEDs (more commonly known as "Neo-Pixel") that can be daisy-chained with as little as three wires by using a cleverly designed single-wire serial protocol. I decided to use the same technique, maybe even to make something that's compatible with the WS28', only 50x more powerful.</div>
<div>
Having considered different approaches (including using the WS2811 and boosting its current), I eventually opted for having a little MCU (PIC12F1571) on each module as well as 3 discrete constant current drivers. My goal was to optimize for cost (I made 50 of these, so every dime matters) while maintaining a nice feature set. I managed to reduce the cost to about $3/module at quantity 50, which is pretty good I think.</div>
<div>
The boards were made at <a href="https://oshpark.com/" target="_blank">OSH Park</a> (awesome!!!) Making 50 of something is not like making 1 or 2. Soldering by hand is prohibitively slow (around 20 small parts on each module). I've been wanting to try poor-man's reflow soldering for a while now, so this was a good excuse. Big shout out to <a href="http://www.oshstencils.com/%C2%A0" target="_blank">OSH Stencils</a> (surprisingly unrelated to OSH Park) that make cheap solder paste stencils in small quantities and fast. The stencil is a piece of Kapton film that is placed on top of the bare PCB and has precision-cut holes in all the places where solder should be applied. A simple jig makes alignment of the stencil with respect to the PCB fast and accurate. A single swipe of a squeegee puts solder paste on all the pads. Then the components were manually placed with tweezers. This has now become by far the most time-consuming step of the process. Once the components are all in place, several modules at a time can be put on a hot electric skillet. Shortly, the solder paste melts and all the components are cleanly soldered to their pads. That easy. 100% yield after the first batch that easily revealed what I should look out for when applying the paste (answer: apply some pressure on the squeegee to keep the stencil tight against the board and the paste layer as thin as the stencil). The LEDs were the only part soldered by hand on the opposite side of the board. I think I'm going to use this technique a lot going forward: the extra few bucks for the stencil are totally worth the time savings and superior quality of the product.</div>
<div style="text-align: center;">
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-Lwffm8qiS0Y/U6ds8c5sJfI/AAAAAAAA3BA/KTgCOyL7EAk/s1600/IMG_20140615_171236374_HDR.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="200" src="http://1.bp.blogspot.com/-Lwffm8qiS0Y/U6ds8c5sJfI/AAAAAAAA3BA/KTgCOyL7EAk/s1600/IMG_20140615_171236374_HDR.jpg" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">An LED module on the solder paste jig</td></tr>
</tbody></table>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-rZlST6zOuoE/U6ds8ZsPhpI/AAAAAAAA3DQ/aUn4AEyPcRw/s1600/IMG_20140615_171250262.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="200" src="http://2.bp.blogspot.com/-rZlST6zOuoE/U6ds8ZsPhpI/AAAAAAAA3DQ/aUn4AEyPcRw/s1600/IMG_20140615_171250262.jpg" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The stencil is perfectly aligned with the PCB</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-dx3XVS3gRms/U6ds8VEh-YI/AAAAAAAA3BA/TTho3-lG7xc/s1600/IMG_20140615_212107740_HDR.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="200" src="http://1.bp.blogspot.com/-dx3XVS3gRms/U6ds8VEh-YI/AAAAAAAA3BA/TTho3-lG7xc/s1600/IMG_20140615_212107740_HDR.jpg" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Reflow soldering a batch of LED modules on a skillet</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-UmwgH8xmPos/U6ds8UXlC-I/AAAAAAAA3BA/T0mNn74aHhs/s1600/IMG_20140616_232600572_HDR.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="200" src="http://2.bp.blogspot.com/-UmwgH8xmPos/U6ds8UXlC-I/AAAAAAAA3BA/T0mNn74aHhs/s1600/IMG_20140616_232600572_HDR.jpg" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Check out the quality of the solder joints!</td></tr>
</tbody></table>
</div>
<div>
These 8-pin MCUs are awesome! At 50 cents a piece they feature 3 channels of 16-bit PWM, an on-die temperature sensor and 8MIPS without an oscillator over a wide voltage range. They implement the serial protocol in software (bit-banging), running at 800kbps. 3 of the MCU pins are each connected to a constant current driver (comprising a FET, a BJT and a shunt resistor), feeding current to each of the Red, Green and Blue LEDs. Constant current is important for getting a consistent color that is not affected by fluctuation of supply voltage, variation of the LEDs, etc. Since the LED modules are dissipating a lot of heat (5W at full brightness), they can get dangerously hot if left on for long. Thus, I used the on-die temperature sensor to shut down if the temperature exceeds 60°C. Another protection feature is to handle cases of software malfunction or loss of communication with the controller. For that purpose I've used the hardware watchdog on the PIC, so that if we don't successfully decode a new command for 2 seconds, we reboot (and as a side-effect turn the LED off).</div>
<div>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-Vf0v7OTGzes/U5f8Ka3wDSI/AAAAAAAA3BA/KGAKfVr2SCg/s1600/IMG_20140610_242534405.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="200" src="http://3.bp.blogspot.com/-Vf0v7OTGzes/U5f8Ka3wDSI/AAAAAAAA3BA/KGAKfVr2SCg/s1600/IMG_20140610_242534405.jpg" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">First assembled LED module, instrumented for firmware development</td></tr>
</tbody></table>
The serial protocol is pretty simple and clever: "zeros" and "ones" are represented by pulses of different widths (durations) on the wire. Each node in the chain consumes the first 24-bits it receives to be its own color, then echoes any following bits to the output (connected to the next node in the chain). When the line is silent (neither zeros nor ones) for a certain duration (milliseconds), all nodes latch at once (i.e. set the color of the LED to the given command and start listening for a new command again). In order to meet the high bandwidth requirements (they translate to allowing long chains at good refresh rates), I wrote assembly interrupt handlers with carefully calculated timing.
</div>
<div>
Once I had everything ready and tested, I wired 48 modules in a long chain using silicon-insulated wires. These wires are very flexible and durable.</div>
<div style="text-align: center;">
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-ozCMuZYCJhY/U6ds8TAwT5I/AAAAAAAA3BA/2MkU1xo1lwk/s1600/IMG_20140621_221510259_HDR.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="200" src="http://1.bp.blogspot.com/-ozCMuZYCJhY/U6ds8TAwT5I/AAAAAAAA3BA/2MkU1xo1lwk/s1600/IMG_20140621_221510259_HDR.jpg" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Many LEDs</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-exzHbaIWNIg/U6ds8cU8UMI/AAAAAAAA3BA/mkbFxA48ak0/s1600/VID_20140615_234333069.mp4" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="200" src="http://4.bp.blogspot.com/-exzHbaIWNIg/U6ds8cU8UMI/AAAAAAAA3BA/mkbFxA48ak0/s1600/VID_20140615_234333069.mp4" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">First test of daisy-chaining </td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-qWzh58yvmtI/U-PLB9RiOTI/AAAAAAAA5tM/8YmpJGn2HcI/s1600/IMG_20140806_232246532.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="200" src="http://3.bp.blogspot.com/-qWzh58yvmtI/U-PLB9RiOTI/AAAAAAAA5tM/8YmpJGn2HcI/s1600/IMG_20140806_232246532.jpg" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Every little task becomes time consuming at large quantities</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-1oy5DiNtmyQ/U-PLB1duL2I/AAAAAAAA5tU/5i-hI350L5w/s1600/IMG_20140806_232347749.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="200" src="http://1.bp.blogspot.com/-1oy5DiNtmyQ/U-PLB1duL2I/AAAAAAAA5tU/5i-hI350L5w/s1600/IMG_20140806_232347749.jpg" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Making holes for the LEDs using a soldering iron</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-wYpfTn_FnW8/U-PLB3NcYmI/AAAAAAAA5rw/-HIhaq9t4-M/s1600/IMG_20140806_232416114.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="200" src="http://1.bp.blogspot.com/-wYpfTn_FnW8/U-PLB3NcYmI/AAAAAAAA5rw/-HIhaq9t4-M/s1600/IMG_20140806_232416114.jpg" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The module is attached to the inside with only the LED peeking through the hole</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-DYRMk37i1rQ/U-PLBxyMe9I/AAAAAAAA5sU/bc5_ua-LKvY/s1600/IMG_20140806_232526933_HDR.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="200" src="http://3.bp.blogspot.com/-DYRMk37i1rQ/U-PLBxyMe9I/AAAAAAAA5sU/bc5_ua-LKvY/s1600/IMG_20140806_232526933_HDR.jpg" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Outside close-up view of an LED</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-WwgRxoUkSUY/U-PLBwz8cJI/AAAAAAAA5rw/Gpx3-Ft_FrU/s1600/IMG_20140807_083905057.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="200" src="http://2.bp.blogspot.com/-WwgRxoUkSUY/U-PLBwz8cJI/AAAAAAAA5rw/Gpx3-Ft_FrU/s1600/IMG_20140807_083905057.jpg" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">All LED modules attached (jacket is inside out) prior to wiring</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-gO3fs51yvnw/U-PLB7xRzRI/AAAAAAAA5to/nN2WA_iGQ-o/s1600/IMG_20140807_084222618.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="200" src="http://2.bp.blogspot.com/-gO3fs51yvnw/U-PLB7xRzRI/AAAAAAAA5to/nN2WA_iGQ-o/s1600/IMG_20140807_084222618.jpg" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Outside view with all the LEDs attached</td></tr>
</tbody></table>
</div>
<h3>
Power System</h3>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-SkwQFW4OtrQ/U5f8KRwKKMI/AAAAAAAA3BA/mF8AyWElqk8/s1600/IMG_20140610_242051420_HDR.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="200" src="http://3.bp.blogspot.com/-SkwQFW4OtrQ/U5f8KRwKKMI/AAAAAAAA3BA/mF8AyWElqk8/s1600/IMG_20140610_242051420_HDR.jpg" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Buck regulator PCB</td></tr>
</tbody></table>
<div>
The LED modules are all designed for a 5V operation. Each LED module takes around 1A when fully on. I designed the power system so that it is able to deliver up to 5A continuously. In other words, I had to constrain my software so that the maximum current is not exceeded. I designed a buck regulator module around the TPS54560 chip. One of the nice features of this chip is that it is pretty easily configurable for different input and output voltages, current limit, etc. So the module I designed and the spare board I now have can easily be used on my next project. Power is supplied by two 2S LiPo packs with 5Ah capacity, for a total of about 75Wh. Under normal usage this can easily last all night on a charge. The two packs were connected in series to form a 4S pack with a nominal voltage of 14.8V. I've also joined the balance connector of the packs, so the battery interface looks exactly like an off-the-shelf 4S pack despite the fact that it is split in two (for ergonomic reasons). I also hooked up a cheap off-the-shelf LiPo voltage indicator / buzzer alarm to be able to constantly monitor the cell voltage and protect against over-discharge.
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-djQdocWp5QA/U5f8KcnCQlI/AAAAAAAA3BA/Z2OfyrxaN2Q/s1600/IMG_20140610_242317394_HDR.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="200" src="http://2.bp.blogspot.com/-djQdocWp5QA/U5f8KcnCQlI/AAAAAAAA3BA/Z2OfyrxaN2Q/s1600/IMG_20140610_242317394_HDR.jpg" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Buck module, hardened and ready to go </td></tr>
</tbody></table>
</div>
<div>
For safety reasons, I mounted the batteries inside safety LiPo pouches made out of thick flame-proof silicon fabric. The pouches where Velcro'ed to the inside of the jacket so that if worst comes to worst (in extreme cases LiPo batteries can ignite), I can quickly remove them from my body.
</div>
<h3>
Controller</h3>
<br />
<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-2GeirLpIeFM/VBkjV1SoY_I/AAAAAAAA6d0/vSqRTCQ1z00/s1600/controller-mounted.PNG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="200" src="http://4.bp.blogspot.com/-2GeirLpIeFM/VBkjV1SoY_I/AAAAAAAA6d0/vSqRTCQ1z00/s1600/controller-mounted.PNG" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Controller mounted</td></tr>
</tbody></table>
<div>
Just for the hell of it, I wanted the controller to be somewhat fancy. I resisted my initial urge to make a IOIO-based controller, because I wanted the jacket to be 100% standalone. I did, however, use the same MCU that's used on the IOIO, both because it's awesome and because I'm very familiar with it and I have many of them lying around the house. The controller board features:</div>
<div>
<ul>
<li>A PIC24FJ256DA206 MCU.</li>
<li>A 128x32 pixel, white OLED display module that I got from eBay on the cheap. It talks to the MCU over SPI.</li>
<li>A rotary + push encoder (knob that can be either turned or pushed) for input.</li>
<li>A tiny microphone with some analog magic circuitry that extracts the audio envelope on a logarithmic scale. The output is fed to an analog input.</li>
<li>A 3-axis accelerometer. It talks to the MCU over I²C.</li>
<li>An output for the LED chain, which also powers the controller.</li>
<li>Several extension ports (digital, analog, I²C, UART, etc.) - I have some ideas for improvements :)</li>
</ul>
</div>
<div>
Being all spoiled from the LED modules, I've ordered a stencil for that one too, even though I only needed one. It was up and running in no time.</div>
<div>
I chose to use an RTOS to facilitate easy authoring of the software while maintaining a very low power consumption when the LEDs are not running. FreeRTOS was a natural choice for me, as it is free and also very familiar to me. There are two main tasks: the higher priority task reads the microphone and controls the LEDs at 50 frames per second; the lower priority task handles the UI (display + knob). The UI presents a list of available LED animations that can be scrolled through by turning the knob and activated by pressing it. I developed a framework that makes it very easy to author new animations, so it was then easy to quickly make about 20 such programs with different feels. Most of them are random in nature because I like this style.<br />
An animation gets a reading of the audio level and acceleration on every frame in case it wants to react to any of them. Due to lack of time, I ended up not implementing the accelerometer feature.</div>
<div style="text-align: center;">
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-_M0MHxAqkp4/VBkjVgU0qQI/AAAAAAAA6d4/6bGL8cUJZMM/s1600/controller-front.PNG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="200" src="http://3.bp.blogspot.com/-_M0MHxAqkp4/VBkjVgU0qQI/AAAAAAAA6d4/6bGL8cUJZMM/s1600/controller-front.PNG" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Controller front (OLED, knob, microphone)</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://2.bp.blogspot.com/-_39MmJZloMc/VBkjVPqnCdI/AAAAAAAA6ds/PX-R5tLTZgc/s1600/controller-back.PNG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="200" src="http://2.bp.blogspot.com/-_39MmJZloMc/VBkjVPqnCdI/AAAAAAAA6ds/PX-R5tLTZgc/s1600/controller-back.PNG" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Controller back</td></tr>
</tbody></table>
</div>
<h3>
Aftermath</h3>
<div>
Off to Black Rock City, NV (where Burning Man lives)! The jacket was a huge success. A lot of people came over to compliment, ask questions and takes pictures. One of the first people who saw me passing by with my "Mr. Pink" animation (fast random blinks of shades of red / pink / white) said: "Hey! This is so cool! You look like you're leaving a trail of fairy dust behind you". From that moment on I shall be know on the Playa as <b>Fairydust!</b></div>
<div>
As with every project, not everything went perfectly. The LED modules are not as robust to their noisy power lines as I had hoped, so every once in a while one of them might suddenly have the wrong color on for a split second. However, I think the general idea was good. I'm considering making another revision on those modules and perhaps offer them as a product (think super-bright drop-in replacement for NeoPixels). If you're interested, drop me a comment below and it will increase the likelihood that I'll actually get myself to do this.</div>
<div>
And last, I've now started working on a scaled-down version (lower power, simpler, lower cost) to use as magician costumes for my kids for Halloween.</div>
Ytaihttp://www.blogger.com/profile/05373159288627167940noreply@blogger.com5tag:blogger.com,1999:blog-4289452895058070746.post-67900373180172499822013-11-05T11:47:00.001+02:002013-11-05T11:48:03.267+02:00How I Became an Artist<h2>
The IOIO Plotter strikes again!</h2>
I'll start with a story and move on to some technical detail on my cool new image processing algorithm.<br />
A couple of weeks ago I was presenting in East Bay Maker Faire with my friend Al. I was showing off <a href="http://ytai-mer.blogspot.com/2013/05/ioio-plotter-and-motor-control-library.html" target="_blank">my plotter</a> among other things, taking pictures of by-passers, making their edge-detection-portrait and giving it to them as a gift. At some point, a woman came in, introduced herself as a curator for an art and technology festival called Codame and invited us to come and present our works there.<br />
<br />
Frankly, at this point I had no idea what Codame was and pretty much decided not to go. Fortunately, I have friends that are not as stupid as me, and a couple of days later Al drew my attention to the fact that some reading on <a href="http://codame.com/" target="_blank">codame.com</a> and our favorite search engine suggested that this is going to be pretty badass.<br />
<br />
OK, so we both said yes, and now we're a week from D-day and I decide that presenting the same thing again would be boring, and anyway edge detection is not artistic enough... I had a rough vision in my head about some random scribbles that would make sense when viewed from a distance, but didn't quite have an idea how to achieve that. But at this point I become mildly obsessed with this challenge, as well as mildly stressed by having to present the thing by the end of the week, so I gave up sleep and started trying out my rusty arsenal of computer vision and image processing tools from days long forgotten.<br />
<br />
I got lucky! Two nights later, and there it was. Just like I imagined it!<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-qdzU7J-pHrY/UnivEiljkdI/AAAAAAAAvcc/252TgyRmiZE/s1600/Screen+Shot+2013-11-05+at+12.38.55+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="479" src="http://4.bp.blogspot.com/-qdzU7J-pHrY/UnivEiljkdI/AAAAAAAAvcc/252TgyRmiZE/s640/Screen+Shot+2013-11-05+at+12.38.55+AM.png" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
If you step away from your monitor a few meters (or feet if you insist) the right picture will start looking like the left one. And if you zoom in, it looks like nothing really. It's all, by the way, a single long stroke, made out of straight line segments.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
From this point, all that was left is to not sleep a few more nights and integrate this algorithm into my Android app that controls the plotter. Barely made it, as usual. The first end-to-end plot saw the light of day in the morning of the opening.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The event was amazing! Seriously, everyone reading this blog who happens to be around San-Francisco should check it out next time. The Codame organization is committed to giving a stage and other kinds of help to works of art that the conventional art institution refuses to acknowledge: art made by code, by circuits, by geeks and by engineers. The exhibits included a lot of video art, computer games and mind-boggling installations as well as tech-heavy performance arts (music and dance).</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
My plotter worked non-stop and I was on a mission to cover an entire wall with its pictures. By the end of two evenings, covered it was! I even gave away some. The reactions where very positive - watching people stand in front of this piece fascinated and smiling joyfully was worth all the hard work. The first time one of them approached me and asked "are you the artist?" I looked behind me to see who he was talking to. "No", I said, "I'm an engineer". But after the tenth time, I just smiled and said "yes" :)</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-_En3jQbH9x0/UncM6BrPHtI/AAAAAAAAN_A/_a47fC5_2w8/w949-h712-no/IMG_0162.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="480" src="http://3.bp.blogspot.com/-_En3jQbH9x0/UncM6BrPHtI/AAAAAAAAN_A/_a47fC5_2w8/w949-h712-no/IMG_0162.JPG" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Now for the geeky part of our show.</div>
<h2>
How Does It Work?</h2>
<div>
After struggling with complicated modifications on Hough transform and whatnot, the final algorithm is surprisingly simple. So much so, that I wouldn't be surprised if somebody has already invented it.</div>
<div>
The main idea is:</div>
<div>
<ul>
<li>At every step (generates one segment), generate N (say, 1000) random candiate lines within the frame. Each line can have both its points random or one point random and the other one forced to where the previous step ended, in order to generate a one-stroke drawing line the one above.</li>
<li>From those N lines, choose the one for which the average <b>darkness</b> it covers in the input image is the greatest.</li>
<li>Subtract this line from the input image.</li>
<li>Repeat until the input image becomes sufficiently light.</li>
</ul>
<div>
A small but important refinement is now required. If we do just that, the algorithm will helplessly try to cover every non-white pixel with black and especially will have an annoying tendency to get stuck in any dark area for too long and darken it too much. To fix that, instead of thinking of a black line as a black line of thickness 1, let's think about it as a 20% gray line of thickness 5 (or any other such reciprocal pair). The intuition behind this is that when viewed from far (or down-sampling), a thin black line darkens its entire environment slightly rather than covers a very small area in black.</div>
</div>
<div>
<br /></div>
<div>
In practice, an efficient way to implement this is simply to work on an input image resized at 20% and draw 20% gray lines on it. Saves a lot of computations too. The coordinates of the actual output lines can still be of arbitrarily fine resolution, limited only by the resolution of our output medium.</div>
<div>
<br /></div>
<div>
Source code, you way? Here: <a href="https://github.com/ytai/ScribblerDemo">https://github.com/ytai/ScribblerDemo</a></div>
<br />Ytaihttp://www.blogger.com/profile/05373159288627167940noreply@blogger.com5tag:blogger.com,1999:blog-4289452895058070746.post-23611179980268011372013-10-20T09:03:00.003+03:002021-04-07T02:00:38.108+03:00Who Wants a IOIO-OTG for $30?<div class="separator" style="clear: both; text-align: center;"><a href="https://1.bp.blogspot.com/-IjuyXRdU7po/YGzoCx3SNfI/AAAAAAAB0uE/j9xNQS-O0rIdJFMCCv2F4SdPJH7TzNXDwCLcBGAsYHQ/s1063/Screen%2BShot%2B2021-04-06%2Bat%2B3.58.20%2BPM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="709" data-original-width="1063" src="https://1.bp.blogspot.com/-IjuyXRdU7po/YGzoCx3SNfI/AAAAAAAB0uE/j9xNQS-O0rIdJFMCCv2F4SdPJH7TzNXDwCLcBGAsYHQ/s320/Screen%2BShot%2B2021-04-06%2Bat%2B3.58.20%2BPM.png" width="320" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div>
<br />
No, this is picture not a negative: it's <a href="http://www.seeedstudio.com/depot/shopping_cart.html" target="_blank">the new IOIO-OTG from SeeedStudio</a>!<br />
<h4>
What's new?</h4>
<br />
<ul>
<li>It's black.</li>
<li>It's selling for <b>$30</b>, including male and female headers and a USB-OTG cable.</li>
</ul>
<div>
Otherwise it's exactly the same.</div>
<h4>
Why?</h4>
<br />
Since I set out to develop the IOIO-OTG I had a goal of making the end-user price be $30. For various reasons that didn't quite work out on the first attempt, but I kept pursuing this goal, with the belief that this is the right price for it. I got strong recommendations on SeeedStudio from Shenzhen, China and soon contacted them with an offer. I was not disappointed! They were very enthusiastic to collaborate and very professional. Working together with them, I closely inspected their manufacturing and testing procedures and I'm happy to report that the quality of their boards meets my highest standards, and I feel that they are very serious and committed to quality and user happiness.<br />
We decided to make it black in order to differentiate it from the existing boards and get people's attention. I also personally love the way it came out looking.<br />
So a big shout-out to those guys for all their hard and excellent work, and I encourage you to support them and the healthy competition they are bringing.<br />
<h4>
What's next for IOIO?</h4>
<div>
I'm now working full-steam on the next software release. It will include:</div>
<div>
<ul>
<li>The motor control library mentioned on my previous post. Took me a while to get it from "working" to "polished" state.</li>
<li>The IOIO-OTG can also work as a USB slave with Android devices that support USB-OTG. That means that the IOIO can be powered by the Android without needing an external power source. This is a contribution by my friends Misha and Nadir (thanks!).</li>
<li>Some bug fixes and cleanup.</li>
</ul>
<div>
I'm also planning a small hardware revision that will add some improved protection against input voltage surges. My friends from Seeed drew my attention to a subtle problem with the current design which I'm intending to fix with that. Stay tuned!</div>
</div>
Ytaihttp://www.blogger.com/profile/05373159288627167940noreply@blogger.com11tag:blogger.com,1999:blog-4289452895058070746.post-76100037536724882762013-05-14T10:11:00.000+03:002013-10-10T08:22:14.289+03:00IOIO Plotter and the Motor Control Library<div class="separator" style="clear: both; text-align: center;">
<iframe align="center" allowfullscreen="" frameborder="0" height="360" src="http://www.youtube.com/embed/5v_nz6qzoZ4" width="640"></iframe>
</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
This is the story of how I built my Android/IOIO/OpenCV-based interactive plotter, as well as the soon-to-be-released motor control library for the IOIO. I'll tell the story of the plotter from the bottom up, which is the order in which I've designed and built it. But before diving into the geeky technical details, a few words about the final product.</div>
It started with me looking for a cool example application for the motor control library I was about to develop for the IOIO, and have this application something I can present in Maker Faire. I wanted it to demonstrate the ability to control some multi-axis machine in a simple, reliable and precise way using high-level Java code running on an Android or a PC. I finally decided on the plotter, as it seemed like a fun thing to make as well as an interesting piece to exhibit. The plotter is based on a very elegant design, which unfortunately isn't my idea (just Google for "whiteboard plotter"). Since building yet-another-one is boring, I wanted to make this one with a twist, taking advantage of the fact that I can easily put an Android device in the system. So my plotter is interactive in that you take a picture with it and it would immediately convert it to paths (via edge detection) and plot them.<br />
Now we're ready for the geeky stuff :)<br />
<h2>
Ultra-Productive Development Environment</h2>
My friend and colleague Anton Staaf, has introduced me to a really cool development strategy he's been using on his projects. He developed this nice little "shell" library, which is essentially a simplified, very portable command shell, to which it is very easy to add new commands. I borrowed his code, and ported it to the PIC24, using the USB CDC as the underlying serial link. Shortly after, I had a IOIO board which I could plug into the USB port of my PC, open a "screen" session to and run commands to exercise whichever new features I'm working on. Combined with the device-mode bootloader of the IOIO-OTG, I was able to have super fast cycles of code-compile-flash-test. It was really fun to work like that. I'm hoping to eventually release this shell-app for the IOIO for others to hack with - it's totally awesome!<br />
Another tool which served me really well here is the XProtoLab from Gabotronics. Since this library is all about generating perfectly synchronized, precisely-timed signals, I needed a way to validate the output signals. I don't have a scope or a digital analyzer, but the XProtoLab is a tiny, beautifully designed, tiny oscilloscope, logic analyzer and signal generator. I bought this one second hand for $30 a while back and it is worth its weight in gold. Highly recommended!<br />
Now I was in good position to start playing around with some ideas for how my library will work, which I eventually ported into the proper IOIO app firmware.<br />
<h2>
H-A-R-D-R-E-A-L-T-I-M-E</h2>
OK, so I develop realtime software for a living, but I never before got to <i>this</i> level of realtime...<br />
I initially drafted the following design principles:<br />
<br />
<ul>
<li>The IOIO will play the role of a sequencer. It will have a buffer of "cues", which keeps getting filled by the client (Android or PC). Those cues are essentially "over this period of time, I want this channel to do this and that channel to do that". A channel can be for example a stepper motor pulse train, a PWM signal for a DC motor or a servo or a digital output pin.</li>
<li>As usual with the IOIO library, I want this to happen with as little as possible CPU intervention, so that it can run in parallel with all the other IOIO functions. So I decided I'll use the output compare modules for generating all the pulse signals and a timer for timing the cues.</li>
<li>But stepper signals are slightly tricky, as you want a precise number of steps over the period of the cue. Not one too many, not one too little. Ever. So one might generate those pulses one-by-one, but that would place a lot of burden on the CPU and would be very difficult to time correctly when multiple channels are involved. So I decided I'll just let the pulse trains run freely during a cue, and just be really really precise about stopping them at the right time, before they generate an extra pulse.</li>
</ul>
<div>
So, OK, one might think that setting a timer to interrupt at the highest possible priority should suffice, but it really doesn't, unless you want to be really way too conservative with how close you allow your last step in every cue to get to the cue point. But that would put a very serious limitation on the maximum pulse rate, which I didn't want to do.</div>
<div>
It took my some time to convince myself that C can't cut it. You just <i>can't</i> really know how many cycles your code is going to take. And even if you could, this could change the next time you upgrade your compiler. So I reverted to assembly. It was actually a lot more fun than I expected, after not having done this for years. And the end-result is something I'm really really happy with! Cycle-accurate timings for everything. I know <i>exactly</i> when each instruction runs with respect to the output waveforms and everything is super-fast, so it doesn't place any significant overhead on the CPU. You can do up to about 30KHz signals, up to 9 such in parallel, in addition to twenty-something binary outputs (e.g. for controlling the stepper direction, solenoids, or LEDs), without ever missing a step jittering on the timing by as little as one CPU cycle.</div>
<div>
Of course, it took me about 10 times to complete than it would have in C...</div>
<div>
Here's a little (underground) video I shared a while ago, demonstrating some early stages of the motor control library:</div>
<iframe allowfullscreen="" frameborder="0" height="315" src="http://www.youtube.com/embed/yH54Zq_eDM4" width="420"></iframe>
<br />
<h2>
Protocol Glue</h2>
<div>
From this point, bootstrapping this library to the IOIO protocol was pretty straightforward, and shortly after I had a semi-baked Java API for feeding the sequencer. The current API is pretty bare-metal, and I'm thinking about providing it with some higher level abstraction layer when I release it, or at least a decent set of handy utilities. For the time being, I developed some utilities that are specific to stepper motors, which is what I needed for the plotter.</div>
<h2>
Plotter Design</h2>
<div>
Finally came the time to make the plotter. The design is pretty simple: two pulleys driven by stepper motors controlling the length of two strings. The two strings are joined in one point attached to the carriage. A rather simple geometric transformation can tell you how long you want each of the strings to be in order to get the carriage to a given point on the sheet in XY coordinates.</div>
<br />
On the carriage is a sharpie. In order to minimize the effect of the carriage swinging on the position of the tip of the sharpie, the hanging point, where the strings connect needs to be as close as possible to the tip. This way, even if the carriage tilts a little, the tip won't deviate by a whole lot.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-pV9uZAoXyJA/UlX3xE6siTI/AAAAAAAAvDk/PVLAp3KpCjU/s1600/IMG_20130418_225357.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="150" src="http://2.bp.blogspot.com/-pV9uZAoXyJA/UlX3xE6siTI/AAAAAAAAvDk/PVLAp3KpCjU/s200/IMG_20130418_225357.jpg" width="200" /></a></div>
<br />
I found a neat little trick for the carriage design: when drawing, the carriage is supported by two ball casters and the tip of the sharpie. This way the sharpie stays perpendicular to the sheet. In order to raise the sharpie (for moving the carriage without plotting), a third ball caster is mounted on an actuated linear bearing, driven by a small hobby servo. The servo can push this third caster into the sheet, so that it is "deeper" than the tip of the sharpie, thus causing the carriage to be supported on the three casters and the sharpie tip to float.<br />
<a href="http://1.bp.blogspot.com/-fAa6v2jGFhQ/UlX3xFc1NTI/AAAAAAAAvDk/C1Y3iiS84kI/s1600/IMG_20130428_204631.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="150" src="http://1.bp.blogspot.com/-fAa6v2jGFhQ/UlX3xFc1NTI/AAAAAAAAvDk/C1Y3iiS84kI/s200/IMG_20130428_204631.jpg" width="200" /></a>
<a href="http://4.bp.blogspot.com/-k3v5Ft9_1aM/UlX3xGWVklI/AAAAAAAAvDk/HzBCevk64ts/s1600/IMG_20130428_204658.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="150" src="http://4.bp.blogspot.com/-k3v5Ft9_1aM/UlX3xGWVklI/AAAAAAAAvDk/HzBCevk64ts/s200/IMG_20130428_204658.jpg" width="200" /></a>
Oh, and remember that I just used the fancy term "linear bearing", causing you to imagine some precision machined awesomeness? Think more like a piece of a shampoo bottle pump in this case :) What can I say, I just hate waiting for parts to arrive or worry about how to fabricate the perfect bearing, when all I really care about is getting this app up and running...<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-84rSVMcGQtY/UlX3xD44-uI/AAAAAAAAvDk/o7WIogu3C1o/s1600/IMG_20130428_204645.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="150" src="http://3.bp.blogspot.com/-84rSVMcGQtY/UlX3xD44-uI/AAAAAAAAvDk/o7WIogu3C1o/s200/IMG_20130428_204645.jpg" width="200" /></a></div>
<br />
Another little trick I found is for mounting the main assembly (with the motors and pulleys) on the easel: I used some square pieces of plastic, originally intended for hot cups, and bent them with the hot air gun I used for soldering. It ended up pretty cool, and I can easily unmount the thing for transportation.<br />
And of course, the IOIO is mounted on the front, and a pair of DRV8825 stepper drivers behind it to help with the heavy-lifting. I dialed them to about 1A per motor, which seems to work well.<br />
<h2>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-22X2YVoGvbE/UlX3xNDssdI/AAAAAAAAvDk/CWg34sYm-mY/s1600/IMG_20130428_204618.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="200" src="http://4.bp.blogspot.com/-22X2YVoGvbE/UlX3xNDssdI/AAAAAAAAvDk/CWg34sYm-mY/s200/IMG_20130428_204618.jpg" width="150" /></a></div>
<br />Now, Plot!</h2>
<div>
There's this part in a project when the hardware is pretty much done and now it's all "just a simple matter of software", as my friend Ed likes to joke. But at this point, having all these million layers of infrastructure at my disposal, I just couldn't wait to draw <i>something</i> with it and see if it's any good. For all I know, I might have a million problems hidden. I coded like crazy for a couple of days, until finally plotting a first circle! Well, let's call it circle-ish, since it did uncover some small mechanical issues that needed addressing. But pretty much, the entire stack of electronics and software worked flawlessly! I wrote some basic utilities to do the coordinate transformations and to expose a high-level Plotter API, which gets an arbitrary list of paths, each represented by x(t), y(t) and plots them.</div>
<div>
<h2>
Pimp Your Plotter</h2>
<div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-2kE1BhgLvB4/UlX3xNJs96I/AAAAAAAAvDk/nlhpisx1w1s/s1600/IMG_20130505_212101.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="150" src="http://2.bp.blogspot.com/-2kE1BhgLvB4/UlX3xNJs96I/AAAAAAAAvDk/nlhpisx1w1s/s200/IMG_20130505_212101.jpg" width="200" /></a></div>
<br />
Since this piece is to be presented, some aesthetics can't hurt. I coincidentally noticed that the pulleys look a lot like yo-yo's and decided to have fun with this concept. My friend Ali took me for an awesome tour in his workshop and let me cut some pieces of MDF on his laser cutter. It's funny that the only precision part in this entire system is the decoration :D</div>
</div>
<h2>
Finally: The App Layer</h2>
So many layers on layers on layers, I finally had a working plotter and it was time for the application. It's been a long time since I wanted to get my hands dirty with OpenCV for Android. It is 100% pure awesome! Makes image manipulation and standard computer vision algorithms really simple to implement. I developed a simple GUI that allows you to pick a picture from your Android gallery (local storage, Web albums or capture an image from the camera), and then interactively tweak the parameters of a Canny edge detector. The detected edges are displayed in red against a grayscale image, so you can easily see what result you are going to get and keep moving the sliders until you're happy.<i>thinning</i> the resulting edges, or otherwise a single edge may actually be two-pixel thick at times, which makes it really annoying to convert into paths. I used the algorithm proposed <a href="http://homepages.inf.ed.ac.uk/rbf/HIPR2/thin.htm" target="_blank">here</a> (thanks, guys!) and implemented it pretty easily with OpenCV. Last, I needed to trace the edges into paths. I did this step pretty dumbly, because I started to run out of time and juice. In the future, it could be pretty nice to:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<a href="http://2.bp.blogspot.com/-1AiHTUtfFo4/UZHM6eyt_ZI/AAAAAAAArOY/ko8Ed2IaT1Q/s1600/screenshot.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="120" src="http://2.bp.blogspot.com/-1AiHTUtfFo4/UZHM6eyt_ZI/AAAAAAAArOY/ko8Ed2IaT1Q/s200/screenshot.png" width="200" /></a>Then, I found that an essential step I needed to take is <br />
<br />
<ul>
<li>Smooth the edges rather than just connect pixels coordinates with straight lines. A nice algorithm to borrow ideas from is <a href="http://potrace.sourceforge.net/potrace.pdf" target="_blank">here</a>.</li>
<li>Be clever about the ordering of paths within an image, so that to attempt minimize the total length of travel of the carriage. In the current implementation, the ordering is pretty stupid, causing the carriage to move from side to side way more than is necessary, significantly slowing down the process.</li>
</ul>
<h2>
Aftermath</h2>
<div>
This weekend I'm going to present this project, along with some other IOIO projects in the Maker Faire Bay Area 2013. If you happen to be around, drop by to say hi. Special thanks to my good friend Al Linke, who made the video shown at the top. Al has made some awesome IOIO-based projects himself, and is going to share the booth with me in Maker Faire.<br />
<hr />
<i><span style="font-family: Georgia, Times New Roman, serif;">I intend to release the motor control library within a few weeks for everybody to enjoy. I hope it will pave the way for driving 3D printers and other CNC machines with a IOIO/Android combo, which seems to me like an elegant way for giving these machines a great user interface, standalone computing and connectivity on the cheap.</span></i><br />
<hr />
Some more fun pictures for those who persisted this far.</div>
<center>
<a href="http://4.bp.blogspot.com/-vfDdn-4M5ro/UlX3xLZhByI/AAAAAAAAvDk/JGL8WvsFdY4/s1600/photo.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://4.bp.blogspot.com/-vfDdn-4M5ro/UlX3xLZhByI/AAAAAAAAvDk/JGL8WvsFdY4/s200/photo.jpg" width="171" /></a><a href="http://3.bp.blogspot.com/-XpjHCbZss_Y/UlY1DuhxPSI/AAAAAAAAvDw/VhE8iImcELM/s1600/DSC00310.JPG" imageanchor="1" style="clear: left; display: inline !important; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="212" src="http://3.bp.blogspot.com/-XpjHCbZss_Y/UlY1DuhxPSI/AAAAAAAAvDw/VhE8iImcELM/s320/DSC00310.JPG" width="320" /></a>
<a href="http://3.bp.blogspot.com/-S6cEiIsAdt8/UZHXyQdUxdI/AAAAAAAArPg/0uEIOQbkC9U/s1600/photo.jpg" imageanchor="1"><img border="0" height="200" src="http://3.bp.blogspot.com/-S6cEiIsAdt8/UZHXyQdUxdI/AAAAAAAArPg/0uEIOQbkC9U/s200/photo.jpg" width="150" /></a><a href="http://2.bp.blogspot.com/-GT3VtQgD4XQ/UlY16v_S5cI/AAAAAAAAvD4/Qd7doDcAoMU/s1600/DSC00231.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="132" src="http://2.bp.blogspot.com/-GT3VtQgD4XQ/UlY16v_S5cI/AAAAAAAAvD4/Qd7doDcAoMU/s200/DSC00231.JPG" width="200" /></a><a href="http://1.bp.blogspot.com/-BrrKP5hYIpw/UlY17KIr9iI/AAAAAAAAvEA/Aacn1-lrxRo/s1600/DSC00300.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="133" src="http://1.bp.blogspot.com/-BrrKP5hYIpw/UlY17KIr9iI/AAAAAAAAvEA/Aacn1-lrxRo/s200/DSC00300.JPG" width="200" /></a>
<a href="http://1.bp.blogspot.com/-bNaPBVdBML8/UlY16EIgLHI/AAAAAAAAvD0/_qytJZ1aoYE/s1600/DSC00340.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="133" src="http://1.bp.blogspot.com/-bNaPBVdBML8/UlY16EIgLHI/AAAAAAAAvD0/_qytJZ1aoYE/s200/DSC00340.JPG" width="200" /></a><a href="http://3.bp.blogspot.com/-q_YHB_bec8A/UlY183oxuhI/AAAAAAAAvEM/8cO3lYMmw78/s1600/DSC00341.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="133" src="http://3.bp.blogspot.com/-q_YHB_bec8A/UlY183oxuhI/AAAAAAAAvEM/8cO3lYMmw78/s200/DSC00341.JPG" width="200" /></a>
<iframe allowfullscreen="" center="" frameborder="0" height="300" src="http://www.youtube.com/embed/yrbR7YBeXZ8" style="display: inline; vertical-align: middle;" width="400"></iframe>
</center>
Ytaihttp://www.blogger.com/profile/05373159288627167940noreply@blogger.com25Sunnyvale, CA 94087, USA37.3492097 -122.0326019000000337.298720700000004 -122.11328290000003 37.3996987 -121.95192090000003tag:blogger.com,1999:blog-4289452895058070746.post-45170986712836818172013-01-25T12:43:00.001+02:002013-01-25T12:43:33.453+02:00Go, Go, IOIO-On-The-Go!<a href="http://4.bp.blogspot.com/-NtccMO1M7f4/UDhhwrx26UI/AAAAAAAAjTI/xwTI4Fb8xVQ/s1600/ioio-logo.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="96" src="http://4.bp.blogspot.com/-NtccMO1M7f4/UDhhwrx26UI/AAAAAAAAjTI/xwTI4Fb8xVQ/s320/ioio-logo.png" width="320" /></a>A year and nine months passed since <a href="http://ytai-mer.blogspot.com/2011/04/meet-ioio-io-for-android.html">the first announcement</a> on the IOIO. Eight months flew by since <a href="http://ytai-mer.blogspot.com/2012/05/second-generation-of-ioio-is-in-works.html">my announcement</a> on the upcoming IOIO-OTG. Almost a year since I started development. Waaaaaay longer than planned. Everything that could have gone wrong went wrong. Hell, even some things that <i>couldn't</i> have gone wrong went wrong! But finally:<br />
<br />
<span style="font-size: x-large;">IOIO-OTG is <a href="https://www.sparkfun.com/products/11343">HERE</a>!!!</span><br />
<br />
Let's start from scratch, as for some of the readers (who've spent the last two years on Mars) this might be your first encounter.<br />
<br />
<h2>
I/O for the I/O-less</h2>
<div>
The IOIO-OTG is a printed circuit board for electronics hobbyists and prototypers, which addresses a very common problem: how do I use my {computer, tablet, phone} to control my {robot, dish-washer, cat-feeder, etc.}. The original IOIO board was the first to offer a complete solution to this problem for Android devices. The IOIO-OTG adds PC support (Windows, Linux, OSX).</div>
<div>
<br /></div>
<div>
<a href="http://1.bp.blogspot.com/-DXI9yvREVkc/UQJO9PlVgnI/AAAAAAAAnL0/NVZ1P7ekShM/s1600/board-nobg.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="163" src="http://1.bp.blogspot.com/-DXI9yvREVkc/UQJO9PlVgnI/AAAAAAAAnL0/NVZ1P7ekShM/s200/board-nobg.png" width="200" /></a>Unlike most other solutions, requiring you to write two pieces of software (board and client), at least one of which is typically complicated, the IOIO takes a different approach, by only requiring you to write the client-side (Android, PC) software, using a high-level programming language (currently Java) with a rich and intuitive API that allows you to manipulate the I/O pins and hardware peripherals on the board, giving you the experience that those I/O capabilities are actually an integral part of your client machine. This feature of the IOIO makes prototyping and development with it very fast and simple. Another great selling point is that it can work with virtually <i>any</i> Android device, even very old ones (Android 1.5 or higher), while most other boards would only work with the latest and greatest.</div>
<div>
<br /></div>
<div>
You can connect the IOIO to its client either over USB or over Bluetooth (using a standard dongle). The pre-installed firmware and the provided software library completely hide away the gory details of the underlying connection. The same code you write will work over either connection type seamlessly.</div>
<div>
<br /></div>
<h2>
Smaller, Cheaper, Stronger</h2>
<div>
The IOIO-OTG is significantly smaller in size and/or cheaper and/or richer in features than alternative solutions. For example, in the Android world, the IOIO-OTG's I/O specs are comparable with an Arduino Mega ADK at a fraction of the size and cost and with all the software advantages mentioned above. In the PC world it would provide an attractive competition as well to boards of similar capabilities, and once again, the savings on software development time are huge.</div>
<div>
<br /></div>
<div>
To make it super-loud-and-clear: I'm not making a case that IOIO-OTG is better than Arduino or vice-versa. Arduino is awesome for what it's good at, which is IMHO for standalone operation. The IOIO boards were never intended to work standalone, but excel when it comes to offering I/O to an existing machine that lacks it. There is an ever increasing number of applications that fall into this category, especially due to the attractiveness of using Android devices in physical computing applications, getting tons of sensors, internet connectivity, lots of computation power, touch screen, etc. in a cheap, easy to use package.</div>
<div>
<br /></div>
<h2>
Constantly Improving</h2>
<div>
The IOIO-OTG is all open-source, software, firmware and hardware. The development has been an ongoing process, with new features and bug fixes introduced on a regular basis. New versions of firmware are distributed in a way that makes it very simple for the user to upgrade: connect the IOIO-OTG to a PC and run a simple program to flash the latest version, or your own custom one if you're into such adventures. Download the software package with libraries and examples from the website and you're good to go.</div>
<div>
<br /></div>
<h2>
Hardware Specs</h2>
<div>
That's what we're here for, aren't we? Here are the main features:</div>
<div>
<ul>
<li>USB-OTG dual-role (host, device).</li>
<li>Input voltage: 5V-15V, from external source or through USB (when connected to a computer).</li>
<li>Output voltage: 5V, up to 3A (!), 3.3V, up to 500mA.</li>
<li>46 I/O pins (digital I/O), built-in pull-ups / pull-downs / open-drain on all pins.</li>
<li>16 Analog inputs.</li>
<li>9 PWM (for driving servos, DC motors, dimming LEDs, etc).</li>
<li>4 UART.</li>
<li>3 TWI (I2C, SMBUS).</li>
<li>3 SPI.</li>
<li>6 Pulse Input (precise pulse-width / frequency measurement).</li>
<li>USB current limiting when acting as USB host (useful in Android mode).</li>
<li>Switch for forcing host mode (for using non-standard USB cables, which are more common than the standard ones...)</li>
<li>On-board LED under user control.</li>
</ul>
<div>
For those who know the IOIO V1, the main changes are the dual-role stuff, the beefier 5V regulator and two less I/O pins. There's also improved circuitry for cleaner analog input and better protection against user error (you can still fry it if you really want to :D)</div>
</div>
<div>
<br /></div>
<h2>
Cutting Costs</h2>
<div>
My main goal in this project is to make it available and useful for as many people as possible. Really. No marketing BS here. This is not my day-job. One of the key factors in meeting this goal (assuming the product is great, of course) is making it affordable for as many people as possible. Making it cheaper also means people will be less frustrated if they happen to fry the board, and make people feel more comfortable leaving the board permanently attached to their project and buying a new one for the next project.</div>
<div>
<br /></div>
<div>
In that, I feel that I have yet to improve. We set our goal at $30 end-user price. It is currently about $40, and during the struggle to cut costs I decided to forego my own royalties of the product. I'm not particularly happy about it, to be honest, but I feel like I have done the right thing. I'm currently considering my options for how to reduce the end-user price while leaving a little something for myself too.</div>
<div>
<br /></div>
<h2>
Coming Up</h2>
<div>
<ul>
<li>Raspberry Pi support. Already have a working prototype, but need to polish.</li>
<li>More applicative features: capacitive sensing, extended stepper motor control, encoder interface.</li>
</ul>
<div>
<br /></div>
</div>
<h2>
Thanks</h2>
<div>
Luckily, I didn't do this alone!</div>
<div>
<b>Aaron Weiss from SparkFun</b> took part of the board design and walked me through the winding road of getting a product out the door.</div>
<div>
<b>David Stadler</b> designed the beautiful new graphics, which preserves (and improves) the yo-yo from the IOIO, but gets rid of the only-for-Android feel.</div>
<div>
<b>Kustaa Nyholm</b> contributed his PureJavaComm library to the community, which opened the door for easy PC integration.</div>
<div>
<b>All the IOIO users</b>, who are slowly turning into a nice community, gave me all the inspiration and motivation to keep working when things went the hard way.</div>
<div>
<b>My dear wife, kids and friends</b>, who gave me the huge amount of support required for such a project and for patiently listening to my boring geeky stories all along.</div>
<div>
<br /></div>
<h2>
Read More</h2>
<div>
Main IOIO homepage: <a href="https://github.com/ytai/ioio/wiki">https://github.com/ytai/ioio/wiki</a></div>
<div>
IOIO project gallery (links I'm collecting): <a href="http://pinterest.com/ytaibt/ioio">http://pinterest.com/ytaibt/ioio</a></div>
<div>
My Google+ profile: <a href="https://plus.google.com/u/0/113760481226159480550">https://plus.google.com/u/0/113760481226159480550</a></div>
Ytaihttp://www.blogger.com/profile/05373159288627167940noreply@blogger.com24tag:blogger.com,1999:blog-4289452895058070746.post-84789376026856150152012-05-27T10:26:00.001+03:002012-05-27T10:48:44.621+03:00The Second Generation of IOIO is in the Works<br />
<div class="p1">
<a href="http://3.bp.blogspot.com/-i4N9-6E0KH0/T8HJg1wVy1I/AAAAAAAAgps/5OHMQzg-_rg/s1600/photo.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em; text-align: justify;"><img border="0" height="142" src="http://3.bp.blogspot.com/-i4N9-6E0KH0/T8HJg1wVy1I/AAAAAAAAgps/5OHMQzg-_rg/s400/photo.jpg" width="400" /></a></div>
<div style="text-align: justify;">
It's been a little over a year since IOIO has been released. During this period it has been used by thousands of users world-wide, who published tens of amazing projects. IOIO has become the first and leading product for interfacing Android with external hardware. Several software / firmware upgrades have been successfully rolled out, which added new features and fixed bugs. Two different manufacturers (SparkFun, Jaycon Systems) currently make IOIOs and an alternative form factor boards from SeeedStudio are just starting to sell. A book has been published on making Android accessories with IOIO. I've given a few workshops on IOIO, one of which at the MIT Media Lab, which has always been a dream place for me. Quite a trip! I was expecting something much more modest when I started, but happily jumped on the train.</div>
<div style="text-align: justify;">
<br /></div>
<h2>
Why a New Version?</h2>
<span style="text-align: justify;">During the whole time, I've been constantly gathering user feedback and looking at other products in the same field and have kept asking myself "what is the most important thing to do next?". Eventually, two main points started to emerge, that could not be addressed by software alone:</span><br />
<br />
<div class="p1">
</div>
<ol>
<li style="text-align: justify;">I find that the paradigm of controlling I/O pins remotely (i.e. from an off-board processor) using a high-level Java API works really well. It has proven really great when you can seamlessly move your connection from wired to wireless or when you can easily integrate the capabilities of the host (Android) with the capabilities that IOIO adds. It has proven great when users with Java-only background could now easily be able to communicate with hardware, without needing to write any embedded code and without needing to develop a communication protocol themselves. I believe this paradigm can be just as useful for the PC world. Currently, the standard way to control I/O from a PC is to use an Arduino or a similar board, and having to write two separate programs which communicate with each other. The bandwidth in this case would be typically limited to 115Kb/s, which is far less than what USB is capable of.</li>
<li style="text-align: justify;">IOIO is too expensive. Not for business reasons, because there's hardly any competition, and making it cheaper might actually decrease net revenue. But my goal is increasing the number of units sold and the number of happy users. I'd consider this project a success if IOIO became something everybody knows and loves, and considered the standard and obvious solution for enhancing a host computer with I/O capabilities.</li>
</ol>
<div style="text-align: justify;">
It became apparent that there's enough motivation for a second generation. And so I started! SparkFun were as great as always, and have been very supportive on both goals.</div>
<div style="text-align: justify;">
<br /></div>
<h2>
So... What's New?</h2>
<div style="text-align: justify;">
The next generation of IOIO will be a USB on-the-go (OTG) device. What this means in practice, is that the new IOIO will be capable of acting either as a USB host (like the current IOIO) or as a USB device (allowing it to connect to a PC as well as be powered by it). Moreover, it will be able to auto-detect which is the right role, according to whichever cable is connected to it (a micro-A or micro-B).</div>
<div style="text-align: justify;">
Making the IOIO an OTG device required some modifications to the power-supply module. While I'm at it, I've managed to design a module that is both cheaper and beefier (2A) than the current one. It will also have a resettable protection fuse and will handle current limiting more elegantly than the current IOIO (which simply has a resistor on the VBUS line).</div>
<div style="text-align: justify;">
I considered upgrading the microcontroller, but was happy to find out after searching a little, that the current one (PIC24F) is one of the most peripheral-rich micros out there if not <i>the</i> richest. Since this is the most important aspect of the microcontroller for this application, I decided to leave it alone. Other than that, I've made a few more nice-to-have changes, such as reducing the noise on the analog inputs and reorganizing the power supply pins in a more accessible way (having GND next to each supply).</div>
<div style="text-align: justify;">
<br /></div>
<h2>
The Development Process</h2>
<div class="" style="clear: both; text-align: center;">
</div>
<div style="text-align: justify;">
In order to save time and money, and according to my beloved tradition, I made the first prototype by home-etching. In this case, I took an old IOIO and gave it a heart transplant to replace all that needed replacing. I wish there was an "ugly but works" contest...</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-sASrnWyo3lc/T26-_hBypaI/AAAAAAAAd5M/aDKIcgi11cE/s891/IMG_20120324_234507.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em; text-align: justify;"><img border="0" height="298" src="http://1.bp.blogspot.com/-sASrnWyo3lc/T26-_hBypaI/AAAAAAAAd5M/aDKIcgi11cE/s400/IMG_20120324_234507.jpg" width="400" /></a></div>
<div style="text-align: justify;">
Then it's software time! The firmware took some time to develop, but it is now close to completion. The IOIOLib part was the most fun. It ported from Android Java to PC Java totally smoothly. Finally, just in time for Maker Faire, I finished a fully functional demo, in which I'm running HelloIOIO on a PC, and controlling the IOIO LED over USB or Bluetooth!</div>
<div style="text-align: justify;">
SparkFun also moved quickly, and provided me with the "pretty but doesn't work" prototype pictured at the top of this post. The "doesn't work" part is probably the fault of my soldering, though :D. But it was working enough for demonstrating the new USB device functionality at Maker Faire.</div>
<div style="text-align: justify;">
So we're probably a couple of months away from production and official launch. It is possible that the initial release will ship new hardware, but with software only capable of USB host and I'll release the device mode in Beta first. Not sure yet. We shall see depending on my estimate of the risk at the time of launch.</div>
<div style="text-align: justify;">
<br /></div>
<h2>
Thanks!</h2>
<div style="text-align: justify;">
I'd like to thank all of the users for their trust, support and feedback; to thank SparkFun for being the most awesome partners on the planet and most of all to thank for my family for putting up with my crazy hobbies and excessive work hours.</div>
<br />Ytaihttp://www.blogger.com/profile/05373159288627167940noreply@blogger.com81Sunnyvale, CA, USA37.36883 -122.036349637.3183525 -122.1153136 37.4193075 -121.9573856tag:blogger.com,1999:blog-4289452895058070746.post-75035970897190498612011-10-28T10:35:00.000+02:002011-10-28T10:35:38.083+02:00IOIO Over Bluetooth (or: Who Needs Cables Anyway?)<div style="text-align: justify;">
Pheeeew.... a few long weeks of crunch-mode right about when I moved to California and then to a new house. However, I felt I had to get this done and the Android Open conference in San-Francisco seemed like a good target date. I made it. Barely, but definitely made it.</div>
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/cFlJm86Qtuk?feature=player_embedded' frameborder='0'></iframe></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
OK, now that I got it off my chest, I can tell you what it's all about.
<br />
<h1>
The Short Story</h1>
With a firmware upgrade on the IOIO, it now supports connecting a standard Bluetooth dongle into its USB jack and is able to establish its connection to the Android phone wirelessly! This actually makes IOIO one of the cheapest, simplest and most powerful Bluetooth-enabled prototyping platforms out there. And some more good news: your application code stays exactly the same. That's the way it should be as far as I'm concerned. End-users should care about what they want to do with their hardware for their project, not about how the heck (or how the hack) to communicate with it. So you only need to write the application-specific code (the <a href="https://github.com/ytai/ioio/blob/App-IOIO0310/software/applications/IOIOSimpleApp/src/ioio/examples/simple/IOIOSimpleApp.java">source code for the application demonstrated above</a> takes less than 30 lines of Java for the IOIO-related stuff), and it seamlessly works on any kind of connection and can even switch from one to another while running. I don't know of any existing platforms that will let you do that so easily and cheaply. The closest one probably being Amarino. Keep in mind that IOIO is also capable of USB connectivity to Android of course (ADB or OpenAccessory), giving superior reliability latency and bandwidth compared to Bluetooth. You do the comparison.
<br />
<h1>
The Long Story</h1>
Although I think there is some real kick-ass little revolution here, this post is going to be more of a story than my usual bunch of technical specs. I'm just in this kind of mood more than the check-out-this-awesome-stuff mood.<br />
Back when I published my <a href="http://ytai-mer.blogspot.com/2011/04/meet-ioio-io-for-android.html">original announcement on IOIO</a>, one of the commenters (Inopia, thanks, man!) cleverly noted that since IOIO is a USB host, using a standard Bluetooth dongle in order to make the connection wireless is just a matter of writing the right firmware. He was right! And I immediately fell in love with the idea and with the challenge it presented. I felt that from all the million features I could develop next, this one will be the real killer. Just imagine: a couple of bucks (cheapest dongle I found is $1.80 including shipping from DealExtreme) and you have yourself a whole new range of possibilities: home automation, R/C toys, and much more.</div>
<div style="text-align: justify;">
Slowly I began to realize some really cool side-effects that this will have. First, the current inability (or more precisely, complexity) to use IOIO and debug your Android at the same time would go away. Second, we're no longer limited to an Android - control IOIO from any Bluetooth-enabled device: IOIOLib is just a bunch of Java code that can easily be ported to other platforms (or rewritten if need be). Third, we're no longer limited to just one IOIO controlled by a single host application.</div>
<div style="text-align: justify;">
<a href="http://4.bp.blogspot.com/-1qXL3m8DpWk/Tqpo95xCcjI/AAAAAAAAXOs/sXv2yR2UZnY/s1600/ioio-btstack.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-1qXL3m8DpWk/Tqpo95xCcjI/AAAAAAAAXOs/sXv2yR2UZnY/s1600/ioio-btstack.png" /></a>You get the point. I just had to do it. One problem: I don't know Jack about Bluetooth. Only know enough to know that it's definitely doable. That's where the second key actor in this story comes in. I'm digging the Web for open-source Bluetooth stack implementations. Pretty soon I come across <a href="http://code.google.com/p/btstack/">btstack</a>, developed by Matthias Ringwald. I also found other options, and at that point, I was not completely sure which one to choose. So I contact Matthias and I start checking out the code of several projects, and throw some of them away for lack of maintenance and others for having Spaghetti code. But btstack turns out to be just <b>perfect</b>. Easy to port, very clean code, doesn't use the memory heap (embedded heaven), active maintenance and great discussion and support forum. Matthias really got it right (at least my idea of getting this sort of things right). Two nights later (mostly struggling with implementing the USB driver for the dongle), and I'm able to open an end-to-end connection from my phone to the IOIO. Then a few weeks of finding these tiny, cruel bugs and getting everything nicely packaged and documented, etc.</div>
<div style="text-align: justify;">
And as I said, not a moment too soon! I got to Android Open two days after having a working demo. There I met Aaron Weiss from SparkFun face-to-face for the first time. Aaron is the engineer from SparkFun's side that worked on IOIO from day one. Meeting him and having him stand next to me while presenting was really great!<br />
At the conference, I attended a keynote by Massimo Banzi, one of the two founders of Arduino. I really admire his work, especially after having taught a course on Arduino that enabled non-techie designers build the most awesome stuff. Quite a great keynote he gave, and a little later I've had the honor of presenting myself and inviting him to see my demo. And he came, and was so kind and positive and that really meant a lot to me.</div>
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/VTm5N41tnBE?feature=player_embedded' frameborder='0'></iframe></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Next exciting event was an interview by Make magazine folks. Needless to say I admire their work too. I think they honestly liked my Bluetooth demo and agreed that this is a little breakthrough in the field.</div>
<div class="separator" style="clear: both; text-align: center;">
<object class="BLOGGER-youtube-video" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" data-thumbnail-src="http://1.gvt0.com/vi/DKJshalr_DE/0.jpg" height="266" width="320"><param name="movie" value="http://www.youtube.com/v/DKJshalr_DE&fs=1&source=uds" />
<param name="bgcolor" value="#FFFFFF" />
<embed width="320" height="266" src="http://www.youtube.com/v/DKJshalr_DE&fs=1&source=uds" type="application/x-shockwave-flash"></embed></object></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The moment I came home after the conference I fell ill for a few days. Totally exhausted. Haven't had a decent sleep in a few weeks. I took a few days off, and then back to work: a demo is nice, but I gotta get this thing released. Fortunately, when preparing the demo I wasn't playing quick 'n' dirty. So I just needed some polish, but no throw-away code. And finally, I'm happy with it and feel confident enough releasing it. It's not perfect-perfect, as multi-device support still needs some care. But it's reliable and definitely useful as-is. I made a video explaining users how to upgrade their IOIO to the new feature, building on top of the <a href="http://ytai-mer.blogspot.com/2011/07/ioio-manager-unleashes-power-of.html">firmware upgrade capabilities that I previously enabled</a>. Some have already reported success.</div>
<h1>
Links</h1>
<div>
More information (and the instructional video) can be found <a href="https://github.com/ytai/ioio/wiki/IOIO-Over-Bluetooth">here</a>.</div>
<div>
IOIO can be purchased from SparkFun (about $50) <a href="http://www.sparkfun.com/products/10748">here</a>.</div>
<div>
The cheapest ($1.80 incl. shipping) Bluetooth dongle I found and tested is <a href="http://www.dealextreme.com/p/super-mini-bluetooth-2-0-adapter-dongle-vista-compatible-11866">here</a>.<br />
Questions are happily answered on <a href="https://groups.google.com/forum/#!forum/ioio-users">the ioio-users discussion group</a>.</div>
<h1>
What's next?</h1>
<div>
There are several possible directions I'm considering (your comments welcome):</div>
<div>
<ul>
<li>Supporting the multi-IOIO use-case properly.</li>
<li>Supporting WiFi dongle (imagine that!).</li>
<li>Releasing OpenAccessory support in non-Beta mode (now the ground is properly laid, with new bootloader and connection abstraction layers).</li>
<li>Adding long overdue features that users requested such as infrared remote control protocol, synchronous parallel I/O, quadrature encoder, PPM output, etc.</li>
</ul>
<div>
Tough choice. All seem to add great value. We shall see...</div>
</div>Ytaihttp://www.blogger.com/profile/05373159288627167940noreply@blogger.com45Sunnyvale, CA, USA37.3492097 -122.032601937.323964200000006 -122.07208390000001 37.3744552 -121.9931199tag:blogger.com,1999:blog-4289452895058070746.post-49424067596555632712011-07-13T01:05:00.005+03:002011-09-11T21:01:47.183+03:00IOIO Manager Unleashes the Power of Firmware Upgrades<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-IBMWinH_pJs/ThyyrfnjBaI/AAAAAAAAUIM/34iQUf5pxSc/s1600/ic_launcher-512.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="200" src="http://1.bp.blogspot.com/-IBMWinH_pJs/ThyyrfnjBaI/AAAAAAAAUIM/34iQUf5pxSc/s200/ic_launcher-512.png" width="200" /></a></div>Exciting news once again, folks!<br />
Since the original design of IOIO, it was planned to make it capable of upgrading its own software, by pulling updates from the Android device it is connected to. This gives a lot of flexibility for where the upgrades come from, be it the Web, a file containing custom firmware that a user has built or even embedded inside an Android application that needs the IOIO to behave in some non-standard way.<br />
To achieve that, the IOIO firmware included a bootloader, which kicks in on every IOIO restart and checks for new firmware. For security purposes, it has been decided that the bootloader will only get its upgrades from a single application, called the IOIO Manager, and check that this application is authentic by enforcing it to be signed be the official IOIO key (i.e. by me). Alas, this IOIO Manager had not yet been born when IOIO was first released, and this cool feature, although available on every IOIO firmware, remained dormant. Until yesterday, that is!<br />
The IOIO Manager application is now available on the Android Market. Install it by scanning the QR code below or by clicking it:<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://market.android.com/details?id=ioio.manager"><img border="0" src="http://chart.apis.google.com/chart?cht=qr&chs=150x150&chl=http%3A%2F%2Fmarket.android.com%2Fdetails%3Fid%3Dioio.manager" /></a></div><h1>Installing New Application Firmware Using the Bootloader</h1><div class="separator" style="clear: both; text-align: left;">This is the most common use case: the IOIO Manager application lets you maintain a library of application images, and then choose the one you want installed on the IOIO at any point in time. Once selected, the IOIO will pull this image after its next restart. This takes less than two seconds and does not require any additional hardware (such as a programmer).</div><div class="separator" style="clear: both; text-align: left;"><b>To remove all doubt</b>: this upgrade mode works great with the existing bootloader version, which all current IOIO owners have. At least in the near future, the bootloader is not expected to change, and those users are able to use IOIO manager to receive upgrades!</div><h1>Upgrading the Bootloader</h1><div class="separator" style="clear: both; text-align: left;">The bootloader cannot upgrade itself by design. This is in order to protect the user from accidentally bricking the board by installing a faulty image that renders the bootloader invalid. My original thought was that the bootloader will never have to be modified anyway. Errrrr, wrong! When designing the bootloader I figured that since the bootloader already contains all the code for establishing an ADB connection to the phone, it might as well provide this service to the application and save the code duplication. While this seemed reasonable enough back then, I overlooked something important - what if the application wants to use some other protocol over USB? One example is of course Open Accessory. Moreover, what if I found a bug in the bootloader, or want to introduce an optimization? Bottom line - we need a way to upgrade the bootloader from time to time and for that we must have a programmer.</div><div class="separator" style="clear: both; text-align: left;">Wait, what?</div><div class="separator" style="clear: both; text-align: left;">But the SparkFun page specifically used to say "you'll never need a programmer", until we figured out this is true only 99% of the time. And yes, we could just fix the bootloader design bug and have the new units shipped with a better bootloader, but what about the users that already bought it and don't have a programmer? I wanted to be as fair as possible to these people who were first to believe in my product, so I decided to go the extra mile...</div><div class="separator" style="clear: both; text-align: left;">So you need a programmer, no doubt about that, but who said you need an <i>off-the-shelf</i> programmer? Let's make one out of a IOIO! And so I did. And it works! So right now, if you want to reprogram your IOIO's bootloader, all you need is another IOIO, be it your friend's or your fellow hacker. Well, people can still argue this is not a free solution in all cases, but I hope they will appreciate I really did anything I could to make things better for them.</div><div class="separator" style="clear: both; text-align: left;">Here's what it looks like when one IOIO programs another:</div><div class="separator" style="clear: both; text-align: left;">Simply connect 5 wires (two of which are supply and ground) between them, select the image and go!</div><div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-xpploS8zsVs/Thy_DrpV_pI/AAAAAAAAUIQ/CmWb9wygLkU/s1600/DSC_0098.JPG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="310" src="http://4.bp.blogspot.com/-xpploS8zsVs/Thy_DrpV_pI/AAAAAAAAUIQ/CmWb9wygLkU/s400/DSC_0098.JPG" width="400" /></a></div><h1>New Possibilities</h1>First, this new feature opened the gate for me to start pushing new features to IOIO on a regular basis. Some of which have been itching me to release for quite some time.<br />
Next, this allows people interested in modifying the code running on the IOIO to do so very easily as well as to distribute the firmware they are producing for others to install with no trouble. I'm really curious to see what will come out of this.<br />
For more information, read <a href="https://github.com/ytai/ioio/wiki/The-IOIO-Manager-Application">the detailed guide to the IOIO Manager on the IOIO Wiki</a>.<br />
<br />
P.S. in retrospect I realized this is a homage to an older project of mine: <a href="http://ytai-mer.blogspot.com/2010/05/avr-programmer-using-picman.html">AVR programmer using the PICMAN</a> (the great-grandfather of the IOIO)Ytaihttp://www.blogger.com/profile/05373159288627167940noreply@blogger.com17tag:blogger.com,1999:blog-4289452895058070746.post-34323505987879621212011-06-05T10:37:00.004+03:002011-09-11T21:00:17.583+03:00IOIO over OpenAccessory (ADK) Available<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-lqNb9lshfW4/TZd6FSjxcmI/AAAAAAAATkY/O_kGj9VySN4/s1600/ioio-logo.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="86" src="http://1.bp.blogspot.com/-lqNb9lshfW4/TZd6FSjxcmI/AAAAAAAATkY/O_kGj9VySN4/s400/ioio-logo.png" width="400" /></a></div>About two months ago, I've announced IOIO on this blog. About a month later, in Google I/O, Google announced the OpenAccessory and the Accessory Developer's Kit (ADK), which enables connecting your Android device (version 2.3.4 and higher) to external peripherals. Today, I'm announcing <b>IOIO's support of the OpenAccessory protocol!</b><br />
<br />
This new feature is currently released in Beta mode. Technical information available <a href="https://github.com/ytai/ioio/wiki/IOIO-Over-OpenAccessory-Beta">on the IOIO wiki</a>. The way this works is that IOIO will attempt to communicate with the Android device with the OpenAccessory protocol. When this is not supported, it will seamlessly fall back to ADB. This enables you to connect the same IOIO board to both new and old devices. Your applications can be very easily be ported to the new mode, requiring only a few non-intrusive modifications to your application's metadata.<br />
<br />
What is this all about? What is the relation between this new technology, IOIO and the other boards out there? I will try to provide some answers and clear some of the confusion that was caused as result of the proximity of all these announcements.<br />
<br />
<h3>What is OpenAccessory?</h3>OpenAccessory is a new Android feature, which enables connecting external peripherals to an Android device over a USB connection. This feature exposes a standardized interface on the USB bus, as well as a Java API that enables an Android application to communicate with the accessory on the other end. This feature is supported on Android 2.3.4 and higher. The OpenAccessory protocol allows the Android device to act as either a host or a device on the USB bus (the host mode is only supported on Android 3.x and higher and only on certain devices).<br />
OpenAccessory is a low-level protocol: it features a single full-duplex communication channel between the Android device and the accessory, over which arbitrary bytes can be sent back and forth - much like a UART connection. It leaves to the accessory designer to design the higher-level protocol, i.e. what messages to send and what their meaning is to the Android application and to the accessory.<br />
Read more about OpenAccessory <a href="http://developer.android.com/guide/topics/usb/index.html">here</a>.<br />
<br />
<h3>What is ADK?</h3><div>The Accessory Developer's Kit (ADK) is a reference implementation of an OpenAccessory-enabled board, developed by Google and announced together with OpenAccessory. This board is essentially an Arduino Mega with an on-board USB host shield. It comes with an Arduino-side C++ library, which implements the protocol. Following Google, several vendors have released compatible boards.</div><div>The term "ADK" is often used synonymously with "OpenAccessory", i.e. one might say "this new board supports ADK" when they actually mean it supports the OpenAccessory protocol.</div><div>In my personal opinion, the ADK has been released mostly for promoting the OpenAccessory protocol and providing a quick-start and demo board, rather than intended to be a consumer product.</div><div><br />
</div><h3>How Does OpenAccessory Compare to ADB?</h3><div>The Android Debug Bridge (ADB) is a debug protocol which existed on every Android device since the early days of Android. Technically, this protocol allows a host connected over USB to open various kinds of communication channels to the Android device. On the Android-side of these communication channels are different services, such as debug, file-system access, Linux shell access. Another note-worthy service (on which IOIO has been based) allows forwarding of the data sent over the channel to a TCP socket. This allows an Android application to listen on a certain port and accept connections coming from the outside world, and do so without the need to modify the OS.</div><div>ADB's main advantages over OpenAccessory are:</div><div><ul><li>Available on any Android device.</li>
<li>Provides useful features, such as file-system access (IOIO uses this for firmware upgrades).</li>
<li>More mature, does not suffer from some problems currently existing in OpenAccessory.</li>
<li>Simpler to work with on the Android application side - just listen on a TCP socket.</li>
</ul><div>OpenAccessory's main advantages over ADB are:</div></div><div><ul><li>Better throughput and latency.</li>
<li>Does not require the user to enable USB debugging.</li>
<li>More secure (IOIO takes its own measures to guarantee that the power of ADB cannot be exploited by a malicious firmware).</li>
<li>Allows applications to be notified upon connection of the accessory. The user can choose which application to launch when the accessory connects. This might be doable with ADB too, but IOIO doesn't do that.</li>
</ul><div>See Inopia's excellent in-depth comparison <a href="http://romfont.com/2011/05/11/a-closer-look-at-googles-open-accessory-development-kit/">here</a>.</div></div><div><br />
</div><h3>How Does IOIO Compare to Other OpenAccessory-Enabled Boards?</h3><br />
<ul><li><b>Supports All Android Versions</b> - since IOIO works with both OpenAccessory and ADB it can communicate with a very large variety of existing Android devices, leveraging OpenAccessory when it exists and leveraging the additional features of ADB when they exist. Other boards, which do not support ADB, are limited to all but the newest Android devices out there.</li>
<li><b>Functionality</b> - IOIO is almost exactly identical to the Arduino Mega in terms of pin counts and functions. The only difference I could spot is in the number of PWM channels (IOIO-9, Mega-16) and TWI channels (IOIO-3, Mega-1).</li>
<li><b>Cost</b> - at $50, IOIO currently seems to be the cheapest available commercial board out there. A close alternative is a DIY version offered <a href="http://romfont.com/2011/05/12/google%E2%80%99s-open-accessory-development-kit-on-standard-arduino-hardware/">here</a>, costing $55 and requires some work.</li>
<li><b>High-Level Software</b> - the other boards out there expect you to write both an Android application and embedded-C code for the board, designing your own communication protocol. IOIO does all that for you, leaving you to write only the Android-side code, while using a high-level Java API for controlling the board's functions.</li>
<li><b>Support Forum and Wiki</b> - IOIO has <a href="https://groups.google.com/forum/#!forum/ioio-users">an active discussion group</a> and <a href="https://github.com/ytai/ioio/wiki">an extensive documentation wiki</a>, which continues to grow quickly. The IOIO project is committed to the hobbyist community, and to the hobbyist community only!</li>
<li><b>Size</b> - IOIO is probably the smallest board out there - almost as small as you could get with 48 I/O pins, numerous supply pins and a USB connector. It is <b>much</b> smaller than the ADK board.</li>
<li><b>Bootloader</b> - IOIO's firmware includes a secure bootloader, which enables firmware upgrades to be performed through the Android device.</li>
<li><b>Power Supply</b> - IOIO has an on-board 5V switch-mode regulator capable of delivering up to 1.5A. This allows for simultaneous charging of the Android and powering two standard servos without problem. Some of the other boards will require an external 5V supply to support this use-case. In addition, IOIO has an on-board trimmer which allows limiting the Android's charging current. This is very useful for battery-operated setups, when you don't want the Android device to drain your battery.</li>
<li><b>Open-Source</b> - Unlike some of the other alternatives - the IOIO's hardware, firmware and software are completely open-source with a FreeBSD license (very permissive). This approach has been chosen because I believe this is what works best for the hobbyist community, and allows people to customize the product for their needs, contribute to it, understand it best, compete on its pricing.</li>
</ul><div>In conclusion, despite my obvious bias, I believe IOIO is very competitive with other OpenAccessory-enabled platforms. To be fair, <a href="http://blog.makezine.com/archive/2011/05/why-google-choosing-arduino-matters-and-the-end-of-made-for-ipod-tm.html">here is another view</a>.</div>Ytaihttp://www.blogger.com/profile/05373159288627167940noreply@blogger.com13tag:blogger.com,1999:blog-4289452895058070746.post-13013195265179251652011-04-30T23:06:00.002+03:002011-09-01T10:57:52.137+03:00IOIO Open-Sourced<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-6m-8Lt5uvmw/TaDL16u6_JI/AAAAAAAATmk/QWZH-59frjc/s1600/ioio-logo.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><br />
</a><a href="http://3.bp.blogspot.com/-6m-8Lt5uvmw/TaDL16u6_JI/AAAAAAAATmk/QWZH-59frjc/s1600/ioio-logo.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="70" src="http://3.bp.blogspot.com/-6m-8Lt5uvmw/TaDL16u6_JI/AAAAAAAATmk/QWZH-59frjc/s320/ioio-logo.png" width="320" /></a></div>The first batch of IOIO's has started shipping these days! I'd like to thank the patience and support of those who bought it in back-order. I can't wait to see what users are going to make of it.<br />
If you make a cool project with IOIO, please let me know about it in the comments, on email or in the discussion group. If there's enough volume, I'll open a page on this blog dedicated to such projects.<br />
<br />
As promised, I'm opening the source-code, under FreeBSD license.<br />
The project's documentation, including a partially complete user guide is here:<br />
<a href="https://github.com/ytai/ioio/wiki">https://github.com/ytai/ioio/wiki</a><br />
I'm now working on filling the missing parts, but there should be enough Javadocs to get those of you who can't wait going. The project's source code is there too, available for download as a tarball or using git.<br />
<br />
SparkFun have recently release a beginner's guide to IOIO here:<br />
<a href="http://www.sparkfun.com/tutorials/280">http://www.sparkfun.com/tutorials/280</a><br />
<br />
I opened a discussion group for IOIO users, where I'll try to answer questions and get feedback. Feel free to subscribe there if you want to know what's going on:<br />
<a href="http://groups.google.com/group/ioio-users">http://groups.google.com/group/ioio-users</a><br />
<br />
If you want to take part in IOIO development, please introduce yourself and submit a request for membership in:<br />
<a href="http://groups.google.com/group/ioio-dev">http://groups.google.com/group/ioio-dev</a>Ytaihttp://www.blogger.com/profile/05373159288627167940noreply@blogger.com4tag:blogger.com,1999:blog-4289452895058070746.post-70456738255354996312011-04-08T00:32:00.001+03:002011-11-15T06:38:44.647+02:00Meet IOIO - I/O for Android<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-lqNb9lshfW4/TZd6FSjxcmI/AAAAAAAATkY/O_kGj9VySN4/s1600/ioio-logo.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="139" src="http://4.bp.blogspot.com/-lqNb9lshfW4/TZd6FSjxcmI/AAAAAAAATkY/O_kGj9VySN4/s640/ioio-logo.png" width="640" /></a></div>
<br />
<a href="http://4.bp.blogspot.com/-Os2SWb-mDeQ/TZgYHj7YhiI/AAAAAAAATlY/Sw0V2FOHmEw/s1600/2011-02-08+15.43.13.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="135" src="http://4.bp.blogspot.com/-Os2SWb-mDeQ/TZgYHj7YhiI/AAAAAAAATlY/Sw0V2FOHmEw/s320/2011-02-08+15.43.13.png" width="320" /></a>I'm very excited to announce the launch of a new product I've been working on for the past months!<br />
IOIO (pronounced: <i>yo-yo</i>) is a product which lets you connect electronic circuits to an Android device and control them from an Android application.<br />
It is comprised of a small (2.7x1.2" = 7x3cm) PCB that connects to an Android device with a USB cable and a software library (Java .jar file) that you use in your Android app which handles all communications with the board.<br />
<b>No firmware programming is required</b> - only Android application authoring with a very simple API (see examples below) for controlling the pins on the board. <b>No modification of the Android device is required</b> - you avoid the complication of modification and the voiding of warranty.<br />
<a href="http://www.sparkfun.com/products/10748" style="font-weight: bold;" target="_blank">IOIO is available for purchase online from SparkFun on this page</a>.<br />
The first few boards will ship within a couple of weeks. Around that time, the entire software and hardware are going to be 100% open-source with a permissive license.<br />
<br />
<h1>
Main features:</h1>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-K-a9fbaO_i8/TZgQ_bh2zwI/AAAAAAAATkw/MHEh7ad6-uc/s1600/IMG_20110403_083125.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="320" src="http://1.bp.blogspot.com/-K-a9fbaO_i8/TZgQ_bh2zwI/AAAAAAAATkw/MHEh7ad6-uc/s320/IMG_20110403_083125.jpg" width="259" /></a></div>
<ul>
<li>48 total I/O pins - all of which can function as digital inputs and outputs.</li>
<li>Up to 16 analog inputs (10-bit).</li>
<li>Up to 9 PWM outputs.</li>
<li>Up to 4 UART channels.</li>
<li>Up to 3 SPI channels.</li>
<li>Up to 3 TWI (I²C-compatible) channels.</li>
<li>On-board switch-mode regulator providing up to 1.5A of 5V supply. Can charge the Android device as well as power a couple of small motors.</li>
<li>Bootloader on the board pulls firmware off phone, enabling OTA firmware upgrades and application-specific firmware.</li>
<li>Pulse-width measurement, capacitance sensing and more (will be pushed with first OTA firmware upgrade).</li>
</ul>
<h1>
Example Code</h1>
Just to give you a hint of how simple it would be to write apps using IOIO, here is a small snippet from an app, which controls a single servo motor (on pin 12) and reads a single potentiometer (on pin 40). Exception handling and proper closing have been omitted for clarity.<br />
<pre>ioio.waitForConnect();
AnalogInput input = ioio.openAnalogInput(40);
PwmOutput pwmOutput = ioio.openPwmOutput(12, 100); // 100Hz
while (true) {
float reading = input.read();
pwmOutput.setPulseWidth(1000 + Math.round(1000 * reading));
sleep(10);
}
</pre>
<br />
<h1>
Example Projects</h1>
<h2>
The Retroid</h2>
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/vSnuzTUuobE?feature=player_embedded' frameborder='0'></iframe></div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<br /></div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
The Retroid is a retro-designed alarm clock hacked to be controlled by an Android phone.</div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
Once connected, the phone's alarm, incoming call and incoming text message notifications appear as different ring and LED patterns on the clock.</div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
Thanks to the amazing <b>The Gifts Project folks</b> for hacking this wonderful project over one weekend!<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<h2>
The Visual Charger</h2>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-738NjMLCoBE/TWTK8f0SFdI/AAAAAAAATXs/yn_j3ngak3E/s1600/IMG_5246.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="http://2.bp.blogspot.com/-738NjMLCoBE/TWTK8f0SFdI/AAAAAAAATXs/yn_j3ngak3E/s320/IMG_5246.JPG" width="213" /></a></div>
<br />
<br />
The Visual Charger is another take on a cool docking station for your phone. It charges your phone while presenting charge level percentage (0-9 or "F" for full) on a large 7-segment LED display. It also uses the dot on the display to signal for pending notifications (e.g. missed calls, unread text messages, etc.).<br />
This project has been done by <b>Misha Seltzer</b> who is also taking a crucial part in IOIO development.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<h2>
Wall Printer</h2>
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/aYUMYyXBaF0?feature=player_embedded' frameborder='0'></iframe></div>
<div>
<br /></div>
The Wall Printer is inspired by old-school pin printers. It has 7 markers in a row, each individually controlled by a servo such that it can go up (not paint) or down (paint). When you manually slide it over a wall, the servo motions are carefully timed to produce text messages. These can include manually entered text, SMS messages, GPS coordinates and more.<br />
The project is not yet complete, and the video above just demonstrates a simple pattern from an early experiment. I'll post an update once there is progress.<br />
This project has been done by my wonderful friend <b>Liat Segal</b>.<br />
<br /></div>
<h1>
Why?</h1>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
Android phones are powerful mobile computers having internet connectivity and a rich variety of built-in sensors (camera, GPS, IMU, touch screen). They are also very easy to write applications for, thanks to the great work done by the Android SDK developers. For many applications, all they are really missing is connectivity to external peripherals. This is exactly where IOIO fits in: it enriches the inherent capabilities of the Android device with the ability to communicate with external circuits.</div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
From a study of existing solutions, they all suffered from one or more of the below:</div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
</div>
<ul>
<li>High cost.</li>
<li>Complicated. Especially so for complete beginners.</li>
<li>High latency.</li>
<li>Low bandwidth.</li>
<li>Required replacement of the Android device OS.</li>
<li>Large physical size.</li>
</ul>
<div>
IOIO does not suffer from any of the above. Its cost (~$50 from SparkFun) is competitive with existing solutions, dead-simple to use, ~3ms one-way latency, ~300KB/sec throughput, works with stock OS, small in size.<br />
<h1>
Credits</h1>
I would like to thank <b>Google</b> for supporting this project with people's 20%-time. This project would never have come to life without their help.<br />
Mostly I would like to thank <b>Ryan Hickman</b>, <b>Arshan Poursohi</b> and <b>Misha Seltzer</b>.<br />
All the rest of the guys from Google that contributed to this project with coding, organization of the hackathon event, and providing critical feedback early in the process. You all know who you are :)<br />
<b>Aaron Weiss from SparkFun</b> helped a lot with the hardware and taught me how PCB design is done in the real world.<br />
My dear friends who took on the task of being the first adopters and built fantastic first IOIO projects.<br />
And last but not least, my beloved wife and kids who were patient and supportive of their tired dad.</div>
<div>
<br /></div>Ytaihttp://www.blogger.com/profile/05373159288627167940noreply@blogger.com213tag:blogger.com,1999:blog-4289452895058070746.post-44739234241235222492010-08-09T09:15:00.001+03:002010-08-09T09:16:08.950+03:00POV Globe - Part IV - Software & DataThis is in continuation to: <a href="http://ytai-mer.blogspot.com/2010/08/pov-global-part-iii-electronics.html">POV Globe - Part III - Electronics</a><br />
<br />
The data layout on the SD card and the software are rather technical and trivial, but still worth a mention.<br />
<h1>Data Layout</h1>I'm using the SD as a raw block device (i.e. no file-system). This is in order to reduce read overhead, as well as to make sure that all image data is in consecutive blocks (as mentioned in the previous post, jumping between non-consecutive blocks takes an eternity of 380us). Since reads are always in blocks, the format is block aligned. Some numbers:<br />
<ul><li>One block of data = 512B = 4096bit = 16 columns.</li>
<li>One revolution (or "frame") = 512 columns = 32 blocks = 16KB.</li>
<li>One second of animation = 50 frames = 800KB.</li>
</ul>A quick calculation shows that 1GB of data can hold a little over 20 minutes of 50FPS animation. My card has 2GB, and it is easy to find cards with more.<br />
The format is as follows:<br />
<ul><li>First 4 bytes are the total number of blocks in the image, followed by 508B of padding.</li>
<li>Then the image itself follows, column-by-column, where the bytes in each column are ordered from top 8 LEDs to bottom 8 LEDs, and the bits in each byte are ordered so that the MSB is the top LED and LSB is the bottom LED.</li>
</ul><br />
In order to write the raw data to the SD card, I'm using a USB card reader and the Linux <i>dd</i> command, directly to the device.<br />
<h1>Software</h1>I will not get into all the details - most of them are just technicalities.<br />
The only part worth mentioning is how the main loop synchronizes the drawing of the columns to the physical location of the LED row, designated by a pulse from the IR sensor, once per revolution. It also needs to take into account possible out-of-sync situations, and "catch-up" if we're late.<br />
<ul><li>A timer keeps the time elapsed since the beginning of the column.</li>
<li>The variable col_dur holds the duration of a single column (1/512 the duration of a revolution) - it is updated every time we get an IR pulse.</li>
<li>The variable pos keeps the current (estimated) physical position of the LEDs, between 0..511.</li>
<li>The variable cur_col keeps the last column that has been drawn, between 0..511.</li>
</ul>And the main loop looks something like this:<br />
<pre>while (true) {
// draw all the columns until the current position
while (cur_col != pos) {
draw_column();
if (++cur_col == 512) col = 0;
}
while (TIMER < col_dur); // wait until the end-of row time
// advance position according to how much time elapsed
do {
TIMER -= col_dur;
if (++pos == 512) pos = 0;
} while (TIMER >= col_dur);
// check position sensor and make adjustments
if (pos == 0) {
... wait for rising edge of the sensor ...
... recalculate col_dur (make it longer or equal), and reset TIMER ...
} else if (sensor_rising_edge()) {
// got a premature signal - we're falling behind
... force pos = 0, recalculate col_dur (make it shorter), and reset TIMER ...
}
}
</pre>The draw_column() function just streams 32B of data from the SD to the LED board, pulses the latch line, and then prepares the next column (i.e. issues a SD command to get the next block and waits for it to become ready, if needed).<br />
In practice, because of the SD latency-related problems described in my previous post, this function currently takes care of skipping the first block, while the second is fetched, and in the future it will also take care of streaming the first block from flash.<br />
The last video in the previous post demonstrates this algorithm in action, taking button presses in lieu of IR switch signals.Ytaihttp://www.blogger.com/profile/05373159288627167940noreply@blogger.com5tag:blogger.com,1999:blog-4289452895058070746.post-37759487556112021832010-08-09T08:19:00.004+03:002010-08-09T09:15:24.963+03:00POV Globe - Part III - ElectronicsThis is in continuation to: <a href="http://ytai-mer.blogspot.com/2010/08/pov-globe-part-ii-mechanics.html">POV Globe - Part II - Mechanics</a><br />
<br />
The first concepts I had were:<br />
<br />
<ul><li>Keep the hardware modular in order to be able to design & test small components separately.</li>
<li>Stream the image or animation to the LED display from a micro-SD card, so that: there's plenty of storage for rich animations, I will not need to worry too much about complicated compression schemes, and it would be really easy for anyone to deploy new animations.</li>
</ul>I started designing the electronics by drafting the following specs:<br />
<br />
<ul><li>256 LEDs per column, 512 columns per revolution, 50 revolutions per second = 6.55 Mbit/second = 39us per column.</li>
<li>Serial communication between the motherboard and the LEDs to avoid having to run lots of wires and use a lot of IO on the microcontroller.</li>
<li>Daisy-chain several LED boards, so that I can create an (almost) arc-shaped row of LEDs.</li>
<li>Synchronize LEDs with rotation angle by using an IR LED on the base of the globe and an IR sensor on the motherboard.</li>
<li>In circuit programming and UART connections on the motherboard for development & debug.</li>
</ul><br />
<h1>LED Boards</h1>I started by designing the LED boards. I needed 16 boards of 16 LEDs each, which can be daisy-chained. My idea was one 16-bit serial-in parallel-and-serial-out shift register, one 16-bit latch and 16 LED drivers (transistors) per board. Apparently, this wasn't only <i>my</i> idea, and I soon found that there are off-the-shelf ICs that do just that, leaving me mostly with designing a very simple board that does little more than routing. A simple survey found that the <a href="http://focus.ti.com/docs/prod/folders/print/tlc5927.html">TLC5927</a> of TI is a perfect match. I'll take this opportunity to really thank TI for being very generous with free samples - 20 pieces of this IC got to my home with a courier within 3 days!<br />
Here is the circuit schematic and (double sided) layout for the LED boards:<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/_LxebaUxx8xw/TF9d-mBBYlI/AAAAAAAATG0/sLd5eViFXz0/s1600/led_schmatic.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://1.bp.blogspot.com/_LxebaUxx8xw/TF9d-mBBYlI/AAAAAAAATG0/sLd5eViFXz0/s200/led_schmatic.png" width="128" /></a><a href="http://2.bp.blogspot.com/_LxebaUxx8xw/TF9d_0_xtkI/AAAAAAAATG8/Qu_pUJUmzZU/s1600/led_layout.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="100" src="http://2.bp.blogspot.com/_LxebaUxx8xw/TF9d_0_xtkI/AAAAAAAATG8/Qu_pUJUmzZU/s200/led_layout.png" width="200" /></a></div><br />
And a picture of the home-etched board (these are actually two pieces connected):<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/_LxebaUxx8xw/TF7wvv0_QUI/AAAAAAAATGc/TJ1zyHwnFFg/s1600/IMG_20100806_131510.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="70" src="http://2.bp.blogspot.com/_LxebaUxx8xw/TF7wvv0_QUI/AAAAAAAATGc/TJ1zyHwnFFg/s320/IMG_20100806_131510.jpg" width="320" /></a></div><br />
BTW, this board has a shiny silver finish, as I finally managed to get my hands on <a href="http://www.mgchemicals.com/products/421.html">Liquid Tin</a>, after a trip to the US. No more rusty copper look... <br />
<br />
Once built, I quickly hooked it to my loyal <a href="http://ytai-mer.blogspot.com/2010/04/picman.html">PICMAN</a> for testing. I'm really starting to like this guy...<br />
As it turns out, the best way to output a stream of bits out of a microcontroller is by using the SPI hardware. With the PICMAN's PIC18F4553, you can reach an effective rate of 12MHz.<br />
Here's a video of the first experiment I did, a simple blinking pattern on 5 LEDs:<br />
<object height="385" width="480"><param name="movie" value="http://www.youtube.com/v/oKIKVCgJw_k&hl=en_US&fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/oKIKVCgJw_k&hl=en_US&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"></embed></object><br />
Then it was time to have some fun with POV effects, so I wrote a simple program that would display a Smiley pattern when the board is wiggled from side to side. It worked! Unfortunately the camera doesn't capture the effect as nicely as the human eye, but in this video you could still see the idea:<br />
<object height="385" width="480"><param name="movie" value="http://www.youtube.com/v/JVZOMZTnLq8&hl=en_US&fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/JVZOMZTnLq8&hl=en_US&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"></embed></object><br />
<h1>Motherboard</h1>First issue to tackle was communication with the SD card. After searching the Web for information, it turns out these devices support an SPI-based interface of up to 25MHz. I took a micro-SD to SD adapter to use as a socket, and soldered pin headers to it. Than I stuck it on the breadboard, connected it to the PICMAN and started playing around with it. Careful! SD-cards are 3.3V devices, so when working with a 5V microcontroller a simple voltage divider on the output pins is needed. After some messing around with the software, I was able to read data blocks from the device.<br />
<br />
Now, how do you stream data from a micro-SD card to the LED boards at 8MHz (cheaply)?<br />
A simple cycle of read-from-card -> write to LEDs would naively take at least a few cycles per-bit, which would require a rather fast microcontroller to support 8Mbit/sec. Fortunately, both the SD card and the LEDs speak SPI, so I had an idea to connect the serial input of the LED board directly to the serial out of the SD card, have the microcontroller initiate a read and then send a latch signal to the LEDs at the right time. This way, the microcontroller doesn't have to bother looking at the incoming data. It turned out to be a really neat trick, and I was able to easily stream data directly from the SD card @8HZ, using a cheap ATmega8A clocked at 16MHz!<br />
From this point the design was rather simple: I added a reset button, UART and programming connections and a connector to the IR sensor. I also used a couple of fast MOSFET gate drivers (TC4427) to function as line drivers for the long lines driving the LEDs.<br />
Here is the schematic and the (double sided) layout of the motherboard. Ignore some 0 resistors in the schematic, used solely as "bridges" above traces for solving layout constraints:<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/_LxebaUxx8xw/TF9d9femaQI/AAAAAAAATGs/FV9NkGAw6XM/s1600/mobo_schematic.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://1.bp.blogspot.com/_LxebaUxx8xw/TF9d9femaQI/AAAAAAAATGs/FV9NkGAw6XM/s200/mobo_schematic.png" width="165" /></a><a href="http://2.bp.blogspot.com/_LxebaUxx8xw/TF9d7v4eM8I/AAAAAAAATGk/ZcvaMTlc-UY/s1600/mobo_layout.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://2.bp.blogspot.com/_LxebaUxx8xw/TF9d7v4eM8I/AAAAAAAATGk/ZcvaMTlc-UY/s200/mobo_layout.png" width="168" /></a></div>A micro-SD to SD adapter is soldered "standing" to the side of the board and reinforced with some hot melt glue.<br />
<br />
I used the PICMAN as an AVR programmer to program the ATMega, as described in <a href="http://ytai-mer.blogspot.com/2010/05/avr-programmer-using-picman.html">my earlier post</a>.<br />
Hurray! A few long nights later, and I had a working system, able to stream data from the SD to the LEDs while synchronizing the rate to the input from the position sensor. In the video below, I'm using a push-button to simulate the IR sensor input. I generated a simple image file which generates a 32 LED scan pattern. You can see that the scan rate adapts to the rate of button pushes:<br />
<object height="385" width="480"><param name="movie" value="http://www.youtube.com/v/BdhlFYEAY1I&hl=en_US&fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/BdhlFYEAY1I&hl=en_US&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"></embed></object><br />
<br />
<h2>Caveats</h2>The motherboard has several problems that I'm intending to fix in the next version. The first problem is related to SD card latencies. After performing some timing measurements here's what I found:<br />
<table border="1"><tbody>
<tr><th>Operation</th><th>Duration [us]</th></tr>
<tr><td>From issuing read command and until the first block is ready</td><td>1340</td></tr>
<tr><td>End of block until the immediately following block is ready</td><td>6</td></tr>
<tr><td>End of block until non-following block is ready</td><td>380</td></tr>
</tbody></table><i>Note: A block is 512 bytes. All read operations are always done in full blocks.</i><br />
<br />
The first value is not very interesting, since it only happens once when the program starts running.<br />
The second value is interesting, because it happens every time we move from one block to the next - every 512 bytes = 4096 bits = 16 columns. This means that when we display a column that is in the beginning of a block, it will take us 6us (latency) + 32us (256 bit @8Hz) = 38us. Just below our spec of 39us/column!<br />
The third value is problematic, because it means that every time we reach the end of the image, if we want to jump back to the beginning of the image we'll be late by about 10 columns. So my idea for solving this was to copy the first (or last) block of the image to the microcontroller flash when the program starts, and then stream this block from flash while the next one is fetched. Alas, I suddenly realized that the way my hardware is built, the LED serial-in is hard-wired to the MISO line, i.e. the SPI <i>input</i> of the microcontroller, and thus I can't stream data out of the microcontroller to the LEDs, only from the SD! As a temporary workaround, I'm just skipping the first block altogether and in order to make sure that those missing 16 columns don't happen too often, I'm just replicating the image many times on the SD.<br />
<br />
Some other problems with the current design are not as bad, but I might as well address them on the next version. Those include: the translation from the microcontroller's 5V to the SD's 3.3V creates a really messy layout; the ability to stream data directly from the microcontroller is nice-to-have regardless of SD latency; ATmega8's are no longer cheaply (under $2.5) available; I really regretted not putting a general purpose button and LED on the board for some basic user interface and debug.<br />
<br />
To address the first problem, the next version will include a mux to select between MOSI (microcontroller output) and MISO (SD output) as LED inputs.<br />
To address the second problem, I'm moving to PIC18F23K20, which is $1.70 from Digikey, works on 3.3V, 16MIPS and 16MHz SPI, does not need an external crystal/resonator to operate at full-speed. In addition, the PICs don't suffer from some of AVR's annoyances, such as the ability to brick the chip by setting wrong fuse values and the sharing of the serial programming lines with the SPI. So much goodness that I just had to buy 10 of those...<br />
I intend to first run a full system (with the said workaround) before designing the new motherboard, since I might encounter a few more problems down the road.<br />
<br />
<h1>Power</h1><b>Q</b>: How do you transfer power to a circuit that's turning?<br />
<b>A</b>: A slip ring.<br />
A slip ring is simply a conductive ring attached to the rotating shaft and a stationary conductive "brush" the keeps in contact with the ring, but slips on it with minimal friction. For transferring power, you would need at least two of these.<br />
Due to the nature of this connection, it is very noisy, and thus not generally suitable for data transfer. This is, by the way, why I put the motherboard on the rotating side. To filter out any noise, or short discontinuities in power, I used a big capacitor (2200uF) on the motherboard, in addition to 0.1uF decoupling capacitors close to each IC. Hopefully, it will do (haven't tried yet).<br />
I made the slip ring myself: turned 2 aluminum rings and a plastic isolating sleeve on the lathe. Then I found that soldering to aluminum is really hard, so I used a conductive glue instead, and buried everything under a lump of hot melt glue.<br />
Here's what the finished module looks like:<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/_LxebaUxx8xw/TF9p_GPRwrI/AAAAAAAATHE/tKskc9WBTD0/s1600/IMG_20100806_125415.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="150" src="http://3.bp.blogspot.com/_LxebaUxx8xw/TF9p_GPRwrI/AAAAAAAATHE/tKskc9WBTD0/s200/IMG_20100806_125415.jpg" width="200" /></a></div>And this is me, making this ring, in a really beautiful panoramic photo taken by <a href="http://www.omercalev.com/">Omer Calev</a>:<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/_LxebaUxx8xw/TF9qsGhXl8I/AAAAAAAATHM/dYB7eV3KCgc/s1600/2972.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="http://1.bp.blogspot.com/_LxebaUxx8xw/TF9qsGhXl8I/AAAAAAAATHM/dYB7eV3KCgc/s320/2972.jpg" width="242" /></a></div><br />
Next: <a href="http://ytai-mer.blogspot.com/2010/08/globe-pov-part-iv-software-data.html">POV Globe - Part IV - Software & Data</a>Ytaihttp://www.blogger.com/profile/05373159288627167940noreply@blogger.com9tag:blogger.com,1999:blog-4289452895058070746.post-33565609870743169892010-08-09T08:18:00.000+03:002010-08-09T08:18:51.565+03:00POV Globe - Part II - MechanicsThis is in continuation to: <a href="http://ytai-mer.blogspot.com/2010/08/pov-globe-part-i-introduction.html">POV Globe - Part I - Introduction</a><br />
<br />
Initially, I completely underestimated the complexity of the mechanics. "Yeah, let's take a 60cm hoop with LEDs and turn it at 50 RPM..." Then, one night I did the simple kinematic calculations, only to find that this means about 3000G(!). Yes, that's right: 3000 times gravity, or simply put, each gram of mass (on the widest part of the hoop) is going to pull the hoop outwards with a force of 3 kilograms. Now that takes a rather rigid structure to support. I started thinking bicycle wheels and the like, but I reckoned that building a machine that is beautiful enough to justify potential killing of a few people is rather challenging. So I started re-thinking the structure, trying to find a way to make is both light and suitable for the kinds of forces that operate here. I also figured that drag is going to be rather substantial, so I'll need a rather sturdy motor to support that.<br />
<br />
Eventually, I came up with this structure:<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/_LxebaUxx8xw/TF7Sc137ILI/AAAAAAAATGE/dDT1N5pkR7o/s1600/Globe.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="http://3.bp.blogspot.com/_LxebaUxx8xw/TF7Sc137ILI/AAAAAAAATGE/dDT1N5pkR7o/s320/Globe.png" width="230" /></a></div><br />
There isn't really any hoop - just "wings" with lengths and spaces chosen carefully that comprise a frame for mounting boards with white LEDs on one side (16 boards, 16 LEDs each) and a single board with the RGB LEDs on the other. Those wings will be made of a strong and light material, preferably transparent, probably poly-carbonate or similar. This part has not yet been built (waiting for a friend with a laser cutter to rescue me).<br />
<br />
Turning a shaft fast enough with the ability to resist friction and vibrations is also not a simple matter. The solution that has been chosen is to mount the shaft on a washing machine bearing and drive it with a washing machine motor. This part has been really fun, since I have never worked with motors of this size or with AC. The controller has also been taken from the same washing machine (it even included a pot for speed control!), so I was only left with some wiring and mounting. I also needed to build a pulley and belt system to achieve the desired transmission ratio and a case to keep everything in place. My friend Shachar contributed his golden hands for this task.<br />
Here are some photos of the build process:<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/_LxebaUxx8xw/TF637KqbjPI/AAAAAAAATE0/OWHUTvcnR0g/s1600/IMG_20100602_091734.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="150" src="http://4.bp.blogspot.com/_LxebaUxx8xw/TF637KqbjPI/AAAAAAAATE0/OWHUTvcnR0g/s200/IMG_20100602_091734.jpg" title="The motor and contoller" width="200" /></a> <a href="http://4.bp.blogspot.com/_LxebaUxx8xw/TF64SFe3eJI/AAAAAAAATE8/aw5_V7p8blk/s1600/IMG_20100609_131001.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="200" src="http://4.bp.blogspot.com/_LxebaUxx8xw/TF64SFe3eJI/AAAAAAAATE8/aw5_V7p8blk/s200/IMG_20100609_131001.jpg" title="Cutting the shaft to length" width="150" /></a> <a href="http://4.bp.blogspot.com/_LxebaUxx8xw/TF64pQKSSTI/AAAAAAAATFE/pw1IzIjf3VM/s1600/IMG_20100609_140537.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="200" src="http://4.bp.blogspot.com/_LxebaUxx8xw/TF64pQKSSTI/AAAAAAAATFE/pw1IzIjf3VM/s200/IMG_20100609_140537.jpg" title="Machining the shaft to fit the bearinaltg" width="150" /></a> <a href="http://2.bp.blogspot.com/_LxebaUxx8xw/TF65d5c6pBI/AAAAAAAATFU/PARCkyjsqKE/s1600/IMG_20100616_143756.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="200" src="http://2.bp.blogspot.com/_LxebaUxx8xw/TF65d5c6pBI/AAAAAAAATFU/PARCkyjsqKE/s200/IMG_20100616_143756.jpg" title="The motor & bearing" width="150" /></a> <a href="http://2.bp.blogspot.com/_LxebaUxx8xw/TF66nIbRcpI/AAAAAAAATFc/mRfACVqq3gU/s1600/IMG_20100616_164500.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="200" src="http://2.bp.blogspot.com/_LxebaUxx8xw/TF66nIbRcpI/AAAAAAAATFc/mRfACVqq3gU/s200/IMG_20100616_164500.jpg" title="Shachar building the case" width="150" /></a> <a href="http://3.bp.blogspot.com/_LxebaUxx8xw/TF67AJN-6BI/AAAAAAAATFk/TQR-k6IA80Y/s1600/IMG_20100617_171617.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="200" src="http://3.bp.blogspot.com/_LxebaUxx8xw/TF67AJN-6BI/AAAAAAAATFk/TQR-k6IA80Y/s200/IMG_20100617_171617.jpg" title="First assembly" width="150" /></a></div><br />
Currently, it is very noisy. I'm still considering my options: possibly I'll fill the case with some acoustic isolating material.<br />
<br />
Here's a video showing the turning mechanism working slowly:<br />
<object height="385" width="480"><param name="movie" value="http://www.youtube.com/v/6IOCHxcky7g&hl=en_US&fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/6IOCHxcky7g&hl=en_US&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"></embed></object><br />
<br />
And this video shows some fast spinning and variation of the speed:<br />
<object height="385" width="480"><param name="movie" value="http://www.youtube.com/v/rj389swl6yE&hl=en_US&fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/rj389swl6yE&hl=en_US&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"></embed></object><br />
<br />
Next: <a href="http://ytai-mer.blogspot.com/2010/08/pov-global-part-iii-electronics.html">POV Globe - Part III - Electronics</a>Ytaihttp://www.blogger.com/profile/05373159288627167940noreply@blogger.com4tag:blogger.com,1999:blog-4289452895058070746.post-5703447133985728312010-08-09T08:13:00.002+03:002010-08-10T03:43:45.961+03:00POV Globe - Part I - Introduction<h4>PO-WHAT??</h4>For those who don't know, POV stands for Persistence of Vision, and in this context it describes a technique that people developed for creating LED-based displays of various forms that appear to be floating in the air.<br />
<br />
The basic principle is rather simple: you take a row of LEDs, spin it very fast while switching the LEDs on and off at very precise timings, carefully synchronized with the location of the LED row. The motion is quick enough that our eyes cannot detect it, and the illusion that is created is of a 2D image composed of the circular paths created by the LEDs.<br />
<br />
Many people have mounted such LED rows on HDD spindles, mostly for creating clocks, such as <a href="http://www.youtube.com/watch?v=gXvZPRu6YUM">this one</a>.<br />
<br />
In other variations of this basic idea, the rotation axis can be parallel to the row of LEDs to create a cylindrical display, and going from cylindrical to spherical is a simple matter of using an arc rather than a straight row of LEDs. People have used the spherical version mostly for displaying of globes.<br />
Yes. Everybody seems to be building those recently. I got my inspiration from <a href="http://www.youtube.com/watch?v=oLygWkHo9nw">this YouTube clip</a>. So why build another one, and what's so different about mine?<br />
First, I wanted my globe to be rather big (60cm in diameter), spin fast for a smooth image (up to 50 revolutions per second), have high resolution (256 LEDs) and be very versatile in terms of what it can display - one could easily load complex animations for it, and change them frequently (more on that later). Second, while taking no credit whatsoever for the idea, the build is still really fun, and coming up with elegant solutions to the various problems that arise still needs a good amount of innovation.<br />
<br />
To make it more interesting, the display is actually comprised of two layers - a sphere made of white LEDs, and a cylinder, of slightly bigger diameter made of RGB LEDs surrounding it. That would enable displaying an animated black and white globe with a colorful text or animation around it.<br />
<br />
In the next series of posts, I intend to document the process of building this installation. At the time of writing this, it is still a work in progress, and I intend to update the posts every once in a while when I'm having some interesting progress. Don't hold your breaths, I'm investing only a few hours a week on this project, so it takes a lot of time and patience.<br />
<br />
Next: <a href="http://ytai-mer.blogspot.com/2010/08/pov-globe-part-ii-mechanics.html">POV Globe - Part II - Mechanics</a>Ytaihttp://www.blogger.com/profile/05373159288627167940noreply@blogger.com5tag:blogger.com,1999:blog-4289452895058070746.post-30761552649191107032010-05-18T14:00:00.001+03:002010-05-18T14:15:44.815+03:00AVR Programmer Using PICMANFor a new project I'm working on I needed to program an ATmega-8. Alas, I didn't have an AVR programmer, nor the will to build one.<br />
<a href="http://1.bp.blogspot.com/_LxebaUxx8xw/S_JyH7zBriI/AAAAAAAASms/6d-s557lcX8/s1600/2010-05-18+13.24.39.jpg" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="175" src="http://1.bp.blogspot.com/_LxebaUxx8xw/S_JyH7zBriI/AAAAAAAASms/6d-s557lcX8/s320/2010-05-18+13.24.39.jpg" width="320" /></a><br />
I decided to make one using the <a href="http://ytai-mer.blogspot.com/2010/04/picman.html">PICMAN</a>. After searching on the internet for a while, I found out about <a href="http://tuxgraphics.org/electronics/200510/article05101.shtml">AVRUSB500</a> from Guido Socher. The software is well-written and open-source, so I decided to port it to PICMAN. A few hours later I had a working USB programmer, STK500v2-compatible, which enables it to work from AVRStudio.<br />
<a href="http://2.bp.blogspot.com/_LxebaUxx8xw/S_JyIUakXtI/AAAAAAAASm0/Hi7laKsN0YU/s1600/Fullscreen+capture+1852010+133457.jpg" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="200" src="http://2.bp.blogspot.com/_LxebaUxx8xw/S_JyIUakXtI/AAAAAAAASm0/Hi7laKsN0YU/s200/Fullscreen+capture+1852010+133457.jpg" width="188" /></a><br />
I used the Microchip CDC device code from the <a href="http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=2680&dDocName=en547784">Microchip USB framework</a> in order for the PICMAN to appear as a COM port on the PC.<br />
Source code and hex available <a href="https://docs.google.com/leaf?id=0B4WsgbOl9eLMNGZiMDkwOGMtNDE1MC00ZmFiLTk4MDktZDg1NDY1NDgxN2E2&hl=en">here</a>, under GPL.<br />
Now I can get on with my life...Ytaihttp://www.blogger.com/profile/05373159288627167940noreply@blogger.com0tag:blogger.com,1999:blog-4289452895058070746.post-47719459230667857052010-04-13T00:09:00.011+03:002010-04-13T21:29:26.757+03:00PICMANFor a long time now I've been wanting to make my own microcontroller-based prototyping board. My original motivation was the unjustified high costs for even the simplest boards (a basic Arduino for $30 - why???) and the challenge of designing something that anyone can make at home within a few hours, with parts that can be cheaply obtained on eBay.<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://2.bp.blogspot.com/_LxebaUxx8xw/S8N8mRs7wBI/AAAAAAAASfs/L895_j0QEJ4/s1600/2010-04-12+22.18.17.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://2.bp.blogspot.com/_LxebaUxx8xw/S8N8mRs7wBI/AAAAAAAASfs/L895_j0QEJ4/s320/2010-04-12+22.18.17.jpg" width="320" /></a></div><br />
Eventually, I came up with the PICMAN. It is:<br />
<br />
<ul><li>Based on Microchip's PIC18LF4553 - a 12MIPS microcontroller with 12-bit A/D, plenty of I/O, built in USB transceiver and tons of other coolness.</li>
<li>A single-layer PCB design - ideal for DIY toner-transfer etching fabrication.</li>
<li>Small form-factor that nicely fits on a solderless breadboard.</li>
<li>Can be powered by USB/external 5V/external 8V-35V using on-board 1.5A regulator.</li>
<li>Has a reset button, a user button a power LED (blue) and 3 user LEDs (red, yellow, green).</li>
<li>Needs <b>zero</b> external components to work.</li>
<li>Programmed with a bootloader, making it possible to download a program via USB.</li>
<li>Can implement any USB device using Microchip's USB stack.</li>
<li>Less than $7 total with easily obtainable parts (not including shipping costs, which are usually low if not free, and assuming that some of the small parts are bought in quantities).</li>
</ul><div>I made two pieces so far, each took a couple of hours' work, requiring some SMD soldering experience. I did the initial programming (bootloader image) with a PICKit2 programmer, after having to struggle a little with the Microchip provided bootloader firmware code. It really works nicely - I like it much better than most Arduinos that cost 5+ times as much and it was really fun to build.<br />
Some ideas that I used in the design:<br />
<ul><li>Mount the PIC at the bottom of the board, between the header pins.</li>
<li>Use the copper layer for text to make it easier to locate individual pins.</li>
<li>Use a mini-B USB connector for smaller form factor (than B) and availability of cables.</li>
</ul>Some assorted design/fabrication tips:<br />
<ul><li>Edit the final PostScript file generated by Eagle with a text editor, replacing the last number in every line ending with "h" with 2000. This effectively resizes all holes to 0.2mm making them perfect for centering the drill bit.</li>
<li>Add a cool logo on the final PDF with Illustrator.</li>
<li>Print in 1200DPI on a transparency with a laser printer.</li>
<li>Cut board with a large paper Guillotine.</li>
<li>Use lamination machine for toner transfer. Let fully cool in air before gently removing transparency. Verify <b>before</b> etching, or otherwise scrape off toner and retry.</li>
<li>1 part HCl, 2 parts 3% H2O2 for etching.</li>
<li>Final cutting of the board to shape with tin snips.</li>
<li>0.6mm holes for PIC and ceramic capacitor, 1mm holes for L7805 and all mounting holes (switch and USB jack), 0.8mm holes for the rest.</li>
<li>1k resistor for the green LED makes it just as bright as the other ones with 330 resistors.</li>
<li>Solder USB jack first. Have a lot of patience ready.</li>
</ul></div><a href="http://4.bp.blogspot.com/_LxebaUxx8xw/S8N8lono-cI/AAAAAAAASfk/-Shl1xSofvU/s1600/2010-04-08+22.02.32.jpg" imageanchor="1" style="margin-bottom: 1em; margin-right: 1em;"><img border="0" height="200" src="http://4.bp.blogspot.com/_LxebaUxx8xw/S8N8lono-cI/AAAAAAAASfk/-Shl1xSofvU/s200/2010-04-08+22.02.32.jpg" width="150" /></a><a href="http://1.bp.blogspot.com/_LxebaUxx8xw/S8N8nCvDPPI/AAAAAAAASf0/EoVRpy30uHY/s1600/2010-04-12+22.19.35.jpg" imageanchor="1" style="margin-bottom: 1em; margin-right: 1em;"><img border="0" height="150" src="http://1.bp.blogspot.com/_LxebaUxx8xw/S8N8nCvDPPI/AAAAAAAASf0/EoVRpy30uHY/s200/2010-04-12+22.19.35.jpg" width="200" /></a><a href="http://2.bp.blogspot.com/_LxebaUxx8xw/S8N8oA5sYoI/AAAAAAAASf8/PMDWe29a8PA/s1600/2010-04-12+22.30.23.jpg" imageanchor="1" style="margin-bottom: 1em; margin-right: 1em;"><img border="0" height="150" src="http://2.bp.blogspot.com/_LxebaUxx8xw/S8N8oA5sYoI/AAAAAAAASf8/PMDWe29a8PA/s200/2010-04-12+22.30.23.jpg" width="200" /></a><br />
Here is the schematic, the layout and the final artwork (mirrored). The Eagle files, firmware images and programming software can be downloaded from <a href="https://docs.google.com/leaf?id=0B4WsgbOl9eLMOGExMTRhYWYtNmM2Zi00Yjk3LTk3MzEtNWEyZWQ0M2FhNDgx&hl=en">here</a>. I'll happily share eBay links, where all these components can be bought cheaply, just ask if you can't find any of them.<br />
If anyone has any constructive comments, or has built one and wants to share it, feel free to comment below.<br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/_LxebaUxx8xw/S8OEqO6tvAI/AAAAAAAASgM/xq5WI9U-Psw/s1600/schematic.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="http://3.bp.blogspot.com/_LxebaUxx8xw/S8OEqO6tvAI/AAAAAAAASgM/xq5WI9U-Psw/s200/schematic.png" width="171" /></a></div><div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/_LxebaUxx8xw/S8OEqO6tvAI/AAAAAAAASgM/xq5WI9U-Psw/s1600/schematic.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"></a><a href="http://1.bp.blogspot.com/_LxebaUxx8xw/S8OE9dkiWGI/AAAAAAAASgU/Po7mNDYYZX0/s1600/layout.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/_LxebaUxx8xw/S8OE9dkiWGI/AAAAAAAASgU/Po7mNDYYZX0/s200/layout.png" width="150" /></a><a href="http://1.bp.blogspot.com/_LxebaUxx8xw/S8QZDSVd2hI/AAAAAAAAShI/axYeCHPMsxA/s1600/artwork.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/_LxebaUxx8xw/S8QZDSVd2hI/AAAAAAAAShI/axYeCHPMsxA/s200/artwork.png" width="150" /></a></div>Ytaihttp://www.blogger.com/profile/05373159288627167940noreply@blogger.com26