Arduino to Processing via Bluetooth dropping Characters

Hello, I am working on a system where the Arduino passes process data to a Processing program I am running on a laptop.
The communication is via an RN42 Bluetooth device. I am receiving data just fine but I the commands are not being received correctly. The commands are of the form “C,S\n” or “C,M\n” or “C,P,45\n”. Ideally my Arduino would take action on what letters are received but when I process the input string usually I only get the comas.
I am using a MEGA2560 and actually using Serial1. Here is some of the code I have tried to thin it down a bit as its size is
Binary sketch size: 20,214 bytes (of a 258,048 byte maximum):

//Includes and Defines
#include <OneWire.h>  //1-Wire Library for talking to Temp sensors etc.
#include <DallasTemperature.h>  //Simplification of Temp reading

#define ONE_WIRE_BUS 12
#define TEMPERATURE_PRECISION 9
const int temp_sensor_time_base_proc =1000;
long temp_sensor_last_time_proc;
const int temp_recording_time_base_proc =10000;
long temp_recording_last_time_proc;

//no more #include or  #define statements but a bunch of variables

// the setup routine runs once when you press reset:
void setup() {

  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
  Serial1.begin(115200);
  //delay (320);
  //Serial1.print ("$$");
  //delay (15);
  //Serial1.println ("U,9600,N");
  //Serial1.begin(9600);

  // reserve 200 bytes for the inputString:
  inputString.reserve(200);

  Serial.println("BMA_7");
  // Start up the library
  TempSensors.begin();

  // Grab a count of devices on the wire
  Temp_Probe_Count_proc = TempSensors.getDeviceCount();

  // Loop through each device, print out address
  for(int i=0;i<Temp_Probe_Count_proc; i++)
  {
    // Search the wire for address
    if(TempSensors.getAddress(tempDeviceAddress, i))
    {
      Serial.print(F("Found device "));
      Serial.print(i, DEC);
      Serial.print(F(" with address: "));
      printAddress(tempDeviceAddress);
      Serial.println();

      Serial.print(F("Setting resolution to "));
      Serial.println(TEMPERATURE_PRECISION, DEC);

      // set the resolution to TEMPERATURE_PRECISION bit (Each Dallas/Maxim device is capable of several different resolutions)
      TempSensors.setResolution(tempDeviceAddress, TEMPERATURE_PRECISION);

      Serial.print(F("Resolution actually set to: "));
      Serial.print(TempSensors.getResolution(tempDeviceAddress), DEC); 
      Serial.println();
    }
    else{
      Serial.print("Found ghost device at ");
      Serial.print(i, DEC);
      Serial.print(" but could not detect address. Check power and cabling");
    }
  }


  // initialize the digital inputs.
  pinMode(Pushbutton_SS_io, INPUT);
  pinMode(Pushbutton_PBG_io, INPUT);
  pinMode(Pushbutton_PBY_io, INPUT);



  // initialize the digital outputs.
  pinMode(Beacon_B_io, OUTPUT);
  pinMode(Beacon_G_io, OUTPUT);
  pinMode(Beacon_H_io, OUTPUT);
  pinMode(Beacon_R_io, OUTPUT);
  pinMode(Beacon_Y_io, OUTPUT);
  pinMode(PBPL_GRN_io, OUTPUT);
  pinMode(PBPL_YEL_io, OUTPUT);
  pinMode(Pump_Run_io, OUTPUT);
  pinMode(Pump2_Run_io, OUTPUT);
  pinMode(HLT_Gas_io, OUTPUT);
  pinMode(BK_Gas_io, OUTPUT);
  pinMode (HLT_Fill_io, OUTPUT);
  pinMode (CCW_Flow_io, OUTPUT);

  HopTimeTest ();

 //a bunch of prints to Serial (not Serial1)

}  //End Setup


// the loop routine runs over and over again forever:
void loop() {

//some code

  ReadHMI ();

//some more code
}  //End Loop

//Read Inputs from HMI
void ReadHMI (){

String sMessageType = "";
String sTagName = "";
String sValue = "";
int iValue = 0;
        
        // print the string when a newline arrives:
  if (stringComplete) {
    //  Serial.println("ReadHMI stringComplete"); 
    //Serial.println(inputString); 
    
    
    sMessageType = inputString.substring(0,1);
Serial.println("String Complete" ); 
Serial.println(inputString ); 
Serial.println(sMessageType ); 
    if (sMessageType == "C")
    {
      sTagName = inputString.substring(2,3);
      sValue =   inputString.substring(4,7);
      iValue = sValue.toInt();
//Serial.println( ); 
//Serial.println(sMessageType ); 
//Serial.println(sTagName ); 
//Serial.println(sValue ); 
//Serial.println(iValue ); 
      ProcessHMICommand(sTagName,iValue);
     }
    
    
    CommandEcho = 'X';
        inputString = "";
    stringComplete = false;
    Serial.println("inputString reset" ); 

    //Serial.println(CommandEcho); 

    
    //process the message that is now read completely from the serial port.
    
    //String Message[] = split(inputString, ",");
    
     
    // clear the string:
    inputString = "";
    stringComplete = false;
  }
  
     //delay(1000);
     
} //end ReadHMI

/*
  SerialEvent occurs whenever a new data comes in the
 hardware serial RX.  This routine is run between each
 time loop() runs, so using delay inside loop can delay
 response.  Multiple bytes of data may be available.
 */
void serialEvent1() {
      //Serial.println ("Entered Serial Event");
    Serial.println ("In SerialEvent");
  while (Serial1.available()) {
    // get the new byte:
    char inChar = (char)Serial1.read(); 
    // add it to the inputString:

    inputString += inChar;
    
    // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    if (inChar == '\n') {
      stringComplete = true;
    CommandEcho = 'X';
     Serial.println ("Cmd Rcvd");
     Serial.println (CommandEcho);
     Serial.println (inputString);
    } 
  }
} //end of serialEvent1

When I have the Serial Monitor print the inputString I usually something like:

,, % // it looked like " , %" on my screen or
,S  //or
C

I have tried to google bluetooth serial but I haven’t found anything helpful.

Thanks in advance for some insight.

When I have the Serial Monitor print the inputString I usually something like:

If you aren't getting good data, the likely culprit is the sender not sending good data. You have not said anything about what is sending data to the Arduino. Nor have you shown that code.

Of course. The other end is a Processing program. It displays several process values and has some pushbuttons and a slider. The push buttons produce the "C,S\n" or "C,M\n" when I click on the slider I get "C,P,45\n" where the number reflect the value of the slider. The output of the processing window suggests the correct string is being sent. I think the Arduino is getting something because it sends back a command echo of X.

import processing.serial.*;
import controlP5.*;
import java.io.BufferedWriter;
import java.io.FileWriter;

String outFilename = "BrewLog.csv";
String sLogData = "";


ControlP5 cp5;

//a bunch more variables defined

void setup () {
  // set the window size:
  size(1000, 675);        
  background(0);

//some other stuff

  //String portName = Serial.list()[1];
  //SerialPort = new Serial(this, portName, 9600);
  SerialPort = new Serial(this, "com4", 115200);  //I have found using com4 works better than the list because the bluetooth is always com4 but its place in the list changes when I plug in the USB cable going to the Arduino.

//some other stuff

  // Add a vertical slider control P
  cp5 = new ControlP5(this); 
  //("SLIDERNAME", min,max, startpos, xpos,ypos, width,height);
  cp5.addSlider("PumpSpeed", 0, 100, 0, 700, 100, 20, 200);
  // Configure the slider properties
  Slider s1 = (Slider)cp5.controller("PumpSpeed");
  s1.setSliderMode(Slider.FLEXIBLE);
  s1.setNumberOfTickMarks(21);
  s1.showTickMarks(true);
  s1.snapToTickMarks(true);


  // create a new button with name 'NextStep'  S
  cp5.addButton("NextStep", 0, 100, 400, 40, 40)
    //.setValue(0)
    //.setPosition(100,400)
    //.setSize(40,40)
    ;

  // create a new button with name 'StartMash'  M
  cp5.addButton("StartMash")
    .setValue(0)
      .setPosition(150, 400)
        .setSize(40, 40)
          ;
}  //End of Setup

void draw () {

//some stuff

  ProcessCommand ();

//some other stuff

}  //end of draw

void PumpSpeed(float PumpSpeedvalue) {
      print("PumpSpeed Called :");

  // Grab slider value (0-100) and send to Arduino
  int PumpSpeedSend = round(PumpSpeedvalue);
  //SerialPort.write("C,P,");
  //SerialPort.write(PumpSpeedSend);
  //SerialPort.write("\n");
  CommandCode = "C,P," + PumpSpeedSend + "\n";
  // uncomment the following line to debug
  //println("LED: "+ LEDbrightness);
}

void controlEvent(ControlEvent theEvent) {
  /* events triggered by controllers are automatically forwarded to 
     the controlEvent method. by checking the name of a controller one can 
     distinguish which of the controllers has been changed.
  */ 
 
  /* check if the event is from a controller otherwise you'll get an error
     when clicking other interface elements like Radiobutton that don't support
     the controller() methods
  */
  
  if(theEvent.isController()) { 
    
    print("control event from : "+theEvent.controller().name());
    println(", value : "+theEvent.controller().value());

    //In the coe below a 2 letter string is sent to the Arduino.  The first letter signifies Control, the second is the function
    if(theEvent.controller().name()=="NextStep") {
      CommandCode = "C,S\n";
    }
    
    if(theEvent.controller().name()=="StartMash") {
      CommandCode = "C,M\n";
    }
    
    if(theEvent.controller().name()=="StartBoil") {
     // CommandCode = "CDEF123\n";
      CommandCode = "C,B\n";
    }
    
    if(theEvent.controller().name()=="HopsAdded") {
      CommandCode = "C,H\n";
    }
    
  }
  
}  //End of controlEvent
void ProcessCommand () {
//  print(" ProcessCommand : ");
//  println(CommandCodeONS);

  if (CommandCode !="") {
    if (!CommandCodeONS) {
  println("SerialPort.write "+CommandCode);
      SerialPort.write(CommandCode);
      CommandCodeONS = true;
    }
  }
}  //End of Process command

Here is what it shows at the bottom of the processing window after I hit a couple of the buttons and set a value on the slider. The long string of numbers with a 'A 'at the end is a normal status. An 'X' at the end is a command echo from the Arduino. What follows is a copy of the window the only editing was to remove several blank lines at the start.

ControlP5 2.0.4 infos, comments, questions at http://www.sojamo.de/libraries/controlP5
PumpSpeed Called :control event from : PumpSpeed, value : 0.0
PumpSpeed Called :control event from : PumpSpeed, value : 0.0
PumpSpeed Called :control event from : PumpSpeed, value : 0.0
control event from : StartMash, value : 0.0
control event from : StartBoil, value : 0.0
control event from : HopsAdded, value : 0.0
SerialPort.write C,H

81,84,-196,83,81,81,0,0,0,0,0,0,0,X
81,84,-196,83,81,81,0,0,0,0,0,0,0,A
81,84,-196,83,81,81,0,0,0,0,0,0,0,A
81,84,-196,83,81,81,0,0,0,0,0,0,0,A
control event from : NextStep, value : 0.0
SerialPort.write C,S

81,84,-196,83,81,81,0,0,0,0,0,0,0,X
81,84,-196,83,81,81,0,0,0,0,0,0,0,A
control event from : StartMash, value : 0.0
SerialPort.write C,M

81,84,-196,83,81,81,0,0,0,0,0,0,0,X
81,84,-196,83,81,81,0,0,0,0,0,0,0,A
PumpSpeed Called :control event from : PumpSpeed, value : 55.0
SerialPort.write C,P,55

PumpSpeed Called :control event from : PumpSpeed, value : 55.0
PumpSpeed Called :control event from : PumpSpeed, value : 55.0
PumpSpeed Called :control event from : PumpSpeed, value : 55.0
PumpSpeed Called :control event from : PumpSpeed, value : 55.0
PumpSpeed Called :control event from : PumpSpeed, value : 55.0
PumpSpeed Called :control event from : PumpSpeed, value : 55.0
81,84,-196,83,81,81,0,0,0,0,0,0,0,X
81,84,-196,83,81,81,0,0,0,0,0,0,0,A
81,84,-196,83,81,81,0,0,0,0,0,0,0,A
81,84,-196,83,81,81,0,0,0,0,0,0,0,A

I think the Arduino is getting something because it sends back a command echo of X.

I thought about providing an answer like this:
XXXXXXXXX XX XXXX XXXX XXXXXXXXXXXXX

But, of course, that would be useless. Why read one character and echo another one? How does that illustrate anything other than that something arrived. It takes NO more effort to echo something useful - like the character you just read. That way, you KNOW that the Arduino did, or did not, receive what was sent.

By the way, I don't see that the 'X' is actually ever sent to the Serial1 instance that Processing is communicating with.

The Arduino send a status message with various process values about every second normally it is an ‘A’ but the first status after a command is received from Processing is an ‘X’. Regardless of the data sent to the Arduino, the CommandEcho is an ‘X’. I am not reading a character rather I am reading a string, the ‘X’ is sent after a ‘\n’ is received. At least that’s what I think I am doing.
Here is the code that writes to Processing, WriteHMI_Cycle_Time_const is 1000.

 // WriteHMI();  //Write the outputs to the HMI
     if (WriteHMI_Timer_proc == 0) {
      WriteHMI_Timer_proc = (WriteHMI_Cycle_Time_const) + millis();
    }
    if (WriteHMI_Timer_proc <= millis()){
      WriteHMI();  //Read the inputs from the Controller
      WriteHMI_Timer_proc = 0;
    }

And here is the WriteHMI() function:

//Write Process Information to HMI
void WriteHMI (){
  //Write Temperatures to HMI

  //while (Serial.available() <= 0) {
  int Valve_Byte_HMI = ((Pump_Run_State_proc * 16) + (HLT_Gas_State_proc * 8) + (BK_Gas_State_proc * 4) + (HLT_Fill_State_proc * 2) + CCW_Flow_State_proc)&Valve_Byte_proc;

if (Mash_Timer_proc ==0) {
  Mash_Timer_HMI = 0;
}
else {
  Mash_Timer_HMI = (Mash_Timer_proc-millis())/60000;
}
if (Brew_Timer_proc ==0) {
  Brew_Timer_HMI = 0;
}
else {
  Brew_Timer_HMI = (Brew_Timer_proc-millis())/60000;
}
if (Hop_Add_Timer_proc ==0) {
  Hop_Add_Timer_HMI = 0;
}
else {
  Hop_Add_Timer_HMI = (Hop_Add_Timer_proc-millis())/60000;
}


   //Valve_State_hmi = (CCW_Valve_Open_io * 128) + (CHL_Valve_Open_io * 64) + (BK_OUT_Valve_Open_io * 32) + (BK_IN_Valve_Open_io * 16) + (MLT_OUT_Valve_Open_io * 8) + (MLT_IN_Valve_Open_io * 4) + (HLT_OUT_Valve_Open_io * 2) + (HLT_IN_Valve_Open_io);   
   Serial1.print(AMB_Temp_proc); Serial1.print(",");
   Serial1.print(HLT_Temp_proc); Serial1.print(",");
   Serial1.print(MLT_Temp_proc); Serial1.print(",");
   Serial1.print(BK_Temp_proc); Serial1.print(",");
   Serial1.print(CHL_Temp_proc); Serial1.print(",");
   Serial1.print(CCW_Temp_proc); Serial1.print(",");
   Serial1.print(Current_Brew_State_proc); Serial1.print(",");
   Serial1.print(Valve_Byte_HMI);  Serial1.print(",");
   Serial1.print(Mash_Timer_HMI);  Serial1.print(",");
   Serial1.print(Brew_Timer_HMI);  Serial1.print(",");
   Serial1.print(Hop_Add_Timer_HMI);  Serial1.print(",");
   Serial1.print(Pump1_Speed_hmi);  Serial1.print(",");
   Serial1.print(Pump2_Speed_hmi);  Serial1.print(",");
   Serial1.print(CommandEcho);
   Serial1.println(); 
   CommandEcho = 'A';
   
//   Serial.print("Pump_Speed_hmi,");  Serial.println(Pump_Speed_hmi,DEC); 
  //}

} //end WriteHMI

I am not reading a character rather I am reading a string, the 'X' is sent after a '\n' is received.

No, you are not. You are reading one character at a time.

  while (Serial1.available()) {
    // get the new byte:
    char inChar = (char)Serial1.read(); 
    // add it to the inputString:

    inputString += inChar;

Forget about all that complex code. Write a simple sketch in Processing that sends "Hello, Joe\n" over and over. Have that sketch echo, using println(), the characters that it receives.

Have the Arduino read characters as they become available, and echo them.

Until you KNOW that what you send is what you receive, you are tilting at windmills.

OK, I was so focused on the InputString I forgot it is built one character at a time.
I tried to do what you said about building a simple program which I thought would send "Hello Joe\n" from Processing to Arduino and echo it back. Of course it doesn't work but I have no idea what to check. Here is the processing code

import processing.serial.*;

Serial SerialPort;        // The serial port
int[] serialInArray = new int[12];    // Where we'll put what we receive
int serialCount = 0;                 // A count of how many bytes we receive
boolean firstContact = false;        // Whether we've heard from the microcontroller


void setup () {
  // set the window size:
  size(1000, 675);        
  background(0);
  //String portName = Serial.list()[1];
  //SerialPort = new Serial(this, portName, 9600);
  SerialPort = new Serial(this, "com4", 9600);  //this was at 115200 I tried to slow it down, no help.

}  //End of Setup

void draw () {
SerialPort.write("Hello, Joe\n");
delay (1000);
//println("Hello, Joe\n");

}  //end of draw


void serialEvent(Serial SerialPort) {
    println(" in serialEvent");

    // read the serial buffer:
  String myString = SerialPort.readStringUntil('\n');  
  if (myString != null) {
  //trim whitespace and formatting characters (like carriage return)
  myString = trim(myString);
  println(myString);
  }
}  //end SerialEvent

and here is the Arduino code

String inputString = "";         // a string to hold incoming data

void setup() {

  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
  Serial1.begin(115200);
  // reserve 200 bytes for the inputString:
  inputString.reserve(200);

  Serial.println("Brewery Blutooth Test");

}  //End Setup


// the loop routine runs over and over again forever:
void loop() {
    Serial1.println (inputString);
    delay (1000);
  
}  //End Loop

void serialEvent1() {
      //Serial.println ("Entered Serial Event");
    Serial.println ("In SerialEvent");
  while (Serial1.available()) {
    // get the new byte:
    char inChar = (char)Serial1.read(); 
    delay (10);
    // add it to the inputString:

    Serial.println (inChar);
    inputString += inChar;
    Serial.println (inputString);


    
    // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    //if (inChar == '\n') {
      //CMD_Data_HMI = inputString.toInt();
     // stringComplete = true;
    //} 
  }
}  //end of SerialEvent1

I would copy what I see in the Arduino Serial Monitor but there must be unprintable characters in it because I see various parts of Hello Joe but I cant copy and past them.
to simulate
o
Ello,
oE
Ello,

H
Ello,

Nothing appears in the Processing window.
It seems like one part is going too fast for the other but I don't understand how to control the bluetooth on the laptop to adjust Baud Parity etc.

So trying to simplify what I was using did not help so I went to the Arduino playground and found the Bluetooth example here http://playground.arduino.cc/learning/tutorial01. I made only simple changes of baud rate and serial port. I also added an echo out the serial monitor on the Arduino.
I am using a Mega2560 with a Roving NetworksRN-42 Bluetooth module connected toSerial1. The only baud rate that produces anything is 115200. The PC lists 2 Bluetooth ports COM4 and COM5; only COM4 seems to work. There is also a COM3 but that is the USB cable.
Here is the Arduino code:

char val; // variable to receive data from the serial port
int ledpin = 25; // LED connected to pin 25 (Beacon connected there)


void setup() {

  pinMode(ledpin, OUTPUT);  // pin 48 (on-board LED) as OUTPUT
  Serial.begin(9600);       // start serial communication at 9600bps
  Serial1.begin(115200);       // start serial communication at 9600bps
                              //changed to 115200as my bluetoth doesn't 
                              //seem to work at any other speed

}

void loop() {

  if( Serial1.available() )       // if data is available to read
                                  //Changedto Serial1 throughout
  {
    val = Serial1.read();         // read it and store it in 'val'
    Serial.println (val);
  }
  if( val == 'H' )               // if 'H' was received
  {
    digitalWrite(ledpin, HIGH);  // turn ON the LED
  } else { 
    digitalWrite(ledpin, LOW);   // otherwise turn it OFF
  }
  delay(100);                    // wait 100ms for next reading

}

And here is the Processing code:

//import class to set up serial connection with wiring board
import processing.serial.*;

Serial port;

//button setup
color currentcolor;
RectButton rect1, rect2;
boolean locked = false;
void setup() {

  //set up window
  size(200, 200);
  color baseColor = color(102, 102, 102);
  currentcolor = baseColor;

  // List all the available serial ports in the output pane. 
  // You will need to choose the port that the Wiring board is 
  // connected to from this list. The first port in the list is 
  // port #0 and the third port in the list is port #2. 
  println(Serial.list()); 

  // Open the port that the Wiring board is connected to (in this case 1
  // which is the second open port in the array) 
  // Make sure to open the port at the same speed Wiring is using (9600bps) 
  port = new Serial(this, Serial.list()[1], 9600);

  // Define and create rectangle button #1
  int x = 30;
  int y = 100;
  int size = 50;
  color buttoncolor = color(153, 102, 102);
  color highlight = color(102, 51, 51); 
  rect1 = new RectButton(x, y, size, buttoncolor, highlight);

  // Define and create rectangle button #2
  x = 90;
  y = 100; 
  size = 50;
  buttoncolor = color(153, 153, 153);
  highlight = color(102, 102, 102); 
  rect2 = new RectButton(x, y, size, buttoncolor, highlight);

}

void draw() {

  background(currentcolor);
  stroke(255);
  update(mouseX, mouseY);
  rect1.display();
  rect2.display();

}

void update(int x, int y) {

  if(locked == false) {

    rect1.update();
    rect2.update();
  } else {
    locked = false;
  }

  //Turn LED on and off if buttons pressed where
  //H = on (high) and L = off (low)
  if(mousePressed) {
    if(rect1.pressed()) {            //ON button
      currentcolor = rect1.basecolor;
      port.write('H');
    } else if(rect2.pressed()) {    //OFF button
      currentcolor = rect2.basecolor;
      port.write('L');
    }
  }

}

class Button {

  int x, y;
  int size;
  color basecolor, highlightcolor;
  color currentcolor;
  boolean over = false;
  boolean pressed = false;   

  void update() 
  {
    if(over()) {
      currentcolor = highlightcolor;
    } else {
      currentcolor = basecolor;
    }
  }

  boolean pressed() 
  {
    if(over) {
      locked = true;
      return true;
    } else {
      locked = false;
      return false;
    }    
  }

  boolean over() 
  { 
    return true; 
  }

  void display() 
  { 

  }

}

class RectButton extends Button {

  RectButton(int ix, int iy, int isize, color icolor, color ihighlight) 
  {
    x = ix;
    y = iy;
    size = isize;
    basecolor = icolor;
    highlightcolor = ihighlight;
    currentcolor = basecolor;
  }

  boolean over() 
  {
    if( overRect(x, y, size, size) ) {
      over = true;
      return true;
    } else {
      over = false;
      return false;
    }
  }

  void display() 
  {
    stroke(255);
    fill(currentcolor);
    rect(x, y, size, size);
  }

}

boolean overRect(int x, int y, int width, int height) {

  if (mouseX >= x && mouseX <= x+width && 
      mouseY >= y && mouseY <= y+height) {
    return true;
  } else {
    return false;
  }

}

Processing draws a window with two boxes in it. If I click the left one, it should transmit a single H. If I click the right one, it should transmit a single L. An H should turn on the light and anything else should turn it off.
What does happen is that somewhere between 6 and 8 characters are transmitted each time one of the boxes are clicked. Some of which will be the intended one. So if I click the left one the light will usually blink. If the last character transmitted was an H the light stays on.

This suggests the Arduino code is working and it is the Processing code that the issue or something with the PC driver etc. Which is, for the record, what PaulS said about 4 posts ago.

Now it looks like the problem is in the Processing code, but this is an example from the Arduino website and I have not seen anyone else complain about that example so it is probably correct. What else can I look at?

So I changed the Arduino code to talk over the USB to Processing. I commented out the echo and changed all the Serial1 to Serial. Everything worked fine. So the problem is definitely the Bluetooth connection.
Not sure which end though.

So the problem is definitely the Bluetooth connection.
Not sure which end though.

I'm not sure why you concluded that. While you press the mouse button, how many times is draw() (and update()) called?

You are sending data if the mouse button IS pressed, not if the mouse button has BECOME pressed.

I suspect that this is the heart of the problem, not the Bluetooth connection.

It's easy enough to test. Connect Processing and the Arduino with a USB cable, instead. Does the problem persist? If so, bluetooth has nothing to do with it.

I'm happy, though, to see you persisting in troubleshooting, rather than giving up.

I did try it with a USB cable and it worked fine. If I can figure out how to send the characters from my phone that might tell which end it is on.