原创:局域网控制系统-上位机-PC机
C#程序代码:
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Linq; 7 using System.Text; 8 using System.Windows.Forms; 9 using System.IO.Ports; 10 //using System.Threading; //用于多线程技术 11 12 namespace WindowsFormsApplication1 //C#不再支持控件数组,也就意味不能灵活控制控件 13 { 14 public partial class Form1 : Form 15 { 16 const string deviceID = "03"; //用于串口通信时,定义本地设备ID 17 const string datapackage_headflag = "A"; //用于串口通信时,定义数据包头部的验证标记 18 19 20 //用来请求主线程的委托,利用delegat实现"请求主线程执行指定函数",由于delegate在定义的时候就确定了传递函数的参数,所以在需要传递不同函数给主线程的时候就需要定义多个delegate 21 public delegate void ChangeUI_1(String arg); //子线程不能操作UI,会导致程序崩毁,需要让主线程操作UI 22 public delegate void ChangeUI_2(int[] arg); 23 public delegate void ChangeUI_3(String[] arg); 24 public delegate Boolean ChangeUI_4(); 25 26 //----------定时器控制指令的发送----------// 27 System.Timers.Timer timer_SendCMD = new System.Timers.Timer(1010); //设定定时器计时周期为1000ms 28 29 //不断获取温度传感器值 30 public void GetTemperature(object source, System.Timers.ElapsedEventArgs e) 31 { 32 UART_send(uart_data_temperature_sensor0, 40); //建议获取一次温度值后产生40ms发送间隔 33 } 34 35 //----------固定发送数据包集----------// 36 const String uart_data_light0off = datapackage_headflag + deviceID + "_Ligt00Off_#"; 37 const String uart_data_light0on = datapackage_headflag + deviceID + "_Ligt00On__#"; 38 const String uart_data_light1off = datapackage_headflag + deviceID + "_Ligt01Off_#"; 39 const String uart_data_light1on = datapackage_headflag + deviceID + "_Ligt01On__#"; 40 const String uart_data_light2off = datapackage_headflag + deviceID + "_Ligt02Off_#"; 41 const String uart_data_light2on = datapackage_headflag + deviceID + "_Ligt02On__#"; 42 const String uart_data_temperature_sensor0 = datapackage_headflag + deviceID + "_SenT00____#"; 43 const String uart_data_try = datapackage_headflag + deviceID + "_Try!______#"; 44 //----------通信监测----------// 45 Boolean NeedToCheckUART = false; 46 Boolean heartbeat = false; //心跳包(用来协助监测通信是否断开) 47 System.Timers.Timer timer_UARTMonitor = new System.Timers.Timer(2000); 48 public void CheckUART(object source, System.Timers.ElapsedEventArgs e) 49 { 50 if (NeedToCheckUART) //检查通信状态 51 { 52 NeedToCheckUART = false; 53 if (heartbeat) 54 { 55 heartbeat = false; 56 } 57 else 58 { 59 this.Invoke(new ChangeUI_4(CloseUART)); 60 this.Invoke(new ChangeUI_1(UpdateNotice), "已断开连接!没有接收到心跳包!"); 61 } 62 } 63 else 64 { 65 NeedToCheckUART = true; 66 //请求接收者反馈心跳包,以确认连接是否出现异常 67 UART_send(uart_data_try,25); 68 } 69 } 70 //----------产生发送数据的间隔----------// 71 Boolean SendCMD_WaitFlag = false; 72 void SetSendCMD_Interval(uint Interval) 73 { 74 System.Timers.Timer timer_SetSendCMD_Interval = new System.Timers.Timer(Interval); 75 timer_SetSendCMD_Interval.Elapsed += new System.Timers.ElapsedEventHandler(Erase_SendCMD_WaitFlag); 76 timer_SetSendCMD_Interval.AutoReset = false; 77 timer_SetSendCMD_Interval.Start(); 78 } 79 public void Erase_SendCMD_WaitFlag(object source, System.Timers.ElapsedEventArgs e) 80 { 81 SendCMD_WaitFlag = false; 82 } 83 //----------温度指示----------// 84 int[] TemperatureSensor = new int[4]; 85 int UpLimit_1 = 301, //300=30℃ 86 DownLimit_1 = 100, 87 UpLimit_2 = 300, 88 DownLimit_2 = 100, 89 UpLimit_3 = 300, 90 DownLimit_3 = 100, 91 UpLimit_4 = 300, 92 DownLimit_4 = 100; 93 SolidBrush brush1, 94 brush2; 95 Graphics g1, 96 g2, 97 g3, 98 g4, 99 g5, 100 g6, 101 g7, 102 g8; 103 //------------------------------------// 104 public Form1() 105 { 106 InitializeComponent(); 107 108 } 109 110 private void Form1_Load(object sender, EventArgs e) 111 { 112 /*--------串口通信监测---------*/ 113 timer_UARTMonitor.Elapsed += new System.Timers.ElapsedEventHandler(CheckUART); // 添加定时器计时满一个周期的后要执行的函数; 114 timer_UARTMonitor.AutoReset = true; //设置定时器是否启动自动复位,true意味着定时器一旦启动,如果没有手动关闭,则定时器会不断周期性执行任务,false意味着启动定时器后,到达周期时间值,执行一次任务,然后自动关闭定时器 115 //----------定时器控制指令的发送----------// 116 timer_SendCMD.Elapsed += new System.Timers.ElapsedEventHandler(GetTemperature); 117 timer_SendCMD.AutoReset = true; 118 /*----------串口通信接口设置----------*/ 119 cmb_SerialPort.SelectedIndex = 0; 120 cmb_BaudRate.SelectedIndex = 1; 121 cmb_Parity.SelectedIndex = 0; 122 cmb_DataBit.SelectedIndex = 0; 123 cmb_StopBit.SelectedIndex = 0; 124 btn_Send.Enabled = false; 125 btn_UpdataReceive.Text = "关闭更新串口数据"; 126 127 //温度警报指示 128 brush1 = new SolidBrush(Color.Red); 129 brush2 = new SolidBrush(Color.Green); 130 g1 = this.pictureBox1.CreateGraphics(); 131 g2 = this.pictureBox2.CreateGraphics(); 132 g3 = this.pictureBox3.CreateGraphics(); 133 g4 = this.pictureBox4.CreateGraphics(); 134 g5 = this.pictureBox5.CreateGraphics(); 135 g6 = this.pictureBox6.CreateGraphics(); 136 g7 = this.pictureBox7.CreateGraphics(); 137 g8 = this.pictureBox8.CreateGraphics(); 138 139 //温度上下限文本框初始化 140 textBox1.Text = Convert.ToString((float)(UpLimit_1)/10); 141 textBox2.Text = Convert.ToString((float)(DownLimit_1)/10); 142 textBox4.Text = Convert.ToString((float)(UpLimit_2)/10); 143 textBox3.Text = Convert.ToString((float)(DownLimit_2)/10); 144 textBox6.Text = Convert.ToString((float)(UpLimit_3)/10); 145 textBox5.Text = Convert.ToString((float)(DownLimit_3)/10); 146 textBox8.Text = Convert.ToString((float)(UpLimit_4)/10); 147 textBox7.Text = Convert.ToString((float)(DownLimit_4)/10); 148 149 } 150 151 /*----------串口通信接口设置----------*/ 152 /* 153 客户端数据包格式解释(长度恒为15): 154 例如:A01_fmq_01Off___# 155 A--------数据包的开始标记(可以为A到Z,意味着数据包可以有26种) 156 01-----设备代号 157 fmq_01Off___--------指令(长度恒为10),指令的前4个人字符是指令头部,指令的后6个字符是指令尾部 158 #---------数据包的结束标记 159 160 服务器端数据包格式解释(长度恒为15): 161 例如:A02_SenT010250# 162 A--------数据包的开始标记(可以为A到Z,意味着数据包可以有26种) 163 02-----设备代号 164 SenT010250--------指令(长度恒为10),指令的前4个人字符是指令头部,指令的后6个字符是指令尾部 165 #---------数据包的结束标记 166 */ 167 SerialPort com = new SerialPort("COM2", 9600, Parity.None, 8, StopBits.One); 168 //串口打开与关闭 169 public Boolean CloseUART() 170 { 171 timer_UARTMonitor.Stop(); //停止定时器监测通信状态 172 timer_SendCMD.Stop(); //停止定时器控制指令的定时发送 173 try 174 { 175 com.Close(); //关闭串口 176 btn_OpenSerial.Text = "打开串口"; 177 lab_Status.Text = "未连接!"; 178 btn_Send.Enabled = false; 179 return true; 180 } 181 catch 182 { 183 return false; 184 } 185 } 186 //处理接收数据包函数(成功处理数据包则返回true,否则返回false) 187 public Boolean Deal_UART_RecData(String ReceStr) 188 { 189 if (ReceStr.Length == 15) //数据包长度为15 190 { 191 if ((ReceStr.Substring(0, 1) == datapackage_headflag) && (ReceStr.Substring(14, 1) == "#")) //数据包头尾标记验证 192 { 193 switch (ReceStr.Substring(1, 1)) //识别发送者设备ID的第1位数字 194 { 195 case "0": 196 switch (ReceStr.Substring(2, 1)) //识别发送者设备ID的第2位数字 197 { 198 case "0": 199 200 return false; 201 case "1": 202 203 return false; 204 case "2": 205 //----------指令分析-----------// 206 switch (ReceStr.Substring(4, 4)) //对指令头部进行分析(4个字符) 207 { 208 case "SenT": 209 //对指令尾部进行分析(6个字符) 210 int[] temp = new int[2]; 211 try 212 { 213 temp[0] = int.Parse(ReceStr.Substring(8, 2)); 214 temp[1] = int.Parse(ReceStr.Substring(10, 4)); 215 TemperatureSensor[temp[0]] = temp[1]; 216 this.Invoke(new ChangeUI_2(UpdateSenT), temp); 217 return true; 218 } 219 catch 220 { 221 this.Invoke(new ChangeUI_1(UpdateNotice), "接收的指令:指令尾部异常"); 222 return false; 223 } 224 case "Beat": 225 heartbeat = true; 226 return true; 227 default: 228 this.Invoke(new ChangeUI_1(UpdateNotice), "接收的指令:指令头部异常"); 229 return false; 230 } 231 default: 232 this.Invoke(new ChangeUI_1(UpdateNotice), "接收的数据包:设备ID异常"); 233 return false; 234 } 235 default: 236 this.Invoke(new ChangeUI_1(UpdateNotice), "接收的数据包:设备ID异常"); 237 return false; 238 } 239 } 240 else 241 { 242 this.Invoke(new ChangeUI_1(UpdateNotice), "接收的数据包:头尾部验证异常"); 243 return false; 244 } 245 } 246 else 247 { 248 this.Invoke(new ChangeUI_1(UpdateNotice), "接收的数据包:长度异常"); 249 return false; 250 } 251 } 252 //打开或关闭串口按钮 253 private void btn_OpenSerial_Click(object sender, EventArgs e) 254 { 255 if (btn_OpenSerial.Text == "打开串口") 256 { 257 try 258 { 259 if (!com.IsOpen) 260 { 261 com.PortName = cmb_SerialPort.Text; 262 com.BaudRate = int.Parse(cmb_BaudRate.Text); 263 com.DataBits = int.Parse(cmb_DataBit.Text); 264 switch (cmb_StopBit.SelectedIndex) 265 { 266 case 0: 267 com.StopBits = StopBits.One; break; 268 case 1: 269 com.StopBits = StopBits.Two; break; 270 case 2: 271 com.StopBits = StopBits.OnePointFive; break; 272 case 3: 273 com.StopBits = StopBits.None; break; 274 } 275 switch (cmb_Parity.SelectedIndex) 276 { 277 case 0: com.Parity = Parity.None; break; 278 case 1: com.Parity = Parity.Odd; break; 279 case 2: com.Parity = Parity.Even; break; 280 } 281 com.Open();//打开串口 282 lab_Status.Text = "已连接!"; 283 } 284 btn_OpenSerial.Text = "关闭串口"; 285 btn_Send.Enabled = true; 286 287 //串口连接成功后进行初始化 288 NeedToCheckUART = false; 289 heartbeat = false; 290 timer_SendCMD.Start(); //每隔一段时间获取一次温度值数据 291 timer_UARTMonitor.Start(); //启动定时器监测通信状态 292 293 try 294 { 295 //给串口添加接收中断函数(串口中断函数在没有被执行的时候,也就是串口接收处理空闲的时候,系统会不断监测接收缓冲区是否有数据存在,如果有,则执行中断函数) 296 com.DataReceived += new SerialDataReceivedEventHandler(com_DataReceived); 297 } 298 catch (Exception err) 299 { 300 lab_Status.Text = err.ToString(); 301 } 302 303 } 304 catch 305 { 306 lab_Status.Text = "串口打开错误"; 307 } 308 } 309 else //关闭串口 310 { 311 CloseUART(); 312 } 313 } 314 //串口接收中断函数(注意:不要出现数据包被分割,导致通信异常;数据包之间间隔时间不能太短) 315 private void com_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) 316 { 317 System.Threading.Thread.Sleep(30); //让当前线程睡眠30ms,因为需要保证数据包完整接收到了(在执行中断函数并获取接收缓冲区接收到的字节数时,假如数据包还没有完全被接收完,这时数据包就会出现被“分割”),再去判断接收缓冲区接收到的字节数,才能保证正常通信 318 int count = com.BytesToRead; //获取接收缓冲区接收到的字节数 319 byte[] readBuffer = new byte[count]; 320 com.Read(readBuffer, 0, count); 321 String strReceive = Encoding.Default.GetString(readBuffer); //将ASCLL码 映射成 字符 322 //String strReceive = getStringFromBytes(readBuffer); //将ASCLL码 转换成 字符串 323 this.Invoke(new ChangeUI_1(AddMessage), strReceive); //尝试更新接收数据框 324 //this.Invoke(new ChangeUI_1(UpdateNotice), strReceive.Length.ToString()); //此行代码用于测试数据包是否出现被分割 325 326 //下面对接收到的数据包(strReceive)进行分析,根据情况执行相应事件 327 if (Deal_UART_RecData(strReceive)) 328 { 329 this.Invoke(new ChangeUI_1(UpdateNotice), "处理接收的数据包成功!"); 330 } 331 332 } 333 //子线程请求主线程要执行的子函数,当发生多次请求时,主线程会分时执行函数(之所以要请求主线程是因为涉及到UI操作,子线程不能操作UI,否则导致程序崩毁) 334 public void UpdateSenT(int[] arg) 335 { 336 Int16 graphy_width = 44; 337 Int16 graphy_heigth = 21; 338 switch (arg[0]) 339 { 340 case 0: 341 if (arg[1] == 9999) 342 { 343 label6.Text = "不工作"; 344 return; 345 } 346 if (arg[1] < 0) 347 { 348 label6.Text = (arg[1] / 10).ToString() + "." + ((arg[1] % 10)*(-1)).ToString() + "℃"; 349 } 350 else 351 { 352 label6.Text = "+"+(arg[1] / 10).ToString() + "." + (arg[1] % 10).ToString() + "℃"; 353 } 354 if (TemperatureSensor[arg[0]] > UpLimit_1) 355 { 356 g1.FillRectangle(brush1, 0, 0, graphy_width, graphy_heigth); 357 g2.FillRectangle(brush2, 0, 0, graphy_width, graphy_heigth); 358 } 359 else if (TemperatureSensor[arg[0]] < DownLimit_1) 360 { 361 g2.FillRectangle(brush1, 0, 0, graphy_width, graphy_heigth); 362 g1.FillRectangle(brush2, 0, 0, graphy_width, graphy_heigth); 363 } 364 else 365 { 366 g1.FillRectangle(brush2, 0, 0, graphy_width, graphy_heigth); 367 g2.FillRectangle(brush2, 0, 0, graphy_width, graphy_heigth); 368 } 369 break; 370 case 1: 371 if (arg[1] == 9999) 372 { 373 label7.Text = "不工作"; 374 return; 375 } 376 if (arg[1] < 0) 377 { 378 label7.Text = (arg[1] / 10).ToString() + "." + ((arg[1] % 10)*(-1)).ToString() + "℃"; 379 } 380 else 381 { 382 label7.Text = "+"+(arg[1] / 10).ToString() + "." + (arg[1] % 10).ToString() + "℃"; 383 } 384 if (TemperatureSensor[arg[0]] > UpLimit_2) 385 { 386 g4.FillRectangle(brush1, 0, 0, graphy_width, graphy_heigth); 387 g3.FillRectangle(brush2, 0, 0, graphy_width, graphy_heigth); 388 } 389 else if (TemperatureSensor[arg[0]] < DownLimit_2) 390 { 391 g3.FillRectangle(brush1, 0, 0, graphy_width, graphy_heigth); 392 g4.FillRectangle(brush2, 0, 0, graphy_width, graphy_heigth); 393 } 394 else 395 { 396 g3.FillRectangle(brush2, 0, 0, graphy_width, graphy_heigth); 397 g4.FillRectangle(brush2, 0, 0, graphy_width, graphy_heigth); 398 } 399 break; 400 case 2: 401 if (arg[1] == 9999) 402 { 403 label8.Text = "不工作"; 404 return; 405 } 406 if (arg[1] < 0) 407 { 408 label8.Text = (arg[1] / 10).ToString() + "." + ((arg[1] % 10) * (-1)).ToString() + "℃"; 409 } 410 else 411 { 412 label8.Text = "+" + (arg[1] / 10).ToString() + "." + (arg[1] % 10).ToString() + "℃"; 413 } 414 if (TemperatureSensor[arg[0]] > UpLimit_3) 415 { 416 g6.FillRectangle(brush1, 0, 0, graphy_width, graphy_heigth); 417 g5.FillRectangle(brush2, 0, 0, graphy_width, graphy_heigth); 418 } 419 else if (TemperatureSensor[arg[0]] < DownLimit_3) 420 { 421 g5.FillRectangle(brush1, 0, 0, graphy_width, graphy_heigth); 422 g6.FillRectangle(brush2, 0, 0, graphy_width, graphy_heigth); 423 } 424 else 425 { 426 g6.FillRectangle(brush2, 0, 0, graphy_width, graphy_heigth); 427 g5.FillRectangle(brush2, 0, 0, graphy_width, graphy_heigth); 428 } 429 break; 430 case 3: 431 if (arg[1] == 9999) 432 { 433 label9.Text = "不工作"; 434 return; 435 } 436 if (arg[1] < 0) 437 { 438 label9.Text = (arg[1] / 10).ToString() + "." + ((arg[1] % 10) * (-1)).ToString() + "℃"; 439 } 440 else 441 { 442 label9.Text = "+" + (arg[1] / 10).ToString() + "." + (arg[1] % 10).ToString() + "℃"; 443 } 444 if (TemperatureSensor[arg[0]] > UpLimit_4) 445 { 446 g8.FillRectangle(brush1, 0, 0, graphy_width, graphy_heigth); 447 g7.FillRectangle(brush2, 0, 0, graphy_width, graphy_heigth); 448 } 449 else if (TemperatureSensor[arg[0]] < DownLimit_4) 450 { 451 g7.FillRectangle(brush1, 0, 0, graphy_width, graphy_heigth); 452 g8.FillRectangle(brush2, 0, 0, graphy_width, graphy_heigth); 453 } 454 else 455 { 456 g7.FillRectangle(brush2, 0, 0, graphy_width, graphy_heigth); 457 g8.FillRectangle(brush2, 0, 0, graphy_width, graphy_heigth); 458 } 459 break; 460 default: 461 lab_Information.Text = "接收的指令:指令尾部异常"; 462 break; 463 } 464 } 465 public void AddMessage(string arg) 466 { 467 //处理接受的字符串,添加到接收文本框中 468 if (btn_UpdataReceive.Text == "关闭更新串口数据") 469 { 470 txt_Receive.Text += arg; 471 } 472 } 473 public void UpdateNotice(string arg) 474 { 475 lab_Information.Text = arg; 476 } 477 //启动串口发送数据 478 private Boolean UART_send(String str,uint MinInterval) //0xFFFFFFFF=4294967295 479 { 480 while (SendCMD_WaitFlag) ; //等待结束上一次发送数据所要求的间隔,以保证每次发送出去的数据包都能被正确接收处理 481 SendCMD_WaitFlag = true; 482 try 483 { 484 //byte[] data = getBytesFromString(str1); //将数字形式的字符串 转换成 ASCLL码 485 byte[] data = System.Text.Encoding.ASCII.GetBytes(str); //将字符 映射成 ASCLL码 486 com.Write(data, 0, data.Length); 487 SetSendCMD_Interval(MinInterval); 488 try 489 { 490 lab_Information.Text = "发送指令成功!"; 491 } 492 catch { } 493 return true; 494 } 495 catch 496 { 497 SendCMD_WaitFlag = false; 498 try 499 { 500 lab_Information.Text = "发送指令失败!"; 501 } 502 catch { } 503 return false; 504 } 505 506 } 507 508 //串口自定义发送 509 private void btn_Send_Click(object sender, EventArgs e) 510 { 511 if (!UART_send(txt_Send.Text,30)) 512 { 513 lab_Information.Text = "串口发送失败"; 514 } 515 } 516 //将ASCLL码映射成字符 517 public static string getStringFromBytes(byte[] pByte) 518 { 519 string str = ""; //定义字符串类型临时变量。 520 //遍历字节数组,把每个字节转换成十六进制字符串,不足两位前面添“0”,以空格分隔累加到字符串变量里。 521 for (int i = 0; i < pByte.Length; i++) 522 str += (pByte[i].ToString("X").PadLeft(2, '0') + " "); 523 str = str.TrimEnd(' '); //去掉字符串末尾的空格。 524 return str; //返回字符串 525 } 526 //将字符串转换成ASCLL码 527 public static byte[] getBytesFromString(string pString) 528 { 529 string[] str = pString.Split(' '); //把字符串按其中的空格字符为分隔标志,得出一组字符串数组。 530 byte[] bytes = new byte[str.Length]; //定义字节数组并初始化,长度为字符串数组的长度。 531 for (int i = 0; i < str.Length; i++) //遍历字符串数组,把每个字符串转换成字节类型赋值给每个字节变量。 532 bytes[i] = Convert.ToByte(Convert.ToInt32(str[i], 16)); 533 return bytes; //返回字节数组。 534 } 535 //是否更新串口数据按钮 536 private void btn_UpdataReceive_Click(object sender, EventArgs e) 537 { 538 if (btn_UpdataReceive.Text == "关闭更新串口数据") 539 { 540 btn_UpdataReceive.Text = "打开更新串口数据"; 541 } 542 else 543 { 544 btn_UpdataReceive.Text = "关闭更新串口数据"; 545 } 546 } 547 //清空接收区 548 private void btn_ClearReceive_Click_1(object sender, EventArgs e) 549 { 550 551 txt_Receive.Text = ""; 552 } 553 //---------设置上下限温度值按钮---------// 554 private void button1_Click(object sender, EventArgs e) 555 { 556 try 557 { 558 UpLimit_1 = (int)(float.Parse(textBox1.Text.ToString())*10); 559 DownLimit_1 = (int)(float.Parse(textBox2.Text.ToString()) * 10); 560 lab_Information.Text = "设置温度上下限成功"; 561 } 562 catch 563 { 564 lab_Information.Text = "请输入正确格式的数据"; 565 } 566 } 567 private void button2_Click(object sender, EventArgs e) 568 { 569 try 570 { 571 UpLimit_2 = (int)(float.Parse(textBox4.Text.ToString())*10); 572 DownLimit_2 = (int)(float.Parse(textBox3.Text.ToString())*10); 573 lab_Information.Text = "设置温度上下限成功"; 574 } 575 catch 576 { 577 lab_Information.Text = "请输入正确格式的数据"; 578 } 579 } 580 private void button3_Click(object sender, EventArgs e) 581 { 582 try 583 { 584 UpLimit_3 = (int)(float.Parse(textBox6.Text.ToString()) * 10); 585 DownLimit_3 = (int)(float.Parse(textBox5.Text.ToString()) * 10); 586 lab_Information.Text = "设置温度上下限成功"; 587 } 588 catch 589 { 590 lab_Information.Text = "请输入正确格式的数据"; 591 } 592 } 593 private void button4_Click(object sender, EventArgs e) 594 { 595 try 596 { 597 UpLimit_4 = (int)(float.Parse(textBox8.Text.ToString()) * 10); 598 DownLimit_4 = (int)(float.Parse(textBox7.Text.ToString()) * 10); 599 lab_Information.Text = "设置温度上下限成功"; 600 } 601 catch 602 { 603 lab_Information.Text = "请输入正确格式的数据"; 604 } 605 } 606 607 //----------------灯光控制----------------// 608 private void btn_light_0_Click(object sender, EventArgs e) 609 { 610 if (btn_light_0.Text == "关") 611 { 612 if (UART_send(uart_data_light0off,2)) 613 { 614 btn_light_0.Text = "开"; 615 } 616 617 } 618 else 619 { 620 if (UART_send(uart_data_light0on,2)) 621 { 622 btn_light_0.Text = "关"; 623 } 624 } 625 } 626 627 private void btn_light_1_Click(object sender, EventArgs e) 628 { 629 if (btn_light_1.Text == "关") 630 { 631 if (UART_send(uart_data_light1off,2)) 632 { 633 btn_light_1.Text = "开"; 634 } 635 636 } 637 else 638 { 639 if (UART_send(uart_data_light1on,2)) 640 { 641 btn_light_1.Text = "关"; 642 } 643 } 644 } 645 646 private void btn_light_2_Click(object sender, EventArgs e) 647 { 648 if (btn_light_2.Text == "关") 649 { 650 if (UART_send(uart_data_light2off,2)) 651 { 652 btn_light_2.Text = "开"; 653 } 654 655 } 656 else 657 { 658 if (UART_send(uart_data_light2on,2)) 659 { 660 btn_light_2.Text = "关"; 661 } 662 } 663 } 664 665 } 666 }
单片机通过串口通信直接跟PC连接,PC控制单片机,如下图所示:
注意:在单片机跟PC进行串口通信的时候,记得把ESP8266给拆下,不然因其干扰而导致通信失败(共用一个串口接口肯定会互相干扰啦)。
想要完整工程文件或疑问可以私聊我~
请另外观看项目的2个部分:
1)局域网控制系统-下位机-单片机
2)局域网控制系统-上位机-Android手机
尊重作者的劳动,转载请记得注明来源:http://www.cnblogs.com/weifeng727/p/5618142.html