2014-02-06 50 views
1

從我的Arduino中,我正在使用Serial.print(「blah」)將多字節數據寫入串行,但在Objective-C中,-serialPort:didReceiveData:(由ORSSerialPort提供)一次只能獲取1個字節的數據。有時候,它會一次抓取2個字節,但從來沒有全部4個。這是預期的嗎?如果是這樣,我怎樣才能讓它一次接收全部4個字節?爲什麼ORSSerialPort serialPort:didReceiveData NSData只有單字節?

阿爾杜伊諾:

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

這是正常的,預期的行爲。底層的串行硬件和軟件無法知道您等待的字節數或完整的數據包的樣子,因此只需傳輸數據即可。您必須將數據緩衝在Objective- C代碼。基本上,這很簡單。在-serialPort:didReceiveData:

_incomingDataBuffer = [[NSMutableData alloc] init]; 

然後:創建一個NSMutableData可以作爲緩衝使用:

@property (strong) NSMutableData *incomingDataBuffer; 

初始化(在-init如)

- (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上有一些討論。如果您對此感興趣,請隨時在此問題上添加您的意見和建議。

+0

感謝您的解釋和建議的解決方案。我可能會加入一個抽象層來緩衝「數據包」。當我有一些時間的時候,我會在GitHub鏈接中對此進行評論。 – 695Multimedia