经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » iOS » 查看文章
iOS与硬件通讯(socket,data拼接,发送指令)
来源:cnblogs  作者:王_聪  时间:2019/1/29 9:36:47  对本文有异议

最近项目中用到了iPad驱动硬件来工作,也就是智能硬件的实现。下面简单说下原理,详细说下socket,wifi通信,数据处理接收,发送,以及数据解析代码。

首先,来说下通信。因为硬件部件比较多,我们采取的是,iPad与主控板进行交换数据,主控板来与各硬件部件进行通信。看图:

 

 

其中,主控与零部件间及时通讯,零部件实时把状态上报给主控。当然,iPad与主控板也是及时通讯,主控需要每秒都上报给iPad各个硬件的当前状态,以供iPad可以实时监控各零部件并且显示不同的状态,比如“ipad上实时显示电冰箱的温度”。后面这黑体加粗才是我们iOS端要做的任务。涉及到
1.与主控建立连接,
2.并保持长链接,实时接收解析主控发来的零部件状态,
3.以及iPad给主控发指令来驱动硬件动作,比如“iPad发送指令让电灯关闭”。

与主控建立连接,我们用到的是GCDAsyncSocket这个类,github地址https://github.com/robbiehanson/CocoaAsyncSocket

  1. //  Created by 王聪 
  2. //  Copyright ? 2018年 apple. All rights reserved.#import "GCDAsyncSocket.h"@property (nonatomic,strong) GCDAsyncSocket *clientSocket;@property (nonatomic,assign) BOOL connected;
  3.  
  4. - (void)setSocketData
  5. {    if (self.clientSocket && self.clientSocket.isConnected) {
  6.         [self.clientSocket disconnect];self.clientSocket = nil;
  7.     }self.clientSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];    NSError *error = nil;self.connected =  [self.clientSocket connectToHost:@"你的地址" onPort:@"你的端口号" viaInterface:nil withTimeout:20 error:&error];
  8. }

连接成功之后会回调GCDAsyncSocketDelegate的连接成功的方法如下。

  1. /**
  2.  * Called when a socket connects and is ready for reading and writing.
  3.  * The host parameter will be an IP address, not a DNS name.
  4. **/
  5. - (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port
  6. {NSLog(@"连接成功,连接主机信息 %@",sock);self.connected = YES;// 连接后,可读取服务端的数据
  7.     [self.clientSocket readDataWithTimeout:-1 tag:1];
  8. }

相对的,断开连接会调用如下回调

  1. - (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err
  2. {NSLog(@"tcp连接断开,%@",err);self.connected = NO;
  3. }

连接成功了,下面读取data

  1. /**
  2.  * Called when a socket has completed reading the requested data into memory.
  3.  * Not called if there is an error.
  4. **/
  5. - (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
  6. {
  7.     [APPDELEGATE.clientSocket readDataWithTimeout:- 1 tag:1];NSLog(@"接收到的数据%@",data);
  8. }

接收到数据了,下面我们来发送指令控制硬件。
先来看下我们与主控约定的协议格式。

 

 

image.png

 

image.png

接下来看代码怎么来发送这个协议数据到主控。

  1. //发送数据的方法
  2. - (void)writeData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag;

那么我们就要构造出这个data,就可以实现发送数据到主控了。
下面介绍两种生成data的方法。

  1. //发送指令
  2. + (void)sendData{NSData *data = [SendDataOp returnSetData];NSLog(@"发送数据Cmd_set%@----------", data.description);
  3.     [APPDELEGATE.clientSocket writeData:data withTimeout:-1 tag:0];
  4. }//构造data
  5. + (NSData *)returnSetData
  6. {//方法1,创建bytes数组//    Byte bytes[8] = {0x11,0xff,0x11,0xff,0x03,0x02,0x01,0x28};//40转为26进制为0x28//    //想操作其中某位可以用下标找到并修改,比如想把最后一位"亮度"改为5//    bytes[7] = 0x05;//    NSData *data = [[NSData alloc] initWithBytes:bytes length:sizeof(bytes)];    
  7.     //方法2,直接拼接dataNSMutableData *data = [NSMutableData data];//表头char head1 = 0x11;
  8.     [data appendBytes:&head1 length:1];char head2 = 0xff;
  9.     [data appendBytes:&head2 length:1];char head3 = 0x11;
  10.     [data appendBytes:&head3 length:1];char head4 = 0xff;
  11.     [data appendBytes:&head4 length:1];    //长度char length = 0x03;
  12.     [data appendBytes:&length length:1];//灯泡号char num = 0x02;
  13.     [data appendBytes:&num length:1];    //命令字char cmd = 0x01;
  14.     [data appendBytes:&cmd length:1];    //灯泡的亮度int lightness = 40;
  15.     [data appendData:[mathUtil convertHexStrToData:[mathUtil ToHex:lightness]]];//这一步是把亮度40转化为16进制字符串,然后16进制字符串转化为NSData。下面粘上这一部分转换的方法//推荐方法2,直接可以调用方法转为NSData,而方法1需要手动将40换算为28再拼上去。    return data;//即拼成了11 ff 11 ff 03 02 01 28
  16. }

10进制转16进制

  1. +(NSString *)ToHex:(long long int)tmpid
  2.  
  3. {    NSString *nLetterValue;    NSString *str =@"";    long long int ttmpig;    for (int i =0; i<9; i++) {
  4.         
  5.         ttmpig=tmpid%16;
  6.         
  7.         tmpid=tmpid/16;        switch (ttmpig)
  8.         
  9.         {                case 10:
  10.                 
  11.                 nLetterValue =@"A";break;                case 11:
  12.                 
  13.                 nLetterValue =@"B";break;                case 12:
  14.                 
  15.                 nLetterValue =@"C";break;                case 13:
  16.                 
  17.                 nLetterValue =@"D";break;                case 14:
  18.                 
  19.                 nLetterValue =@"E";break;                case 15:
  20.                 
  21.                 nLetterValue =@"F";break;                default:nLetterValue=[[NSString alloc]initWithFormat:@"%lli",ttmpig];
  22.         }
  23.         str = [nLetterValue stringByAppendingString:str];        if (tmpid == 0) {            break;
  24.             
  25.         }
  26.     }return str;
  27. }

16进制转为NSData

  1. + (NSData *)convertHexStrToData:(NSString *)str
  2. {if (!str || [str length] == 0) {return nil;
  3.     }    NSMutableData *hexData = [[NSMutableData alloc] initWithCapacity:20];NSRange range;if ([str length] % 2 == 0) {
  4.         range = NSMakeRange(0, 2);
  5.     } else {
  6.         range = NSMakeRange(0, 1);
  7.     }for (NSInteger i = range.location; i < [str length]; i += 2) {unsigned int anInt;NSString *hexCharStr = [str substringWithRange:range];NSScanner *scanner = [[NSScanner alloc] initWithString:hexCharStr];
  8.         
  9.         [scanner scanHexInt:&anInt];NSData *entity = [[NSData alloc] initWithBytes:&anInt length:1];
  10.         [hexData appendData:entity];
  11.         
  12.         range.location += range.length;
  13.         range.length = 2;
  14.     }return hexData;
  15. }

结束。谢谢看官!

原文链接:http://www.cnblogs.com/wangcongiOS/p/wangcong.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号