HC-05 bluetooth communication issue

Hello!
I'm not sure if this question is suited for this forum or the Project Guidance one, anyway here goes.

Basically I'm making an Android app, which communicates with Arduino by using the popular HC-05 Bluetooth module. Although I'm able to send data back and forth, the quality of the data is worse than I would like, usually only ~30-60% of the data is usable.

For example, if I send "12345" with the Arduino, on the Android end the order of the characters often goes bad, and I might receive "23451" or something similar. However, the problem doesn't last too long and generally the message goes in the correct order.
On the other hand, sending "abcde" from the Android device to the Arduino is much more prone to errors. Not only it suffers from the message getting out of order, but it also prints out gibberish characters for a few message cycles before going back to normal.

I attached the code from both devices below.

Arduino code:

#include <SoftwareSerial.h>

SoftwareSerial mSerial(10, 11); // RX, TX


char bytes[6];
int index = 0;
boolean reading = false;

void setup() {
  mSerial.begin(4800);
  Serial.begin(9600);
  Serial.println("Startup completed");
}

void loop() {

  read();
  mSerial.write(",12345");
  delay(200);
}

void read() {
  if (!reading && mSerial.read() == ',') {
    reading = true;
  }
  if (reading) {
    int i = mSerial.available();
    while (i > 0 && index < 5) {
      bytes[index] = mSerial.read();
      i--;
      index++;
    }
    if (index >= 4) {
      for (int j = 0; j < 5; j++) {
        Serial.print(bytes[j]);
      }
      Serial.println();
      index = 0;
      reading = false;
    }
  }
}

Android code:

/* Imports */

@TargetApi(Build.VERSION_CODES.GINGERBREAD_MR1)
public class Main extends Activity {

	private Reader ReadThread = null;

	private String name = null;
	private String address = null;

	BluetoothAdapter adapter = null;
	BluetoothSocket socket = null;
	BluetoothDevice device = null;
	BluetoothServerSocket ServerSocket = null;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_list_item);
		System.out.println("OnCreate started");
		bluetooth();
	}

	protected void onDestroy() {
		super.onDestroy();

		try {
			socket.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	public void bluetooth() {

		Boolean foundit = false;
		adapter = BluetoothAdapter.getDefaultAdapter();

		if (!adapter.isEnabled()) {
			Intent turnOn = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
			startActivityForResult(turnOn, 0);
		}

		Set<BluetoothDevice> pairedDevices = adapter.getBondedDevices();
		// If there are paired devices
		if (pairedDevices.size() > 0) {
			// Loop through paired devices
			for (BluetoothDevice deviceTmp : pairedDevices) {
				if (deviceTmp.getName().toString()
						.equalsIgnoreCase("ARDUINOBT")) {
					name = deviceTmp.getName();
					address = deviceTmp.getAddress();
					device = deviceTmp;
					Toast.makeText(getApplicationContext(),
							"Name: " + name + ", address:" + address,
							Toast.LENGTH_SHORT).show();
					foundit = true;
				}
				break;
			}
			if (!foundit) {
				Toast.makeText(getApplicationContext(), "BT device not found",
						Toast.LENGTH_SHORT).show();
				;
			}
		} else {
			Toast.makeText(getApplicationContext(), "No paired devices",
					Toast.LENGTH_SHORT).show();

		}

		UUID mDeviceUUID = UUID
				.fromString("00001101-0000-1000-8000-00805F9B34FB");
		try {
			adapter.cancelDiscovery();
			socket = device
					.createInsecureRfcommSocketToServiceRecord(mDeviceUUID);

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		try {
			socket.connect();

		} catch (IOException connectException) {
			// Unable to connect; close the socket and get out

			try {
				socket.close();
			} catch (IOException closeException) {
			}
		}

		System.out.println("Bluetooth initialized!");

		ReadThread = new Reader();
		while (true) {
			write(",abcde");
			try {
				Thread.sleep(200);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}
	}

	/** Will cancel an in-progress connection, and close the socket */
	public void cancel() {
		try {
			socket.close();
		} catch (IOException e) {
		}
	}

	public void write(String msg) {

		msg = msg;

		try {
			socket.getOutputStream().write(msg.getBytes());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.print("SENT: ");
		System.out.println(msg);

	}

	private class Reader implements Runnable {
		private Thread t;

		public Reader() {
			t = new Thread(this, "Input Thread");
			t.start();

		}

		@Override
		public void run() {
			InputStream mmInStream = null;
			byte[] buffer = new byte[5];
			int index = 0;
			boolean read = false;
			try {
				mmInStream = socket.getInputStream();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			while (true) {

				// Keep listening to the InputStream until an exception occurs
				try {
					
					if ((char) mmInStream.read() == ',') {
						read = true;
					}
					if (read) {
						int i = mmInStream.available();
						while (i > 0 && index < 5) {
							buffer[index] = (byte) mmInStream.read();
							i--;
							index++;
						}
						if (index >= 4) {
							// String strInput = new String(buffer, 0, 5);
							String strInput = "";
							for (int j = 0; j < buffer.length; j++) {
								strInput = strInput + (char) buffer[j];
							}
							System.out.print("READ: ");

							System.out.println(strInput);

							index = 0;
							read = false;
						}
					}

				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}

				try {
					Thread.sleep(200);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
}

As you can see, I inserted delay() and Thread.sleep() in both Arduino and Android code to increase the stability of the connection. At first I tried 10ms, but that resulted in horrible message quality, therefore I increased it to the largest acceptable delay/sleep time (if I increase it more, the communication will be too slow for my intended purpose, rendering it useless).
Also, I add a comma to the beginning of each message as it works as a start bit - the bytes of the message are stored in the buffer array only after a comma has been received and read. This did seem to increase the quality of the communication a little bit, however, it didn't change much and the results were similar without using anything like this.

Lastly, I have set the HC-05 module to 4800 baud/s, because it seemed to be more stable at lower speeds, in fact, higher baud rates delivered gibberish bytes. Also, the module now is working without a parity or a stop bit, which can be enabled in its settings (AT mode). Should they be enabled or using commas as an improvised start/stop bit is just as good?

Hopefully someone can help out, thanks!

void read() {
  if (!reading && mSerial.read() == ',') {
    reading = true;
  }
  if (read) {

read is a function. Of course it is true.

#include <SoftwareSerial.h>// import the serial library

No. That is NOT what that statement does. If you are going to have useless comments, you must make them correct useless comments.

What is sending data to the SoftwareSerial instance?

Sorry, I had somehow copied my old, half - modified code, where the boolean was named "read". Either way I corrected the OP and the function of the boolean is to wait for the "start" byte (comma, in this case) before starting to record the message.

Also sorry about that comment as it was already there in the library example; thought that it wouldn't be a problem, so I left it there.

I'm not sure if this is the exact thing you're asking me, but right now, as you can see, the loop function sends some data every loop to the software serial.

as you can see, the loop function sends some data every loop to the software serial.

What I can NOT see is what is connected to the software serial port. I've googled, and mSerial suggests nothing.

PLEASE go back to your original post and put all the code between code tags (the # button) rather than quote tags. At the moment it takes up so much space it is hard to get to your comments at the bottom.

I don't know enough about Android programming to comment on that code.
And there are as many different ways of writing Arduino serial input code as there are Forum members.

This demo shows how to communicate between a PC and an Arduino using Python. I suggest you write some Android code to communicate with that working Arduino code as a start as that will mean you know that half of the system works and the only doubt is whether your Android code works. The general approach in the Python code should apply just as well to an Android app.

...R