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

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

 
image.png

其中,主控与零部件间及时通讯,零部件实时把状态上报给主控。当然,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.
  3. #import "GCDAsyncSocket.h"
  4. @property (nonatomic,strong) GCDAsyncSocket *clientSocket;
  5. @property (nonatomic,assign) BOOL connected;
  6. - (void)setSocketData
  7. {
  8. if (self.clientSocket && self.clientSocket.isConnected) {
  9. [self.clientSocket disconnect];
  10. self.clientSocket = nil;
  11. }
  12. self.clientSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
  13. NSError *error = nil;
  14. self.connected = [self.clientSocket connectToHost:@"你的地址" onPort:@"你的端口号" viaInterface:nil withTimeout:20 error:&error];
  15. }

连接成功之后会回调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. {
  7. NSLog(@"连接成功,连接主机信息 %@",sock);
  8. self.connected = YES;
  9. // 连接后,可读取服务端的数据
  10. [self.clientSocket readDataWithTimeout:-1 tag:1];
  11. }

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

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

连接成功了,下面读取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];
  8. NSLog(@"接收到的数据%@",data);
  9. }

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

 
image.png
 
image.png

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

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

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

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

10进制转16进制

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

16进制转为NSData

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

结束。谢谢看官!

iOS与硬件通讯(socket,data拼接,发送指令,解析指令)的更多相关文章

  1. [深入浅出Cocoa]iOS网络编程之Socket

    http://blog.csdn.net/kesalin/article/details/8798039 版权声明:本文为博主原创文章,未经博主允许不得转载.   目录(?)[+]   [深入浅出Co ...

  2. iOS实现XMPP通讯(二)XMPP编程

    项目概述 这是一个可以登录jabber账号,获取好友列表,并且能与好友进行聊天的项目. 使用的是第三方库XMPPFramework框架来实现XMPP通讯. 项目地址:XMPP-Project 项目准备 ...

  3. HTTP 笔记与总结(3 )socket 编程:发送 GET 请求

    使用 PHP + socket 模拟发送 HTTP GET 请求,过程是: ① 打开连接 ② 构造 GET 请求的数据:写入请求行.请求头信息.请求主体信息(GET 请求没有主体信息) ③ 发送 GE ...

  4. Socket.io各个发送消息的含义【发送对象范围】

    Socket.io各个发送消息的含义   // send to current request socket client socket.emit('message', "this is a ...

  5. iOS开发网络篇—Socket编程

    一.网络各个协议:TCP/IP.SOCKET.HTTP等 网络七层由下往上分别为物理层.数据链路层.网络层.传输层.会话层.表示层和应用层. 其中物理层.数据链路层和网络层通常被称作媒体层,是网络工程 ...

  6. iOS 网络编程:socket

    @import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/c ...

  7. 项目总结22:Java UDP Socket数据的发送和接收

    项目总结22:Java UDP Socket数据的发送和接收 1-先上demo 客户端(发送数据) package com.hs.pretest.udp; import java.io.IOExcep ...

  8. error: 'Can't connect to local MySQL server through socket '/data/3307/data/mysql.sock' (2)'

    centos7.5 重启mysql报错 问题: [root@db01-51 ~]# mysqladmin -uroot -p123 -S /data/3307/data/mysql.sock shut ...

  9. iOS开发过程中使用Core Data应避免的十个错误

    原文出处: informit   译文出处:cocoachina Core Data是苹果针对Mac和iOS平台开发的一个框架,主要用来储存数据.对很多开发者来说,Core Data比较容易入手,但很 ...

随机推荐

  1. 镶嵌数据集 Mosaic Dataset 的常见数据组织方式

    镶嵌数据集是ESRI公司推出一种用于管理海量影像数据的数据模型,定义在GeoDatabase数据模型中. 它的常见数据组织方式有两种: 1. 源镶嵌数据集 Source Mosaic Dataset ...

  2. 网络 TCP三次握手及滑动窗口

    三次握手客户端向服务器发出触发请求syn=1:因为这时还没有得到服务器的回应,所以ack=0服务器接收到客户端的触发请求,回复ack=1,表示已经接收到客户端的请求:同时服务器也向客户端发出触发请求, ...

  3. hibernate中指定非外键进行关联

    /** * 上级资源 */ @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "PARENT_ID", reference ...

  4. spring boot(9)-mybatis关联映射

    一对多 查询type表的某一条数据,并且要同时查出所有typeid与之配置的user,最终要得到一个以下类型的Type对象 public class Type { String id; String ...

  5. docker集群部署

    一.使用自定义网桥连接跨主机容器 要是Linux可以工作在网桥模式,必须安装网桥工具bridge-utils,运行命令:# yum install bridge-utils 查看桥连状态:# brct ...

  6. NodeJS做中转服务器,转发接口

    搬家后的博客地址:http://www.cnblogs.com/shihaibin821/p/7683752.html

  7. jQuery1.7版本之后的on方法

    之前就一直受这个问题的困扰,在jQuery1.7版本之后添加了on方法,之前就了解过,其优越性高于 live(),bind(),delegate()等方法,在此之前项目中想用这个来测试结果发现,居然动 ...

  8. Oracle 客户端库时引发 BadImageFormatException

    程序提示错误: 试加载 Oracle 客户端库时引发 BadImageFormatException.如果在安装 32 位 Oracle 客户端组件的情况下以 64 位模式运行,将出现此问题. 出现场 ...

  9. [翻译] CHTCollectionViewWaterfallLayout

    CHTCollectionViewWaterfallLayout https://github.com/chiahsien/CHTCollectionViewWaterfallLayout CHTCo ...

  10. [翻译] About Core Image

    About Core Image Core Image is an image processing and analysis technology designed to provide near ...