Friday, October 17, 2014

Point Grey cameras suck.

Spent way too many hours fighting with two different Flea3 cameras from Point Grey lately.  All the software is hidden behind a login page, and they'll spam you if you sign up.  Lots of different obscure and unhelpful error messages, and one of the cameras bricked when I tried a firmware upgrade.

It's not too much to ask for a machine vision camera that:
 - Works with linux
 - Has Open Source software that I can "apt-get install"

Suggestions for alternatives welcome.

Wednesday, October 01, 2014

IOIO otg + Ubuntu quickstart

I picked up a IOIO board from SparkFun.  I want to control its PWM channels from my Ubuntu workstation (no android involved).  Fortunately, I work near Ytai, so I was able to pick his brain when I got stuck!

This was a reasonable place to start, and helped me get my udev rule set up so that I saw /dev/IOIO0 when I plugged in the board:
https://github.com/ytai/ioio/wiki/Using-IOIO-With-a-PC

It also reminded me to set the switch on "A" instead of "H".

Next I downloaded App-IOIO504.zip from here:
https://github.com/ytai/ioio/wiki/Downloads

I unzipped it, and tried to run HelloIOIOSwing.jar:
$ java -jar HelloIOIOSwing.jar -Dioio.SerialPorts=/dev/IOIO0
[D/IOIOConnectionRegistry] Successfully added bootstrap class: ioio.lib.pc.SerialPortIOIOConnectionBootstrap
[W/SerialPortIOIOConnectionBootstrap] ioio.SerialPorts not defined.
Will attempt to enumerate all possible ports (slow) and connect to a IOIO over each one.
To fix, add the -Dioio.SerialPorts=xyz argument to the java command line, where xyz is a colon-separated list of port identifiers, e.g. COM1:COM2.
[D/SerialPortIOIOConnectionBootstrap] Adding serial port ttyACM0
[D/SerialPortIOIOConnectionBootstrap] Adding serial port ttyS4
Exception in thread "AWT-EventQueue-0" purejavacomm.PureJavaIllegalStateException: JTermios call returned -1 at class purejavacomm.PureJavaSerialPort line 1107
...

We hypothesized that it didn't like the -D at the end, so we tried again with different argument order, and that got us a little farther:
$ java -Dioio.SerialPorts=ACM0 -jar HelloIOIOSwing.jar
[D/IOIOConnectionRegistry] Successfully added bootstrap class: ioio.lib.pc.SerialPortIOIOConnectionBootstrap
[D/SerialPortIOIOConnectionBootstrap] Adding serial port ACM0
[D/IOIOImpl] Waiting for IOIO connection
[V/IOIOImpl] Waiting for underlying connection
...

Ytai had me install screen and run $ screen /dev/IOIO0, and we verified that it got back some printable data from IOIO when it started up, so we knew the board was alive.  Next we checked what firmware revision was on the board using ioiodude (also from the downloads page above).

We also downloaded the latest version of the firmware, App-IOIO0500.ioioapp, by clicking on the QR code next to the link to the .zip file.

$ unzip IOIODude-0102.zip
$ ./ioiodude --port=/dev/IOIO0 versions
IOIO Application detected.

Hardware version: SPRK0020
Bootloader version: IOIO0400
Application version: IOIO0330

We rebooted the IOIO otg in bootloader mode so that it could be reflashed.  That involved jumpering the "boot" pin to ground while powering up the board.  Then we could reflash it:

$ ./ioiodude --port=/dev/IOIO0 write App-IOIO0500.ioioapp 
Comparing fingerprints...
Fingerprint mismatch.
Writing image...
[########################################]
Writing fingerprint...
Done.

After that, the Swing and Console apps worked:
$ java -Dioio.SerialPorts=/dev/IOIO0 -jar HelloIOIOSwing.jar 
[D/IOIOConnectionRegistry] Successfully added bootstrap class: ioio.lib.pc.SerialPortIOIOConnectionBootstrap
[D/SerialPortIOIOConnectionBootstrap] Adding serial port /dev/IOIO0
[D/IOIOImpl] Waiting for IOIO connection
[V/IOIOImpl] Waiting for underlying connection
[V/IOIOImpl] Waiting for handshake
[I/IncomingState] IOIO Connection established. Hardware ID: SPRK0020 Bootloader ID: IOIO0400 Firmware ID: IOIO0500
[V/IOIOImpl] Querying for required interface ID
[V/IOIOImpl] Required interface ID is supported
[I/IOIOImpl] IOIO connection established

$ java -Dioio.SerialPorts=/dev/IOIO0 -jar HelloIOIOConle.jar 
[D/IOIOConnectionRegistry] Successfully added bootstrap class: ioio.lib.pc.SerialPortIOIOConnectionBootstrap
[D/SerialPortIOIOConnectionBootstrap] Adding serial port /dev/IOIO0
[D/IOIOImpl] Waiting for IOIO connection
[V/IOIOImpl] Waiting for underlying connection
[V/IOIOImpl] Waiting for handshake
[I/IncomingState] IOIO Connection established. Hardware ID: SPRK0020 Bootloader ID: IOIO0400 Firmware ID: IOIO0500
[V/IOIOImpl] Querying for required interface ID
[V/IOIOImpl] Required interface ID is supported
[I/IOIOImpl] IOIO connection established
T
Unknown input. t=toggle, n=on, f=off, q=quit.
t
q

I want to make a simple app to control PWM channels on the IOIO board, and I'm not an eclipse user, so Ytai showed me how to extract and create the appropriate .jar files.  First I unpacked the HelloIOIOSwing app:

$ mkdir unpacked
$ cd unpacked/
$ jar -xvf ../HelloIOIOSwing.jar 

Then he had me delete the ioio/examples directory and make a jar file for the IOIO framework:
$ cd ioio
$  rm -rf examples/
$ cd ..
$ jar -cvf ioio.jar ioio

ioio.jar, jna-4.0.0.jar and purejavacomm-0.0.21.jar should then suffice to let me build my own app.

I put the three jarfiles in a clean directory, then I downloaded HelloIOIOConsole.java from here:
https://github.com/ytai/ioio/tree/6189875afe0cf4b430a0a226425edc6df2e9b4f8/software/applications/pc/HelloIOIOConsole/src/ioio/examples/hello_console

and put it in a subdirectory ioio/examples/hello_console/

I compiled it like so:
$ javac -cp .:ioio.jar:purejavacomm-0.0.21.jar:jna-4.0.0.jar ioio/examples/hello_console/HelloIOIOConsole.java

And it worked!

$ java -Dioio.SerialPorts=/dev/IOIO0 -cp .:ioio.jar:purejavacomm-0.0.21.jar:jna-4.0.0.jar ioio/examples/hello_console/HelloIOIOConsole 
[D/IOIOConnectionRegistry] Successfully added bootstrap class: ioio.lib.pc.SerialPortIOIOConnectionBootstrap
[D/SerialPortIOIOConnectionBootstrap] Adding serial port /dev/IOIO0
[D/IOIOImpl] Waiting for IOIO connection
[V/IOIOImpl] Waiting for underlying connection
[V/IOIOImpl] Waiting for handshake
[I/IncomingState] IOIO Connection established. Hardware ID: SPRK0020 Bootloader ID: IOIO0400 Firmware ID: IOIO0500
[V/IOIOImpl] Querying for required interface ID
[V/IOIOImpl] Required interface ID is supported
[I/IOIOImpl] IOIO connection established
t
t
^C

Tuesday, September 30, 2014

Xadow PWM only supports 1 (or 2) pins

As far as I can tell, the only pin on the Xadow flex cable that you can do PWM with (at least using the arduino IDE) is SCL.   (And if you screw up and plug in the breakout board backward, SCL will show up on the pin labeled A5).

You can also do PWM on the green LED, but that isn't routed to the flex cable.

So that sucks, especially since Xadow is billed as having 7 PWM channels (which the underlying Atmel chip does indeed have).

Saturday, August 16, 2014

Xadow connectors aren't interchangeable

Well that wasted an embarrassing amount of time.  The xadow boards have flex cable connectors at each end so that you can daisy chain them.  I had the breakout board hooked up the wrong way, and spent several hours wondering why the A5 ADC input was showing up on the SCL pin.  Rotated it 180 degrees and now it works right.

Monday, August 11, 2014

Xadow analogRead

Updated: figured it out

I can't make sense of the pin mapping on this Xadow board to read analog values.  Note that analogRead() has funny behavior to start with.  But I looped through pins 18-29 (A0..A10 in pins_arduino.h), and the only one that came up with anything on analogRead() was 23, which seems to correspond with the pin labeled SCL on the breakout board.

I can't find anything that would explain how SCL/23/A5 relate to each other, or what other values would even be sensible to try.  There's a pin labeled A5 on the board, but pins_arduino.h #defines it as 23, and somehow that ends up on the pin labeled SCL.

At least I found one pin on which I can read the ADC.

Thursday, August 07, 2014

Seeed Xadow "couldn't find a Leonardo" / "buffered memory access not supported" error when uploading

Spent an hour or two trying to figure out why I couldn't upload sketches from arduino to my Xadow board.  Turns out the serial port wasn't selected in Tools... Serial Port (even though /dev/ttyACM0 was the only option available).  Selected that and now it works great.

Tuesday, June 10, 2014

Visible light spectrum as the sun sets

Today I played with a ColorMunki Design, using it with argyll in Linux to record the spectrum of ambient light in the sky as the sun set.

I ran "spotread -a -H -s log.txt" to record using the ambient diffuser, in high res mode (3.3nm per sample instead of 10nm per sample), and recording tab-separated values to log.txt. 

Normally spotread waits for a keypress between readings, so I hacked it up to record continuously.  It was tricky to figure out how to do that; it took me a while to chase into munki_imp.c, in munki_imp_measure, short-circuiting the loop that waits for user input:
  if (m->trig == inst_opt_trig_user_switch) { 
    m->hide_switch = 1;            /* Supress switch events */ 
#ifdef USE_THREAD 
    { 
      int currcount = m->switch_count;    /* Variable set by thread */ 
      while (currcount == m->switch_count) { 
            ev = MUNKI_USER_TRIG; 
            user_trig = 1; 
            break;            /* Trigger */
In high-res mode it reports 380nm-730nm in 3.33nm increments every 3-4 seconds.  I let it run in my shaded backyard while the sun was setting, collecting through the ColorMunki's ambient diffuser pointed upward, from 7:33pm to 8:32pm (Sunset was 8:29pm tonight).

Here's a gnuplot of the data.  The colors help see the shape of the plot but have nothing to do with wavelength.  Back to front is increasing time (you can see the sky getting darker as the plot comes toward us), and wavelength goes from red on the left to blue on the right.  So the main thing that happened during this interval is that the blues were attenuated as it got dark.




To see the spectral shift over time, regardless of overall brightness, I normalized the data so that the max intensity wavelength was 1.0 in each sample.  Here's that plot:

(I wish there was a good way to generate an interactive plot, or at least an animated gif).  

Here I've rotated the graph around, so that time increases as we go from front to back, and we have red on the right this time with blue on the left.  So with the normalization you can see that blue remains the dominant color, but as it gets later in the evening, the reds start coming up (red sunset perhaps?).  Overall the curves are pretty interesting -- the shortest blues (relatively) decrease, the greens peak in the middle, and lots of increase in the reds as the sun sets.

It decided to stop after an hour when it decided it wanted to be recalibrated, which was disappointing because it meant it didn't record past sunset.

The gnuplot command for the second plot was this.  It took me forever to find "matrix", which lets it accept a data file full of Z values (instead of rows of x,y,z), and "every", which let me decimate to a manageable number of points:

gnuplot> splot './normalized.txt' every 10:5 matrix palette with impulses