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

About the jerky data transfer on the Duemilanove

When trying out serial transfer speeds a while back, I noticed the data flow on the Arduino Duemilanove to be “jerky” compared tho the Arduino Uno. This held true to other boards using the FTDI chip, too. Seems, like there is an explanation for it. I came across Jan Axelson’s book Serial Port Complete (2nd ed), where it says (on page 332) that there are two situations for slow data transfer:

The first occurs when sending only very little data as the FTDI chip likes to fill it’s buffer of 62 bytes before passing them on the USB-bus. (This USB-endpoint sends packets of 62 data and 2 status bytes.) The chip has a latency timer of 16 ms, after which it sends the data regardless of the buffer’s lower byte count. [Edit: the 64 byte packet size is for full-speed USB, but high-speed USB requires 512 byte packets. (p. 345)]

The second case probably explains my problem: When receiving data at 38.75 kbps or higher, the driver holds the data until it has received 4096 bytes (or it’s latency timer has timed out) before passing it to the application.

I assume that the Arduino UNO’s serial driver just moves smaller chunks of data at a time. (Judging by source code that is provided with the Arduino environment, the USB-serial is in UNO’s case programmed on the Atmega8U2 or Atmega16U2 using LUFA.)

The book also suggests reading this app. note. It describes a few methods to adjust some latency times and buffer sizes – in windows. It also says that modem status lines can be used to flush the (FTDI’s, I assume) buffer.