Unity实现串口通信发送16进制字符

Unity实现串口通信发送16进制字符

前言

Unity在与硬件设备进行串口通信的时候,硬件那边只接收字符串有时候是不行的,还需要接收16进制的数据,在这里简单介绍下使用Unity发送16进制的串口信号。

步骤

一、首先开发配置文件功能,代码如下所示,完成后将其挂载到场景的物体上,在这里不再赘述:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using System;

/// <summary>
/// 配置文件读取
/// </summary>
public class ConfigTest : MonoBehaviour
{
    private string configPath;
    //在实际项目中我一般不会用静态类,在有频繁跳转场景的时候很容易出问题
    //public static Dictionary<string, Dictionary<string, string>> dic;
    public Dictionary<string, Dictionary<string, string>> dic;

    private void Awake()
    {
        //读取配置文件(StreamingAssets)路径
        configPath = Path.Combine(Application.streamingAssetsPath, "Config.txt");
        if (dic == null)
        {
            dic = new Dictionary<string, Dictionary<string, string>>();
            LoadConfig();
        }
    }
    /// <summary>
    /// 读取所有的数据
    /// </summary>
    void LoadConfig()
    {
        string[] lines = null;
        if (File.Exists(configPath))
        {
            lines = File.ReadAllLines(configPath);
            BuildDic(lines);
        }
    }
    /// <summary>
    /// 处理所有数据
    /// </summary>
    /// <param name="lines"></param>
    private void BuildDic(string[] lines)
    {
        string mainKey = null;//主键
        string subKey = null;//子键
        string subValue = null;//值
        foreach (var item in lines)
        {
            string line = null;
            line = item.Trim();//去除空白行
            if (!string.IsNullOrEmpty(line))
            {
                if (line.StartsWith("["))//取主键
                {
                    mainKey = line.Substring(1, line.IndexOf("]") - 1);
                    if (dic.ContainsKey(mainKey))
                    {
                        return;
                    }
                    dic.Add(mainKey, new Dictionary<string, string>());
                }
                else//取主键
                {
                    var configValue = line.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries);
                    subKey = configValue[0].Trim();
                    subValue = configValue[1].Trim();
                    subValue = subValue.StartsWith("\"") ? subValue.Substring(1) : subValue;
                    dic[mainKey].Add(subKey, subValue);
                }
            }
        }
    }
}

二、在Assets中新建StreamingAssets文件夹,在里面新建一个Config.txt的文件,在Config.txt里面输入以下内容。
在这里插入图片描述
三、开发串口通信功能,代码如下所示:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO.Ports;
using System;

public class PortManager : MonoBehaviour
{
    #region 参数
    string getPortName;
    int baudRate = 19200;
    private Parity parity = Parity.None;
    private int dataBits = 8;
    private StopBits stopBits = StopBits.One;
    SerialPort sp = null;
    private string _data;
    private string testString0, testString1, testString2, testString3, testString4, testString5,
        closeString0, closeString1, closeString2, closeString3, closeString4, closeString5;
    string reciveString;
    //配置文件类
    public ConfigTest thisConfigTest;
    #endregion

    #region 常规方法
    // Use this for initialization
    void Start()
    {
        getPortName = thisConfigTest.dic["端口号"]["portName"];
        baudRate = int.Parse(thisConfigTest.dic["波特率"]["baudRate"]);
        testString0 = thisConfigTest.dic["信号0"]["string0"];
        testString1 = thisConfigTest.dic["信号1"]["string1"];
        testString2 = thisConfigTest.dic["信号2"]["string2"];
        testString3 = thisConfigTest.dic["信号3"]["string3"];
        testString4 = thisConfigTest.dic["信号4"]["string4"];
        testString5 = thisConfigTest.dic["信号5"]["string5"];
        closeString0 = thisConfigTest.dic["关灯信号0"]["closeString0"];
        closeString1 = thisConfigTest.dic["关灯信号1"]["closeString1"];
        closeString2 = thisConfigTest.dic["关灯信号2"]["closeString2"];
        closeString3 = thisConfigTest.dic["关灯信号3"]["closeString3"];
        closeString4 = thisConfigTest.dic["关灯信号4"]["closeString4"];
        closeString5 = thisConfigTest.dic["关灯信号5"]["closeString5"];
        reciveString = thisConfigTest.dic["接收信号"]["receiveString"];
        OpenPort(getPortName);
        StartCoroutine(DataReceiveFunction());
    }

    #endregion
    #region 串口通信控制

    /// <summary>
    /// 串口信号控制
    /// </summary>
    private void PortSignalControl()
    {
        if (_data == System.Text.Encoding.ASCII.GetBytes(reciveString)[0].ToString())
        {
            //Debug.Log("收到串口信号" + testString);
        }

    }
    //打开串口
    public void OpenPort(string DefaultPortName)
    {
        sp = new SerialPort(DefaultPortName, baudRate, parity, dataBits, stopBits);
        sp.ReadTimeout = 10;
        try
        {
            if (!sp.IsOpen)
            {
                sp.Open();
            }
        }
        catch (Exception ex)
        {
            Debug.Log(ex.Message);
        }
    }
    //关闭串口
    public void ClosePort()
    {
        try
        {
            sp.Close();
        }
        catch (Exception ex)
        {
            Debug.Log(ex.Message);
        }
    }
    IEnumerator DataReceiveFunction()
    {
        byte[] dataBytes = new byte[128];//存储长度
        int bytesToRead = 0;//记录获取的数据长度

        while (true)
        {
            if (sp != null && sp.IsOpen)
            {
                try
                {
                    //通过read函数获取串口数据
                    bytesToRead = sp.Read(dataBytes, 0, dataBytes.Length);
                    _data = dataBytes[0].ToString();
                    print(_data);
                    PortSignalControl();
                    //串口数据已经被存入dataBytes中
                }
                catch (Exception ex)
                {

                }
            }
            yield return new WaitForSeconds(Time.deltaTime);
        }
    }
    //发送一个字节
    public void SendSerialPortData(string data)
    {
        if (sp.IsOpen)
        {
            sp.WriteLine(data);
        }
    }
    //发送一个字节
    public void SendSerialPortData0(byte[] data)
    {
        if (sp.IsOpen)
        {
            sp.Write(data,0,data.Length);
        }
    }
    /// <summary>
    /// 发送一个字符串0
    /// </summary>
    public void SendString0()
    {
        //SendSerialPortData(testString0);
        SendMsg(testString0);
    }

    
    /// <summary>
    /// 发送字符串1
    /// </summary>
    internal void SendString1()
    {
        //SendSerialPortData(testString1);
        SendMsg(testString1);
    }
    /// <summary>
    /// 发送字符串2
    /// </summary>
    internal void SendString2()
    {
        //SendSerialPortData(testString2);
        SendMsg(testString2);
    }

    /// <summary>
    /// 发送字符串3
    /// </summary>
    internal void SendString3()
    {
        //SendSerialPortData(testString3);
        SendMsg(testString3);
    }
    /// <summary>
    /// 发送字符串4
    /// </summary>
    internal void SendString4()
    {
        //SendSerialPortData(testString4);
        SendMsg(testString4);
    }

    /// <summary>
    /// 发送字符串5
    /// </summary>
    internal void SendString5()
    {
        //SendSerialPortData(testString5);
        SendMsg(testString5);
    }

    /// <summary>
    /// 发生关灯信号0
    /// </summary>
    internal void SendCloseString0()
    {
        //SendSerialPortData(closeString0);
        SendMsg(closeString0);
    }

    /// <summary>
    /// 发生关灯信号1
    /// </summary>
    internal void SendCloseString1()
    {
        //SendSerialPortData(closeString1);
        SendMsg(closeString1);
    }
    /// <summary>
    /// 发生关灯信号2
    /// </summary>
    internal void SendCloseString2()
    {
        //SendSerialPortData(closeString2);
        SendMsg(closeString2);
    }

    /// <summary>
    /// 发生关灯信号3
    /// </summary>
    internal void SendCloseString3()
    {
        //SendSerialPortData(closeString3);
        SendMsg(closeString3);
    }

    /// <summary>
    /// 发生关灯信号4
    /// </summary>
    internal void SendCloseString4()
    {
        //SendSerialPortData(closeString4);
        SendMsg(closeString4);
    }

    /// <summary>
    /// 发生关灯信号5
    /// </summary>
    internal void SendCloseString5()
    {
        //SendSerialPortData(closeString5);
        SendMsg(closeString5);
    }

    private void OnApplicationQuit()
    {
        ClosePort();
    }
    private void OnDisable()
    {
        ClosePort();
    }

    #endregion

    #region 信号转16进制方法


    public void SendMsg(string s)
    {
        string msg = s;
        //byte[] cmd = new byte[1024 * 1024 * 3];
        //cmd = Convert16(msg);
        //SendSerialPortData0(cmd);
        byte[] cmd = textWork16(s);
        SendSerialPortData0(cmd);
    }
    
    /*
    private byte[] Convert16(string strText)
    {
        strText = strText.Replace(" ", "");
        byte[] bText = new byte[strText.Length / 2];
        for (int i = 0; i < strText.Length / 2; i++)
        {
            bText[i] = Convert.ToByte(Convert.ToInt32(strText.Substring(i * 2, 2), 16));
        }
        return bText;
    }
    */

    /*
    public byte[] HexStringToBytes(string hs)
    {
        string[] strArr = hs.Trim().Split(' ');
        byte[] b = new byte[strArr.Length];
        //逐个字符变为16进制字节数据
        for (int i = 0; i < strArr.Length; i++)
        {
            b[i] = Convert.ToByte(strArr[i], 16);
        }
        //按照指定编码将字节数组变为字符串
        return b;
    }
    */

    private byte[] textWork16(string strText)
    {
        strText = strText.Replace(" ", "");
        byte[] bText = new byte[strText.Length / 2];
        for (int i = 0; i < strText.Length / 2; i++)
        {
            bText[i] = Convert.ToByte(Convert.ToInt32(strText.Substring(i * 2, 2), 16));
        }
        return bText;
    }
    #endregion
}

四、这个脚本和我之前写的串口通信功能类似,只是添加了一个字符串转16进制的功能,如下图所示:
在这里插入图片描述
五、在场景中新建portManager物体,将PortManager.cs脚本挂载到portManager物体上,并将configTest物体赋值到该物体上,如下图所示:
在这里插入图片描述
六、在场景中新建一个Button,将SendString0方法赋值到该按钮中,如下图所示:
在这里插入图片描述
七、打开串口助手,将串口助手配置设置如下所示:
在这里插入图片描述
八、运行项目,点击场景中的按钮,可以看到串口已经收到了数字码,如下图所示:
在这里插入图片描述

相关链接

项目Demo

  • 6
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 16
    评论
Unity中,要发送16数据流,可以通过TCP连接来实现。下面是一个示例代码,解释了如何在Unity发送16数据。 首先,需要使用Unity内置的NetworkStream类和TcpClient类来创建TCP连接并发送数据。然后,将要发送的数据从字符串转换为16字节数组。最后,使用NetworkStream的Write方法发送字节数组。 ```c# using UnityEngine; using System; using System.IO; using System.Net; using System.Net.Sockets; public class TcpSender : MonoBehaviour { public string serverIP = "127.0.0.1"; public int serverPort = 8888; public string hexData = "ff00d245370022"; private TcpClient client; private NetworkStream stream; void Start() { client = new TcpClient(); client.Connect(IPAddress.Parse(serverIP), serverPort); stream = client.GetStream(); SendHexData(hexData); client.Close(); } private void SendHexData(string hexData) { try { byte[] byteArray = StringToByteArray(hexData); stream.Write(byteArray, 0, byteArray.Length); Debug.Log("数据已发送"); } catch (Exception e) { Debug.Log("发送失败:" + e.Message); } } private byte[] StringToByteArray(string hex) { hex = hex.Replace(" ", ""); int charCount = hex.Length; byte[] byteArray = new byte[charCount / 2]; for (int i = 0; i < charCount; i += 2) byteArray[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16); return byteArray; } } ``` 在此示例中,我们创建了一个TcpSender类,该类在Start()方法中创建TCP连接,并通过SendHexData()方法发送16数据。StringToByteArray()方法将16字符串转换为字节数组,然后使用NetworkStream的Write()方法发送字节数组。需要根据实际情况修改serverIP、serverPort和hexData的值。 请注意,该代码仅提供了一个基本的示例,实际应用中可能需要更多的错误处理和异常处理机来确保数据正确发送

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

波波斯维奇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值