Gumstix/FTDI: Eat Your PySerial!

This is a short note on using the Gumstix Overo’s USB OTG port with a client device that has an FTDI chip for serial-over-USB communications. One example would be an Arduino, but I wrote this while testing out this USB Geiger tube.

First, if you don’t already have at least these packages installed, download and save them to your bootable MMC card’s /home/root directory:

www.gumstix.net/feeds/unstable/ipk/glibc/armv7a/machine/overo/kernel-module-ftdi-sio_2.6.31-r50.5_overo.ipk
www.gumstix.net/feeds/unstable/ipk/glibc/armv7a/base/libpython2.6-1.0_2.6.2-ml8.0.5_armv7a.ipk
www.gumstix.net/feeds/unstable/ipk/glibc/armv7a/python/python-core_2.6.2-ml8.0.5_armv7a.ipk
www.gumstix.net/feeds/unstable/ipk/glibc/armv7a/python/python-pyserial_2.4-ml1.5_armv7a.ipk

The first package (FTDI serial I/O) must match the card’s kernel version, 2.6.31 in this case. Reboot the Gumstix and install all packages:

root@overo:~# opkg install kernel-module-ftdi-sio_2.6.31-r50.5_overo.ipk
root@overo:~# opkg install libpython2.6-1.0_2.6.2-ml8.0.5_armv7a.ipk
root@overo:~# opkg install python-core_2.6.2-ml8.0.5_armv7a.ipk
root@overo:~# opkg install python-pyserial_2.4-ml1.5_armv7a.ipk

(Depending on what you have installed, additional dependencies may be required. The http://www.gumstix.net/feeds/unstable/ipk/glibc/ packages site has everything you need. And ignore errors about “hicolor-icon-theme.postinst,” which seem to occur whenever a package is installed.)

Post install, you will be able to do this without error:

root@overo:~# python
Python 2.6.2 (r262:71600, Jan  8 2010, 17:02:00)
[GCC 4.3.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import serial
>>>

Once everything is installed, reboot and load the FTDI module into the kernel:

root@overo:~# cd /lib/modules/2.6.31-omap1/kernel/drivers/usb/serial/
root@overo:~# depmod -a ftdi_sio.ko
root@overo:~# insmod ftdi_sio
root@overo:~# modprobe ftdi_sio

At this point I had to reboot again with my USB device plugged into the USB OTG port. (Otherwise, that port seems not to be enabled, and you can’t even use it to power a device.) On reboot, you should see something like this:

usb 1-1: Manufacturer: FTDI
USB Serial support registered for FTDI USB Serial Device
ftdi_sio 1-1:1.0: usb_probe_interface
ftdi_sio 1-1:1.0: usb_probe_interface - got id
ftdi_sio 1-1:1.0: FTDI USB Serial Device converter detected
usb 1-1: FTDI USB Serial Device converter now attached to ttyUSB0
usbcore: registered new interface driver ftdi_sio
ftdi_sio: v1.5.0:USB FTDI Serial Converters Driver

And you should have a device entry along the lines of /dev/ttyUSB0. Once that’s confirmed, create a serial-listener.py script like this:

#!/usr/bin/python

import serial

s = serial.Serial('/dev/ttyUSB0',9600)
c = s.read(1)
print c

(Change /dev/ttyUSB0 to the exact name appearing in the /dev directory upon device insertion.)

Run your serial-listener.py:

root@overo:~# ./serial-listener.py

Voila — serial-over-USB communications with the FTDI-based Geiger counter or peripheral of your choice.

Repair of Vacuum Fluorescent Display after Hilarious Polarity Mixup

A while back I was playing around with a Noritake 7002 vacuum fluorescent display (VFD) module. (Available here for $70, elsewhere for a bit less.) VFDs are those things they use on car stereos, with brighter characters and more fonts than character LCDs.

Noritake VFD

The 7002 has built-in asynchronous and synchronous serial interfaces, and even a parallel interface too. What it doesn’t have is a four-cent diode to prevent reverseral of the +5V power and GND pins from instantaneously destroying the entire unit. (For the record: pin 1 is +5V and 3 is GND.)

It’s possible to fix such a damaged device, though. Above the display, in between a row three holes labeled CN2 and serial pin 1 (+5V), is a surface-mount fuse labeled “FUSE 1.” Here’s a blurry picture:

Noritake VFD Fuse

Bypassing this fuse with a wire restores the unit to normal operation. Since I didn’t have any replacement SMT fuses on hand, I just used a huge blob of solder to more permanently repair the device:

Noritake VFD Fuse Bypassed

I’m still waiting to see if it explodes now during prolonged use…

Noritake VFD Repaired

How to install GCC on the Gumstix Overo without using Open Embedded

One of the things that threw me for a loop last fall when I got my Gumstix Overo was the fact that there didn’t seem to be a C compiler on the device. After quite a bit of time searching on the matter, I came to the (erroneous) conclusion that one needed to load the Open Embedded build environment on his or her development machine and build a new image from scratch that included gcc.

Here’s a much simpler method. Start out with a binary image (following directions in this tutorial) and then go to the packages repository at http://www.gumstix.net/feeds/unstable/ipk/glibc/armv7a/base/. There you’ll find:

You’ll even find the Boost C++ libraries. Anyway, to install the above packages, download the .ipk files on your development machine, copy them to your home directory (/home/root) on your bootable MMC card, and then boot the Gumstix with it.

Confusingly, the “ipkg” system doesn’t have a namesake command; instead, you use “opkg.” (Why???) For instance, do this from the Gumstix in the directory where you wrote the .ipk files:

root@overo:~# opkg install gcc_4.3.3-r10.1.5_armv7a.ipk

Irrespective of the package being installed, for me this generates a bunch of error messages about some missing icon:

root@overo:~# opkg install python-threading_2.6.2-ml8.0.5_armv7a.ipk
Installing python-threading (2.6.2-ml8.0.5) to root...
Configuring hicolor-icon-theme
//usr/lib/opkg/info/hicolor-icon-theme.postinst: line 7:
  can't create /etc/gtk-2.0/gdk-pixbuf.loaders: nonexistent directory
//usr/lib/opkg/info/hicolor-icon-theme.postinst: line 7: gdk-pixbuf-query-loaders: not found
//usr/lib/opkg/info/hicolor-icon-theme.postinst: line 13: gtk-update-icon-cache: not found
postinst script returned status 127
Configuring python-threading
Collected errors:
 * ERROR: hicolor-icon-theme.postinst returned 127

At first, I couldn’t figure out why it was looking for this icon business during a text mode terminal session on a machine without any X Window installation anywhere. Then, I noticed the first two lines and the second to last. The install actually goes all the way to completion (or fails) independently of those icon messages.

Once you’ve installed all the packages listed earlier, plus any additional dependencies that opkg requests, you can type cc or gcc as usual.

(To develop device drivers, you’ll want a way to avoid having to do development on the target hardware. Read this. It describes a way to have your Gumstix (if it has Ethernet) share a network mount with your development machine so you can cross compile on the latter and test immediately on the former. Note that this does require you to build Open Embedded on the dev machine to get the ARM cross compiler.)

Gumstix Overo Meets Arduino (via I2C)

This post is about how to set up a Gumstix Overo as an I2C bus master, with one or more Arduino devices as slaves. Here’s a picture of the basic set up:

Gumstix/Arduino I2C

Why? Gumstix and Arduino are two very different, but very awesome, open-source hardware projects. The 2” Gumstix board runs a complete Linux distribution on a 600 MHz ARM processor. Unlike a microcontroller, it’s not a very good fit for reading simple sensor data or doing stuff at precisely timed intervals. It’s also not for the kernel-mode faint of heart: to get things like external interrupts working you’ll have to roll your own drivers. However, with 256 MB of DRAM and up 8 GB of Compact Flash, you can do complex embedded processing tasks from the relative comfort of a Python script.

Arduino on the other hand is a simple AVR microcontroller board – a modern day Basic Stamp – with a huge user community that includes artists and designers as well as engineers. (User-written tutorials range from how to flash an LED to advanced high-speed photography of exploding Peeps Easter candies). While Arduino is pretty much the coolest thing to happen to microcontrollers since internal pullups, it’s fundamentally still an 8-bit micro that’s limited to simple tasks like reading sensors and turning servo motors.

I2C (Inter-Integrated Circuit) is a serial bus protocol that also goes by TWI, SMBus and “Wire” (in Arduinospeak). Although you should connect the Gumstix and Arduino through USB if you can (it’s less work), using up the Gumstix’s lone USB OTG port like this may not be acceptable in all cases and also runs up against a well-documented Arduino feature/bug by which the Arduino will reset every time you try to re-open a serial connection to it. If the Arduino is buffering sensor data to transmit to the more-sophisticated-but-less-I/O-oriented Gumstix, you obviously can’t have it do hard resets all the time. There are other solutions to this problem, but connecting the two through I2C is the one I’ll describe here.

Hardware I’m using this hardware:

  1. Gumstix Overo Earth module + Summit expansion board - The Gumstix is our bus master. I2C port #3 on its OMAP processor is brought out on the Summit board’s 40-pin header as holes 23 (SCL) and 24 (SDA). The Linux i2c driver will expose this as /dev/i2c-3 as we’ll see in a moment.
  2. Arduino Duemilanove - The AVR’s I2C port is brought out on Arduino’s analog pins 4 (SDA) and 5 (SCL). The Arduino will be the one and only slave device on our bus.
  3. Logic-level Converter - Since the Gumstix uses 1.8V logic versus 5V logic on the Arduino, some logic level conversion is needed in between. The red SPE board takes care of this. Its inputs are confusingly labeled, though. Just use the two “TX” lines (which are bidirectional) and don’t try to understand why the terms “transmit” and “receive” were used on the board instead of “bi” and “uni”.

At the beginning of this post there was a picture of the complete setup. Here are close ups on each part of that picture (note that Gumstix is rotated 90 degrees CW to correspond w/ pinout):

Gumstix Connections Logic Level Converter Connections Arduino Connections

Erratum #1: wire colors are supposed to be consistent as you go from left to right across the three pictures, but I screwed up the bottom one, which should have been yellow on both sides.

Erratum #2: short red wire jumping over level converter in the middle picture is not necessary. The two grounds are already joined by a trace on the SPE board.

Software For the software, the Arduino Wire library includes examples called “slave_sender” and “slave_receiver” that set up the Arduino as an I2C slave. In either case, we assign the Arduino an address and then it listens for that address to be asserted on the bus. Then, in the first example, it responds by sending back data. Here’s the code:

#include <Wire.h>
void setup()
{
  Wire.begin(0x11);                // join i2c bus with address #17 (0x11)
  Wire.onRequest(requestEvent); // register event
}
void loop()
{
  delay(100);
}
void requestEvent()
{
  Wire.send("hello ");
}

Now, on the Gumstix, we can use the command line tool i2cdetect to check whether anyone else is on i2c bus #3:

root@overo:~# i2cdetect -y -r 3
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- 11 -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

One device at address 0×11 (17 decimal). So let’s put a request on i2c bus #3 for that device and dump the response:

root@overo:~# i2cdump -y 3 17 i
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef
00: 68 65 6c 6c 6f 20 ff ff ff ff ff ff ff ff ff ff    hello ..........
10: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
20: 68 65 6c 6c 6f 20 ff ff ff ff ff ff ff ff ff ff    hello ..........
30: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
40: 68 65 6c 6c 6f 20 ff ff ff ff ff ff ff ff ff ff    hello ..........
50: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
60: 68 65 6c 6c 6f 20 ff ff ff ff ff ff ff ff ff ff    hello ..........
70: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
80: 68 65 6c 6c 6f 20 ff ff ff ff ff ff ff ff ff ff    hello ..........
90: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
a0: 68 65 6c 6c 6f 20 ff ff ff ff ff ff ff ff ff ff    hello ..........
b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
c0: 68 65 6c 6c 6f 20 ff ff ff ff ff ff ff ff ff ff    hello ..........
d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................
e0: 68 65 6c 6c 6f 20 ff ff ff ff ff ff ff ff ff ff    hello ..........
f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff    ................

Brandon Stafford for Linux Users

Hi Brandon, I have taken the liberty of converting your Powerpoint slides to PDF format (736 kb PDF) so that they are viewable on non-Windows systems, such as those based on the popular GNU/Linux operating system.

I know how you often make condescending remarks like “Open source is for losers” and generally frown upon vendor-neutral solutions, but some of the best bloggers in the alternative energy community do not share your zealous support of proprietary file formats.

Dreamforce ‘08 Session Notes: Saas Key Metrics (according to Bessemer)

Philippe Botteri - investment analyst at BVP, ex-McK guy, talking about financial modeling for Saas startups

5 c’s of Saas:

  • CMRR (committed monthly recurring ration) - Bessemer-designed metric, equals GAAP revenue plus contracts signed but not yet recognized (b/c not yet implemented)
  • churn - 1% per month is considered good
  • cash - about $60-$126 million in pre-IPO capital required (SFDC and Netsuite, respectively), but he sees it going down because of cloud
  • CAC (customer acquisition cost)
  • CLTV ratio (customer lifetime value)

Note: these notes omit Philippe’s technical discussion of how to build the financial model using these 5 metrics; email them to get the PPT deck

Discounts cash flows at 15% for Saas companies.

Dreamforce ‘08: Org Merge Breakout Notes

These are just my rough notes from a Dreamforce ‘08 session about merging orgs.

Note: his deck will be posted on successforce.com

Alternative approach: Salesforce-to-Salesforce (interesting idea!), but you can only share a few standard objects (Cases, Ops, Prods are NOT shareable this way)

Four steps to org merge:

  1. System Review Process — what does the “goal org” look like, what is the test plan
  2. Process Review Process — know what was configured and why (strongly agree –MWG)
  3. Data Considerations — map out what the data is, rules for merging data, create a data map
  4. Migration Strategy — who is involved, deadlines, sign off from project sponsors

Make backups using SFDC data export tool, or data loader

Holly: set expectations, go slowly

3rd party tools:

  1. Paul: “DBM for Force” - like an ODBC driver
  2. Holly: “Demand Tools” from CRM Fusion
  3. Moderator: “Snapshot”
  4. Presenter: “Monarch”

Q: Can you downgrade from UE to EE without a migration? Can SFDC just flip a switch? A: No, b/c of differences in limits, e.g., how do we know which of the custom fields to kill if UE org exceeds the limit imposed on EE org?

Q: How does SFDC professional services do it? Do they really do it all with spreadsheets? A: Yes, spreadsheets are used. There’s no silver bullet.

Holly: don’t forget about user level settings vs. global settings

“Courtesy licenses” — they will do this during the period of overlap if you present a reasonable project plan

How to deal with user ids:

  1. Put “x” in front of old login (e.g., xmike@mwgaa.com).
  2. Set up new org with courtesy lics re-using the real addresses

Use this grid when going EE to UE etc: app setup limits

Selenium IDE script to set up a new Salesforce DE org

You still have to read the captcha graphic and press the submit button yourself, but all the other fields are filled in for you. Instructions are below the code for those new to the Selenium IDE Firefox plugin.

<?xml version=”1.0″ encoding=”UTF-8″?>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Strict//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml” xml:lang=”en” lang=”en”>
<head profile=”http://selenium-ide.openqa.org/profiles/test-case”>
<meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8″ />
<link rel=”selenium.base” href=”http://wiki.apexdevnet.com/events/workbook/registration.php” />
<title>NewDEFromScratch</title>
</head>
<body>
<table cellpadding=”1″ cellspacing=”1″ border=”1″>
<thead>
<tr><td colspan=”3″>NewDEFromScratch</td></tr>
</thead><tbody>
<tr>
<td>open</td>
<td>http://wiki.apexdevnet.com/events/workbook/registration.php</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>Name_First</td>
<td>Mike</td>
</tr>
<tr>
<td>type</td>
<td>Name_Last</td>
<td>Goelzer</td>
</tr>
<tr>
<td>type</td>
<td>Email</td>
<td>mike@mwgaa.com</td>
</tr>
<tr>
<td>type</td>
<td>Phone</td>
<td>650-329-8500</td>
</tr>
<tr>
<td>type</td>
<td>State</td>
<td>CA</td>
</tr>
<tr>
<td>type</td>
<td>PostalCode</td>
<td>94301</td>
</tr>
<tr>
<td>type</td>
<td>Organization</td>
<td>MWG & Associates LLC</td>
</tr>
<tr>
<td>select</td>
<td>platformInterest</td>
<td>Not Sure</td>
</tr>
<tr>
<td>select</td>
<td>developerJobRole</td>
<td>Administrator</td>
</tr>
<tr>
<td>select</td>
<td>developerInterest</td>
<td>Prospective Customer</td>
</tr>
<tr>
<td>store</td>
<td>javascript{ prompt(’Enter a new login (e.g., “mike22″)’) }</td>
<td>varLogin</td>
</tr>
<tr>
<td>type</td>
<td>userUsername</td>
<td>${varLogin}@mwgaa.com</td>
</tr>
<tr>
<td>click</td>
<td>userUsername</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>subscriptionAgreement</td>
<td></td>
</tr>
<tr>
<td>verifyChecked</td>
<td>subscriptionAgreement</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>CaptchaResponse</td>
<td></td>
</tr>

</tbody></table>
</body>
</html>

If you’ve never used Selenium before, here is what you do:

1. Save the code above to a file called NewDEFromScratch.html. Change the name and email to your own.
2. Install the Firefox extension “Selenium IDE” and restart the ‘fox.
3. Go to the menu Tools | Selenium IDE. The Selenium window will pop up next to the main browser.
4. Click File | Open… while the Selenium window is in the foreground. This matters because Selenium offers a bunch of extra items in the File menu only when it’s window is in active:

Selenium File Menu

5. Click the Run Test button: Selenium Run Button.
6. When the script finishes, manually type in the captcha graphic and click the submit button.

ADN’s Dreamforce within a Dreamforce

Things definitely got more interesting this afternoon when I headed upstairs to meet up with friend and former Stanford classmate Jim. He kindly gave me the Cliff’s Notes SparkNotes version of Benioff’s various announcements during the keynote. ZDNet has a good summary.

Then I wandered in to the Apex Developer Network area, which was like its own mini-conference, complete with (independent) sponsorship from Apple and Google, informal presentations, and a plentiful supply of test machines (iMacs, of course) that anyone could use to play with the new Visualforce interface technology unveiled this morning.


The ADN Mini ConferenceADN’s Conference within a ConferencePeople inside the ADN miniconference area

UPDATE: All pics are now on Flickr: www.flickr.com/mikegoelzer

Liveblogging Dreamforce 2007 (or, A Reluctant Blogger Returns to his Soapbox)


Dreamforce 2007

My attempt at liveblogging Dreamforce 2007 is off to a bit of a slow start. After a very, very late night of sketching out how I could make use of the super-cool Mono.Fuse library for the SDrive system, I arrived at the Moscone Center totally exhausted. I assumed that a cup of coffee would restore me to my normal state, but I had no such luck: as soon as I sat down on one of the couches to drink the coffee I dozed off for over an hour!

Sweet dreams at Dreamforce, I guess.

Here are some more pictures. (More substantive posts are coming up soon.)


Dreamforce 2007Dreamforce 2007Dreamforce 2007Dreamforce 2007Dreamforce 2007Dreamforce 2007Dreamforce 2007Dreamforce 2007Cheetah with her cubs

(OK, the last picture of the cheetah and her cubs is from my trip to South Africa, not Dreamforce. Just trying to keep you on your toes.)