ksiri
Posts: 4
Joined: Fri Jan 27, 2017 10:39 am

Scrambled Data in serial read from Bluetooth rfcomm

Fri Jan 27, 2017 12:07 pm

I have created an interface between Arduino(HC-05) and my Raspberri Pi 3 via Bluetooth. I am programming in C++. I am trying to read the data from the /dev/rfcomm0 port using the standard read function, but the data is either scrambled or shifted.

I have a separate thread running to read the /dev/rfcomm0 port, which runs at processor speed.

I am sending a string like "st,0.63,142.86,0.63,en" from Arduino where "st" indicates start of data and "en" indicates the end. Each float value is comma separated.

When I debug my code, the data is being shifted in the read buffer, something like "0.63,142.86,0.63,en\nst" or "t0.63,142.86,0.63,en\ns". When I execute the code in normal speed, the read buffer never returns 23 bytes of data.

The first problem is synchronisation where read buffer is not accumulating with correct data. The second problem is shifting of data in debug mode.

Both Arduino and RPi are at 9600 baud.

I opened minicom in the terminal on RPi 3 to check the data. It is being received perfectly.


My arduino code looks like:

Code: Select all

int sensorPin = A0;

int sensor1Value = 0;
int sensor2Value = 0;
int sensor3Value = 0;
float voltage;
float resistance;

void setup()
{
  Serial.begin(9600);
}

void loop()
{     
      sensor1Value = analogRead(sensorPin);
      sensor2Value = analogRead(sensorPin);
      sensor3Value = analogRead(sensorPin);
      voltage = (float)(sensor1Value * 5) / 1024;

      resistance = (float) 1000 * (voltage/(5 - voltage));
  
      Serial.print("st,");
      Serial.print(voltage);
      Serial.print(",");
      Serial.print(resistance);
      Serial.print(",");
      Serial.print(voltage);
      Serial.print(",en\n");
      delay(1000);
}
This amounts to exactly 23 bytes of data, which I'm trying to read from /dev/rfcomm0. My serial open and read code is as follows:

Code: Select all

int serialOpen (char *device, int baud)
{
	int fd = open (device, O_RDWR | O_NOCTTY | O_SYNC);
	
	struct termios tty;
    memset (&tty, 0, sizeof tty);
    if (tcgetattr (fd, &tty) != 0)
    {
        printf ("Error %d from tcgetattr\n", errno);
        return -1;
    }

	speed_t baudRate;
	switch (baud)
	{
		case 9600:
			baudRate = B9600;
			break;
		case 19200:
			baudRate = B19200;
			break;
		case 38400:
			baudRate = B38400;
			break;
		case 57600:
			baudRate = B57600;
			break;
		case 115200:
			baudRate = B115200;
			break;
		default:
			printf("Unsupported baud rate: %d\n", baud);
	  		return -1;
	}
    cfsetospeed (&tty, baudRate);
    cfsetispeed (&tty, baudRate);

    tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8;
    tty.c_iflag &= ~IGNBRK;
    tty.c_lflag = 0;
    tty.c_oflag = 0;
    tty.c_iflag &= ~(IXON | IXOFF | IXANY);
    tty.c_cflag |= (CLOCAL | CREAD);
    tty.c_cflag &= ~(PARENB | PARODD);
    tty.c_cflag &= ~CSTOPB;
    tty.c_cflag &= ~CRTSCTS;
    tty.c_cflag &= ~HUPCL;   /* disable hangup-on-close to avoid auto reset */
    tty.c_cc[VMIN]  = 0;
    tty.c_cc[VTIME] = 10;

    if (tcsetattr (fd, TCSANOW, &tty) != 0)
    {
        printf ("Error %d setting term attributes\n", errno);
        return -1;
    }
    
	return fd;
}

Code: Select all

int serialReadData (int fd, char * outStr)
{
    char data[23];
    int i = 0;
    int n = read(fd,&data,23);

   if((n == 23) && (data[0] == 's') && (data[1] == 't'))
    {
        for(int i = 0; i < 21; i++)
        {            
            if((data[i+3] != 'e') && (data[i+4] != 'n'))
            {
                outStr[i] = data[i+3];
            }
            else
            {
                outStr[i] = '\n';
                break;
            }
        }
        return 1;
    }
    return 0;
}
I will be really glad if someone can help me figure out what mistake I'm doing in reading data from the serial port.

Best Regards,
Ksir

User avatar
Gert van Loo
Posts: 2487
Joined: Tue Aug 02, 2011 7:27 am
Contact: Website

Re: Scrambled Data in serial read from Bluetooth rfcomm

Fri Jan 27, 2017 2:21 pm

You are working with an synchronized serial stream.
Sending 'packetised' data over a serial port is non-trivial.
You must process the data on a byte-by-byte basis and synchronize to the start by hunting for the 's'.
For example code have a look at the serial drivers for my product: www.gertbot.com
(Python and C code source code is available)

ksiri
Posts: 4
Joined: Fri Jan 27, 2017 10:39 am

Re: Scrambled Data in serial read from Bluetooth rfcomm

Fri Jan 27, 2017 2:43 pm

Gert van Loo wrote:You are working with an synchronized serial stream.
Sending 'packetised' data over a serial port is non-trivial.
You must process the data on a byte-by-byte basis and synchronize to the start by hunting for the 's'.
For example code have a look at the serial drivers for my product: http://www.gertbot.com
(Python and C code source code is available)

Thank you for your reply. I did see your code and how you're reading byte-by-byte. I need to get the entire packet of data (all 23 bytes) in one single call of the "serialReadData" function. How do you suggest I re-write my function to do this byte-by-byte?
Also, must my thread reading the serial port be modified to synchronise to the serial buffer data?

Best Reagrds,
Ksir

User avatar
Gert van Loo
Posts: 2487
Joined: Tue Aug 02, 2011 7:27 am
Contact: Website

Re: Scrambled Data in serial read from Bluetooth rfcomm

Fri Jan 27, 2017 4:33 pm

I need to get the entire packet of data (all 23 bytes) in one single call of the "serialReadData" function
In 'serialReadData' I suggest you hunt for the start, discarding bytes until you have it .
Then keep reading until you have 23 bytes which should be a packet and return that.
Here you have a choice: keep reading until you have 23 bytes (Which may lock-up your program)
or give up after a time/number tried and return an error status to your calling program.

Note that losing bytes because of the discarding, should only ever happen on your first call or after something went wrong.
But in general it is a good idea to allow for data loss or data errors in the whole program.

Return to “Troubleshooting”