找回密码
 注册帐号

扫一扫,访问微社区

Like Unity串口通信详解,附源码!

14
回复
2388
查看
[ 复制链接 ]
排名
64951
昨日变化

5

主题

44

帖子

818

积分

Rank: 9Rank: 9Rank: 9

UID
354297
好友
0
蛮牛币
551
威望
0
注册时间
2020-11-3
在线时间
763 小时
最后登录
2021-2-28
2020-11-5 00:13:55 显示全部楼层 阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?注册帐号

x
【前言

实习生第一份工作做的是街机游戏,看到自己开发游戏给很多小孩子玩,爷的青春也就结束了,因为这一片都是做街机、VR,所以会接触到很多关于硬件设备的通信,到现在为止,还是挺喜欢这种基于硬件的游戏开发,做街机的时候,没做多久,所以当初最遗憾的事情就是没有学会串口通信,到现在为止,串口觉得也就是一个收发消息的集成类。

懒的话可以直接下载使用,直接拖进Asset里,附上码云链接::https://gitee.com/likeji/unity-serial-communication


【对于刚接触串口的同学们来说

一定要了解串口的几个属性和串口接收助手的使用,串口的属性在串口助手面板也有所体现,需要设置才能打开串口,完成连接。
如果没有串口设备想了解串口通信的话,可以使用串口模拟消息接收,相关链接:https://www.hd2y.net/archives/the-debugging-and-development-of-serial-communication

以下我们都是通过实际开发串口通信来说明:
串口的几个属性,一定要与之对应才能正确连接,一般来说,硬件没有做特殊设置,只需要设置串口名,其他保持默认就行了





串口接收助手下载链接:链接:https://pan.baidu.com/s/1aPfa7u_RKvfaGicMno3Vfg
提取码:ui2r

在做项目时,先使用串口接收助手方便接收串口数据,这样可以用现成的工具先检测串口设备的收发信息的状况,如果通信良好,则开始程序的编写了。


【串口通信的程序编写,无码何以平天下,Show Me Code~

一.先展示一下我们的手柄(有两个按钮+前后左右的遥感功能)


二.插上我们的串口设备之后,然后在我的电脑-属性-设备管理器中查看当前插入的串口设备号(COM*),当前我的串口设备名是COM3



三.开始编写串口通信的类
1.首先定义我们的设备的输入按钮,方便后面判断输入调用
public enum KeyType { 圆形按钮 方形按钮 前 后 左 右 }//按钮   
public KeyType keyType;

2.定义我们的串口属性变量,建议串口属性使用配置文件来管理方便适配不同的串口设备

public string portName =\\\"COM3\\\";
public int baudRate = 9600;
public int dataBits = 8;
public StopBits stopBits = StopBits.None;
public Parity parity = Parity.None;


3.Start里打开串口和开启线程处理串口消息

void Start()
{
OpenPort();//打开串口
thread_reviceData = new Thread(new ThreadStart(DataReviceThread));
thread_reviceData.Start();//开启接收线程
}


4.打开串口和关闭串口的方法,关闭串口一般用于关闭程序之后调用
void OpenPort()
{
print(\\\"打开串口\\\");
try
{
serialPort = new SerialPort(portName baudRate parity dataBits stopBits);
serialPort.Open();
}
catch (System.Exception ex)
{
print(\\\"串口打开异常:\\\"+ex);
}
}


void OnApplicationQuit()
{
ClosePort();
}


void ClosePort()
{
print(\\\\\\\"关闭串口\\\\\\\");
try
{
serialPort.Close();
thread_reviceData.Abort();
}
catch (System.Exception ex)
{
print(\\\"串口关闭异常:\\\" + ex);
}
}


5.发送消息到串口测试,OnGUI方法用作发送测试,不用时可以自行删除OnGUI方法

#region 发送数据
    public void WriteData(string dataStr)
    {
        if (sp.IsOpen)
        {
            sp.Write(dataStr);
        }
    }
    void OnGUI()
    {
        message = GUILayout.TextField(message GUILayout.Width(200) GUILayout.Height(50));
        if (GUILayout.Button(\\\"发送输入信息到串口对象\\\"GUILayout.Width(200)GUILayout.Height(50)))
        {
            WriteData(message);
        }
        string test = \\\"AA BB 01 12345 01AB 0@ab 发送\\\";//测试字符串
        if (GUILayout.Button(\\\"发送默认信息到串口对象\\\" GUILayout.Width(200)GUILayout.Height(50)))
        {
            WriteData(test);
        }
    }
    #endregion

6.多线程接收串口消息方法并将解析的消息放入队列池

void DataReviceThread()
{
byte[] bytes_read = new byte[1024];
int count = 0;
while (serialPort != null && serialPort.IsOpen)
{
try
{
count = serialPort.Read(bytes_read 0 bytes_read.Length);//读取消息并获取字节数
if (count == 0)
continue;
else
{

//===================else部分就是接收到的串口消息,关于解析也是在这个逻辑之下,由于每种协议的制定和解析各不相同,这里就留给读者自行分析解析数据了
//print(\\\"字节数量:\\\" + count);
//if (count == 6)
//{
// StringBuilder stringBuilder = new StringBuilder();
// for (int i = 0; i < count; i++)
// {
// stringBuilder.Append(Convert.ToString(bytes_read));
// }
// str_data = stringBuilder.ToString();
// //print(str_data);
// queue_data.Enqueue(str_data);//将接收的消息放入队列
//}
}
}
catch (Exception ex)
{
print(\\\"串口读取数据异常:\\\" + ex);
}
Thread.Sleep(10);
}
}//数据接收的多线程


                           
                 图文无关

7.将解析的数据做处理,用bool来检测我们的按键输入,以便于我们转换成输入的方法
public bool[] KeyClickState = new bool[6];//手柄按钮点击的状态

void Update()
{
if (queue_data.Count > 0)
{
queue_data.Dequeue();//清除第一条队列
switch (str_data)
{
case \\\"255142542515\\\"://圆形
KeyClickState[0] = true;
//print(\\\"圆形按钮\\\");
break;
case \\\"255152542504\\\"://方形
KeyClickState[1] = true;
//print(\\\"方形按钮\\\");
break;
case \\\"255182542479\\\"://前
KeyClickState[2] = true;
//print(\\\"前\\\");
break;
case\\\"255172542486\\\"://后
KeyClickState[3] = true;
//print(\\\"后\\\");
break;
case\\\"255162542497\\\"://左
KeyClickState[4] = true;
//print(\\\"左\\\");
break;
case\\\"255112542540\\\"://右
KeyClickState[5] = true;
//print(\\\"右\\\");
break;
default:
break;
}
}
else
{
for (int i = 0; i < KeyClickState.Length; i++)
{
KeyClickState = false;//重置所有的按钮状态
}
}
}


8.按下判定和任意键按钮判定
public bool InputKeyClickDown(KeyType keyType)
{
return KeyClickState[(int)keyType];
}//如果按下按钮,由于update刷新bool为false,所以只返回一次true



public bool anyKeyDown()
{
count_key = Enum.GetNames(keyType.GetType()).Length;//获取枚举的长度
for (int i = 0; i < count_key; i++)
{
if (KeyClickState)
{
return KeyClickState;
}
}
return false;
}//如果按下了任意的按键



【调用测试
void Update()
{
if(SerialPortManagr.Instance.InputKeyClickDown(KeyType.圆形按钮))
{
print(\\\"点击了圆形按钮\\\");
}


if (SerialPortManagr.Instance.anyKeyDown())
{
foreach (KeyType type in Enum.GetValues(typeof(KeyType)))
{
if (SerialPortManagr.Instance.InputKeyClickDown(type))
{
print(\\\"点击了\\\" + type);
}
}
}
}

【最后想说


这两天发表蛮牛,从博客复制过来全是格式错误,搞到了一点多才差不多理清楚,身心俱疲,明早还要一早起来去出差,写专栏不易,且行且珍惜,感谢看到最后的朋友,如果想要源码记得看开头的的前言部分,临表涕零,不知所言!











回复

使用道具 举报

4四处流浪
310/500
排名
64951
昨日变化

0

主题

45

帖子

310

积分

Rank: 4

UID
327914
好友
0
蛮牛币
242
威望
0
注册时间
2019-7-23
在线时间
263 小时
最后登录
2021-2-26
2020-11-5 10:57:57 显示全部楼层
感谢分享
回复

使用道具 举报

4四处流浪
332/500
排名
48147
昨日变化

0

主题

55

帖子

332

积分

Rank: 4

UID
297600
好友
1
蛮牛币
7
威望
0
注册时间
2018-9-19
在线时间
273 小时
最后登录
2020-12-28
2020-11-5 19:29:49 显示全部楼层
感谢大佬分享
回复

使用道具 举报

7日久生情
1991/5000
排名
4166
昨日变化

19

主题

460

帖子

1991

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
18541
好友
8
蛮牛币
985
威望
0
注册时间
2014-3-22
在线时间
1154 小时
最后登录
2021-2-25
2020-11-6 08:43:36 显示全部楼层
感谢分享
回复

使用道具 举报

排名
64951
昨日变化

5

主题

44

帖子

818

积分

Rank: 9Rank: 9Rank: 9

UID
354297
好友
0
蛮牛币
551
威望
0
注册时间
2020-11-3
在线时间
763 小时
最后登录
2021-2-28
楼主 2020-11-6 14:15:51 显示全部楼层

谢谢支持
回复 支持 反对

使用道具 举报

排名
64951
昨日变化

5

主题

44

帖子

818

积分

Rank: 9Rank: 9Rank: 9

UID
354297
好友
0
蛮牛币
551
威望
0
注册时间
2020-11-3
在线时间
763 小时
最后登录
2021-2-28
楼主 2020-11-10 11:25:51 显示全部楼层
帖子的代码里出现 \\\"\\\" 是由于字符串“”在网页中发布引起的,暂时不好修改,对比代码时注意一下!
回复 支持 反对

使用道具 举报

5熟悉之中
508/1000
排名
9110
昨日变化

2

主题

169

帖子

508

积分

Rank: 5Rank: 5

UID
208862
好友
0
蛮牛币
246
威望
0
注册时间
2017-2-27
在线时间
219 小时
最后登录
2021-2-27
2020-11-17 21:03:43 显示全部楼层
“到现在为止,还是挺喜欢这种基于硬件的游戏开发,做街机的时候,没做多久,所以当初最遗憾的事情就是没有学会串口通信,到现在为止,串口觉得也就是一个收发消息的集成类”
回复 支持 反对

使用道具 举报

5熟悉之中
508/1000
排名
9110
昨日变化

2

主题

169

帖子

508

积分

Rank: 5Rank: 5

UID
208862
好友
0
蛮牛币
246
威望
0
注册时间
2017-2-27
在线时间
219 小时
最后登录
2021-2-27
2020-11-17 21:05:08 显示全部楼层

“到现在为止,还是挺喜欢这种基于硬件的游戏开发,做街机的时候,没做多久,所以当初最遗憾的事情就是没有学会串口通信,到现在为止,串口觉得也就是一个收发消息的集成类”---------------------------所以,最后我想知道,你学会串口通信了吗?串口只是一个收发消息的集成类吗?
回复 支持 反对

使用道具 举报

排名
64951
昨日变化

5

主题

44

帖子

818

积分

Rank: 9Rank: 9Rank: 9

UID
354297
好友
0
蛮牛币
551
威望
0
注册时间
2020-11-3
在线时间
763 小时
最后登录
2021-2-28
楼主 2020-11-19 16:08:58 显示全部楼层
eha123 发表于 2020-11-17 21:05
“到现在为止,还是挺喜欢这种基于硬件的游戏开发,做街机的时候,没做多久,所以当初最遗憾的事情就是没 ...

那你说说看,乐意请教
回复 支持 反对

使用道具 举报

排名
64951
昨日变化

0

主题

8

帖子

34

积分

Rank: 1

UID
264079
好友
0
蛮牛币
8
威望
0
注册时间
2018-1-12
在线时间
24 小时
最后登录
2020-12-16
2020-12-11 14:42:25 显示全部楼层
留个脚印
回复

使用道具 举报

3偶尔光临
286/300
排名
10111
昨日变化

0

主题

83

帖子

286

积分

Rank: 3Rank: 3Rank: 3

UID
191422
好友
0
蛮牛币
506
威望
0
注册时间
2016-12-12
在线时间
95 小时
最后登录
2021-1-18
2020-12-22 12:16:42 显示全部楼层
感谢分享
回复

使用道具 举报

7日久生情
1636/5000
排名
3598
昨日变化

0

主题

107

帖子

1636

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
71644
好友
0
蛮牛币
2694
威望
0
注册时间
2015-1-28
在线时间
1113 小时
最后登录
2021-2-26
2020-12-29 16:55:09 显示全部楼层
感谢分享!!!
回复

使用道具 举报

5熟悉之中
682/1000
排名
48147
昨日变化

0

主题

275

帖子

682

积分

Rank: 5Rank: 5

UID
208145
好友
0
蛮牛币
1307
威望
0
注册时间
2017-6-23
在线时间
403 小时
最后登录
2021-2-28
2021-1-6 17:54:16 显示全部楼层
66666666666666
回复

使用道具 举报

3偶尔光临
249/300
排名
9487
昨日变化

0

主题

37

帖子

249

积分

Rank: 3Rank: 3Rank: 3

UID
179290
好友
0
蛮牛币
3
威望
0
注册时间
2016-10-29
在线时间
92 小时
最后登录
2021-1-10
2021-1-7 16:18:32 显示全部楼层
写得太好了  专业!!!
回复 支持 反对

使用道具 举报

2初来乍到
149/150
排名
11659
昨日变化
329

0

主题

24

帖子

149

积分

Rank: 2Rank: 2

UID
355858
好友
0
蛮牛币
873
威望
0
注册时间
2021-1-12
在线时间
39 小时
最后登录
2021-2-28
2021-1-15 10:49:36 显示全部楼层
感谢分享666666666
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册帐号

本版积分规则