H_SafeExperienceDrivingSystem/U3D_DrivingSystem/Assets/Script/ModbusTcpClient.cs

168 lines
6.1 KiB
C#
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Net.Sockets;
using System.Threading.Tasks;
using UnityEngine;
using System;
using System.Net.Sockets;
using System.Threading.Tasks;
using UnityEngine;
public class ModbusTcpClient
{
private TcpClient tcpClient;
private string serverIp = "172.16.1.17";
private int serverPort = 12315;
public ModbusTcpClient()
{
tcpClient = new TcpClient();
}
/// <summary>
/// 接口为TCP/IP接口。
/// 协议为MODBUS/TCP,数据为十六进制数据。
/// 硬件设备为服务器端IP地址192.168.0.100,端口12315电脑为客户端。
/// </summary>
public async Task ConnectToServer()
{
try
{
await tcpClient.ConnectAsync(serverIp, serverPort);
Debug.Log("已连接到Modbus服务器。");
await SendModbusRequest();
}
catch (Exception ex)
{
Debug.Log("连接Modbus服务器时出错: " + ex.Message);
}
}
/// <summary>
/// 连接成功后,电脑主动发送(十六进制数据): 00 00 00 00 00 06 01 03 00 00 00 10
/// "00 00 00 00 00 06"为TCP报文头06表示后面有六个字节。
/// "01"表示硬件设备编号
/// "03"表示读数据
/// "00 00" 表示读数据从0000开始
/// "00 10" 表示读16个数据
/// </summary>
private async Task SendModbusRequest()
{
byte[] request = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, 0x10 };
NetworkStream stream = tcpClient.GetStream();
if (stream.CanWrite)
{
await stream.WriteAsync(request, 0, request.Length);
Debug.Log("Modbus请求已发送。");
await ReadResponse(stream);
}
}
/// <summary>
/// 设备回复: 00 00 00 00 00 24 01 03 20 00 01 00 02 00 03 00 04 00 05 00 06 00 07 00 08 00 09 00 0A 00 0B 00 0C 00 0D 00 0E 00 0F 00 10
/// "00 00 00 00 00 24" 为TCP报文头24 表示后面有三十六个字节。
/// "01" 表示硬件设备编号。
/// "03" 表示读数据。
/// "20" 表示后面有三十二个字节数据即16个数据。
/// 后续数据为硬件反馈回来的数据:
/// - "00 01" 为钥匙开关数据0 熄火1 通电2 启动。
/// - "00 02"为方向盘数据,左打方向盘为负数,右打方向盘为正数,打方向盘幅度越大,绝对值越大。
/// - "00 03" 为方向盘上喇叭状态01 为喇叭按下。
/// - "00 04"为刹车踏板数据, 0-100,踩到底为100
/// - "00 05" 为油门踏板数据。0-100,踩到底为100
/// - "00 06" 为离合踏板数据。0-100,踩到底为100
/// - "00 07" 为手刹数据01 表示手刹有效。
/// - "00 08" 为挡位数据00 空挡1 前进档2 倒挡3 为 P 档。
/// - "00 09" 为雨刮数据00 空档1 手动一次雨刮2 自动雨刮慢速3 自动雨刮快速。
/// - "00 0A" 为灯光数据00 未开灯1 近光2 远光。
/// - "00 0B" 为转向灯数据00 未开转向灯1 左转向灯2 右转向灯。
/// - "00 0C"为点火钥匙数据00是熄火1是通电2是点火
/// 后面为预留。
/// </summary>
private async Task ReadResponse(NetworkStream stream)
{
byte[] response = new byte[256];
int bytesRead = await stream.ReadAsync(response, 0, response.Length);
Debug.Log("已接收到Modbus服务器的响应。");
if (bytesRead > 9) // 确保响应长度足够
{
int length = response[5];
byte deviceId = response[6];
byte functionCode = response[7];
Debug.Log($"设备ID: {deviceId}, 功能码: {functionCode}, 数据长度: {length}");
for (int i = 9; i < 9 + length; i += 2)
{
ushort dataValue = (ushort)(response[i] << 8 | response[i + 1]);
switch ((i - 9) / 2)
{
case 0:
Debug.Log($"钥匙开关数据: {dataValue}");
break;
case 1:
Debug.Log($"方向盘数据: {dataValue}");
break;
case 2:
Debug.Log($"方向盘上喇叭状态: {dataValue}");
break;
case 3:
Debug.Log($"刹车踏板数据: {dataValue}");
break;
case 4:
Debug.Log($"油门踏板数据: {dataValue}");
break;
case 5:
Debug.Log($"离合踏板数据: {dataValue}");
break;
case 6:
Debug.Log($"手刹数据: {dataValue}");
break;
case 7:
Debug.Log($"挡位数据: {dataValue}");
break;
case 8:
Debug.Log($"雨刮状态: {dataValue}");
break;
case 9:
Debug.Log($"灯光状态: {dataValue}");
break;
case 10:
Debug.Log($"转向灯状态: {dataValue}");
break;
case 11:
Debug.Log($"点火钥匙数据: {dataValue}");
break;
default:
Debug.Log($"预留数据 {i / 2 - 4}: {dataValue}");
break;
}
}
}
else
{
Debug.Log("响应长度无效。");
}
}
public void CloseConnection()
{
if (tcpClient != null)
{
if (tcpClient.Connected)
{
tcpClient.GetStream().Close();
tcpClient.Close();
Debug.Log("已关闭与Modbus服务器的连接。");
}
}
}
}