1

在我的 Arduino 中,我正在使用 Serial.print("blah") 将多字节数据写入串行,但在 Objective-C 中,-serialPort:didReceiveData:(由 ORSSerialPort 提供)一次只能获取 1 个字节的数据。有时,它会一次抓取 2 个字节,但绝不会全部抓取 4 个字节。这是预期的吗?如果是这样,我怎样才能让它一次接收所有 4 个字节?

阿杜诺:

void loop() {
    Serial.print("blah");
    delay(1000);
}

对象-C:

- (void)serialPort:(ORSSerialPort *)serialPort didReceiveData:(NSData *)data {
   NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
   NSLog(@"%@",string);
}

在这个方法中设置一个断点表明data它只保存 1 个字节。

4

1 回答 1

0

这是正常的预期行为。底层串行硬件和软件无法知道您正在等待多少字节,或者一个完整的数据包是什么样的,因此它只是在数据进入时提供数据。您必须在 Objective- 中缓冲数据C 代码。从根本上说,这非常简单。创建一个NSMutableData可以用作缓冲区的:

@property (strong) NSMutableData *incomingDataBuffer;

初始化它(例如 in -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 上的这个问题中有一些关于这些东西的讨论。如果您对此感兴趣,请随时添加您对该问题的意见和建议。

于 2014-02-06T16:20:01.010 回答