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
  }
}

Serial speeds on the Arduino

In the case of having to send lots of data back to a PC, I tested an Arduino UNO (rev 1) for different serial speed setups. I used this simple program on the Arduino to send running counter values and a Processing sketch to read the values and report an error it would receive a value that was out of order. After reading a forum post, I was actually a bit amazed how fast the thing could go using the Atmega8U2 as the USB-serial port. So, I also did the same measurement for an older Arduino Duemilanove which uses the FTDI-chip as the USB-serial port. This was a like the previously mentioned forum post predicted as 230400 was the maximum speed. Also, the Duemilanove’s data rate seemed “jerky” at lower speeds (although the data on the 328’s TX pin seemed to flow evenly).

Arduino Duemilanove

  • 115200 OK
  • 230400 OK
  • 250000 Failed
  • 500000 Errors
  • 1000000 Errors

Arduino UNO (rev 1)

  • 115200 OK
  • 230400 OK
  • 250000 Failed
  • 500000 OK
  • 1000000 OK

It would be interesting to know what limits the Duemilanove’s performance. Wheter it’s in the software or the FTDI interface? The FTDI-chip itself should be capable of even faster speeds than 1Mbit/sec. Go figure.

Distance measurement

Fixed the Processing sketch that attempts to measure distances based on acceleration. (It was off by a factor of 10. Guess who didn’t convert from g to m/s^2.) Anyhow, instead of compensating for tilting in code, I built a rail:

sled_1

Of course, this doesn’t mean I might not have to take the orientation into account at some point. Still, with the rail I can roughly measure the moved distance as the change in acceleration happens almost exclusively on the x axis.

sled_2

Drifting is quite bad, though. I’ve got a good 15cm of travel on the rail and measuring movement that’s done right after the measurement starts (within a couple of seconds) seems accurate within +/- 1 cm. But when measuring a completely stationary sensor over a time of 30 seconds, the measurement may have wandered off even beyond 40cm. Currently, I’m fresh out of ideas on how to counter this.

I figured that building a data glove that can track the hands position in 3D space may be quite difficult measuring the accelration of the glove alone. Because the MPU-6050 is able to produce orientation data (as a quaternion), one could of course track the hands position from the shoulder on onward. The shoulder would be a “fixed point” with a ball joint. Having sensors on the upper and fore arm measuring the direction where the arm is pointing to (and knowing one’s arm’s length), one could calculate the location of the hand in relation to the shoulder. It’s not ideal for motion capturing either since the shoulder is capeable of subtle movements, but I think it might be the way to go.

MPU-6050 /w DMP accelerometer demo

After connecting the MPU-6050 again to an Arduino, initializing the DMP and realizing that the accelrometer data is in *signed* 16-bit integers, I’ve got the following:

  • Looks like the default setup is for the 4 g range. That’s very nice.
  • The x- and y-axis are fairly precise, but in my case, the z-axis shows slightly less than 0.9 g, when it should be 1.0 g. I wonder if it varies from chip to chip..

I converted the previous demo for the analog accelerometer for the MPU-6050. You can download the thing here. (There are 2 Processing sketches: one showing the 16-bit measurements and one showing those measurements converted to g forces.)

Also: I wrote a Processing sketch that tries to measure a traveled distance based on the accelerometer. It just uses the s = 0.5 a * t^2 + v*t formula. Currently the results are way off. But this is partly, because rotation isn’t taken into account. Tilting the sensor one way causes it to “accelerate” into two directions (because I compare the acceleration to a pre-measured offset). So, there is plenty room for improvement. I uploaded it here. (Use the same sketch for Arduino as in the aforementioned “mpuAccelerometerDemo”.)

About Jeff Rowberg’s I2C lib for the MPU-6050

Jeff Rowberg has written an excellent library for the MPU-6050. It encapsulates the basic functions and hides all the I2C traffic management. You can download the code directly from github. You’ll need the I2Cdev files and the MPU6050 stuff. Copy the files to Arduino’s workspace’s “libraries” directory (for example “My Documents\Arduino\libraries\“) under directories I2Cdev and MPU6050. If the “libraries” directory doesn’t exist, you need to create it.

Basically there are two ways to use the MPU-6050 with this library: 1) Include the “MPU6050.h” header for all the basic functionality that is also documented by the official Register map or 2) instead include the “MPU6050_6Axis_MotionApps20.h” header to gain access to the reverse engineered DMP (Digital Motion Processor) functionality.

The library’s code is documented in a way from which you can generate a nice HTML documentation using Doxygen. It looks a lot like JavaDoc. (The Doxygen installer puts the Doxygen user’s guide in HTML-format into program’s folder. For example in my case the folder “file:///C:/Program%20Files/doxygen/html/doxygen_usage.html“) In short: To create documentation from the code you’ll need to type two commands from the command line:  “doxygen -g configFile” and “doxygen configFile” (replace configFile by name of choice).

That, or you might just look at the readily available MPU-6050.h documentation online.

I think the best (and only) way to explore the DMP-functionality is to examine the Teapot demo. Just upload the example code to an Arduino. When connecting the MPU-6050 to an Arduino, remember also to connect the interrupt signal (INT pin on the MPU-6050 to Arduino Diecimila or UNO’s digital pin 2) as the MPU-6050 with DMP is set up to fire interrupts whenever it has data ready.

To visualize the Teapot on the PC, you’ll need to have Processing installed and copy an additional toxiclibs library into Processing’s workspace’s libraries folder (much like you had to add the MPU’s libaries to the Arduino IDE’s libraries folder). If the folder “Processing\libraries” doesn’t exist, you’ll have to create it. Then save the Teapot demo “MPUTeapot.pde” under “Processing\MPUTeapot” (or the Processing IDE will later ask you to move the file to this directory).

I made a few changes to the MPUTeapot demo as it – in my opinion – didn’t properly catch the data packages sent by the Arduino..

InvenSense also has an official Teapot demo. I tried to run it, but it seems I’m missing a winusb.dll and didn’t really bother to investigate further. It should work though – I’ve seen it on youtube 🙂

Analog accelerometer demo

Made a small Arduino and Processing sketch to display data from an older analog 3-axis accelerometer: the MMA7260Q by Freescale (a spin off company from Motorola). You can download the code here. I tried to keep it as simple as possible.

I’ve wired the accelerometer up to handle 4g, which seems alright for faster hand gestures too. It can be maxed out by very quick hand movement and slapping, though.