WinForm 与 Arduino 进行串口通信实现 LED 灯开关操作
参考
- DeepSeek
- https://www.cnblogs.com/xiaqiuchu/p/16740592.html
- https://blog.csdn.net/lhwanglei/article/details/108569051
- https://docs.arduino.cc/language-reference/en/variables/constants/highLow/
- https://www.qutaojiao.com/199.html
- https://wenku.csdn.net/answer/be476e1871e04d7e93971a6239110081
- https://www.cnblogs.com/whuanle/p/8622830.html
- https://blog.csdn.net/ba_wang_mao/article/details/113642066
- https://www.cnblogs.com/vuciao/p/10586742.html
- https://q.cnblogs.com/q/29277
- https://www.cnblogs.com/xiaqiuchu/p/18886268
- https://learn.microsoft.com/zh-cn/dotnet/api/system.io.ports.serialport?view=netframework-4.8
- https://blog.csdn.net/ba_wang_mao/article/details/113642066
- https://learn.microsoft.com/zh-cn/dotnet/api/system.io.ports.serialport?view=netframework-4.8
- https://blog.csdn.net/xpj8888/article/details/84628762
- https://blog.csdn.net/weixin_38531633/article/details/117632465
- https://www.cnblogs.com/EasyInvoice/p/6047772.html
- https://blog.csdn.net/xiaogongzhu001/article/details/131080593
- https://zhidao.baidu.com/question/367816029.html
- https://cn.bing.com/search?pc=MOZI&form=MOZLBR&q=C%23+base64
环境
| 软件/系统 | 版本 | 说明 | 
|---|---|---|
| Windows | windows 10 专业版 22H2 64 位操作系统, 基于 x64 的处理器 | |
| Microsoft Visual Studio | Community 2022 (64 位) - Current 版本 17.14.5 | |
| .NET Framework | 4.8 | |
| Arduino IDE | 2.3.6 | 
| 硬件/设备 | 数量 | 说明 | 
|---|---|---|
| Arduino UNO | 1 | |
| LED灯 | 1 | |
| 220Ω电阻 | 1 | |
| 杜邦线 | 若干 | 
预览
- 
上位机界面 
  
- 
Arduino接线 图片来源 https://blog.csdn.net/lhwanglei/article/details/108569051   
正文
上位机
- Form1.Designer.csnamespace ConsoleSerialPortTest { partial class Form1 { /// <summary> /// 必需的设计器变量。 /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// 清理所有正在使用的资源。 /// </summary> /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows 窗体设计器生成的代码 /// <summary> /// 设计器支持所需的方法 - 不要修改 /// 使用代码编辑器修改此方法的内容。 /// </summary> private void InitializeComponent() { this.label1 = new System.Windows.Forms.Label(); this.textBox1 = new System.Windows.Forms.TextBox(); this.label2 = new System.Windows.Forms.Label(); this.radioButton1 = new System.Windows.Forms.RadioButton(); this.radioButton2 = new System.Windows.Forms.RadioButton(); this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); this.button1 = new System.Windows.Forms.Button(); this.button2 = new System.Windows.Forms.Button(); this.textBox2 = new System.Windows.Forms.TextBox(); this.label3 = new System.Windows.Forms.Label(); this.comboBox1 = new System.Windows.Forms.ComboBox(); this.button3 = new System.Windows.Forms.Button(); this.flowLayoutPanel1.SuspendLayout(); this.SuspendLayout(); // // label1 // this.label1.AutoSize = true; this.label1.Location = new System.Drawing.Point(226, 89); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(82, 24); this.label1.TabIndex = 0; this.label1.Text = "波特率"; // // textBox1 // this.textBox1.Location = new System.Drawing.Point(345, 86); this.textBox1.Name = "textBox1"; this.textBox1.Size = new System.Drawing.Size(200, 35); this.textBox1.TabIndex = 1; this.textBox1.Text = "9600"; // // label2 // this.label2.AutoSize = true; this.label2.Location = new System.Drawing.Point(240, 143); this.label2.Name = "label2"; this.label2.Size = new System.Drawing.Size(58, 24); this.label2.TabIndex = 2; this.label2.Text = "开灯"; // // radioButton1 // this.radioButton1.AutoSize = true; this.radioButton1.Location = new System.Drawing.Point(3, 3); this.radioButton1.Name = "radioButton1"; this.radioButton1.Size = new System.Drawing.Size(65, 28); this.radioButton1.TabIndex = 3; this.radioButton1.Text = "开"; this.radioButton1.UseVisualStyleBackColor = true; this.radioButton1.CheckedChanged += new System.EventHandler(this.radioButton_CheckedChanged); // // radioButton2 // this.radioButton2.AutoSize = true; this.radioButton2.Checked = true; this.radioButton2.Location = new System.Drawing.Point(74, 3); this.radioButton2.Name = "radioButton2"; this.radioButton2.Size = new System.Drawing.Size(65, 28); this.radioButton2.TabIndex = 4; this.radioButton2.TabStop = true; this.radioButton2.Text = "关"; this.radioButton2.UseVisualStyleBackColor = true; this.radioButton2.CheckedChanged += new System.EventHandler(this.radioButton_CheckedChanged); // // flowLayoutPanel1 // this.flowLayoutPanel1.Controls.Add(this.radioButton1); this.flowLayoutPanel1.Controls.Add(this.radioButton2); this.flowLayoutPanel1.Location = new System.Drawing.Point(347, 143); this.flowLayoutPanel1.Name = "flowLayoutPanel1"; this.flowLayoutPanel1.Size = new System.Drawing.Size(200, 40); this.flowLayoutPanel1.TabIndex = 5; // // button1 // this.button1.Location = new System.Drawing.Point(244, 218); this.button1.Name = "button1"; this.button1.Size = new System.Drawing.Size(117, 45); this.button1.TabIndex = 6; this.button1.Text = "连接"; this.button1.UseVisualStyleBackColor = true; this.button1.Click += new System.EventHandler(this.button1_Click); // // button2 // this.button2.Location = new System.Drawing.Point(430, 218); this.button2.Name = "button2"; this.button2.Size = new System.Drawing.Size(117, 45); this.button2.TabIndex = 7; this.button2.Text = "关闭"; this.button2.UseVisualStyleBackColor = true; this.button2.Click += new System.EventHandler(this.button2_Click); // // textBox2 // this.textBox2.Location = new System.Drawing.Point(69, 288); this.textBox2.Multiline = true; this.textBox2.Name = "textBox2"; this.textBox2.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; this.textBox2.Size = new System.Drawing.Size(736, 772); this.textBox2.TabIndex = 8; // // label3 // this.label3.AutoSize = true; this.label3.Location = new System.Drawing.Point(226, 34); this.label3.Name = "label3"; this.label3.Size = new System.Drawing.Size(106, 24); this.label3.TabIndex = 9; this.label3.Text = "串口列表"; // // comboBox1 // this.comboBox1.FormattingEnabled = true; this.comboBox1.Location = new System.Drawing.Point(345, 31); this.comboBox1.Name = "comboBox1"; this.comboBox1.Size = new System.Drawing.Size(200, 32); this.comboBox1.TabIndex = 10; // // button3 // this.button3.Location = new System.Drawing.Point(579, 24); this.button3.Name = "button3"; this.button3.Size = new System.Drawing.Size(117, 45); this.button3.TabIndex = 11; this.button3.Text = "刷新"; this.button3.UseVisualStyleBackColor = true; this.button3.Click += new System.EventHandler(this.button3_Click); // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(12F, 24F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(918, 1087); this.Controls.Add(this.button3); this.Controls.Add(this.comboBox1); this.Controls.Add(this.label3); this.Controls.Add(this.textBox2); this.Controls.Add(this.button2); this.Controls.Add(this.button1); this.Controls.Add(this.flowLayoutPanel1); this.Controls.Add(this.label2); this.Controls.Add(this.textBox1); this.Controls.Add(this.label1); this.Name = "Form1"; this.Text = "Form1"; this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing); this.Load += new System.EventHandler(this.Form1_Load); this.flowLayoutPanel1.ResumeLayout(false); this.flowLayoutPanel1.PerformLayout(); this.ResumeLayout(false); this.PerformLayout(); } #endregion private System.Windows.Forms.Label label1; private System.Windows.Forms.TextBox textBox1; private System.Windows.Forms.Label label2; private System.Windows.Forms.RadioButton radioButton1; private System.Windows.Forms.RadioButton radioButton2; private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; private System.Windows.Forms.Button button1; private System.Windows.Forms.Button button2; private System.Windows.Forms.TextBox textBox2; private System.Windows.Forms.Label label3; private System.Windows.Forms.ComboBox comboBox1; private System.Windows.Forms.Button button3; } }
- Form1.csusing System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Drawing; using System.IO.Ports; using System.Linq; using System.Reflection; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using static System.Windows.Forms.VisualStyles.VisualStyleElement; namespace ConsoleSerialPortTest { public partial class Form1 : Form { static SerialPort _serialPort; static Thread readThread; public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { // readThread = new Thread(Read); readThread.Start(); // GetComs(); } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { readThread.Abort(); } public void LinkArduino() { _serialPort = new SerialPort(comboBox1.SelectedItem.ToString(), int.Parse(textBox1.Text)); _serialPort.Encoding = System.Text.Encoding.UTF8; // 定时读取串口数据,超时会出发异常 //_serialPort.ReadTimeout = 500; //_serialPort.WriteTimeout = 500; try { _serialPort.Open(); Log("串口连接成功!"); } catch (Exception ex) { Log($"串口连接失败:{ex.Message}"); } } // 使用 SerialPort.DataReceive 事件更好,接受数据后自动触发 public void Read() { while (true) { // 非连接状态下,直接跳过 if (!IsOpen()) { continue; } try { string message = _serialPort.ReadLine(); // 去除空字符与换行,就可以接受正式数据了 if (!string.IsNullOrEmpty(message) && message != "\r") { // base64 是为了捕获换行符,然后进行过滤 // Convert.ToBase64String(Encoding.UTF8.GetBytes(message)) Log($"收到串口返回数据:{message}"); } } catch (Exception e) { Debug.WriteLine(e.Message); continue; } } } /// <summary> /// 检测串口是否打开 /// </summary> /// <returns></returns> public static bool IsOpen() { if (_serialPort is null) { return false; } return _serialPort.IsOpen; } public void GetComs() { string[] ports = System.IO.Ports.SerialPort.GetPortNames(); this.comboBox1.Items.Clear(); for (int i = 0; i < ports.Length; i++) { this.comboBox1.Items.Add(ports[i]); } if (this.comboBox1.Items.Count > 0) { this.comboBox1.SelectedIndex = 0; } } private void button3_Click(object sender, EventArgs e) { this.GetComs(); } private void button1_Click(object sender, EventArgs e) { LinkArduino(); } /// <summary> /// 开启LED /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void radioButton_CheckedChanged(object sender, EventArgs e) { var rb = sender as RadioButton; if (rb.Checked && IsOpen()) { Log(rb.Text); if ("开".Equals(rb.Text)) { _serialPort.WriteLine("1"); } if ("关".Equals(rb.Text)) { _serialPort.WriteLine("0"); } } } /// <summary> /// /// </summary> public void Log(string msg) { Debug.WriteLine(msg); // 判断是否在同一线程 if (!this.textBox2.InvokeRequired) { this.textBox2.Text += msg + "\r\n"; } else { this.Invoke(new Action( () => { this.textBox2.Text += msg + "\r\n"; } )); } } private void button2_Click(object sender, EventArgs e) { _serialPort.Close(); } } }
Arduino
- main.ino// 初始化引脚 int LED=9; void setup() { Serial.begin(9600); Serial.println("start arduino"); // pinMode(LED,OUTPUT); } // 读取数据 String readAllPort(){ String comdata = ""; while (Serial.available() > 0){ comdata += char(Serial.read()); //每次读一个char字符,并相加 delay(2); } return comdata; } // https://docs.arduino.cc/language-reference/en/variables/constants/highLow/ void loop() { String comdata = readAllPort(); if (comdata.length() > 0){ Serial.println("收到上位机消息 received:"+comdata); int isOpen = comdata.toInt(); if(isOpen == 1){ //设置该引脚为高电平,点亮LED / HIGH = 1 or true digitalWrite(LED,HIGH); } if(isOpen == 0){ //设置该引脚为低电平,关闭LED / LOW = 0 or false digitalWrite(LED,LOW); } comdata = ""; } }
    博  主 :夏秋初
地 址 :https://www.cnblogs.com/xiaqiuchu/p/18931338
 
如果对你有帮助,可以点一下 推荐 或者 关注 吗?会让我的分享变得更有动力~
转载时请带上原文链接,谢谢。
    
地 址 :https://www.cnblogs.com/xiaqiuchu/p/18931338
如果对你有帮助,可以点一下 推荐 或者 关注 吗?会让我的分享变得更有动力~
转载时请带上原文链接,谢谢。
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号