Partage de technologie

Transfert de données du port série C# vers le port réseau pour réaliser la détection de la vitesse et de la direction du vent

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

1. Construction de formulaire

Ajouter du temps (minuterie)

Parce que la vitesse et la direction du vent doivent être actualisées automatiquement

2. Effectuer la détection de l'air du port réseau

①Bouton de connexion au serveur

  1. // 连接按钮
  2. private void button1_Click(object sender, EventArgs e)
  3. {
  4. if (button1.Text =="连接")
  5. {
  6. ConnectSocke();// 连接服务器
  7. }
  8. else
  9. {
  10. CloseSocket(); // 关闭服务器
  11. }
  12. }
  13. Socket soc;
  14. // 连接方法
  15. void ConnectSocke()
  16. {
  17. try
  18. {
  19. // 创建socket对象
  20. soc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);// 套接字对象
  21. // 连接服务器ip地址,端口号
  22. soc.Connect(this.textBox1.Text, int.Parse(this.textBox2.Text));
  23. button1.Text = "关闭";
  24. textBox1.Enabled = false;
  25. textBox2.Enabled = false;
  26. }
  27. catch (Exception ex)
  28. {
  29. MessageBox.Show("串口服务器连接失败");
  30. }
  31. }
  32. // 关闭方法
  33. void CloseSocket()
  34. {
  35. if (soc!=null && soc.Connected)
  36. {
  37. soc.Close();
  38. }
  39. button1.Text = "连接";
  40. this.textBox1.Enabled = true;
  41. this.textBox2.Enabled = true;
  42. }
  43. // 连接方法
  44. void ConnectSocke()
  45. {
  46. try
  47. {
  48. // 创建socket对象
  49. soc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);// 套接字对象
  50. // 连接服务器ip地址,端口号
  51. soc.Connect(this.textBox1.Text, int.Parse(this.textBox2.Text));
  52. button1.Text = "关闭";
  53. textBox1.Enabled = false;
  54. textBox2.Enabled = false;
  55. }
  56. catch (Exception ex)
  57. {
  58. MessageBox.Show("串口服务器连接失败");
  59. }
  60. }

Déterminez si bouton1.text est "connecté". S'il est connecté, exécutez la méthode ConnectSocke(); sinon CloseSocket();

Méthode de connexion : utilisez la gestion des exceptions try catch, créez une variable globale Socket soc ; créez un numéro de port IP de connexion d'objet, remplacez textbox1.text par fermé, textBox1.Enabled=false empêche la zone de saisie de saisir, la gestion des exceptions catch détermine le code in try Faut-il signaler une erreur ? Si une erreur est signalée, exécutez le code dans catch.

Méthode de déconnexion : déterminez si le soc est vide ou si le soc est connecté. Si la connexion est fermée soc.Close();, définissez button1.text="Connect" pour que textbox1 et 2 puissent Enabled=true annuler ;

3. Méthode de connexion

  1. // 发送按钮
  2. private void button2_Click(object sender, EventArgs e)
  3. {
  4. string sendS = this.textBox3.Text.Trim();// 发送字符串
  5. if (soc == null || !soc.Connected)
  6. {
  7. MessageBox.Show("服务器没连接");
  8. return;
  9. }
  10. if (string.IsNullOrEmpty(sendS))
  11. {
  12. MessageBox.Show("指令不能为空");
  13. return;
  14. }
  15. //1 把字符串转成字符数组
  16. byte[] data = StringToHexByte(sendS);
  17. //2 计算校检码
  18. byte[] b1 = CRCCalc(data);
  19. //3 合并字节数组和校检码数组
  20. data = data.Concat(b1).ToArray();
  21. button2.Enabled = false;
  22. Task.Run(() =>
  23. {
  24. //4 发起请求帧
  25. soc.Send(data);// 发消息 请求 温度请求帧data = []
  26. Thread.Sleep(1000);// 休眠1秒
  27. //5 接受数据 // 接收温度
  28. byte[] rec = new byte[1024]; // rec =
  29. int length = soc.Receive(rec);
  30. // 6 解析数据并且展示数据 把字节数组转成字符串
  31. string s = ByteToString(rec, length);
  32. s += "rn";
  33. int temp = (rec[3] * 256 + rec[4]) / 10;// 温度
  34. this.richTextBox1.Invoke((Action)(() =>
  35. {
  36. richTextBox1.AppendText(s);// 响应帧
  37. richTextBox1.AppendText($"当前温度温度为:{temp}摄氏度,时间为:{DateTime.Now.ToString()}rn");
  38. button2.Enabled = true;
  39. }));
  40. });
  41. }
  42. string ByteToString(byte[] b1,int l)
  43. {
  44. StringBuilder sb = new StringBuilder();// 可变字符串
  45. for (int i = 0; i < l; i++)
  46. {
  47. sb.Append(b1[i].ToString("X2")+" ");
  48. }
  49. return sb.ToString();
  50. }
  51. // 字符串转成字符数组
  52. byte[] StringToHexByte(string s)
  53. {
  54. string[] ss = s.Split(' ');
  55. byte[] result = new byte[ss.Length];// 字节数组
  56. for (int i = 0; i < ss.Length; i++)
  57. {
  58. result[i] = Convert.ToByte(ss[i], 16);//转成16进制字节
  59. }
  60. return result;
  61. }
  62. // 校检方法
  63. public static byte[] CRCCalc(byte[] data)
  64. {
  65. //crc计算赋初始值
  66. int crc = 0xffff;
  67. for (int i = 0; i < data.Length; i++)
  68. {
  69. //XOR
  70. //(1) 0^0=0,0^1=1 0异或任何数=任何数
  71. //(2) 1 ^ 0 = 1,1 ^ 1 = 0 1异或任何数-任何数取反
  72. //(3) 1 ^ 1 = 0,0 ^ 0 = 0 任何数异或自己=把自己置0
  73. //异或操作符是^。异或的特点是相同为false,不同为true。
  74. crc = crc ^ data[i]; //和^表示按位异或运算。
  75. //0x0fff ^ 0x01 Console.WriteLine(result.ToString("X"));
  76. // 输出结果为4094,即十六进制数1001
  77. for (int j = 0; j < 8; j++)
  78. {
  79. int temp;
  80. temp = crc & 1; // & 运算符(与) 1 & 0 为 0 ;0 & 0 为0;1 & 1 为1
  81. //右移 (>>) 将第一个操作数向右移动第二个操作数所指定的位数,空出的位置补0。右移相当于整除. 右移一位相当于除以2;右移两位相当于除以4;右移三位相当于除以8。
  82. //int i = 7;
  83. //int j = 2;
  84. //Console.WriteLine(i >> j); //输出结果为1
  85. crc = crc >> 1;
  86. crc = crc & 0x7fff;
  87. if (temp == 1)
  88. {
  89. crc = crc ^ 0xa001;
  90. }
  91. crc = crc & 0xffff;
  92. }
  93. }
  94. //CRC寄存器的高低位进行互换
  95. byte[] crc16 = new byte[2];
  96. //CRC寄存器的高8位变成低8位,
  97. crc16[1] = (byte)((crc >> 8) & 0xff);
  98. //CRC寄存器的低8位变成高8位
  99. crc16[0] = (byte)(crc & 0xff);
  100. return crc16;
  101. }

3. Bouton Actualiser

  1. // 刷新按钮
  2. private void button3_Click(object sender, EventArgs e)
  3. {
  4. Refresh1();
  5. }
  6. void Refresh1()
  7. {
  8. if (soc == null || !soc.Connected)
  9. {
  10. MessageBox.Show("没连接");
  11. return;
  12. }
  13. Task.Run(() =>
  14. {
  15. // 请求帧的组织
  16. byte[] bs = new byte[] {0x01,0x03,0x00,0x00,0x00,0x02};// 风速和风向请求放在一起
  17. // 数据和校检
  18. bs = bs.Concat(CRCCalc(bs)).ToArray();
  19. soc.Send(bs);// 发送
  20. Thread.Sleep(1000);
  21. // 接受数据表
  22. byte[] rec = new byte[1024];
  23. int length = soc.Receive(rec);
  24. double wind = (rec[3] * 256 + rec[4]) * 0.01;
  25. double dir = (rec[5] * 256 + rec[6]);
  26. this.Invoke((Action)(() =>
  27. {
  28. this.textBox4.Text = wind + "m/s";
  29. this.textBox5.Text = dir + "";
  30. }));
  31. });
  32. }
  33. // 定时器
  34. private void timer1_Tick(object sender, EventArgs e)
  35. {
  36. if (checkBox1.Checked)// 复选框被选中
  37. {
  38. Refresh1();
  39. }
  40. }
  41. }
  42. }