从我的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个字节。
答案 0 :(得分:0)
这是正常的预期行为。底层的串行硬件和软件无法知道您正在等待多少字节,或者完整的数据包是什么样的,所以它只是在数据传入时提供数据。您必须在目标中缓冲数据。 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上的issue中对这些内容进行了一些讨论。如果您对这个问题感兴趣,请随时添加您对该问题的意见和建议。