Error inside Serial.ports() in Processing

HI,

I keep getting this error in Processing debuggung window when trying to communicate to arduino via serial. Is it a java rxtx library error? I am using 64 bit Ubuntu 10.10 and 64 bit Arduino. Everything works fine on my other 32 bit machine:

Error inside Serial.ports()

java.lang.UnsatisfiedLinkError: /home/matjaz/Clairvision/Project_Signal/Processing/Processing_software/processing-1.2.1/libraries/serial/library/librxtxSerial.so: /home/matjaz/Clairvision/Project_Signal/Processing/Processing_software/processing-1.2.1/libraries/serial/library/librxtxSerial.so: wrong ELF class: ELFCLASS32 (Possible cause: architecture word width mismatch) thrown while loading gnu.io.RXTXCommDriver
java.lang.UnsatisfiedLinkError: /home/matjaz/Clairvision/Project_Signal/Processing/Processing_software/processing-1.2.1/libraries/serial/library/librxtxSerial.so: /home/matjaz/Clairvision/Project_Signal/Processing/Processing_software/processing-1.2.1/libraries/serial/library/librxtxSerial.so: wrong ELF class: ELFCLASS32 (Possible cause: architecture word width mismatch)
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1803)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1728)
at java.lang.Runtime.loadLibrary0(Runtime.java:823)
at java.lang.System.loadLibrary(System.java:1028)
at gnu.io.CommPortIdentifier.(CommPortIdentifier.java:83)
at processing.serial.Serial.list(Unknown Source)
at fish_matjaz_minimtest.setup(fish_matjaz_minimtest.java:82)
at processing.core.PApplet.handleDraw(Unknown Source)
at processing.core.PApplet.run(Unknown Source)
at java.lang.Thread.run(Thread.java:662)
processing.app.debug.RunnerException: RuntimeException: Error inside Serial.ports()
at processing.app.Sketch.placeException(Sketch.java:1543)
at processing.app.debug.Runner.findException(Runner.java:582)
at processing.app.debug.Runner.reportException(Runner.java:558)
at processing.app.debug.Runner.exception(Runner.java:498)
at processing.app.debug.EventThread.exceptionEvent(EventThread.java:367)
at processing.app.debug.EventThread.handleEvent(EventThread.java:255)
at processing.app.debug.EventThread.run(EventThread.java:89)
Exception in thread "Animation Thread" java.lang.RuntimeException: Error inside Serial.ports()
at processing.serial.Serial.errorMessage(Unknown Source)
at processing.serial.Serial.list(Unknown Source)
at fish_matjaz_minimtest.setup(fish_matjaz_minimtest.java:82)
at processing.core.PApplet.handleDraw(Unknown Source)
at processing.core.PApplet.run(Unknown Source)
at java.lang.Thread.run(Thread.java:662)

Confiuration::
Ubuntu 10.10., 64 bit
Sun java 6
64 bit arduino 0021, regular 32bit Processing 1.2.1 (no 64 available)

Other threads indicate problem in arduino's java rxtx libraries. I have replaced them but still keep getting this error.
Used this links:
http://chemicaloliver.net/arduino/fixing-arduino-on-ubuntu-9-10-karmic-x64/
http://myy.haaga-helia.fi/~karte/arduino_editor_on_64_bit_ubuntu_gutsy.html

Any clues? I'm in a need to make it work...

Thanks.

M

What Processing sketch are you running? What Arduino do you have? I don't think Processing plays well with the Uno.

I'm using Duemilanove.

Error is generated with any Processing sketch that involves Serial function in a code, in my case:
println(Serial.list());
myPort=new Serial(this, Serial.list()[0],9600);

The whole code:

import ddf.minim.*;
import ddf.minim.signals.*;

Minim minim;
AudioOutput out;
SineWave sine;

// 1. Use the right port (replace 12000). modify pd sketch to receive the osc signal

//Camera capture of the fish in aquarium. Arduino dimms LED according to the fish position (X axis).

import codeanticode.gsvideo.*;     // library to work around QuickTime (which doesn't work with Linux)
import processing.serial.*;
//import oscP5.*;
//import netP5.*;

Serial myPort;

boolean new_video_image=false;
boolean fish;
int fast_parse=1;
int threshold_fish_detection=1500/fast_parse;
int average_column_difference;
int num_pixels;
int[] bgnd_lum;
int[] diff_lum;
int[] column_difference;
int[] ringbuffer_position;
float[] ringbuffer_target_position;
int left_cut;
int right_cut;
int middle;
int diff_sum;
int video_x=320;
int video_y=240;
int image_x=320;
int image_y=270;
int video_fps;
int draw_fps;
int video_fps_old;
int draw_fps_old;
int send_fish;

//OscP5 oscP5;
//NetAddress myRemoteLocation;

String index_number[]=new String[1];

GSCapture video;          //

PFont font;

void setup() {
  background(0);
  size(image_x, image_y); 
  background(0);

   println(Serial.list());
   myPort=new Serial(this, Serial.list()[0],9600);
  //oscP5 = new OscP5(this,12000);
  //myRemoteLocation = new NetAddress("127.0.0.1",12000); // need to define the port (change 12000)

  video = new GSCapture(this, video_x,video_y);
  num_pixels = video_x*video_y;

  bgnd_lum = new int[num_pixels];
  diff_lum = new int[num_pixels];
  column_difference = new int[video_x];
  ringbuffer_position=new int [100];
  ringbuffer_target_position=new float [100];
  loadPixels();

  minim = new Minim(this);
  // get a line out from Minim, default bufferSize is 1024, default sample rate is 44100, bit depth is 16
  out = minim.getLineOut(Minim.STEREO);
  // create a sine wave Oscillator, set to 440 Hz, at 0.5 amplitude, sample rate from line out
  sine = new SineWave(440, 0.5, out.sampleRate());
  // set the portamento speed on the oscillator to 200 milliseconds
  sine.portamento(200);
  // add the oscillator to the line out
  out.addSignal(sine);
}

void draw() {                                                // LOOP BEGINS HERE

  new_video_image=false;                       
  draw_fps_old=draw_fps;                                    // draw refresh speed
  draw_fps=millis();                                        // """"""""""""""""""

  if (video.available()) {                                 

    video.read();                                           // load new video image ...
    video.loadPixels();                                     // ... in pixel array

    //-------------------------------------------------------- parse video image for differences to previous image
    for (int i=0;i<video_x;i++) {  
      column_difference[i]=0;
    }

    diff_sum=0;                                               // reset difference of all video pixels
    for (int x=0;x<video_x;x++) {                             // draw video image & difference image 
      for (int y=0;y<video_y;y+=fast_parse) {
        int i=(y*video_x)+x;                          // parse all video pixels for difference to previous video image
        int   curr_lum = ((video.pixels[i] >> 16) & 0xFF) + ((video.pixels[i] >> 8) & 0xFF) + (video.pixels[i] & 0xFF); // calculate luminance of pixel
        diff_lum[i] = abs(curr_lum - bgnd_lum[i]);            // calculate luminance difference to previous video pixel
        diff_sum+=diff_lum[i];                                // sum up difference of all video pixels
        column_difference[i%video_x]+= diff_lum[i];           // sum up difference for every column                                                           
        bgnd_lum[i]=curr_lum;                                 // store new background reference
      }
    }

    if (diff_sum>0) {                                        // if new video image is different from previous video image
      new_video_image=true;                                 // => new video image detected 
      video_fps_old=video_fps;                              // video refresh speed
      video_fps=millis();                                   // """""""""""""""""""
    }                  

    if (new_video_image) {                                  // if there's a new video image [with, really, different content than the previous videoimage]
      for (int x=0;x<video_x;x++) {                         // draw video image & difference image 
        for (int y=0;y<video_y;y+=fast_parse) {
          int image_pos=(y*image_x)+x;
          int video_pos=(y*video_x)+x;
          pixels[image_pos] = video.pixels[video_pos];      // draw video [left side]
          // pixels[image_pos+319] = 0xff000000 | (diff_lum[video_pos]<<8);// draw difference [right side; green]
        }
      }
      updatePixels();                                       // refresh pixel array
      for(int i = 2; i < video_x-2; i++) {                  // smooth all column differences (mix with neighbours)
        column_difference[i]=(column_difference[i-1]+column_difference[i-2]+column_difference[i]+column_difference[i+1]+column_difference[i+2])/5;
      }

      average_column_difference=diff_sum/video_x;           // calculate average column difference as reference


      //-------------------------------------------------------- calculate position of the fish

      fish=false;                                         // reset fish detection
      right_cut=0;            
      for(int i = 0; i < video_x; i++) {                    // parse [from left to right] for position, where difference exceeds threshold 
        if (column_difference[i]-threshold_fish_detection>average_column_difference) {
          right_cut=i;
          fish=true;
        }
      }

      left_cut=320;        
      for(int i = video_x-1; i >= 0; i--) {                 // parse [from right to left] for position, where difference exceeds threshold
        if (column_difference[i]-threshold_fish_detection>diff_sum/video_x) {
          left_cut=i;
          fish=true;
        }
      }

      if (fish && right_cut-left_cut>15) {                // if difference in the picture is wider than 15 columns: 
        middle=(left_cut+right_cut)/2;                      // => calculate middle
      }
      else {                                                // if difference is less ...
        fish=false;                                       // => fish is not accepted
      } 

      stroke(0,255,0);
      line(middle,0,middle,240);                            // draw middle of the fish [green]
      strokeWeight(1);
      fill(0,255,0,230);
      text("FISH POSITION",2,255);              // """""""""""""""""""""""""""" [text]

      //-------------------------------------------------------- serial communication


      //  myPort.clear();                                         
      send_fish=int(map(middle, 10, 310, 0, 222));
      send_fish=constrain(send_fish,0,222); 
      myPort.write(send_fish);
       //if(myPort.available()>0) {
       //char inByte = myPort.readChar();
       //real_position=int(inByte);
       
    }
  }

  // with portamento on the frequency will change smoothly
  float freq = map(send_fish, 0, 222, 1200, 40);
  sine.setFreq(freq);

 // OscMessage send_fish = new OscMessage("/test");
 // send_fish.add(123); /* add an int to the osc message */
 // oscP5.send(send_fish, myRemoteLocation);
}


/* incoming osc message are forwarded to the oscEvent method. */
//void oscEvent(OscMessage theOscMessage) {
  /* print the address pattern and the typetag of the received OscMessage 
  print("### received an osc message.");
  print(" addrpattern: "+theOscMessage.addrPattern());
  println(" typetag: "+theOscMessage.typetag());
}
*/
void stop()
{
  out.close();
  minim.stop();

  super.stop();
}

Ha! Interesting...

The above example I posted works in a direction from Processing to Arduino.

Now I have just tried uploading a different sketch on Arduino and plugged in the ultrasonic sensor. Serial monitor showed correct distance measurements dependent on my hand movement towards the sensor and back. SO Arduino works!!
Then I ran related Processing sketch that should turn the distance signal into graphics and there was the error. Processing couldn't read serial.

The problem is therefore with Processing...Hmm

Now what...?

Well, I had trouble finding all the libraries to make that previous sketch even compile. Once I did, it threw an exception when I tried to run it on windows.

So, post the (simpler) Processing app that gets sensor data from the Arduino.

I'm pretty sure that the problem is not Processing per se, but some issue with your operating system, since I spent a bunch of time yesterday getting a Processing application to control a servo attached to the Arduino, via the serial port, on Windows (7, 64 bit) with no problems (on the Processing end).

OK, cool.
You probably had problems with the libraries because GSCapture is a linux version of Video Capture - which is for Win and Mac (works only with QuickTime player)

Here is the arduino code for the ultrasonic sensor:

 /* Ultrasonic Sensor
 *
 * Reads values (00014-01199) from an ultrasound sensor (3m sensor)
 * and writes the values to the serialport.
 */
 

int ultraSoundSignal = 7; // Ultrasound signal pin
int val = 0;
int ultrasoundValue = 0;
int timecount = 0; // Echo counter
int ledPin = 13; // LED connected to digital pin 13

void setup() {
  Serial.begin(9600);            // Sets the baud rate to 9600
  pinMode(ledPin, OUTPUT);       // Sets the digital pin as output
}

void loop() {
 timecount = 0;
 val = 0;
 pinMode(ultraSoundSignal, OUTPUT); // Switch signalpin to output

// Send low-high-low pulse to activate the trigger pulse of the sensor

digitalWrite(ultraSoundSignal, LOW); // Send low pulse
delayMicroseconds(2); // Wait for 2 microseconds
digitalWrite(ultraSoundSignal, HIGH); // Send high pulse
delayMicroseconds(5); // Wait for 5 microseconds
digitalWrite(ultraSoundSignal, LOW); // Holdoff

// Listening for echo pulse
 
pinMode(ultraSoundSignal, INPUT); // Switch signalpin to input
val = digitalRead(ultraSoundSignal); // Append signal value to val
while(val == LOW) { // Loop until pin reads a high value
  val = digitalRead(ultraSoundSignal);
}

while(val == HIGH) { // Loop until pin reads a high value
  val = digitalRead(ultraSoundSignal);
  timecount = timecount +1;            // Count echo pulse time
}

//Writing out values to the serial port

ultrasoundValue = timecount; // Append echo pulse time to ultrasoundValue

Serial.write('A'); // Example identifier for the sensor
Serial.print(ultrasoundValue);
Serial.write(10);
//serialWrite(13);

// Light up LED if any value is passed by the echo pulse

if(timecount > 0){
  digitalWrite(ledPin, HIGH);
}

// Delay of the program

delay(100);
}

Here is the Processing sketch for the ultrasonic sensor graphics:

import processing.serial.*;

  float x1,y1,x2,y2,a,ai,b,bi,theta;  // cord parameters
  float H,S,B,Hi,Si,Bi;  // color parameters
  int fr;
  
   
  // variables for the serial port connection object
  Serial port;
  String portname = "/dev/ttyUSB0";  // find the name of your serial port in your system setup!
  int baudrate = 9600;  //  set baudrate
  int value;  // variables used to store value from serial port
  String buf=""; // String buffer to store serial values
  int value1;  // value1 is the read value
  int speedrate=100;
  float range=2.7;  //works well between 2.5 and 3.5
  int t=2;  //scales up the circle range


// the serial event function takes the value of the event and store it in the corresponding variable
void serialEvent(int serial)

{
    if(serial!=10) {        
          buf += char(serial);          
          } else {
          buf = buf.substring(1,buf.length());   //extract the value from the string 'buf'
          value1 = int(buf);    //cast the value to an integer
          buf="";
      }
     }
// initialize display and serial port objects
void setup(){
  
  size(500,500,P2D);
  fr=80;
  frameRate(fr);
  smooth();
  a=b=0.0;
  ai=bi=0.01;
  H=0; S=100; B=100; Hi=1; Si=0; Bi=0;

      port = new Serial(this, portname, baudrate);
      println(port);
     }

// draw listens to serial port, draw 
void draw(){
  
  while(port.available() > 0){
        value = port.read();
        serialEvent(value);
    }
if(value1/t > width){
       value1 = width*2;  // range is set to 1200 mm (equivalent to 1200 pixels). Higher causes flickering
   }
     
  // center and scale
  translate(width/2,height/2);
  scale(width/2);
   
  // initialize color
  colorMode(RGB);
  background(0);
  colorMode(HSB,360,100,100);
   
  // draw 360 cords around a circle
    for(float i=value1/range;i<360;i++){
    theta=(float)i*PI/180;
    x1=sin(theta);
    y1=cos(theta);
    x2=sin(b*theta); 
    y2=cos(a*theta);
    
     
    // each cord gets color in wheel
    H=i;
    stroke(H,S,B);
    line(x1,y1,x2,y2);
    
  }
    a+=ai*(value1/speedrate);  //uncommenting these two lines makes a nice radar screen graphics :)
    b+=bi*(value1/speedrate); 
  }

Any luck PaulS?

I'm still researching...

Well, I don't have an ultrasonic sensor, either. So I modified your Arduino sketch to send the time, instead.

Useless for what Processing is actually doing, but communications don't depend on Processing doing anything useful with the data - only that it gets the data.

Which, using Windows, it did just fine.