PDA

View Full Version : [Resolved] Data over bluetooth using RFCOMMChannel is split up incorrectly




Tweetdezweet
May 16, 2013, 04:27 AM
Hi all, I am new to objective-c and mostly have experience in COBOL and Java.
As part of my internship project I have to connect a Mac computer with a custom build device over bluetooth.
All commands are sent through a bi-directional serial connection.
(9600 baud, 8 bit, no parity, no handshake)

The documentation on bluetooth was rather sparse but I did manage to get the devices to pair.
The most useful example I copied and tweaked as needed I found here (https://gist.github.com/crazycoder1999/3139668).

On the Mac I am receiving data from the other device but it splits up the data incorrectly.
For instance when the state of the device changes it sends the following command over bluetooth:
w31CRLF, where w stands for state change and 31 are the parameters and CRLF is a Carriage Return followed by a LineFeed.

When I log the incoming data using the rfcommChannelData delegate method it only takes the alphanumeric value and logs the numerical + Carriage return separately, following by the LineFeed as in the following output in the console:


2013-05-15 16:56:20.581 TimeBurger[4144:303] received: w (1)
2013-05-15 16:56:20.589 TimeBurger[4144:303] received: 33
(4)
2013-05-15 16:56:21.568 TimeBurger[4144:303] received: w (1)
2013-05-15 16:56:21.569 TimeBurger[4144:303] received: 31
(4)
2013-05-15 16:56:22.190 TimeBurger[4144:303] received: w (1)
2013-05-15 16:56:22.191 TimeBurger[4144:303] received: 21
(4)



note that I added the length passed to rfcommChannelData in the log to doublecheck the incorrect splitting up

the openConnection delegate method as I have it atm:

//Open the connection.
-(BOOL) openConnection:(BluetoothRFCOMMChannelID *) chanId{
IOBluetoothRFCOMMChannel *channel;
if ([_btDevice openRFCOMMChannelAsync:&channel withChannelID:*chanId delegate:self] != kIOReturnSuccess) { // after connection it is established.. the delegates methoed are triggered.
NSLog(@"Couldn't open channel");
return NO;
}
[channel setSerialParameters: 9600 dataBits: 8 parity: kBluetoothRFCOMMParityTypeNoParity stopBits: 2];
[channel closeChannel];
return YES;
}



the rfcommChannelData delegate method:

//reading data from rfcomm
- (void)rfcommChannelData:(IOBluetoothRFCOMMChannel*)rfcommChannel data:(void *)dataPointer length:(size_t)dataLength {
NSString *newStr = [[NSString alloc] initWithBytes:dataPointer length:dataLength encoding:NSUTF8StringEncoding];

NSLog(@"received: %@ (%zu)",newStr, dataLength);

// NSLog(@"received lengt: %zu",dataLength);
}


I have used the following encoding types as well during test but with the same result:
NSASCIIStringEncoding
NSUTF8StringEncoding
NSWindowsCP1250StringEncoding

I have spend a lot of time looking for a solution over the past two days so I would truely appreciate any help



robbieduncan
May 16, 2013, 05:27 AM
What makes you so sure the device is not sending the string split as you see it receiving? Or perhaps this is simply timing: the Mac layer may split based on time. Can you not simply accumulate the string until the CRLF terminator is seen?

Tweetdezweet
May 16, 2013, 05:41 AM
What makes you so sure the device is not sending the string split as you see it receiving? Or perhaps this is simply timing: the Mac layer may split based on time. Can you not simply accumulate the string until the CRLF terminator is seen?

When I pair the device with my macbook and look for incoming commands by using the screen command in a terminal window I get the command without any splitting up.

Accumulating the string until the CRLF terminator is seen is an option but I was hoping for a more "elegant" solution.

Is there a way to determine if it is a timing issue and if so, is there a way to influence that timing?

thx for your quick answer :)

robbieduncan
May 16, 2013, 05:49 AM
Erm the screen command is probably just echoing exactly what comes in.

So if it receives two data packets only one of which has a CRLF at the end this will get printed on the same line. So this does not prove that there is any different behavior from what you are seeing. Essentially it's doing the accumulation on screen...

Unless you can alter the time the Bluetooth stack waits for more data before passing that to you there is no way. Given a long enough string before CRLF you'd always see this so the correct answer is for you to accumulate and split on CRLF.

Tweetdezweet
May 16, 2013, 05:58 AM
oki thx, in that case I am going to accumulate and split on CRLF

really awesome to get such a fast reply after 2 frustrating days of googling :)

robbieduncan
May 16, 2013, 06:49 AM
oki thx, in that case I am going to accumulate and split on CRLF

really awesome to get such a fast reply after 2 frustrating days of googling :)

Not a problem: I did some programming with the Bluetooth framework way back in the day so am familiar with the lack of examples!