Reading data from BT in Processing

Hi everyone,

I’d be very thankful for any help with my project. I believe I reached the point where I bit off more than I could chew. I’ve read the most topics about arduino<>Processing connection, but I believe I still lack something.

Basically, I used a Pro Micro board to create a controller. But in my effort to make it wireless, I forgot, that my Bluetooth module can’t send HID data as Keyboard.press().

As a solution, modified the sketch for my controller so that it sends just packets of data instead of mouse events, in order for a Processing application to read them and convert into key/mouse events on my PC.

The export data look like and so on. I use <> chars to define beginning and ending of each command - Serial.print("");

So far my processing app reads the data but does nothing:

Processing code:

import org.firmata.*;
import cc.arduino.*;
import processing.serial.*;
import java.io.*;
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.*; 

Robot WRobot;

Serial WPort;
final static int SERIAL_PORT_NUM = 3 ;
final static int SERIAL_PORT_BAUD = 9600;

int EOP = 62;
String inStr = null;

void setup()
{
  String portName = Serial.list()[SERIAL_PORT_NUM];
  WPort = new Serial(this, portName, 9600);
  WPort.clear();  

//Let's Robot...
  try { 
    WRobot = new Robot();
  } catch (AWTException e) {
    e.printStackTrace();
    exit();
  } 
  
// Graphics
  size(200, 200);
  smooth();
  noStroke();
   
}

void draw()
{
  // Read all serial data available, as fast as possible
 
  inStr = WPort.readStringUntil(EOP);          
  }
  
void serialEvent(Serial WPort) { 
  
  if (inStr != null)
     {
  print(inStr);
     }
  if (inStr == "<L1>")
     {
  print("Left button");
     }
  
}

The part with (inStr != null) does work, but can’t recognize the (inStr == “”) equation in order to create Left mouse button event.

Any hint would be appreciated.

So far my processing app reads the data

It doesn’t even do that properly. The draw() function is NOT where to read serial data.

You should use the bufferUntil() method of the Serial class to define when the serialEvent() method gets called.

  if (inStr != null)
     {
  print(inStr);
     }
  if (inStr == "<L1>")

Piss poor indenting!

If the String is not NULL, print it. Then, regardless of whether or not it is NULL, see if it equals “”. Does that make sense?

int EOP = 62;

Why on earth would you use an int to store a char value? Why NOT use the name that makes sense?

char EOP = '>';

Now, think about what this does:

  inStr = WPort.readStringUntil(EOP);

Suppose that you do indeed send “”. What portion of that will the readStringUntil() method transfer into inStr? Any answer other than “<L1” is wrong.

So, expecting inStr to equal “” is unrealistic.

Also, think about what will still be in the incoming serial buffer still to be read. It you are using Serial.print() on the Arduino, then there will be nothing left. If you are using Serial.println(), the carriage return and line feed will still be in the buffer.

You should be using Serial.println() on the Arduino, Serial::bufferUntil() in setup() in Processing, and String::trim() in the serialEvent() method, to trim non-printing characters from the String populated by the Serial::readString() method.

Thank you for your advice, PaulS!

I’ve modified both parts of the code according to your post, but something still just doesn’t work. :confused:

import processing.serial.*;
import java.io.*;
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.*; 

Robot WRobot;

Serial WPort;
final static int SERIAL_PORT_NUM = 3 ;
final static int SERIAL_PORT_BAUD = 9600;

char EOP = '>';
String inStr;
String inCom;
String msg;


void settings()
{
 size(200, 200);
  smooth();

}

void setup()
{
//Serial port setup 
  String portName = Serial.list()[SERIAL_PORT_NUM];
  WPort = new Serial(this, portName, SERIAL_PORT_BAUD);
  WPort.clear(); 
  WPort.bufferUntil(EOP); 

//robot
  try { 
    WRobot = new Robot();
  } catch (AWTException e) {
    e.printStackTrace();
    exit();
  } 
  
 
}


void serialEvent(Serial WPort) { 
  
    inStr = WPort.readString();
    inCom = trim(inStr);
    print(inCom);  //to be sure it does receive at least anything. It sends input as <L1>, <R1> and so on, BTW
      
          if(inCom == "<L1>"){       // both <L1> and <L1 are not recognized. Why?
           msg = "Left Button";
          }
          if(inCom == "<R1>"){
           msg = "Right Button";
          }
          if(inCom == "<W1"){
           msg = "Wheel Down";
          }
          if(inCom == "<W2"){
           msg = "Wheel Up";
          }
        
} 

void draw()
{

background(0);
  text("Incoming: " + inCom, 10,50);
  text("Recognized: " + msg, 10,100);
}

I’ve modified both parts of the code

But, you haven’t shown the Arduino code.

    print(inCom)

When you are looking to KNOW what is in a string, this is NOT the way to print it.

print("inCom = [");
print(inCom);
println("]");

Will convey a LOT more information.

          if(inCom == "<L1>"){       // both <L1> and <L1 are not recognized. Why?
          if(inCom == "<R1>"){
          if(inCom == "<W1"){
          if(inCom == "<W2"){

Why do some have the > and others don’t?

PaulS:
Why do some have the > and others don't?

It was just for testing purposes, to try all the buttons and find, if any return the expected result. As I said, nothing is returned.

Please note, that arduino part is now sending output like “R0>” and so on, just because the < char has proved itself useless.

I modified both parts of the code accordingly.

I also tried your method with

print("inCom = [");
print(inCom);
println("]");

The output now looks like:

inCom = [M-1,-1>]
inCom = [L1>]
inCom = [R0>]
inCom = [L1>]
inCom = [R0>]
inCom = [L0>]
inCom = [L0>]
...

So the values look like expected, I guess, but still are somehow unrecognized.

Nevermind, thank you for your help, I resolved the case.

It seems, that Processing was recognizing the string char poorly. I modified the input so taht it could be used in int variables, and everything works well.