Friday, October 28, 2011

IOIO Over Bluetooth (or: Who Needs Cables Anyway?)

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.

OK, now that I got it off my chest, I can tell you what it's all about.

The Short Story

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 source code for the application demonstrated above 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.

The Long Story

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.
Back when I published my original announcement on IOIO, 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.

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.

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 btstack, 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 perfect. 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.

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!
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.

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.

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 firmware upgrade capabilities that I previously enabled. Some have already reported success.

@DIYTough choice... access point mode would give you p2p standalone connectivity a la ARDrone while client mode would give you accessibility from the internet and the ability to control multiple devices from a single master in a wifi covered environment (e.g. home automation etc). I'm also not sure what those dongle provide in terms of access point mode.@evillanuevaall the code is always publicly available on github and always has been. Or do you mean NEW source code? :)

@evillanuevaNot sure what you mean. The source code has been there ever since I wrote it. I'm normally pushing my work to github very often, even before things are fully working:https://github.com/ytai/ioio

If it is difficult to make the dongle as AP à la ARdrone, I suggest another good P2P mode that I already realized in my recent projects (https://market.android.com/details?id=com.diyphonegadgets.yandroidcontroller&feature=search_result): using android as a WiFi tethering hotspot (AP) and you can connect any wifi client to it, in your case, the client can be the WiFi dongle on IOIO. The WiFi tethering hotspot (AP) is supported by Android 2.2 Froyo or above. One interesting thing that I noticed is that on all Android devices I have tested so far, the ip address of the Android AP is always 192.168.43.1. That makes it so easy to develop client applications without considering the server's ip address. What's more, I can even programmatically enable tethering mode and define the AP name in my Android code. I hope that helps:)

@MarkusI did do these tests. IIRC round-trip latency was around 40ms and effective throughput is 200Kb/s running in both directions concurrently.For ADB, these numbers are around 4ms / 800Kb/sFor ADK, 1ms / 1600Kb/s or so.

@MishaTrue. The advantages of IOIO:1. Cheap (especially if you already have a IOIO - just add $1.80 compared to $20+ for a serial module).2. Very simple to connect (USB).3. Already has all the required software in place to enable easy control of peripherals from Android. Don't underestimate this - it's tons of non-trivial code that took a long time to write.4. Seamless transition from Bluetooth to ADB with no impact on user code.

@MarkusKb = kilobit. I need to double-check these numbers, my memory may be betraying me.

As for your second question, see the "I don't know Jack about Bluetooth" part above :) My guess is that most of this latency is probably an artifact of the stacks running on both ends and not the standard. You would probably smash your favorite Bluetooth keyboard if it had a 20ms one-way latency...

@MishaAgreed, but you're comparing apples to oranges.A reasonable comparison would be IOIO vs. Arduino Mega in terms of I/O count and built-in peripherals. In this case IOIO wins on both price and size.

But of course, if your use-case permits you may be able to use a cheaper / smaller setup. You may not need so much I/O and functions. You may not need the on-board 1.5A voltage regulator, etc.

Well, it could be inherent to RFCOMM, since I get about the same numbers with a Bluetooth-Serial adapter (http://www.ebay.com/itm/Wireless-Serial-Bluetooth-RF-Transceiver-Module-rs232-/260697768531), and a Bluetooth keyboard probably uses L2CAP/HID which could have lower latency but also lower throughput.

But I'm only guessing here, since currently I share the "I don't know Jack about Bluetooth" with you :)

Ytai, a "uC of your choice" might be something like LPC2103 (20USD or less). A 32bit ARM running at up to 70MHz with nice set of peripherals with BT-to-serial module might be a good alternative to IOIO. I guess, often a project needs smaller uC. Perhaps, something like Arduion Nano for the same 20USD.However, nothing comes for free. ;) One has to have some basic skills to make a uC with BT module to talk to an Android based app.

@MishaIOIO is about $20 in parts. Take out the fancy 5V VREG and you're looking at about $10-$12, and with not much more than a uC, USB jack, a 3.3V reg. Almost the bare minimum. I'm not saying you couldn't get any cheaper, but there's not much to reduce from.The price you're paying for a full-PCB from a retailer is obviously higher than parts costs, and has all the obvious advantages.Having said all that, you're welcome (and encouraged) to freely use some or all of the IOIO code and port to your favorite platform. I didn't intend the SparkFun version to necessarily be the only one - that's the beauty of open-source.

Hello,Congratulations for your job!! Ytai, I´d like to know if you could help me...What files in your source code deal with the bluetooth stack and protocol. My idea is to "port" your code for the 8051 architeture. Could you help me in this challenging quest

@brunomontenegroThe Bluetooth stack code is not mine. It is taken from btstack.If for some reason you insist on using the IOIO version of it (which is only slightly modified), the files are under firmware/libbtstack.

HI, thanks for the code. I don't have an IOIO yet, since I'm in Australia I am using this shield: http://www.freetronics.com/products/usbdroid. Do you know if your code will work on my shield or do I need to get an IOIO? Thanks.

It will definitely not work on this board as is, since this is an AVR and the IOIO is PIC... If all you want is an ADB connection, look into the MicroBridge. If you want the full IOIO stack, you should probably get a IOIO. It shouldn't be a problem to get it in Australia.

Hi Ytai, I am hoping you (or someone) can recommend a way to connect the Host A port on my tablet to the Host A port on ioio board. I have had it for a few weeks nw, but I have been unable to get a physical connection because you can't connect Host A USB to Host A USB without burning out something. I wonder if you or anyone else has run into this problem. I could try USB Bridge cable, but that requires drivers to be loaded and I've seen no bridge cable available for a tablet. I have a Ematic Eglide II tablet (I got it for free) with android 2.2 on it. Another way I could maybe try is USB to serial, then a null modem connection to serial to USb and see if that works but am hesitant to buy all that unless I know for sure. Buying an additional ioio board and\or that little pic board for firmware upgrade to try usb Bluetooth isn't in the budget now. Plus my tablet doesn't support Bluetooth. Any help or recommendation sir?Thank you

IOIO wasn't designed for this use case. That is not to say that this isn't an important and interesting use case. Perhaps in the future IOIO boards will support USB OTG which will enable them to function as host or device.At present, you can either connect the IOIO to an Android and have the Android tunnel the data over TCP, or you can connect it to your PC over Bluetooth and port IOIOLib to the PC, which should be close to trivial.As far as upgrading the firmware, you can try to ask on the ioio-users list if there's someone in your area that has a IOIO that you can meet and upgrade each other's boards. This has worked for several people in the past.

I'm not sure what you mean by "porting the manager" and what is your vision for making the programmer cheaply. There are PIC programmers out there for little over $20. IOIOs sell for about $45.Also not sure how the USB<->serial adapter fits into this picture. Would you mind elaborating a little about how you imagine this thing would look like?

There is problem with Apples lack of supporting serial drivers on OS X. Same with third party drivers, most of them (if not all) are unsupported on newer systems and require you to mess with files in the systemfolder. On the other hand there is support for serial communication over bluetoot and strait forward to connect.

So if I hade a method to send apps to a PIC from my Mac there would not be any need for other programers. So if the Android IOIO maneger was on my mac and Android IOIO libs I could do everything on a Mac without going thru a Android or other Programer.

And yes IOIO is mere expensive than a programmer but at the same IOIO is the produkt and programer... ;-)

If you'll want to program a IOIO using this technique, you'll need two of them (one as a programmer, the other as the target).It is definitely doable, and most of the code should port rather easily to a standard Java environment.However, I think your driver argument is inaccurate - I've been working with PICkit3 on OSX (snow leopard) for ages without problems.

My thought was that if (and be patient, there are many ifs) the next version of IOIO had Bluetooth firmware from the beginning and if the maneger was ported to Mac and if there was a compiler that worked without a complicated IDE, then you would have a good compliment to the Arduino family. The idea was: editing in BBEdit, compile and send to IOIO with your Maneger over Blutooth. With time and some Shields, I think it would become more popular than the Arduino, specially if there was ​​a simple IDE that combined your Maneger, compiler and possibly an editor.

About usb2serial: it works for unix / terminal / java, but not OS X. Have to do something with changes to the system and kext files. But I have several customers who have problems with this and old plotters, that I solved in the Snow Leopard somehow, but not in Lion.

I think you're confusing several separate issues.IIUC, what you wish is:"Have a microcontroller board which can be programmed over Bluetooth."

While it is certainly possible to bake in Bluetooth support to the IOIO bootloader (currently the bootloader works by reading an image file from an Android device), I don't see a lot of added value in this. Here's why:- In comparison to Arduino, there won't be much added value. You simply replace wired programming with wireless programming, and you pay by losing all the Arduino advantages for firmware development (e.g. IDE, as you mentioned).- The IOIO approach is that the user doesn't touch the firmware very often. Only once in a while, when a new firmware version is released, the user can upgrade. Spending a lot of effort on making this process doable from a PC over Bluetooth rather than through an Android device is probably not worth the added-value.

Having said that, if IOIO is ever to become controllable from a PC (which is very likely to happen at some point), it may make sense to also enable firmware upgrades from a PC, but I don't think the end result would be exactly what you expect, in the sense that the typical user will only do the Java-side programming, and won't care much about the firmware.

I have placed an order on two IOIO (and a PICkit3 with a dev board). But now you make me second guess that. My understanding was that with the bootloader i can write 'apps' or 'image' and send them to IOIO. The apps would be logic that i write in MPLab and compile there and the bootloader will start it for me after download, same as on Arduino. Is that wrong? Anyway there is no problem if so, can use the IOIO with PICkit but I was plying with the thought to rewrite some part of your code to a droplet for downloading the 'app' to IOIO via BT (or share so bootloader can get it).

Maybe in future I can mail you so we don't need make this too boring for others? I have your mail if its OK.

Well, if you have 2 IOIOs you might as well cancel the PK3 :)The IOIO can act as a PIC programmer (for the kind of PIC that's on the IOIO).

You weren't wrong with your understanding of the technology, but the key point in what I was trying to say that while being definitely possible, having the common user write custom firmware for the IOIO wasn't one of my design goals, so I haven't worked much on making this use-case very friendly.

If you want, you can certainly add Bluetooth support to your custom bootloader - most of the building blocks you'll need (BT USB driver, BT stack) are already there.

You can follow up this discussion on the ioio-dev list, which is a good home for such matters. I'm sure a lot of the audience there will find this interesting.

I think most vendors now will give you a recent firmware version that supports Bluetooth. I know for certain that SparkFun does. If you want to be 100% sure you'll have to contact the vendor and ask.The list of supported dongles is here.

Great stuff, Ytai! Could you tell me how easy it would be to add a SD card to log sensor data while the IOIO is not connected to an android phone? I'd like to leave a data logger in a location for a couple weeks and then offload the data via an android app.

Doing what you're describing involved changing the IOIO firmware to work while disconnected for the Android as well as autonomously log to the SDCard. Last, you'll need to read from the card when the time comes and a request comes in. While certainly possible, it is not trivial, as the current IOIO firmware is purposely not intended for standalone operation. There are probably easier ways to achieve what you want.