为什么ORSSERIALPORT SERIALPORT:DIDRECEIVEDATA NSDATA只有单个字节



从我的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上,在此问题中对此内容进行了一些讨论。如果您感兴趣的话,请随时添加有关该问题的评论和建议。

最新更新