Friday, November 14, 2014

Un-bricking a Parrot Ar.Drone 2.0 with a Xadow (arduino)

The Ar.Drone 2.0 creates a wifi access point using network 192.168.1.*, which conflicted with another network I was using on my laptop.  I telnetted in and changed bin/wifi_setup.sh to use 10.0.0. instead, but somehow when I rebooted, the Ar.Drone managed to assign my laptop the illegal address 0.0.0.2, which the rest of the TCP/IP stack refused to cooperate with.

I ordered a CP2102 USB adapter which people said they'd had success using to talk to the 1.8v TTL serial port on the Ar.Drone 2.0, but didn't want to wait for it to arrive.

So instead, I found an arduino board that runs on 3.3v and supports USB serial.  Some arduino variants won't do USB serial at all (even if they can be programmed over USB), and others tie the TX/RX pins to the USB serial.  The latter would have been fine, except that those boards tend to use 5v instead of 3.3v.

The xadow main + breakout boards fit the bill.  Unfortunately, the xadow board requires some tweaks to the arduino installation, but once I had that set up, I was able to use this sketch to link up the USB and TTL serial ports:

void setup() {
  Serial.begin(115200);
  Serial1.begin(115200);
}
void loop() {
  if (Serial.available()) {
    int r = Serial.read();
    Serial1.write(r);
  }
  if (Serial1.available()) {
    int r = Serial1.read();
    Serial.write(r);
  }
}


Then I connected the grounds together (pin3 on the header on the bottom of the Ar.Drone 2.0, accessible by removing a black rectangular sticker).  Pin5 went to rx on the xadow breakout board, then I connected tx to pin6 through a 3.3k resistor to limit the current that I think ends up flowing from the 3.3v xadow board through the protection diodes in the IC in the Ar.Drone that's receiving the data and running at 1.8v.  A proper level conversion would have been better, but the Ar.Drone doesn't seem to mind.

Once I got it connected, plugging in the battery on the Ar.Drone booted it up, and I saw the startup messages in the arduino serial monitor.  I exited out of the arduino IDE, then used 'screen /dev/ttyACM0' to connect to the USB serial port in a way that supports things like colors and arrow keys.

Unfortunately, I didn't look at ifconfig before I fixed the wifi_setup.sh script and rebooted.  The script looked fine, and later I was able to change BASE_ADDRESS back to 10.0.0. and it seemed to work fine.  So the original failure is a mystery to me.

Tuesday, November 04, 2014

Polaroid Cube sucks

I tried out the new Polaroid Cube camera today, and figured I'd start with the basic outdoor selfie.  And this pretty much sums it up:

If you're going to make a camera without a display, it probably shouldn't completely blow out in afternoon fall sunlight.

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.