从我的arduino中,我正在将多字节数据编写为serial.print(" blah"),但在Objective-C,-serialPort:didReceiveData:
(由OrsSerialPort提供)中,只能得到这个数据1字节一次。有时,它会立即抓住2个字节,但绝不是全部4个字节。这是期望的吗?如果是这样,我该如何一次收到所有4个字节?
arduino:
void loop() {
Serial.print("blah");
delay(1000);
}
obj-c:
- (void)serialPort:(ORSSerialPort *)serialPort didReceiveData:(NSData *)data {
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"%@",string);
}
在此方法内设置一个断点,表明data
仅容纳1个字节。
这是正常的,预期的行为。基本的串行硬件和软件无法知道您正在等待多少个字符,或者是一个完整的数据包,因此它只是提供数据时提供的数据。您必须在目标 - C代码。从根本上讲,这很简单。创建一个可以用作缓冲区的NSMutableData
:
@property (strong) NSMutableData *incomingDataBuffer;
初始化它(例如,在-init
中):
_incomingDataBuffer = [[NSMutableData alloc] init];
然后,在您的-serialPort:didReceiveData:
中:
- (void)serialPort:(ORSSerialPort *)serialPort didReceiveData:(NSData *)data
{
[self.incomingDataBuffer appendData:data];
if ([self dataBufferHasCompletePacket]) { // Check to see if buffer contains a complete, valid packet
[self processReceivedDataPacket:self.incomingDataBuffer]; // Do whatever you need to do with the received data
[self.incomingDataBuffer replaceBytesInRange:NSMakeRange(0, [self.incomingDataBuffer length]) withBytes:NULL length:0]; // Clear data buffer
}
}
这是一个不错的开始。它存在一些缺陷,即它会停滞不前,并且永远不会发现如果例如损坏的数据包紧随电线,然后是有效的包装,或者串行电缆在数据包中间被拔下。这些缺陷可以通过设计良好的数据包格式的组合来解决,包括唯一的标头,校验和/或结束序列以及导致接收器重置其状态的末端序列和超时。
我已经想到了一些增强能力,可以在Orsserialport本身解决这个问题。在Github上,在此问题中对此内容进行了一些讨论。如果您感兴趣的话,请随时添加有关该问题的评论和建议。