679 lines
22 KiB
C#
679 lines
22 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.ComponentModel;
|
||
using System.Data;
|
||
using System.Drawing;
|
||
using System.Linq;
|
||
using System.Reflection.Emit;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
using System.Windows.Forms;
|
||
using static System.Windows.Forms.VisualStyles.VisualStyleElement.Button;
|
||
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
|
||
using System.IO.Ports;
|
||
using System.Security.Cryptography;
|
||
using System.Threading;
|
||
using System.IO;
|
||
using static System.Windows.Forms.VisualStyles.VisualStyleElement.ToolBar;
|
||
using System.Runtime.ConstrainedExecution;
|
||
using System.Net;
|
||
using static System.Net.Mime.MediaTypeNames;
|
||
|
||
namespace NTADCP
|
||
{
|
||
public partial class Form1 : Form
|
||
{
|
||
ADCP adcp = new ADCP();
|
||
//获取当前程序运行路径
|
||
private string Save_Path = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase + @"数据采集\";
|
||
|
||
//单线程
|
||
private System.Threading.Timer _flash_page;
|
||
|
||
private System.Threading.Timer timer_beckoff_01;
|
||
DateTime dateTime;
|
||
|
||
//定义全局变量,接收数据返回字段
|
||
private static string MessageAll = "";
|
||
|
||
//定义全局变量,存储上一个数据来源时间节点
|
||
private static DateTime TimeOld = System.DateTime.Now;
|
||
|
||
|
||
//218.91.223.39:19001
|
||
private string main_ip = "218.91.223.39";
|
||
private int main_port = 19001;
|
||
private Client _client = new Client(); //主板客户端
|
||
|
||
public Form1()
|
||
{
|
||
InitializeComponent();
|
||
|
||
textBox1.Text = main_ip;
|
||
textBox2.Text = main_port.ToString();
|
||
|
||
//波特率
|
||
string[] btl = new string[] { "110", "300", "600", "1200", "2400", "4800", "9600", "14400", "19200", "38400", "56000", "57600", "115200", "128000", "256000" };
|
||
for (int i = 0; i < btl.Length; i++)
|
||
{
|
||
comboBox2.Items.Add(btl[i]);
|
||
}
|
||
comboBox2.Text = "9600";
|
||
|
||
//刷新界面的线程
|
||
_flash_page = new System.Threading.Timer(new System.Threading.TimerCallback(WritetoPage), null, 2000, 1000);
|
||
|
||
button2.Enabled = false;
|
||
button3.Enabled = false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取本机串口号
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void comboBox1_DropDown(object sender, EventArgs e)
|
||
{
|
||
comboBox1.Items.Clear();
|
||
//获取当前设备所有的串口号
|
||
string[] portsname = tools.GetSerialPort();
|
||
for (int i = 0; i < portsname.Length; i++)
|
||
{
|
||
comboBox1.Items.Add(portsname[i]);
|
||
}
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 打开串口
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void button1_Click(object sender, EventArgs e)
|
||
{
|
||
if (button1.Text == "打开串口")
|
||
{
|
||
open_port();
|
||
if (serialPort1.IsOpen)
|
||
{
|
||
button1.Text = "关闭串口";
|
||
comboBox1.Enabled = false;
|
||
this.comboBox2.Enabled = false;
|
||
button2.Enabled = true;
|
||
button3.Enabled = true;
|
||
|
||
}
|
||
else
|
||
{
|
||
MessageBox.Show("串口未打开,请检查串口是已经被占用!");
|
||
return;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (button2.Text == "停止测量")
|
||
{
|
||
MessageBox.Show("请先停止测量,后关闭串口!");
|
||
return;
|
||
}
|
||
else
|
||
{
|
||
serialPort1.Close();
|
||
if (serialPort1.IsOpen == false)
|
||
{
|
||
button1.Text = "打开串口";
|
||
comboBox1.Enabled = true;
|
||
button2.Text = "开始测量";
|
||
button2.Enabled = false;
|
||
button3.Enabled = false;
|
||
this.comboBox2.Enabled = true;
|
||
}
|
||
else
|
||
{
|
||
serialPort1.Dispose();
|
||
MessageBox.Show("串口未正常关闭,已释放串口的所有资源!");
|
||
return;
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Socket连接
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void button3_Click(object sender, EventArgs e)
|
||
{
|
||
if (button3.Text == "连接")
|
||
{
|
||
//连接Socket
|
||
_client.InitSocket(textBox1.Text, Convert.ToInt32(textBox2.Text));
|
||
bool isConnected = _client.Connect();
|
||
if (isConnected)
|
||
{
|
||
_client.pushSockets = ReceiveMess;//注册推送器
|
||
button3.Text = "断开";
|
||
textBox1.Enabled = false;
|
||
textBox2.Enabled = false;
|
||
|
||
}
|
||
}
|
||
else if (button3.Text == "断开")
|
||
{
|
||
_client.Stop();
|
||
button3.Text = "连接";
|
||
textBox1.Enabled = true;
|
||
textBox2.Enabled = true;
|
||
}
|
||
|
||
}
|
||
/// <summary>
|
||
/// socket 重连
|
||
/// </summary>
|
||
/// <param name="o"></param>
|
||
public void DoSocket1Connect(object o)
|
||
{
|
||
if (button3.Text == "连接")
|
||
{
|
||
Task.Run(new Action(async () =>
|
||
{
|
||
await Task.Delay(150);
|
||
|
||
//连接Socket
|
||
_client.InitSocket(textBox1.Text, Convert.ToInt32(textBox2.Text));
|
||
bool isConnected = _client.Connect();
|
||
if (isConnected)
|
||
{
|
||
_client.pushSockets = ReceiveMess;//注册推送器
|
||
button3.Text = "断开";
|
||
textBox1.Enabled = false;
|
||
textBox2.Enabled = false;
|
||
|
||
}
|
||
}));
|
||
}
|
||
else if (button3.Text == "断开")
|
||
{
|
||
Task.Run(new Action(async () =>
|
||
{
|
||
await Task.Delay(100);
|
||
|
||
_client.Stop();
|
||
button3.Text = "连接";
|
||
textBox1.Enabled = true;
|
||
textBox2.Enabled = true;
|
||
}));
|
||
}
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 客户端数据接收
|
||
/// </summary>
|
||
/// <param name="sks"></param>
|
||
private void ReceiveMess(Sockets sks)
|
||
{
|
||
if (sks.ex != null)
|
||
{
|
||
if (sks.ClientDispose == true)
|
||
{
|
||
//由于未知原因引发异常.导致客户端下线. 比如网络故障.或服务器断开连接.
|
||
//wirte_textbox(string.Format("客户端下线.!异常消息:{0}\r\n", sks.ex));
|
||
}
|
||
else
|
||
{
|
||
//SetClientState(string.Format("异常消息:{0}\r\n", sks.ex));
|
||
}
|
||
//timerConnect.Enabled = true;
|
||
}
|
||
else if (sks.Offset == 0)
|
||
{
|
||
//客户端主动下线
|
||
//wirte_textbox("客户端下线!");
|
||
}
|
||
else
|
||
{
|
||
byte[] buffer = new byte[sks.Offset];
|
||
Array.Copy(sks.RecBuffer, buffer, sks.Offset);
|
||
string str = Encoding.UTF8.GetString(buffer);
|
||
|
||
try
|
||
{
|
||
ParsingSocketData(new List<byte>(buffer));
|
||
}
|
||
catch (Exception)
|
||
{
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// 开始测量
|
||
/// 流速方向 -> 表面流速
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
private void button2_Click(object sender, EventArgs e)
|
||
{
|
||
if (button2.Text == "开始测量")
|
||
{
|
||
timer_beckoff_01 = new System.Threading.Timer(new System.Threading.TimerCallback(receive_timer_01), null, 1000, 30000);
|
||
button2.Text = "停止测量";
|
||
}
|
||
else if (button2.Text == "停止测量")
|
||
{
|
||
timer_beckoff_01.Dispose();
|
||
timer_beckoff_01 = null;
|
||
button2.Text = "开始测量";
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 发送数据
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
|
||
private void receive_timer_01(object sender)
|
||
{
|
||
string Direction = "3403000C000141AC";
|
||
byte[] bytea = tools.ConvertHexStringToBytes(Direction);
|
||
tools.Logging_data(Direction);
|
||
serialPort1.Write(bytea, 0, bytea.Length);
|
||
|
||
Thread.Sleep(1000);
|
||
string FaceVelocity = "3403000F0002F1AD";
|
||
byte[] FaceVelocitybyte = tools.ConvertHexStringToBytes(FaceVelocity);
|
||
tools.Logging_data(FaceVelocity);
|
||
serialPort1.Write(FaceVelocitybyte, 0, FaceVelocitybyte.Length);
|
||
}
|
||
|
||
|
||
//数据写入界面
|
||
private void WritetoPage(object sender)
|
||
{
|
||
Invoke((EventHandler)(delegate
|
||
{
|
||
label4.Text = System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
||
|
||
label6.Text = adcp.SurfaceVelocity.ToString() + " " + "m/s";
|
||
if (adcp.FlowDirection == 1)
|
||
{
|
||
label8.Text = "正向";
|
||
}
|
||
else if (adcp.FlowDirection == 0)
|
||
{
|
||
label8.Text = "逆向";
|
||
}
|
||
else
|
||
{
|
||
label8.Text = "";
|
||
}
|
||
|
||
}));
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 打开串口前检查及数据获取
|
||
/// </summary>
|
||
public void open_port()
|
||
{
|
||
if (string.IsNullOrEmpty(comboBox1.Text))
|
||
{
|
||
Invoke((EventHandler)(delegate
|
||
{
|
||
MessageBox.Show("请检查串口名称!!!");
|
||
}));
|
||
return;
|
||
}
|
||
if (string.IsNullOrEmpty(comboBox2.Text))
|
||
{
|
||
Invoke((EventHandler)(delegate
|
||
{
|
||
MessageBox.Show("请检查波特率!!!");
|
||
}));
|
||
return;
|
||
}
|
||
serialPort1.PortName = comboBox1.Text;
|
||
serialPort1.BaudRate = int.Parse(comboBox2.Text);
|
||
serialPort1.Parity = Parity.None;
|
||
serialPort1.DataBits = 8;
|
||
serialPort1.StopBits = StopBits.One;
|
||
serialPort1.ReceivedBytesThreshold = 1;
|
||
serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
|
||
try
|
||
{
|
||
serialPort1.Open();
|
||
}
|
||
catch (Exception)
|
||
{
|
||
Invoke((EventHandler)(delegate
|
||
{
|
||
MessageBox.Show("串口打开失败!请检查串口配置!");
|
||
}));
|
||
return;
|
||
}
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 串口数据接收
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
|
||
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
|
||
{
|
||
try
|
||
{
|
||
//将两秒接收的数据作为1组
|
||
System.Threading.Thread.Sleep(1000);
|
||
//将缓冲区内字节数大小设置为数组大小
|
||
byte[] byteRead = new byte[serialPort1.BytesToRead];
|
||
//将缓冲区内数据写入字节数组中
|
||
serialPort1.Read(byteRead, 0, byteRead.Length);
|
||
//清除串口缓冲区
|
||
serialPort1.DiscardInBuffer();
|
||
if (byteRead.Length == 0)
|
||
return;
|
||
//数据解析
|
||
ParsingData(new List<byte>(byteRead));
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine(ex.Message);
|
||
}
|
||
}
|
||
|
||
string diretion;
|
||
string SurfaceVelocity;
|
||
float total = 0;
|
||
|
||
// 定义一个List存储流速
|
||
List<float> SurfaceVelocityList = new List<float>();
|
||
|
||
/// <summary>
|
||
/// 串口数据解析及平台发送
|
||
/// </summary>
|
||
/// <param name="byteList"></param>
|
||
private void ParsingData(List<byte> byteList)
|
||
{
|
||
string rec_16 = null;
|
||
for (int i = 0; i < byteList.Count; i++)
|
||
{
|
||
rec_16 += byteList[i].ToString("X2"); //16进制显示
|
||
}
|
||
//校验当前List是否为空或者长度
|
||
if (byteList == null || byteList.Count == 0)
|
||
return;
|
||
//获取当前系统时间
|
||
DateTime time_DataBase = System.DateTime.Now;
|
||
//帧头
|
||
byte[] _header = new byte[] { 0X34 };
|
||
//功能码
|
||
byte _fun_code = 0;
|
||
|
||
//校验帧头
|
||
if (byteList[0] != _header[0])
|
||
{
|
||
return;
|
||
}
|
||
|
||
//功能码
|
||
_fun_code = byteList[2];
|
||
|
||
System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)); // 当地时区
|
||
DateTime dt = new DateTime();
|
||
|
||
switch (_fun_code)
|
||
{
|
||
//读取流向 -- 00 01 流速方向为迎水;若为 00 00 则流速方向为顺水
|
||
case 0x02:
|
||
if (byteList[3] == 0x00 && byteList[4] == 0x01)
|
||
{
|
||
adcp.FlowDirection = 1;
|
||
diretion = "正向";
|
||
|
||
}
|
||
else if (byteList[3] == 0x00 && byteList[4] == 0x00)
|
||
{
|
||
adcp.FlowDirection = 0;
|
||
diretion = "逆向";
|
||
}
|
||
break;
|
||
|
||
//读取流速
|
||
case 0x04:
|
||
adcp.SurfaceVelocity = BitConverter.ToSingle(new byte[] { byteList[3], byteList[4], byteList[5], byteList[6] }, 0);
|
||
SurfaceVelocity = adcp.SurfaceVelocity.ToString();
|
||
break;
|
||
default:
|
||
Console.WriteLine("未能识别功能码!");
|
||
break;
|
||
|
||
|
||
}
|
||
if (SurfaceVelocity != "" && diretion != "" && SurfaceVelocity != null)
|
||
{
|
||
var text = "测量时间:" + time_DataBase + "," + "流速:" + SurfaceVelocity + "," + "方向:" + diretion;
|
||
//数据存入
|
||
tools.AddLgoToTXT("测量结果.txt", Save_Path + System.DateTime.Now.ToString("yyyy_MM_dd") + @"\", System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " ---- " + text + "\r\n");
|
||
|
||
SurfaceVelocityList.Add(adcp.SurfaceVelocity);
|
||
|
||
if ((SurfaceVelocityList.Count != 0) && (time_DataBase.Hour != TimeOld.Hour))
|
||
{
|
||
foreach (var item in SurfaceVelocityList)
|
||
{
|
||
if (SurfaceVelocityList.Count == 1)
|
||
{
|
||
total = item;
|
||
}
|
||
else
|
||
{
|
||
total += item;
|
||
}
|
||
}
|
||
adcp.SurfaceVelocity = total / SurfaceVelocityList.Count();
|
||
SurfaceVelocityList.Clear();
|
||
|
||
tools.Logging(time_DataBase + ": " + "本地开始向平台上发送数据!");
|
||
SendMessage(adcp.SurfaceVelocity, adcp.FlowDirection);
|
||
DoConnect();
|
||
|
||
}
|
||
TimeOld = time_DataBase;
|
||
|
||
|
||
//判断当前时间是否为整点,如果为整点,就向平台上发送数据
|
||
//if (time_DataBase.ToString("mm:ss") == "00:00")
|
||
//{
|
||
// tools.Logging(time_DataBase + ": " + "本地开始向平台上发送数据!");
|
||
// SendMessage(adcp.SurfaceVelocity, adcp.FlowDirection);
|
||
// DoConnect();
|
||
|
||
//}
|
||
|
||
diretion = "";
|
||
SurfaceVelocity = "";
|
||
}
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// Socket数据解析
|
||
/// </summary>
|
||
/// <param name="byteList"></param>
|
||
private void ParsingSocketData(List<byte> byteList)
|
||
{
|
||
string rec_16 = null;
|
||
for (int i = 0; i < byteList.Count; i++)
|
||
{
|
||
rec_16 += byteList[i].ToString("X2"); //16进制显示
|
||
}
|
||
|
||
//校验当前List是否为空或者长度
|
||
if (byteList == null || byteList.Count == 0)
|
||
return;
|
||
|
||
|
||
MessageAll = rec_16;
|
||
|
||
//232330303737514E3D323032333036323 如果是以这个开头的,说明数据正常反馈
|
||
if (rec_16.StartsWith("2323"))
|
||
{
|
||
var text = System.DateTime.Now + " " + "接收到一条回复";
|
||
tools.Logging(text);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// 数据平台发送流速及流向
|
||
/// </summary>
|
||
/// <param name="SurfaceVelocity">流速</param>
|
||
/// <param name="direction">流向</param>
|
||
private void SendMessage(float SurfaceVelocity, float direction)
|
||
{
|
||
//包头
|
||
string Head = "##";
|
||
//数据域长度
|
||
string date_length = "";
|
||
|
||
//请求编码
|
||
string RequestEncoding = "QN=" + DateTime.Now.ToString("yyy-MM-dd HH.mm.ss.fff").Replace("-", "").Replace(" ", "").Replace(".", "") + ";";
|
||
|
||
//系统编码
|
||
string SystemCoding = "ST=21;";
|
||
|
||
//命令编码
|
||
string CommandCode = "CN=2061;";
|
||
|
||
//访问密码
|
||
string AccessPassword = "PW=123456;";
|
||
|
||
//设备唯一辨识
|
||
string DeviceIdentification = "MN=32060020200003;";
|
||
|
||
//拆分包及应答标志
|
||
string Response = "Flag=9;";
|
||
|
||
//指令参数
|
||
string CP = "CP=&&DataTime=" + DateTime.Now.ToString("yyyy-MM-dd HH:00:00").Replace("-", "").Replace(" ", "").Replace(":", "") + ";";
|
||
|
||
//流速
|
||
string Velocity = "w21112-Avg=" + SurfaceVelocity + ",w21112-Flag=N;";
|
||
|
||
//流向
|
||
string dir = "e01205-Avg=" + direction + ",e01205-Flag=N" + "&&";
|
||
|
||
//数据域
|
||
string Data = RequestEncoding + SystemCoding + CommandCode + AccessPassword + DeviceIdentification + Response + CP + Velocity + dir;
|
||
|
||
//更新数据域长度
|
||
date_length = "0" + Data.Length;
|
||
|
||
//数据域转化为byte数组
|
||
byte[] ByteData = System.Text.Encoding.Default.GetBytes(Data);
|
||
|
||
//计算crc
|
||
byte[] crc = CRC16_CheckOut(ByteData);
|
||
string crc1 = crc[0].ToString("X2");
|
||
string crc2 = crc[1].ToString("X2");
|
||
|
||
//完整的数据字符串
|
||
string FullData = Head + date_length + Data + crc1 + crc2;
|
||
|
||
//将完整的数据转化为byte数组
|
||
byte[] FullByteData = System.Text.Encoding.Default.GetBytes(FullData);
|
||
|
||
//包尾 (回车、换行)
|
||
byte[] rn = new byte[2];
|
||
rn[0] = 0x0D;
|
||
rn[1] = 0x0A;
|
||
|
||
|
||
List<byte> data = FullByteData.ToList();
|
||
data.AddRange(rn);
|
||
string list = tools.byteToHexStr(data.ToArray());
|
||
byte[] bytea = tools.ConvertHexStringToBytes(list);
|
||
_client.SendData(bytea);
|
||
|
||
}
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// CRC16 循环冗余校验算法
|
||
/// </summary>
|
||
/// <param name="pushMsg"></param>
|
||
/// <returns></returns>
|
||
private byte[] CRC16_CheckOut(byte[] pushMsg)
|
||
{
|
||
int crc_reg, check;
|
||
crc_reg = 0xFFFF;
|
||
for (int i = 0; i < pushMsg.Length; i++)
|
||
{
|
||
crc_reg = (crc_reg >> 8) ^ pushMsg[i];
|
||
for (int j = 0; j < 8; j++)
|
||
{
|
||
check = crc_reg & 0x0001;
|
||
crc_reg >>= 1;
|
||
if (check == 0x0001)
|
||
{
|
||
crc_reg ^= 0xA001;
|
||
}
|
||
}
|
||
}
|
||
|
||
byte[] returnMsg = new byte[2];
|
||
returnMsg[0] = (byte)(crc_reg >> 8);
|
||
returnMsg[1] = (byte)(crc_reg & 0xFF);
|
||
return returnMsg;
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 检查连接状态
|
||
/// </summary>
|
||
/// <param name="Message"></param>
|
||
private async void DoConnect()
|
||
{
|
||
int i = 0;
|
||
await Task.Run(() =>
|
||
{
|
||
Thread.Sleep(2000);
|
||
|
||
while (i < 3)
|
||
{
|
||
Thread.Sleep(2000);
|
||
if (MessageAll == null || MessageAll == "" || (!MessageAll.StartsWith("2323")))
|
||
{
|
||
tools.Logging("未收到IP:" + main_ip + "端口号:" + main_port + " 回复的信息,开始重新连接");
|
||
Thread.Sleep(10000);
|
||
DoSocket1Connect("连接");
|
||
Thread.Sleep(1000);
|
||
SendMessage(adcp.SurfaceVelocity, adcp.FlowDirection);
|
||
i++;
|
||
}
|
||
else if (MessageAll.StartsWith("2323"))
|
||
{
|
||
tools.Logging("收到IP:" + main_ip + "端口号:" + main_port + " 回复的信息,连接成功");
|
||
break;
|
||
}
|
||
|
||
}
|
||
MessageAll = "";
|
||
i = 0;
|
||
|
||
});
|
||
}
|
||
}
|
||
}
|