接线图
上位机的问题就是,当单击停止按钮关闭COMPort之后,整个窗体处于假死状态,不知道是不是跟.Net的读串口需要另开线程有关,由于是新学,这个问题存疑。
Arduino端的程序问题是,通过串口返回给上位机的信息,i+“ | ”+ Value这个木有返回,更严重的是,返回的东西每隔一段时间就会有乱码。
上位机程序代码:
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 int FillSerialPorts()
{
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)
{
//if serialPort1.
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)
{
serialPort1.Write("P");
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)
{
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);
}
}
}
}
原图中没有LED显示方式,借用新图 |
Arduino端程序与串口监视工具界面:
char CMD; //Command included in the chars received from PC
char* Str; //strings received
int PWMValue; //PWM value received from PC
int PinOUT=10;
char* Str; //strings received
int PWMValue; //PWM value received from PC
int PinOUT=10;
void setup()
{
Serial.begin(9600);
pinMode(PinOUT, OUTPUT);
}
{
Serial.begin(9600);
pinMode(PinOUT, OUTPUT);
}
int ReadPWM()
{
int Result=255;
while (!Serial.available())
{
//等到有输入再退出等待
}
Result = Serial.read();
{
int Result=255;
while (!Serial.available())
{
//等到有输入再退出等待
}
Result = Serial.read();
Serial.flush();
return Result;
}
return Result;
}
void loop()
{
int i=0;
if (Serial.available())
{
CMD = Serial.read();
Serial.flush();
switch(CMD) //根据不同的控制命令,来决定是否需要接收参数
{
case 'P':
PWMValue = ReadPWM();
//PWMWave(PWMValue); //取消
Serial.println(PWMValue);
break;
}
}
//根据不同的控制命令,实现对应的功能
switch(CMD)
{
case 'P':
//Debug
Serial.println("");
Serial.println("command P");
Serial.println("");
PWMWave(PWMValue);
break;
}
}
{
int i=0;
if (Serial.available())
{
CMD = Serial.read();
Serial.flush();
switch(CMD) //根据不同的控制命令,来决定是否需要接收参数
{
case 'P':
PWMValue = ReadPWM();
//PWMWave(PWMValue); //取消
Serial.println(PWMValue);
break;
}
}
//根据不同的控制命令,实现对应的功能
switch(CMD)
{
case 'P':
//Debug
Serial.println("");
Serial.println("command P");
Serial.println("");
PWMWave(PWMValue);
break;
}
}
void PWMWave(int Value)
{
int i;
for (i=0; i<=100; i++)
{
//debug
Serial.println(i+" | "+ Value);
if (i<= Value)
{
digitalWrite(PinOUT,HIGH);
//Debug
Serial.println("HIGH");
// delay(10);
}
else
{
digitalWrite(PinOUT,LOW);
//DEBUG
Serial.println("LOW");
}
delay(10);
}
}
{
int i;
for (i=0; i<=100; i++)
{
//debug
Serial.println(i+" | "+ Value);
if (i<= Value)
{
digitalWrite(PinOUT,HIGH);
//Debug
Serial.println("HIGH");
// delay(10);
}
else
{
digitalWrite(PinOUT,LOW);
//DEBUG
Serial.println("LOW");
}
delay(10);
}
}
另外从上位机发PWM值,有时候arduino似乎只循环一次,之后LED灯熄灭,但是从串口监视工具发指令,似乎又正常。
先把代码贴出来,错误有待慢慢去修改。
源代码中存在一些错误,修改后的代码见另外一篇博客
回复删除http://ardypro.blogspot.com/2011/07/carduino.html
主要问题为:
C#代码:
Serial.Write(),原来是传递Char,但是ANSI ASCII码表只支持128个,其余的传递给Arduino之后,会变成ASCII码63,现在改为传递byte类型的无符号数。
Arduino部分:
在switch(CMD)代码块中,增加了default块,当控制指令无效时,可以执行原来的过程而不至于停止。