последовательная связь в iOS

Я работаю над своим первым приложением. Это приложение предназначено для связи с внешним оборудованием, используя кабель, который я получил от RedPark. Они предоставляют библиотеку, которая имеет несколько функций, удобных в использовании. Теперь мне нужно потребовать таблицу 9 * 9 с номером float в ней, отправив команду для ее запроса.

Для чтения используется функция, называемая (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 номеров.

Может ли кто-нибудь дать мне несколько советов по этому поводу? Заранее большое спасибо.

Обновление: по отладке, я видел, что метод чтения читает только 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; } } 

    ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ. У меня нет этого кабеля, поэтому я не могу его протестировать, и, возможно, код не работает. Но это просто слепая демонстрация, как я это сделаю. Это код с поддержкой 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