Skip to content

Commit

Permalink
更新AutoUI到V0.032 加入串口通信组件
Browse files Browse the repository at this point in the history
  • Loading branch information
Auto committed Apr 23, 2021
1 parent 3efb78a commit 4872481
Show file tree
Hide file tree
Showing 7 changed files with 293 additions and 9 deletions.
12 changes: 9 additions & 3 deletions Assets/AutoUI/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@
## 简介
- **AutoUI框架**来组织**页面**切换的通用逻辑。
- 只需定制每个**页面**的业务逻辑内容,将页面的切换交给框架来处理。
- *当前版本:* **AutoUI-V0.031**
- *当前版本:* **AutoUI-V0.032**
- 更新内容:
- 加入**缓冲池**来优化打开和关闭面板时的性能开销。(打开过的页面会进入缓冲池。缓冲池会占用一定的显存和内存,来缓存页面加速页面加载。加入缓冲池能有效的解决页面切换时的性能开销以解决瞬时性能开销暴涨导致的程序崩溃。)
- 加入缓冲池不影响程序接口,按照事例场景中添加一个PanelBufferPoolParent,并将其拖拽到UIManager的PanelBufferPoolParent属性上即可。
- 加入**串口通信组件**

- *Author:* [SmalBox](https://smalbox.top),*GitHub:* [GitHub/SmalBox](https://github.com/smalbox)

Expand Down Expand Up @@ -135,6 +134,13 @@
- 获取本组件,注册 **SocketReceiveCallBack** 用来接收消息,用 **Send** 发送消息。
- *注:本组件需要实用工具中的AutoUIUtilities.GetInfoForConfig来帮助获取ip端口配置文件。*
-StreamingAssets/Config/Config.txt 中 的 **UDPServerIP**, **UDPServerPort** 属性填写对应的ip和端口号。在程序中获取此组件注册回调来接收消息,调用Send可以发送消息(消息是ASCII编码,不要输入此编码外的字符,例如不要传输中文,使用ASCII表中的字符)。
- **串口组件**
- 串口组件位于 AutoUI/Scripts/SerialPort/
- **AutoUISerialPort**
- 获取本组件,注册 **ComReceiveCallBack** 用来接收串口消息。
- *注:本组件需要实用工具中的AutoUIUtilities.GetInfoForConfig来帮助获取ComName配置文件。*
-Inspector 中可配置串口名、波特率等串口配置,当开启 isConfigComName 选项后,可修改配置文件中的 COMName 为实际串口名。
- 组件可接收串口发来的消息,并且自动计算校验码解析命令(已做了错误命令过滤),在成功接收到完整命令后调用 ComReceiveCallBack 回调。

## 高级功能
- **创建页面管理工具**
Expand Down
8 changes: 8 additions & 0 deletions Assets/AutoUI/Scripts/SerialPort.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

229 changes: 229 additions & 0 deletions Assets/AutoUI/Scripts/SerialPort/AutoUISerialPort.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO.Ports;
using System;
using SmalBox.AutoUI;
/// <summary>
/// 串口通信组件,可在inspector中配置要连接的串口属性,在外部配置文件中修改串口号。
/// 提供串口接收消息的回调 ComReceiveCallBack , 当收到串口消息时此组件会自动解析命令
/// 解析到完整命令后会自动调用 ComReceiveCallBack 回调来执行处理命令。
/// 通过配置 CMD_LENGTH 配置命令长度。
/// </summary>
public class AutoUISerialPort : MonoBehaviour
{
public SerialPort sp;
public bool isConfigComName = false;
public string comName = "COM1";
public int baudRate = 9600;
public Parity parity = Parity.None;
public int dataBits = 8;
public StopBits stopBits = StopBits.One;

public int CMD_LENGTH = 9;

public Action<String> ComReceiveCallBack;

private Queue buffQueue;
private List<byte> cmd;

private void Awake()
{
sp = new SerialPort();
sp.ReadTimeout = 400;
sp.RtsEnable = true;
//sp.DataReceived += new SerialDataReceivedEventHandler(PortDataReceived); // unity 无法触发这个回调。手动调用read读取数据
//sp.ReceivedBytesThreshold = 1; // Unity 支持不全
InitSP();
OpenSP();
buffQueue = new Queue();
cmd = new List<byte>();
ComReceiveCallBack = (string str) => { };
}
private void Update()
{
if (sp != null && sp.IsOpen && sp.BytesToRead > 0)
{
try
{
byte[] dataBytes = new byte[sp.BytesToRead];
sp.Read(dataBytes, 0, sp.BytesToRead);
foreach (var item in dataBytes)
{
print("收到:" + item.ToString("X2"));
// 加入缓冲队列
buffQueue.Enqueue(item);
}
// 解析缓冲队列
ParsedData();
}
catch (Exception ex)
{
print("输出错误:" + ex.ToString());
}
}
#region 数据测试
if (Input.GetKeyDown(KeyCode.Space))
{
if (sp != null && sp.IsOpen)
{
print("当前接受到的字符个数:" + sp.BytesToRead);
}
}
if (Input.GetKeyDown(KeyCode.A))
{
print("开始输出消息");
if (sp != null && sp.IsOpen && sp.BytesToRead > 0)
{
try
{
byte[] dataBytes = new byte[9];
sp.Read(dataBytes, 0, dataBytes.Length);
foreach (var item in dataBytes)
{
print(item.ToString("X2"));
}
}
catch (Exception ex)
{
print("输出错误:" + ex.ToString());
}
}
}
if (Input.GetKeyDown(KeyCode.B))
{
//byte[] data = { 0x00, 0x5A, 0x58, 0x00, 0x07, 0x00, 0x00, 0x00, B9 };
byte[] data = new byte[9];
// 取字节的ascii数值 求和 ,转换成16进制,即使校验和。
}
if (Input.GetKeyDown(KeyCode.C))
{
print("数据队列长度:" + buffQueue.Count);
}

if (Input.GetKeyDown(KeyCode.Q))
{
print(sp.ReadLine());
}
if (Input.GetKeyDown(KeyCode.W))
{
//print(sp.Read());
}
if (Input.GetKeyDown(KeyCode.E))
{
print(sp.ReadByte());
}
#endregion
}

private void InitSP()
{
if (isConfigComName)
{
sp.PortName = AutoUIUtilities.GetInfoForConfig("COMName");
}else
{
sp.PortName = comName;
}
sp.BaudRate = 9600;
sp.Parity = Parity.None;
sp.DataBits = 8;
sp.StopBits = StopBits.One;
}
private void OpenSP()
{
try
{
print("打开串口" + sp.PortName);
sp.Open();
}
catch ( Exception ex)
{
print("打开出错,错误信息:" + ex.ToString());
return;
}
}
private void CloseSP()
{
try
{
print("关闭串口" + sp.PortName);
sp.Close();
}
catch ( Exception ex)
{
print("关闭出错,错误信息:" + ex.ToString());
return;
}
}

// 解析数据
private void ParsedData()
{
int emptyData;
// 将缓冲区数据填充命令列表

// 查看命令列表当前字节数,与命令长度对比计算有几个空位字节
emptyData = CMD_LENGTH - cmd.Count;
// 向空位填充字节,填充时通过缓冲区剩余个数控制数组别越界
for (int i = 0; i < emptyData; i++)
{
if (buffQueue.Count > 0)
{
cmd.Add((byte)buffQueue.Dequeue());
}
}
// 填充后再次查看字节数,当空余字节数为0时,计算校验和对比
emptyData = CMD_LENGTH - cmd.Count;
if (emptyData == 0)
{
if (cmd[CMD_LENGTH - 1] == CalculateChecksum()) // 当校验和正确时
{
// 对比成功则执行命令
ExeCmd();
} else
{
// 对比失败查看缓冲区数据是否为空,不为空则向后移动命令列表一个位置继续判断
if (buffQueue.Count > 0)
{
cmd.RemoveAt(0);
ParsedData();
}
}
}
}
// 执行命令
private void ExeCmd()
{
// 判断命令 列表长度 和 校验和 是否符合要求
if (cmd.Count < CMD_LENGTH || cmd[CMD_LENGTH - 1] != CalculateChecksum())
return;
// 解析地址,根据地址判断哪个内容播放
// 将命令字节列表转化成字符串对比
string cmdStr = "";
ComReceiveCallBack?.Invoke(cmdStr);
// 命令执行完毕,清空命令列表
cmd.Clear();
}
// 计算校验和
private byte CalculateChecksum()
{
if (cmd.Count < CMD_LENGTH)
return 0x00;
byte sum = 0x00;
for (int i = 0; i < CMD_LENGTH - 1; i++)
{
sum += cmd[i];
}
return sum;
}

private void PortDataReceived(object sender, SerialDataReceivedEventArgs e)
{
print("收到串口" + sp.PortName + "的消息:");
}
private void OnDestroy()
{
CloseSP();
}
}
11 changes: 11 additions & 0 deletions Assets/AutoUI/Scripts/SerialPort/AutoUISerialPort.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion Assets/StreamingAssets/Config/Config.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,9 @@
##UDPServerIP##:127.0.0.1
##UDPServerPort##:55666
##LocalUDPServerIP##:127.0.0.1
##LocalUDPServerPort##:22333
##LocalUDPServerPort##:22333
##addr1##:005A58002000FF00D1
##addr2##:005A580020FBFF00CC
##addr3##:005A580020F7FF00C8
##addr4##:005A580020EFFF00C0
##COMName##:COM2
23 changes: 21 additions & 2 deletions ProjectSettings/ProjectSettings.asset
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
--- !u!129 &1
PlayerSettings:
m_ObjectHideFlags: 0
serializedVersion: 15
serializedVersion: 18
productGUID: 66f99a8b96074954bb60304390c35e23
AndroidProfiler: 0
AndroidFilterTouchesWhenObscured: 0
Expand Down Expand Up @@ -41,6 +41,12 @@ PlayerSettings:
height: 1
m_SplashScreenLogos: []
m_VirtualRealitySplashScreen: {fileID: 0}
m_ShowUnitySplashAds: 0
m_AdsAndroidGameId:
m_AdsIosGameId:
m_ShowSplashAdsSlogan: 0
m_SloganImage: {fileID: 0}
m_SloganHeight: 150
m_HolographicTrackingLossScreen: {fileID: 0}
defaultScreenWidth: 1024
defaultScreenHeight: 768
Expand All @@ -52,8 +58,8 @@ PlayerSettings:
m_StackTraceTypes: 010000000100000001000000010000000100000001000000
iosShowActivityIndicatorOnLoading: -1
androidShowActivityIndicatorOnLoading: -1
iosAppInBackgroundBehavior: 0
displayResolutionDialog: 1
iosUseCustomAppBackgroundBehavior: 0
iosAllowHTTPDownload: 1
allowedAutorotateToPortrait: 1
allowedAutorotateToPortraitUpsideDown: 1
Expand Down Expand Up @@ -104,14 +110,18 @@ PlayerSettings:
xboxOneMonoLoggingLevel: 0
xboxOneLoggingLevel: 1
xboxOneDisableEsram: 0
xboxOneEnableTypeOptimization: 0
xboxOnePresentImmediateThreshold: 0
switchQueueCommandMemory: 0
switchQueueControlMemory: 16384
switchQueueComputeMemory: 262144
switchNVNShaderPoolsGranularity: 33554432
switchNVNDefaultPoolsGranularity: 16777216
switchNVNOtherPoolsGranularity: 16777216
switchNVNMaxPublicTextureIDCount: 0
switchNVNMaxPublicSamplerIDCount: 0
vulkanEnableSetSRGBWrite: 0
useSecurityBuild: 0
m_SupportedAspectRatios:
4:3: 1
5:4: 1
Expand Down Expand Up @@ -143,6 +153,9 @@ PlayerSettings:
oculus:
sharedDepthBuffer: 1
dashSupport: 1
lowOverheadMode: 0
protectedContext: 0
v2Signing: 0
enable360StereoCapture: 0
protectGraphicsMemory: 0
enableFrameTimingStats: 0
Expand Down Expand Up @@ -228,6 +241,7 @@ PlayerSettings:
metalEditorSupport: 1
metalAPIValidation: 1
iOSRenderExtraFrameOnPause: 0
iosCopyPluginsCodeInsteadOfSymlink: 0
appleDeveloperTeamID:
iOSManualSigningProvisioningProfileID:
tvOSManualSigningProvisioningProfileID:
Expand Down Expand Up @@ -275,6 +289,7 @@ PlayerSettings:
- m_BuildTarget: WebGL
m_StaticBatching: 0
m_DynamicBatching: 0
m_BuildTargetEncrypting: []
m_BuildTargetGraphicsAPIs:
- m_BuildTarget: AndroidPlayer
m_APIs: 0b00000008000000
Expand Down Expand Up @@ -412,6 +427,7 @@ PlayerSettings:
switchRatingsInt_9: 0
switchRatingsInt_10: 0
switchRatingsInt_11: 0
switchRatingsInt_12: 0
switchLocalCommunicationIds_0:
switchLocalCommunicationIds_1:
switchLocalCommunicationIds_2:
Expand Down Expand Up @@ -468,6 +484,7 @@ PlayerSettings:
ps4ShareFilePath:
ps4ShareOverlayImagePath:
ps4PrivacyGuardImagePath:
ps4ExtraSceSysFile:
ps4NPtitleDatPath:
ps4RemotePlayKeyAssignment: -1
ps4RemotePlayKeyMappingDir:
Expand Down Expand Up @@ -508,6 +525,8 @@ PlayerSettings:
ps4disableAutoHideSplash: 0
ps4videoRecordingFeaturesUsed: 0
ps4contentSearchFeaturesUsed: 0
ps4CompatibilityPS5: 0
ps4GPU800MHz: 1
ps4attribEyeToEyeDistanceSettingVR: 0
ps4IncludedModules: []
monoEnv:
Expand Down
Loading

0 comments on commit 4872481

Please sign in to comment.