C#与Arduino的对话

功能需求:

PC机作为上位机,通过串口发送控制指令 F(ading) or B(link) 给Arduino,根据不同指令来实现LED闪烁或者渐明渐暗。



实现方式:

单片机选用Arduino MEGA 1280,PWM10脚作为输出口,接220欧限流电阻至高亮LED,再与GND脚共地。


5993160891_25a9f3bd87_b.jpg

2011-10-10 10:04 上传
(51.33 KB)





上位机用C#作为编程语言,IDE选择VS2010,.Net版本选择了4.0,不过应该能够兼容其它版本的.net framework。之前上位机跟单片机通信时,传递的是字符串,方法是先将PWM值视为ASCII码,转换成对应的Char,然后将Char再转换成String类型。由于ANSI ASCII码表只支持128个字符,所以128-255之间的数在传递的时候就遇到难题,通过串口监视发现,超过127的ASCII发给arduino之后,都被修改为63,导致传输失效。



现在的方法改为直接传递byte类型的无符号数,解决了这个问题。



运行界面如下:

5993164199_c868def214_b.jpg

2011-10-10 09:56 上传
(60.41 KB)







上位机源代码:using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.Threading;

namespace WindowsFormsApplication1
{
public partial class frmMain :
Form
{
int FlashTimes;
int FlashCounts;
Label FlashingLED;
string TextRead;
public frmMain()
{
InitializeComponent();
}
private intFillSerialPorts()
{
int PortCount;
PortCount = 0;
//加载串口列表
SerialPort _tempPort;
String[] Portname = SerialPort.GetPortNames();
foreach (string str in Portname)
{
try
{
_tempPort = new SerialPort(str);
_tempPort.Open();
if (_tempPort.IsOpen)
{
cboCOMPorts.Items.Add(str);
_tempPort.Close();
PortCount++;
}
}
catch (Exception ex)
{
tsMessage.Text = ex.ToString();
}
}
if (!(PortCount ==0))
cboCOMPorts.SelectedIndex =0;
tsCOMPort.Text = cboCOMPorts.Text;
return PortCount;
}
private void trkPWM_ValueChanged(object sender, EventArgs e)
{
lblPWM.Text = trkPWM.Value.ToString ();
}
private void button1_Click(object sender, EventArgs e)
{
txtRead.Clear();
if (cboCOMPorts.Text == "")
{
tsMessage.Text = "尚未选择串口!";
}
else
{
if (!serialPort1.IsOpen)
{
serialPort1.PortName = cboCOMPorts.Text;
serialPort1.Open();
try
{
tsCOMPort.Text = cboCOMPorts.Text;
tsCOMState.Text = "开启";
}
catch (Exception ex)
{
tsMessage.Text = ex.ToString(); // "串口打开过程中遇到错误,串口不存在或者已经被占用!";
tsCOMPort.Text = "";
tsCOMState.Text = "已断开";
}
}
if (serialPort1.IsOpen)
{
if (rbFading.Checked)
{
serialPort1.Write("F");
byte[] bytesToSend = new byte[1] ;
bytesToSend[] =Convert.ToByte ( trkPWM.Value *2.55 ); //疑问:当Value=100,ToByte=255,但是((int)(trkPWM.Value * 2.55)).ToString()却是254?
serialPort1.Write(bytesToSend, 0, 1);

//serialPort1.Write( ((Char ) ((int) trkPWM.Value *2.55 )).ToString () ); //这个方法不能传递高于127的数
//tsMessage.Text = ((int)(trkPWM.Value * 2.55)).ToString();
}
else
{
serialPort1.Write("B");
serialPort1.Write(Convert.ToChar(Convert.ToInt16(trkPWM.Value)).ToString());
}
FlashLED(lblRX, 10);
}
}
}
private void Form1_Load(object sender, EventArgs e)
{
FillSerialPorts();
trkPWM.Value = 80;
}
private void FlashLED(Label LED, int Count)
{
FlashingLED = LED;
FlashCounts = Count;
timer1.Enabled = true;
}
private void DisplayText(object sender, EventArgs e)
{
txtRead.AppendText(TextRead);
}
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
if (chkReceive.Checked)
{
TextRead = serialPort1.ReadExisting();
this.Invoke(new EventHandler(DisplayText));
FlashLED(lblRX, 10);
}
}
private void timer1_Tick(object sender, EventArgs e)
{
//add flash times
if (FlashTimes <= FlashCounts)
{
FlashingLED.Visible = !FlashingLED.Visible;
FlashTimes++;
}
else
{
timer1.Enabled = false;
FlashCounts = 0;
FlashTimes = 0;
FlashingLED.Visible = true;
}
}

private void frmMain_Activated(object sender, EventArgs e)
{
if (cboCOMPorts.Items.Count ==0 )
FillSerialPorts ();
}
private void button2_Click(object sender, EventArgs e)
{
serialPort1.Close();
timer1.Enabled = false;
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
pictureBox1.Invalidate();
int yOffset=100;
int yBase = 40;
int xOffset = 40;
int i ;
int x=0;
Pen p = new Pen(Color.Yellow ,1);
Graphics g = e.Graphics;
if (trkPWM.Value ==100)
g.DrawLine(p, pictureBox1.Left , pictureBox1.Height - yOffset , pictureBox1.Left + 10 , pictureBox1.Height - yOffset ); // __
else
g.DrawLine(p, pictureBox1.Left , pictureBox1.Height - yBase, pictureBox1.Left + 10 , pictureBox1.Height - yBase); //
for (i = 0; i <= 5; i++)
{
x = 100 * i;
if (!((trkPWM.Value ==0 )||(trkPWM.Value ==100)))
g.DrawLine(p, pictureBox1.Left + 10 + x, pictureBox1.Height - yBase, pictureBox1.Left + 10 + x, pictureBox1.Height - yOffset); // |
//p.Color = Color.Blue ;
xOffset = trkPWM.Value;
g.DrawLine(p, pictureBox1.Left + 10 + x, pictureBox1.Height - yOffset, pictureBox1.Left + 10 + xOffset + x, pictureBox1.Height - yOffset);//--
if (!((trkPWM.Value == 0) || (trkPWM.Value == 100)))
g.DrawLine(p, pictureBox1.Left + 10 + xOffset + x, pictureBox1.Height - yOffset, pictureBox1.Left + 10 + xOffset + x, pictureBox1.Height - yBase);//|
g.DrawLine(p,pictureBox1.Left + 10 + xOffset + x, pictureBox1.Height - yBase, pictureBox1.Left + 10 + xOffset + x + 100 -trkPWM.Value , pictureBox1.Height - yBase);//

e.Graphics.DrawString(trkPWM.Value.ToString () + "%", panel1.Font , new SolidBrush(Color.White ), panel1.Left +120 , 5, StringFormat.GenericDefault);
}
}
private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
{
if (serialPort1.IsOpen)
serialPort1.Close();
}
private void 清空ToolStripMenuItem1_Click(object sender, EventArgs e)
{
txtRead.Clear();
}
}
}
复制代码
via - 极客工坊

标签: Arduino教程