风筝
发表于: 2017-2-9 15:57:28 | 显示全部楼层

在本文中,我们将一个Arduino Pro Mini开发板连接到PC,并且使用C# Windows应用程序与其进行通信。


将硬件连接到PC是非常有利的,不仅是因为你可以发送命令以及监控状态,还可以实时调试代码。当你正在努力制作一个模块,想知道模块的响应以及跟踪你的状态机时,检查变量会特别有帮助。


关于Arduino Pro Mini和C#

首先,我想向大家描述一下我选择Arduino Pro Mini的原因。 在我看来,小尺寸是当今设计的一个优势。 如今,随着便携式物联网设备的日益普及,对小型化的需求变得越来越重要,而且Arduino Pro Mini开发板除了小,也没有其他特殊功能。


Arduino Pro Mini开发板针对小空间进行了优化(当您需要尽可能小的电路板时),但是当它用于构建项目时功能却十分强大。 另一个好处是它没有焊接插头,这会占用很多的垂直空间。 您可以通过将导线焊接到引脚来简单地访问所需的引脚。 由于其体积小,它没有内置USB组件,因此您需要为该功能使用其他的组件。 市场上有许多串行转USB转换器,但是,我个人更喜欢选择一个可以向我提供所有的握手引脚的转换器,而不仅仅只是Rx和Tx。


这就是为什么我设计了一个基于FT232R的简单接口板。 我使用了芯片上的所有的串行信号。 你可以在图1看到我从数据表中摘取的电路。


其次,我想解释一下为什么选择C#。 有众多的编程语言和许多使得Windows的可视化应用程序编程更简单的可视化程序。 每种编程语言都有各自的优势和缺点。 但是,对我来说,使用visual studio可以为我做很多工作。 它允许访问众多的预编译库和工具,帮助我们高效地构建我们的应用程序。 它还允许我们使用功能强大的C#语言进行编程。 所以在本文中我们使用C#,因为它很方便,并且我比较熟悉。

FT232-2-2.jpg


所需的硬件和软件

     ●     Arduino Pro Mini 5V

     ●     FT232R USB转串口模块

     ●     面包板

     ●     导线,用于将插头连接到FT232R电路板以及将引脚3连接到LED

     ●     Arduino IDE

     ●     Visual Studio


设置

我使用我自己的FT232R电路板来编程以及与Arduino Pro Mini 5V开发板通信。 Arduino PM有的六个引脚用于编程,标记为“BLK”、“GND”、“VCC”、“RXI”、“TXO”和“GRN”,如图2所示。

Amin_C_Arduino_1.jpg

6-2.jpg


在图3所示的用于编程的六个引脚中,第一个引脚BLK接地。 GND和VCC显然需要连接到FT232R电路板的VCC和GND。 这样,Arduino将由USB提供电源,不需要额外的电源。


我们应该考虑的事情是USB端口的电流限制。 如果我们的电路耗电超过500mA,我们应该增加一个外部电源。 RXI应连接到FT232的TX,TXO连接到FT232的RX,GRN连接到FT232的DTR,这将使得FT232可以在任何需要时复位开发板。


接线后,电路如图4所示。现在我们已经准备好对Arduino Pro Mini进行编程了。

photo303779429529791011.jpg


上传代码草稿

出于测试的目的,我们将写一个简单的代码来读取串口的输入,并相应地设置引脚3的状态:

  1. const int led = 3;

  2. int state=0;  

  3. void setup()   

  4. {   

  5.     Serial.begin(115200); //Starts the serial connection with 115200 Buad Rate   

  6.     pinMode(led, OUTPUT); //Sets led pin as an output

  7.     Serial.write("ALL ABOUT CIRCUITS!");//Send "ALL ABOUT CIRCUITS!" to the PC

  8. }   

  9. void loop()   

  10. {   

  11.     String data = Serial.readString();//Read the serial buffer as a string

  12.         if(data.indexOf("ON")!=-1)//checks if it is "ON"

  13.         {

  14.             digitalWrite(led, HIGH); // Sets the led ON   

  15.             state=0;// Sets the state value to 0

  16.         }

  17.         else if(data.indexOf("OFF")!=-1)//checks if it is "OFF"

  18.         {  

  19.             digitalWrite(led, LOW); //Sets the led OFF   

  20.             state=0;// Sets the state value to 1

  21.         }

  22.         else if(data.indexOf("STATE")!=-1)//checks if it is "STATE"

  23.         {

  24.             Serial.write("state=");//Sends the state

  25.             Serial.println(state);

  26.         }

  27. }   
复制代码

我们需要做的是将开发板设置为Arduino Pro或Pro Mini(见图5),然后上传我们的代码草稿。

1-2.jpg


编写C#应用程序

编写C#应用程序时,我们在Visual Studio开发环境中创建一个简单的窗体。 接下来,从工具箱部分,我们需要拖放“串行端口”工具。 可以在工具的属性部分中配置所有设置。 将端口名称设置为FT232的端口名称。 并且将波特率设置为115200,握手设置为“无”。 我们还需要添加一个按钮来切换LED状态以及一个文本框来显示接收到的数据。 我们可以简单地从工具箱中添加这些。 设置应如图6所示。

4-2.jpg


做完视图之后,我们可以准备写一些代码。 首先,为了使用串行端口,我们需要打开它,然后我们可以写入或从串行缓冲区读取。 我们可以在代码中访问串行中断。 串行通信中的中断提供更好的响应,因为我们只有在数据可用时才处理数据。 C#串行端口也有一个事件,当数据到达缓冲区时将触发该事件。 我们可以通过转到属性部分中的事件选项卡并双击DataReceived(参见图7)来使用此事件。 Visual studio将自动创建该事件。

5-2.jpg


在发送或接收数据之前,我们需要打开串口:

  1. private void Form1_Load(object sender, EventArgs e)

  2. {

  3. serialPort1.Open();

  4. }
复制代码

然后我们可以读取或写入数据。

代码如下所示:

  1. public delegate void AddDataDelegate(String myString);// Delegate for richtextbox
  2. public AddDataDelegate myDelegate;// An instance of AddDataDelegate
  3. public delegate void AddDataDelegate_button(String myString);// Delegate for button
  4. public AddDataDelegate_button myDelegate_button;// An instance of AddDataDelegate_button
  5. bool status=false;// LED status
  6. public Form1()
  7. {
  8.     InitializeComponent();
  9. }

  10. private void Form1_Load(object sender, EventArgs e)
  11. {
  12.     serialPort1.Open();//Opening the serial port
  13.     this.myDelegate = new AddDataDelegate(AddDataMethod);//Assigning "the function that changes richtextbox text" to the delegate
  14.     this.myDelegate_button = new AddDataDelegate_button(AddDataMethod_button);//Assigning "the function that changes button text" to the delegate
  15.     serialPort1.WriteLine("STATE");
  16.    
  17. }
  18. public void AddDataMethod_button(String myString)
  19. {
  20.     button1.Text = myString;//changes button text
  21. }
  22. public void AddDataMethod(String myString)
  23. {
  24.     richTextBox1.Text = myString + Environment.NewLine;//changes richtextbox text
  25. }
  26. private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
  27. {
  28.     string s = serialPort1.ReadExisting();//reads the serialport buffer
  29.     if (s.Contains("state="))//checks if it is status
  30.     {
  31.         s=s.Trim();
  32.         string new_s = s.Replace("state=", "");
  33.         if (new_s.Contains("0"))
  34.         {
  35.             status = false;
  36.             button1.Invoke(this.myDelegate_button, new Object[] { "ON" });//sets button text to on
  37.         }
  38.         else
  39.         {
  40.             status = true;
  41.             button1.Invoke(this.myDelegate_button, new Object[] { "OFF" });//sets button text to off
  42.         }
  43.     }
  44.     else
  45.     {
  46.         richTextBox1.Invoke(this.myDelegate, new Object[] { s });//adds the recieved bytes to the richtextbox
  47.     }
  48. }

  49. private void button1_Click(object sender, EventArgs e)
  50. {
  51.     if(button1.Text.Contains("ON"))
  52.     {
  53.         serialPort1.WriteLine("OFF");//sends off command when the previous state was on
  54.         button1.Text = "OFF";
  55.         status = false;
  56.     }
  57.     else
  58.     {
  59.         serialPort1.WriteLine("ON");//sends on command when the previous state was off
  60.         button1.Text = "ON";
  61.         status = true;
  62.     }
  63. }
复制代码

代码说明

示例代码通过ASCII字符进行通信。 这种方法比较方便并且可以扩展。


在C#代码中,我们需要从Arduino Pro Mini读取引脚的状态,所以我们向Arduino开发板发送“STATE”命令。 Arduino将通过串口回答“state = 0”或“state = 1”来进行应答。 Arduino向我们发送状态后,我们将相应地更新按钮文本。


事件在与主表单线程分开的线程中运行,因此它们具有不同的速度。例如,在我们的示例中,当我们从串行端口接收到文本时,我们可能希望在文本框中显示它。 然而,在从一开始创建所有控制处理程序的主Windows线程控制器中可能有一些其他控制器未完成的任务,这些控制器可以是一个文本框或按钮;在这种条件下,如果我们从与主处理程序分开的另一个线程中调用一个文本框,程序将会崩溃,因为是多线程的情况。 文本框控制器可能同时会有两个不同的属性,因此我们应该等到它的工作完成。


这就是为什么我们不能从另一个线程更改文本框文本,如串口接收线程。 为了避免这种情况,我们可以使用Invoke方法。 每个控制器都有一个Invoke方法,使得我们能够从另一个线程更改其属性;Invoke方法可以从另一个线程执行某个委托。 代理像C ++中的指针,这意味着它们引用某个特定的方法并安全地执行它。 因此,首先,我们需要定义一个更改控制器属性的代理,在代码中命名为“myDelegate”,然后将其关联到Invoke方法。 从代码中可以看出,使用Invoke函数,我们可以进行线程安全调用。


其余的代码很简单。 只要用户按下按钮,我们只需将“ON”或“OFF”命令写入串口。


总结

在本文中,我们学习了如何编写一个与Arduino Pro Mini开发板交互的C#应用程序。 我们使用简单的ASCII命令/响应协议,该协议可以很容易地适用于各种各样的应用程序。

跳转到指定楼层
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题 714 | 回复: 1501



手机版|

GMT+8, 2024-12-21 21:12 , Processed in 0.104694 second(s), 10 queries , Gzip On, MemCache On. Powered by Discuz! X3.5

YiBoard一板网 © 2015-2022 地址:河北省石家庄市长安区高营大街 ( 冀ICP备18020117号 )

快速回复 返回顶部 返回列表