2012-10-11 50 views
2

我正在開發我的第一款應用程序。這個應用程序是使用我從RedPark獲得的電纜與外部硬件進行通信。 他們提供了一個庫,它有幾個易於使用的功能。 現在我需要通過發送一個命令來請求一個帶有浮點數的9 * 9表格。iOS中的串行通信

一個名爲(void)readBytesAvailable的函數用於讀取,並且它是事件驅動的。 起初,我用的NSMutableArray把表:

for (int i=0; i<81; i++) { 
     NSNumber *number = [NSNumber numberWithFloat:rxLoopBuffer[i]]; 
     [self.arrayRead addObject:number]; 
     NSLog(@"%f",[number doubleValue]); 
    } 

但是從控制檯,它只得到了11號,其餘70均爲0。 我想也許我需要首先獲得所有81個字節,然後將其推入陣,所以我做了一些變化:

NSMutableData *dataRead = [[NSMutableData alloc]initWithBytes:&rxLoopBuff length:81]; 
    unsigned char buffer[100]; 
    [dataRead getBytes:buffer]; 
    if (!self.arrayRead) { 
    [self.arrayRead removeAllObjects]; 
    } 
    for (int i=0; i<81; i++) { 
    NSNumber *number = [NSNumber numberWithFloat:buffer[i]]; 
    [self.arrayRead addObject:number]; 
    NSLog(@"%f",[number doubleValue]); 
    } 

但它仍然得到11個數字。

任何人都可以給我一些建議嗎? 非常感謝。

更新: 通過調試,我看到read方法一次最多隻能讀取16個字節。我正在下載由同一家公司提供的新版本庫,以瞭解我可以做什麼。 的方法代碼的一部分:

- (void) readBytesAvailable:(UInt32)numBytes 
    { 
    int bytesRead; 
    BOOL res = NO; 

// Read the data out 
bytesRead = [rscMgr read:(rxLoopBuff+loopbackCount) length:numBytes]; 
rxCount += bytesRead; 

    //NSLog(@"Read %i, total=%i\n", bytesRead, rxCount); 
    if (this is the package I need) 
    { 
     //do something; 
    } 

    } 
+0

如何填寫'rxLoopBuff'?與串口通信的代碼在哪裏?該代碼只讀取'rxLoopBuff'並從緩衝區創建數字。 – robertvojta

+0

你確定所有的數據都在同一個數據包中傳輸嗎?我的第一個假設是,或者所有的數據都沒有被傳輸。請嘗試將電纜連接到計算機,並使用簡單的終端程序查看是否得到相同的結果。 – Brian

+0

@RobertVojta嗨,根據我的理解,rxLoopBuff充滿了自己。當有數據進入readBytesAvailable時會自動調用。但是你的評論確實提醒了我。所以我打印出每次收到的所有字節和計數,結果我每次只收到最多16個字節,有時候是3或7次。我把這些代碼放在我的文章中。 – user1491987

回答

0

免責聲明 - 我沒有這個線,所以,我無法測試它,也許代碼不起作用。但這只是盲目的演示,我該怎麼做。它是ARC啓用的代碼。

SerialPortCommunication.h

#import <Foundation/Foundation.h> 

@interface SerialPortCommunication : NSObject 

- (void)readBytes:(UInt32)numberOfBytes 
      success:(void(^)(NSData *data))success 
      failure:(void(^)(NSData *dataReadSoFar, NSError *error))failure; 

@end 

SerialPortCommunication.m

#import "SerialPortCommunication.h" 
#import "RscMgr.h" 

#define BUFFER_SIZE 128 

@interface SerialPortCommunication() <RscMgrDelegate> { 
    RscMgr *_rscMgr;   // Resource Manager 
    BOOL _portAvailable;  // Can we use port? 
    NSMutableData *_data;  // Buffer for data 
    UInt32 _totalBytesToRead; // Number of total bytes to read 

    // Success block to call 
    void(^ _successBlock)(NSData *data); 

    // Failure block to call 
    void(^ _failureBlock)(NSData *dataReadSoFar, NSError *error); 

    UInt8 *_buffer; 
} 

@end 

@implementation SerialPortCommunication 

#pragma mark - Lifecycle 

- (void)dealloc { 
    free(_buffer); 
} 

- (id)init { 
    self = [super init]; 
    if (self) { 
    _rscMgr = [[RscMgr alloc] init]; 
    [_rscMgr setDelegate:self]; 

    _buffer = malloc(BUFFER_SIZE * sizeof(UInt8)); 
    // DO SERIAL PORT CONFIGURATION HERE 
    } 
    return self; 
} 

#pragma mark - Public 

- (void)readBytes:(UInt32)numberOfBytes 
      success:(void(^)(NSData *data))success 
      failure:(void(^)(NSData *dataReadSoFar, NSError *error))failure { 
    if (! _portAvailable) { 
    if (failure) { 
     // Create some NSError that port is not available 
     failure(nil, nil); 
     return; 
    } 
    } 

    if (_data) { 
    if (failure) { 
     // Create some NSError that port is in use 
     failure(nil, nil); 
     return; 
    } 
    } 

    _failureBlock = failure; 
    _successBlock = success; 
    _totalBytesToRead = numberOfBytes; 

    _data = [NSMutableData data]; 
    // Now we're waiting for delegate methods 
} 

#pragma mark - RscMgrDelegate 

- (void)cableConnected:(NSString *)protocol { 
    // From now on you can use serial port 
    _portAvailable = YES; 
    [_rscMgr open]; 
} 

- (void)cableDisconnected { 
    // From now on you can't user serial port 
    _portAvailable = NO; 

    // Ouch, we can't read, fire failure 
    if (_failureBlock) { 
    // Create NSError which describes cable disconnection 
    _failureBlock(_data, nil); 
    } 

    // Our task ends here 
    _successBlock = nil; 
    _failureBlock = nil; 
    _data = nil; 
    _totalBytesToRead = 0; 
} 

- (void)portStatusChanged { 
    // Check status if everything's alright and you can still user serial port 
    // Set _portAvailable accordingly 

    // Replace if (NO) with condition if port is still alright and we can read 
    if (NO) { 
    if (_failureBlock) { 
     // Create NSError which describes status change and we can't use serial port 
     _failureBlock(_data, nil); 
    } 

    // Our task ends here 
    _successBlock = nil; 
    _failureBlock = nil; 
    _data = nil; 
    _totalBytesToRead = 0; 

    _portAvailable = NO; 
    } else { 
    _portAvailable = YES; 
    } 
} 

- (void)readBytesAvailable:(UInt32)length { 
    if (! _data) { 
    // Here no one's interested in received data 
    // So you can decide if you want to save them for later use or trash them 
    // We are going to trash them 
    [_rscMgr read:_buffer length:MIN(BUFFER_SIZE, length)]; 
    return; 
    } 

    UInt32 bytesToRead; 

    // First of all, we can't read more than our buffer size 
    bytesToRead = MIN(BUFFER_SIZE, length); 

    // Also it's enough to read only what user requested 
    UInt32 remainingBytes = _totalBytesToRead - _data.length; 
    bytesToRead = MIN(bytesToRead, remainingBytes); 

    // Now read bytes 
    UInt32 bytesRead = [_rscMgr read:_buffer length:bytesToRead]; 
    if (bytesRead > 0) { 
    [_data appendBytes:_buffer length:bytesRead]; 
    } 

    if (_data.length == _totalBytesToRead) { 
    if (_successBlock) { 
     _successBlock(_data); 
    } 

    _successBlock = nil; 
    _failureBlock = nil; 
    _data = nil; 
    _totalBytesToRead = 0; 
    } 
} 

@end 

串行端口使用

這裏就是我會用我的課。

#import "SerialPortUser.h" 
#import "SerialPortCommunication.h" 

@interface SerialPortUser() { 
    SerialPortCommunication *_serial; 
} 

@end 

@implementation SerialPortUser 

- (id)init { 
    self = [super init]; 
    if (self) { 
    _serial = [[SerialPortCommunication alloc] init]; 
    } 
    return self; 
} 

- (void)getData { 
    [_serial readBytes:81 
      success:^(NSData *data) { 
       // Here you have NSData with 81 bytes for sure 
      } 
      failure:^(NSData *dataReadSoFar, NSError *error) { 
       // Here you have NSData with dataReadSoFar.length bytes only 
       // read so far, because an error happens 
       // And error is in NSError *error 
      }]; 
} 

@end