Serial Processing


#1

Hi Team,

I am trying to read the data from the Serial port that is sent by the micro-pulser attached to the USART pin on the PC com port.
The sequence of data to be received is based on the command sent to the micro pulser.
I can see that data on the oscilloscope that is transmitted and received.
The problem is that the data received on the RX pin i.e. using the function port.read() gives different behaviours.

  1. If I place breakpoint and then proceed with copying the data obtained in the port.buffer into an array of 1024 bytes I get below error.
    java.lang.ArrayIndexOutOfBoundsException: 1024
    at uPulserTester.draw(uPulserTester.java:292)
    at processing.core.PApplet.handleDraw(PApplet.java:2429)
    at processing.awt.PSurfaceAWT$12.callDraw(PSurfaceAWT.java:1557)
    at processing.core.PSurfaceNone$AnimationThread.run(PSurfaceNone.java:313)

2)If I place the breakpoint after the loop where the data is copied into the array of 1024 bytes, no values are copied into this buffer even though the bytes were copied that were received from pulser Tx.

3)Now if I place the break point and then single step through the code where it copies the value of the port.buffer[] into the array of 1024 bytes, i can see the value getting copied but the data type changes from int to unsigned int value meaning whatever is captured in int type that number is getting converted into un signed int.

void draw() // this runs at refresh rate, this is an autonomous operation...runs to completion before any other callbacks execute
{ 
  values =  new int[1024];

  if (iPause == 0) 
  {
    background(0);


    background(0);
  fill(75, 75, 75);
  rect(0, 0, 50, iVectorWindowY);
  rect(974, 0, 50, iVectorWindowY);
  fill(255, 255, 255);
  triangle(10, 10, 20, 0, 20, 20);
  triangle(1004, 0, 1014, 10, 1004, 20);
  textFont(f);
  fill(255); 
  
text("EcoInsight Pulser Test rev:"+rev, iControlX+10, iControlY);

textAlign(RIGHT);
  text("Gain", c4, iControlY+100);
  text("Zoom", c4, iControlY+130);
  text("Average", c4, iControlY+160);
  text("Thresold", c4, iControlY+190);
textAlign(LEFT);

    
    stroke(204, 102, 0); // draw orange horizontal line
    line(0, ((255-iThreshold)*iVectorWindowY/256), 1023, ((255-iThreshold)*iVectorWindowY/256));


println("here");
          
        
          if(connected){
          port.write(0x02);  // <STX>

          port.write(0x00);  // send command to start probe sample

          delay(10);
           if(port.available () > 0){
            println("STX: "+port.read()); // get LSB #bytes
            port.read();    // get <STX> from probe
          }
           if(port.available () > 0){
            println("LSB: "+port.read()); // get LSB #bytes
            port.read();
          }
           if(port.available () > 0){
            println("MSB: "+port.read());  // get MSB #bytes7
            port.read();
          }

          // ********* get vector from probe ************
          int x_val = 0;
          {
            while (port.available () > 0){
              values[x_val++]= (port.read());  // read 1024 bytes
//              println(port.read());
//              sample_file.println(values[x]);
//              sample_file.println(port.read());
            }
          } // get vector for loop
    
          while (port.available () < 1){
            port.read();  // get <EOT> from Probe
          }
 stroke(255);

        for (int x=0; x<1023; x++)
          {
            x1 = x;
            x2 = x+1;
            y1 = (255-values[x1])*iVectorWindowY/256; // scale the values
            y2 = (255-values[x2])*iVectorWindowY/256;
            line(x1, y1, x2, y2);
            println(x1+","+y1+","+x2+","+y2);
          } // draw vector for loop
           //******** Threshold Logic ***********
           //Compare each point in the vector to a threshold
           //When the compare triggers display the time of the Echo
    
          for (int x=0; x<1024; x++) 
          {
    
            if (iThreshold >= values[x])
            {
              println("Bittime in seconds:"+Bittime()+" Time:"+ (x*(Bittime())+(iRGD*Bittime()))*1000000);
              //sample_file.println("Bittime in seconds:"+Bittime()+" Time:"+ (x*(Bittime())+(iRGD*Bittime()))*1000000);

        
              strikeRefl = (x*(Bittime())+(iRGD*Bittime()))*1000000;
              if (strikeRefl < 90){
                text("Reflector Peak "+((x*(Bittime())+(iRGD*Bittime()))*1000000)+" us", iControlX+300, iControlY);
                println ("Strike Reflector = "+strikeRefl);
                //sample_file.println ("Strike Reflector = "+strikeRefl);

                fVelocity = (reflDist*2)/strikeRefl;
                println ("fVelocity) = "+fVelocity);
                //sample_file.println ("fVelocity) = "+fVelocity);

                text("In Situ Velocity: " +fVelocity +" mm/us", iControlX+300, iControlY+30);
          
                stroke(255, 0, 0);
                line(x, 0, x, iVectorWindowY);
                break;
              }
            }
          } // threshold for loop
  
          for (int x=0; x<1024; x++) 
          {
            if (iThreshold >= values[x])
            {
              strikeInt = (x*(Bittime())+(iRGD*Bittime()))*1000000;
                if (strikeInt > 90)
                {
                  text("Interface Peak: ",  iControlX+100, iControlY);  
                  text(strikeInt +" us",  iControlX+100, iControlY+30); 
                  text("Oil Column Depth:", iControlX+100, iControlY+60);
                  text((0.5*strikeInt*fVelocity)+" mm", iControlX+100, iControlY+90);
                  stroke(255, 0, 0);
                  line(x, 0, x, iVectorWindowY);
          
                  //sample_file.println ("Interface Peak: "+strikeInt);
                  //sample_file.println ("Oil Column Depth: "+(0.5*strikeInt*fVelocity));

                  break;
                }
              }
            }
    
 
         // ************* PP Logic ****************
         iPeakMax = 0;
         iPeakMin = 512;      
      
        for (int x=0; x<1024; x++) 
          {
            if (values[x] > iPeakMax)
              iPeakMax = values[x];
            if (values[x] < iPeakMin)
              iPeakMin = values[x];
          }
    
        text("Relative Peak Attenuation: " +(iPeakMax-iPeakMin),iControlX+300, iControlY+60);
    
      
        // ************ draw vector ************
        stroke(255);

        for (int x=0; x<1023; x++)
          {
            x1 = x;
            x2 = x+1;
            y1 = (255-values[x1])*iVectorWindowY/256; // scale the values
            y2 = (255-values[x2])*iVectorWindowY/256;
            line(x1, y1, x2, y2);
            //sample_file.println(x1+","+y1+","+x2+","+y2);
          } // draw vector for loop

  }
 
  
    // draw the vertical cursor

    if (mouseX<1024 && mouseY<iVectorWindowY) 
    {
      stroke(204, 102, 0);
      line(mouseX, 0, mouseX, iVectorWindowY);
      text(nf(Time(mouseX), 0, 2)+"us", mouseX, 500);
      if ((mousePressed == true) && (mouseX > 50) && (mouseX < 974)) 
      {// set start time to cursor position
        starttime(str(int(Time(mouseX))));
      } 
      else if ((mousePressed == true) && (mouseX > 0) && (mouseX < 50)) 
      { // set start time earlier
        iStarttime = iStarttime - int((512.0*Bittime()*1000000.0));
        if (iStarttime < 0)
        iStarttime = 0;
        starttime(str(iStarttime));
      } 
      else if ((mousePressed == true) && (mouseX > 974) && (mouseX < 1024))  
      {// set start time later
        iStarttime = iStarttime + int((512.0*Bittime()*1000000.0));
        starttime(str(iStarttime));
      }
    }
  

  
  
    // draw the x/y axis and label them
    stroke(128, 128, 128);
    line(0, iVectorWindowY/2, 1024, iVectorWindowY/2);
    line(0, iVectorWindowY, iVectorWindowX, iVectorWindowY);
    for (int x = 0; x< 1024; x= x+42) 
    {
      line(x, iVectorWindowY/2+5, x, iVectorWindowY/2-5);
    }
    text(nf(Time(0), 0, 2)+"µs", 10, iVectorWindowY/2+20); 
    textAlign(RIGHT);
    text(nf(Time(1024), 0, 2)+"µs", iVectorWindowX-10, iVectorWindowY/2+20);
  textAlign(LEFT);

  
}
}

This the draw code.

Below is the setup code.

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

ControlP5 cp5;

float rev=0.2;

boolean connected = false;
byte port_num=-1;  // the Serial.list() call below will list all the available serial ports on your host...Enter the port number here
boolean setup = true;



int BitTimes=0;
int Attenuation=0;
int iBittime=3;
int iAttn=5;
int iRGD=1500;
int iSamples=10;
int iThreshold=70;
int Samples=1;
int Threshold=0;
int iPulsedelay=0;
int iStarttime = 0;
int iPeakMin;
int iPeakMax;
float strikeRefl;
float strikeInt;
int reflLimit = 80;
int intLimit = 80;
float reflDist = 41;
float colDepth;
String timeName;
String dateName;
int savedTime;
int totalTime = 1500;
PrintWriter sample_file;  // Vector output tofile

PFont f, b, s;  
Serial port;  // Create object from Serial class
int[] values; // Vector array received from the serial port
//byte[] values; // Vector array received from the serial port


// Variable Gain unit specific change here.
int mode_reg=0x0C;  // VGA type

int x1, x2, y1, y2;

int iPause = 0;  // state variable to control the draw method 0 = draw, 1 = pause
int iScreenX;
int iScreenY;

int iVectorWindowX;
int iVectorWindowY = 512;
float fVelocity = 1.497; // water mm/us = 1497 m/s
//float fVelocity = 6.100; // steel mm/us = 6100 m/s

int iControlX = 0; // location of controls
int iControlY = 550;
int c1, c2, c3, c4;
void setup() 
{
  size(1024, 768);
  iScreenX = width;
  iScreenY = height;
  iVectorWindowX = iScreenX;
  iVectorWindowY = iScreenY*512/768;
  iControlX = 0;
  iControlY = iScreenY*550/768;
  c1 =10;
  c2 = iScreenX/3-150;
  c3 = iScreenX/3*2-200;
  c4 = iScreenX-310;
  println("c1: "+c1+"  c2: "+c2+"  c3: "+c3+" c4: "+c4);


String[] availablePorts = Serial.list();
  printArray(Serial.list());
  for(int i = 0;i< availablePorts.length-1;i++){
    if (availablePorts[i].contains("tty.usbserial")||
        availablePorts[i].contains("COM10")||
        availablePorts[i].contains("ACM0")){
      port_num = (byte)i;    
      println(i);
      connected=true;
}
  }
  /*if (port_num!=-1)*/{
  //port = new Serial(this, Serial.list()[port_num], 9600);
  port = new Serial(this, "COM10", 9600);
  connected = true;
  }

println("Connected");
  f = loadFont("GillSans-24.vlw");
  b = loadFont("GillSans-14.vlw");
  s= loadFont("GillSans-12.vlw");
  textFont(f);
  textFont(b);
  textFont(s);
  fill(255, 255, 255);
  println("Make Buttons");
  cp5 = new ControlP5(this);
  cp5.addButton("Stop")
    //.setFont(b)
    //.setValue(0)
    .setPosition(c1, iControlY+90)
    .setSize(100, 39)
    ;
  cp5.addButton("Pause")
    //.setFont(b)
    //.setValue(0)
    .setPosition(c1, iControlY+130)
    .setSize(100, 39)
    ;
  cp5.addButton("Resume")
    //.setFont(b)
    //.setValue(0)
    .setPosition(c1, iControlY+170)
    .setSize(100, 39)
    ;
println("MakeSliders");

  cp5.addSlider("Attenuation")
    .setPosition(c2, iControlY+105)
    .setSize(200, 29)
    .setRange(0, 127)
    .setSliderMode(Slider.FLEXIBLE)
    //.setFont(s)
    ;
  cp5.getController("Attenuation").getCaptionLabel().align(ControlP5.LEFT, ControlP5.TOP_OUTSIDE).setPaddingX(2);
  cp5.getController("Attenuation").getValueLabel().align(ControlP5.RIGHT, ControlP5.TOP_OUTSIDE).setPaddingX(2);

  cp5.addSlider("BitTimes")
    .setPosition(c2, iControlY+170)
    .setSize(200, 29)
    .setRange(0, 3)
    .setNumberOfTickMarks(4)
    .setSliderMode(Slider.FLEXIBLE)
    .setValue(iBittime)
    //.setFont(s)
    ;
  cp5.getController("BitTimes").getCaptionLabel().align(ControlP5.LEFT, ControlP5.TOP_OUTSIDE).setPaddingX(2);
  cp5.getController("BitTimes").getValueLabel().align(ControlP5.RIGHT, ControlP5.TOP_OUTSIDE).setPaddingX(2);

  cp5.addSlider("Samples")
    .setPosition(c3, iControlY+105)
    .setSize(200, 29)
    .setRange(1, 25)
    .setSliderMode(Slider.FLEXIBLE)
    .setValue(Samples)
    //.setFont(s)
    ;
  cp5.getController("Samples").getCaptionLabel().align(ControlP5.LEFT, ControlP5.TOP_OUTSIDE).setPaddingX(2);
  cp5.getController("Samples").getValueLabel().align(ControlP5.RIGHT, ControlP5.TOP_OUTSIDE).setPaddingX(2);

  cp5.addSlider("Threshold")
    .setPosition(iControlX+c3, iControlY+170)
    .setSize(200, 29)
    .setRange(0, 255)
    .setSliderMode(Slider.FLEXIBLE)
    .setValue(iThreshold)
    //.setFont(s)
    ;
  cp5.getController("Threshold").getCaptionLabel().align(ControlP5.LEFT, ControlP5.TOP_OUTSIDE).setPaddingX(2);
  cp5.getController("Threshold").getValueLabel().align(ControlP5.RIGHT, ControlP5.TOP_OUTSIDE).setPaddingX(2);
   println("Set Frame rate and background");

  frameRate(10);
  background(0);
  //Setbaud(230400);
  Setbaud(9600);
  setup = true;
}

Please help as I am new to Processing.
Also I need to know how to write something into .txt file using Processing since if I try to use the
sample_file.println() function it throws Java Null Pointer exception.

Regards,
Vikram