Looking at wires and ways to attach the sensors

The wires of the glove are currently pieces of ribbon cable separated from an old “IDE-cable” and connected to 0.1″-spaced crimp connectors. This works pretty well. Each sensor is connected directly to a DIY Arduino shield and is quite easily exchangeable. However, it’s a lot of wire and I’d like to find a better (looking) solution, but I’m having a hard time to come up with ideas.

The old 40-wire IDE-cable I’m using is good, because it has stranded wires unlike many of the 80-wire PATA/UDMA cables. Although smaller, the solid wires are stiffer and I’m afraid they’ll break sooner by bending them about.

There are some bendy 4-wire cables, but they all seem a bit thick. Also, a thicker cable will push harder against the sensor itself and may thus severe the connecting joint or displace the sensor.

The flat flex cables with surface mount ZIF-connectors would be nice, but they make the cables stick out of the back of the glove, as it is now. Another downside is that I can’t cut the cable to a wanted length, but instead they need to be bought individually. Although I found a nice selection on digikey, the price of almost $5 per cable makes me want to find a better alternative as I don’t want to spend $150 only for the cabling of the fingers on a pair of gloves.

The 2€ headphones I bought turned out to have very thin solid core wires. So, although very nice otherwise, I’m afraid of them eventually breaking. They are difficult to put on a connector for easy replacement of the sensor, too. I still haven’t found good connector or a source for stranded headphone wire (other than headphones).

Conductive thread is much like the headphone wire. There are at least two kinds of conductive thread: silver plated thread or stainless steel thread. The former can’t be soldered (nylon melts) and silver oxidizes over time. The latter might be an alternative, but as it is uncoated, one has to worry about shorts.

EDIT: Here is a neat idea to make flexible PCBs stretch a little: the LIMBERboard. Reminds me a lot of the Seeeduino film.

Making PCBs

There is a first time for everything and this time it’s about drawing a PCB and using a board house to manufacture it.

I drew a even smaller breakout board for the MPU-6050 with Eagle and sent the files to Seeedstudio’s “Fusion PCB service”. Now we’ll have to wait and see what comes out of it. (Btw, Seeedstudio has also a stencil service.) Eagle’s freeware version is limited to 100 x 80 mm 2-layer boards and non-profit applications. I chose Eagle over open source KiCAD, because Seeedstudio had downloadable design rules and a gerber generator that plug straight into Eagle. (One note: even though it says on the Seeedstudio site, that “the Gerber file must be RS-274x format”, the drill file generated by the gerber generator is not of that format by default. And from my very very limited experience that seems to be correct and no changes are needed.) Anyway, if these boards turn out OK, I’m likely to use this service again. It’s almost too easy and the price seems quite affordable:)

A couple of great tutorials have also helped me: Jeremy Blum‘s Eagle tutorials on youtube and, because he hasn’t made the 3rd part yet, this article from Dangerous Prototypes. Also there was some Spanish tutorial on youtube about the CAM stuff and Gerber generation, but I didn’t bookmark the link.. ah, well. Then there is SparkFun’s tutorial, which is something I definitely should have read before sending the files:)

EDIT: Sparkfun also posted this and this video recently.

EDIT #2: Ben Heck also published an Eagle tutorial. (Note: Eagle has now close ties with Farnell/Element14, but you are forced to use their services (not yet, anyway) when using Eagle.)

One of the advantages of using Eagle is the option to use nice and simple part libraries from both Adafruit and SparkFun. The latter has even a schematic and layout for the MPU-6050 breakout board linked to in the product description. They include the most common components and you won’t have to go through the whole parts jungle. If you can’t find the part you’re looking for, there’s a tutorial to create your own.

That about covers this topic for now, but as a note to self, here are some “loose ends” I’ve gathered:

Some DMP troubles – part 2

Alright, it appears that I’m NOT colliding with reading the FIFO and new data coming in, as I thought earlier. Instead, in a previous loop, the resetting of the FIFO probably snaps off the “head” of some data packet being pushed in by the DMP at the same time. Makes a lot more sense, doesn’t it?

I duplicated the original problem with an Arduino UNO using basically jrowberg’s code out of the box, but by removing the Interrupt handler and replacing it by polling the FIFO_COUNT in the main program loop. After eventually reading the 42-byte data packet from the FIFO, I reset the FIFO. By adding a delay of 30 ms or so into the main loop (beyond the update rate of 10ms), I get the “jitter” effect on the little “teapot” airplane. It’s not severe, but it is detectable and annoying.

Then, I modified the program a little: By polling in a loop and letting the FIFO_COUNT go up to 400-something before reading the FIFO data and resetting it, I can see the FIFO_COUNT increase like this:

Multiples of 42 for reference: 42, 84, 126, 168, 210, 252, 294, 336, 378, 420, 462, 504, 546

...
FIFO while waiting: 126
FIFO while waiting: 294
FIFO while waiting: 420
FIFO before reading: 546
Resetting FIFO

FIFO while waiting: 154
FIFO while waiting: 294
FIFO while waiting: 420
FIFO before reading: 546
Resetting FIFO

FIFO while waiting: 136
FIFO while waiting: 262
FIFO while waiting: 388
FIFO before reading: 514 --> Glitch: Read quaternion magn. not 1
Resetting FIFO

FIFO while waiting: 126
FIFO while waiting: 252
FIFO while waiting: 378
FIFO before reading: 504
Resetting FIFO
...

This shows that the increasing FIFO_COUNT before the glitch keeps showing an offset of 10 bytes, but I can’t trust it to always be some constant value when polling.

I don’t really have a solution for this, as I want to read 20 totally unsynchronized sensors at the same time, but at least the problem got re-defined.

Some DMP troubles

Jeff Rowberg’s DMP code uses interrupts to notify the Arduino when a new set of data – a 42-byte packet – is available in the FIFO buffer. In the Teapot example the quaternion form this packet is sent to the PC. I modified the Arduino sketch so, that it does NOT use interrupts but instead polls the FIFO_COUNT register to see if a new packet is available i.e. the count is at least 42. If this is done fast enough it seems to work.

However, when delays are added, say 30us or more, and I read the packet from the FIFO every now and then it probably collides with the DMP writing new data into the FIFO. The result is corrupt data, I think. I found that in the case when the FIFO_COUNT read just prior to reading the FIFO buffer is not a multiple of 42 (the packet size), the quaternion extracted from that packet is not a unit quaternion as it should be.

This makes it a bit hard for my parallel TWI implementation (I don’t want to call it parallel I2C because of trademarks) to read many unsynchronized MPUs without having to discard glitchy data. Here is a related forum post, but I guess it’s only visible to registered users. I’ll quote: “DMP is meant to utilize the interrupt and FIFO system so that it can be synchronized with the host processor, and store the appropriate Quaternion data in the FIFO register. You can utilize the MPU-6050 without these features in raw data mode, but it is required for DMP operation.

(On the same note, the FIFO Count Register description first claims that it contains the “sample count” and later “the number of bytes stored”. I’ll go with “bytes stored”.)

EDIT: Haven’t yet checked if the MPU would do some I2C clock stretching (and I’m ignoring that). I’ll need to check that next.

EDIT #2: Didn’t look for clock stretching. Instead, I’ve got a new theory.

Arduino DUE’s SerialUSB and Processing

The Arduino DUE can have two serial ports over USB: the programming port and the native USB port acting as a CDC device. The programming port can be used through the Serial-object and the native port through the SerialUSB-object.

The trouble was this: I wanted to use the Arduino DUE’s SerialUSB-object (native port) to transmit application data to a Processing sketch. However Processing wouldn’t read anything from the port connected to the DUE’s native port. The Arduino IDE and PuTTY were able to read the native port just fine. The difference: When conneced to the programming port, both the Arduino IDE and PuTTY reset the Arduino (via DTR-signal) and Processing didn’t. So, I gather that it must be a handshake problem of some kind. (Apparently the Java RXTX library used by Processing doesn’t give you access to the control lines?)

Dug up the method size_t Serial_::write(const uint8_t *buffer, size_t size) in the CDC.cpp (arduino-1.5.2\hardware\arduino\sam\cores\arduino\USB) and commented out the check for if (_usbLineInfo.lineState > 0).

I think that did the trick for now… Seems like the Arduino sketch hangs when a certain (buffered?) amount of data is sent until it is actually read by the Processing sketch. Don’t know if there will be other side effects.

Here’s some code to illustrate the point for those who want to try this for themselves. First for the Arduino DUE:

uint8_t counter;

void setup() {

  Serial.begin(115200);
  SerialUSB.begin(115200); // speed is irrelevant for native port
  counter = 0;
}

void loop() {

  Serial.print("Programming port. Counter is at ");
  Serial.println( counter);

  SerialUSB.print("Native port. Counter is at ");
  SerialUSB.println( counter);

  counter++;
  delay(500);
}

And here is the Processing sketch (You’ll need to edit the line portName = Serial.list()[1]; to set the port you want to open on your machine):

import java.util.Arrays;
import processing.serial.*;

String portName;
Serial serialPort;
int speed = 115200;
int bytesReceived = 0;

void setup() {
  size(640, 480);
  System.out.println("Available serial ports are: " + Arrays.toString( Serial.list())); //debug

  // Open 2nd visible serial port
  portName = Serial.list()[1];

  // Serial.list() array's indexes on my machine (this is machine specific):
  // 0 = integrated serial on motherboard
  // 1 = Arduino DUE programming port (when plugged in) - gets received by IDE, PuTTY, Processing
  // 2 = Arduino DUE native port (when plugged in also) - gets received by IDE, PuTTY, but NOT by Processing

  serialPort = new Serial(this, portName, speed);
  System.out.println( "Opened port " + portName); //debug
}

void draw() {
  background(100);
  text("Reading: " + portName, 50, 50);
  text("Received " + bytesReceived + " bytes.", 50, 80);
}

void serialEvent( Serial port) {
  while( port.available() > 0) {
    char c = (char)port.read();
    bytesReceived++;
    System.out.print( c); //debug
  }
}