Cannot setup USB Serial in Android mode

edited March 2014 in Android Mode

Hello everyone,

I am trying to rewrite an functional processing code in Java mode into Android application that will read and process analog inputs from Arduino ADK via USB.

Problem is probably in serial communication. So i downloaded Android serial library created by dbaba and changed Serial.list() to Serial.list(this) as advised. https://github.com/inventit/processing-android-serial/

When i run the project my tablet blinks and then i get en error message " 'app_name' stoped working" on the screen.

Could anyone help me to get this code running in Android? Any help/direction is greatly appreciated.

Processing error:

FATAL EXCEPTION: Animation Thread
java.lang.IllegalStateException: Cannot setup USB Serial.
    at com.yourinventit.processing.android.serial.UsbSerialCommunicator.doStart(UsbSerialCommunicator.java:108)
    at com.yourinventit.processing.android.serial.AbstractAndroidSerialCommunicator.start(AbstractAndroidSerialCommunicator.java:333)
    at com.yourinventit.processing.android.serial.AbstractAndroidSerialCommunicator.start(AbstractAndroidSerialCommunicator.java:308)
    at com.yourinventit.processing.android.serial.AbstractAndroidSerialCommunicator.start(AbstractAndroidSerialCommunicator.java:297)
    at com.yourinventit.processing.android.serial.Serial.<init>(Serial.java:51)
    at com.yourinventit.processing.android.serial.Serial.list(Serial.java:263)
    at processing.test.oscope_processing.oscope_processing.setup(oscope_processing.java:102)
    at processing.core.PApplet.handleDraw(Unknown Source)
    at processing.core.PGraphicsAndroid2D.requestDraw(Unknown Source)
    at processing.core.PApplet.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:856)

Application code:

// * ------------------ HOT KEYS ------------------
final char T_UP       = 'w'; // Translate waveform up
final char T_DOWN     = 's'; //                    down
final char T_LEFT     = 'a'; //                    left
final char T_RIGHT    = 'd'; //                    right
final char Z_IN       = 'c'; // Horizontal zoom in
final char Z_OUT      = 'z'; //                 out
final char S_IN       = 'e'; // Vertical scale in
final char S_OUT      = 'q'; //                out
final char MGL_UP     = 'r'; // Minor grid lines increase
final char MGL_DOWN   = 'f'; //                  decrease
final char TOG_PAUSE  = 'p'; // Toggle pause (unpause resets waveform)
final char RESET_AXIS = ' '; // Reset axis settings
final char MEAS_TIME  = 'x'; // Adds and/or highlights vertical bars (time measurement)
final char BAR_LEFT   = ','; // Move highlighted vertical bar left (can also mouse click)
final char BAR_RIGHT  = '.'; //                               right
// * ----------------------------------------------

// * --------------- STARTING STATE ---------------
float zoom    = 1.0;
float scale   = 0.5;
int centerV   = 0;
int centerH   = 0;
int gridLines = 0;
int com_port  = 0;   // Index number in Serial.list
// * ----------------------------------------------

// Global vars
import com.yourinventit.processing.android.serial.*;
Serial port;                    // Create object from Serial class
int val;                        // Data received from the serial port
long valTime;                   // Time data was received
int[] values;
long[] times;
float voltage;
float measTime = 0;
int   timeMode = 0;
int[] timeBars = {
  0, 0
};
PFont f;
boolean pause;

// Setup
void setup() {
 // size(1280, 480);
  port = new Serial(this, Serial.list(this)[com_port], 9600);    // Com port specified here
  values = new int[width];
  times = new long[width];
  timeBars[0] = width/3;
  timeBars[1] = 2*width/3;
  pause = false;
  smooth();
  f = createFont("Arial", 16, true);
}

// Read value from serial stream
int getValue() {
  int value = -1;
  while (port.available () >= 3) {
    if (port.read() == 0xff) {
      value = (port.read() << 8) | (port.read());
    }
  }
  return value;
}

// Get a y-value for the datapoint, varies based on axis settings
int getY(int val) {
  return (int)(height/2 -(val-512+centerV)*scale / 1023.0f * (height - 1));
}

// Push the values in the data array
void pushValue(int value) {
  for (int i=0; i<width-1; i++)
    values[i] = values[i+1];
  values[width-1] = value;
}

// Push the timestamps in the time array
void pushTime(long time) {
  for (int i=0; i<width-1; i++)
    times[i] = times[i+1];
  times[width-1] = time;
}

// Draw waveform
void drawLines() {
  int x0 = 0, x1 = 0, y0 = 0, y1 = 0;
  stroke(255, 255, 0);
  for (int i=0; i<width; i++) {
    x1 = round(width - ((width-i) * zoom) + centerH);
    y1 = getY(values[i]);
    if (i > 1)
      line(x0, y0, x1, y1);
    x0 = x1;
    y0 = y1;
  }
}

// Draw gridlines (bounds, minor)
void drawGrid() {
  // Get scaled values for bounds
  int pFive = getY(1023);
  int zero  = getY(0);

  // Draw voltage bounds
  stroke(255, 0, 0);
  line(0, pFive-1, width, pFive-1);
  line(0, zero+1, width, zero+1);

  // Add voltage bound text
  textFont(f, 10);
  fill(255, 0, 0);
  text("+5V", 5, pFive+12);
  text(" 0V", 5, zero-4);

  // Draw minor grid lines
  int gridVal = 0;
  stroke(75, 75, 75);
  for (int i = 0; i < gridLines; i++) {
    gridVal = getY(round((i+1.0)*(1023.0 / (gridLines+1.0))));
    line(0, gridVal, width, gridVal);
  }

  // Add minor grid line text
  if (gridLines > 0) {
    textFont(f, 16);
    fill(204, 102, 0);
    float scaleVal = truncate(5.0f / (gridLines+1), 3);
    text("Grid: " + scaleVal + "V", 1170, height-12);
  }

  // Print difference between vertical 'time' bars
  if (timeMode > 0) {
    textFont(f, 16);
    fill(204, 102, 0);

    int idx0 = round(width + (timeBars[0] - width - centerH)/zoom);
    int idx1 = round(width + (timeBars[1] - width - centerH)/zoom);

    // Ensure time bars are over a recorded portion of the waveform
    if (idx1 < 0 || idx0 < 0 || idx1 > (width-1) || idx0 > (width-1) || times[idx1] == 0 || times[idx0] == 0)
      text("Time: N/A", 30, height-12);
    else {
      float timeDiff = truncate((times[idx1] - times[idx0])/2000000.0, 2);
      text("Time: " + timeDiff + "ms", 30, height-12);
    }
  }
}

// Draw vertical 'time bars' (seperate from above for better layering)
void drawVertLines() {
  stroke(75, 75, 75);
  if (timeMode == 1) {
    line(timeBars[1], 0, timeBars[1], height);
    stroke(100, 100, 255);
    line(timeBars[0], 0, timeBars[0], height);
  }
  else if (timeMode == 2) {
    line(timeBars[0], 0, timeBars[0], height);
    stroke(100, 255, 100);
    line(timeBars[1], 0, timeBars[1], height);
  }
}

// Truncate a floating point number
float truncate(float x, int digits) {
  float temp = pow(10.0, digits);
  return round( x * temp ) / temp;
}

// When a key is pressed down or held...
void keyPressed() {
  switch (key) {
  case T_UP: 
    centerV += 10/scale; 
    break;                     // Move waveform up
  case T_DOWN: 
    centerV -= 10/scale; 
    break;                   // Move waveform down
  case T_RIGHT: 
    centerH += 10/scale; 
    break;                  // Move waveform right
  case T_LEFT: 
    centerH -= 10/scale; 
    break;                   // Move waveform left
  case MGL_UP:                                               // Increase minor grid lines
    if (gridLines < 49)
      gridLines += 1;
    break;
  case MGL_DOWN:                                             // Decrease minor grid lines
    if (gridLines > 0)
      gridLines -= 1;
    break;
  case BAR_LEFT:                                             // Move the time bar left (also mouse click)
    if (timeMode == 1 && timeBars[0] > 0)
      timeBars[0] -= 1;
    else if (timeMode == 2 && timeBars[1] > 0)
      timeBars[1] -= 1; 
    break;
  case BAR_RIGHT:                                            // Move the time bar right (also mouse click)
    if (timeMode == 1 && timeBars[0] < width-1)
      timeBars[0] += 1;
    else if (timeMode == 2 && timeBars[1] < width-1)
      timeBars[1] += 1; 
    break;
  }
}

// When a key is released...
void keyReleased() {
  println(key+": "+(int)key);
  switch (key) {
  case Z_IN:                                                 // Zoom horizontal
    zoom *= 2.0f;
    if ( (int) (width / zoom) <= 1 )
      zoom /= 2.0f;
    break;
  case Z_OUT:                                                // Zoom horizontal
    zoom /= 2.0f;
    if (zoom < 1.0f)
      zoom *= 2.0f;
    break;
  case S_IN: 
    scale*=2; 
    break;                                // Scale vertical
  case S_OUT: 
    scale /= 2; 
    break;                             // Scale vertical
  case RESET_AXIS:                                           // Reset all scaling
    centerV = 0; 
    centerH = 0;
    scale = 0.5; 
    zoom  = 1; 
    gridLines = 0;
    break;
  case MEAS_TIME: 
    timeMode = (timeMode + 1) % 3; 
    break;      // Change the vertical bars (off, left bar, right bar)
  case TOG_PAUSE:                                            // Toggle waveform pausing
    if (pause) {
      centerH = 0;
      for (int i=0; i<width; i++) {
        values[i] = 0;                                       // Clear data on resume
        times[i] = 0;
      }
    }
    pause = !pause;
  }
}

// Use mouse clicks to quickly move vertical bars (if highlighted)
void mousePressed() {
  if (timeMode == 1)
    timeBars[0] = mouseX;
  else if (timeMode == 2)
    timeBars[1] = mouseX;
}

// Primary drawing function
void draw()
{
  background(0);
  drawGrid();
  // Get current voltage, time of reading
  val = getValue();
  valTime = System.nanoTime();

  // If not paused
  if (!pause && val != -1) {
    // Push value/time onto array
    pushValue(val);
    pushTime(valTime);

    // Print current voltage reading
    textFont(f, 16);
    fill(204, 102, 0);
    voltage = truncate(5.0*val / 1023, 1);
    text("Voltage: " + voltage + "V", 1170, 30);
  }
  drawLines();
  drawVertLines();
}

Answers

  • From the source code, it appears that this error is thrown when the library is unable to find a USB serial driver. Your device may not have support for USB serial...

  • Hi calsign, thank you for your answer. I am using Lenovo IdeaTab A1000. I installed drivers and other application that i have tried run fine in android mode.

Sign In or Register to comment.