墙的高度跟砖头的厚度没关,有关系的是对思想控制的欲望和愚民的政策。当初邓公讲打开窗户的时候飞进来几只苍蝇没什么事的。可是多年过去,为了这几只所谓的苍蝇,我们不仅连纱窗关掉,连门窗都要紧闭,彻底关上了我们通往世界的大门,留下的只有我们对外面的偷窥...
牢骚几句,作为穿墙的纪念。
2011年9月18日星期日
2011年8月19日星期五
Arduino软件生成遥控方波与AUX遥控器原始方波的对比
这篇博客是前面AUX遥控器红外信号分析的续篇。
由于红外协议有好几种,功力原因,分析起来比较困难,因此权衡之后,还是决定采取用软件方式,模拟AUX空调的遥控信号。
前面博文分析得出结论是,帧与帧之间的间隔(这个词语可能跟标准术语有区别,在此是指相邻的下降沿和上升沿之间的间隔时间)是760us,源代码中设置的间隔为912us,这个数字是综合考虑delay以及源程序中其它指令的耗时等因素,以及考察红外方波波形之后计算所得。
而实际产生的波形与遥控器的原始波形之间,存在比较大的差异,而且这个差异比较怪异,
源代码:
char *strOpen="000000000111101101101010101011011011011011010101010110101010101011011011011010101101010101010101010101011010101010101010101010101010101101010101010101010101010101010101010101010101010110101010101010101101101101101011010101010101010101101101010110";
int lenOfOpen =246;
unsigned int openCode[246];
int pinOut= 28;
void setup()
{
pinMode(pinOut,OUTPUT);
Serial.begin(9600);
StringToArray();
}
void StringToArray()
{
int i;
char c;
for (i=0; i<lenOfOpen; i++)
{
c= strOpen[i];
//Serial.print(c);
//Serial.print('|');
if (c=='1')
openCode[i]=1;
else
openCode[i]=0;
//debug mode
//Serial.println(openCode[i]);
}
}
void loop()
{
int i;
for (i=0; i< lenOfOpen; i++)
{
digitalWrite(pinOut, openCode[i]);
delayMicroseconds(912);
//Serial.println(openCode[i]);
}
}
需要重新计算间隔时间。
由于红外协议有好几种,功力原因,分析起来比较困难,因此权衡之后,还是决定采取用软件方式,模拟AUX空调的遥控信号。
前面博文分析得出结论是,帧与帧之间的间隔(这个词语可能跟标准术语有区别,在此是指相邻的下降沿和上升沿之间的间隔时间)是760us,源代码中设置的间隔为912us,这个数字是综合考虑delay以及源程序中其它指令的耗时等因素,以及考察红外方波波形之后计算所得。
而实际产生的波形与遥控器的原始波形之间,存在比较大的差异,而且这个差异比较怪异,
- 整个信号宽度比原始信号要宽出一截(见图1);
- 1T、2T波形的宽度有比较大的差距,比原始信号要宽(见图2);
- 4T比原始信号宽度要窄(见图3);
- 两个9T信号之间几乎没有差别(见图3)。
![]() |
| 图1 |
![]() |
| 图2 |
![]() |
| 图3 |
源代码:
char *strOpen="000000000111101101101010101011011011011011010101010110101010101011011011011010101101010101010101010101011010101010101010101010101010101101010101010101010101010101010101010101010101010110101010101010101101101101101011010101010101010101101101010110";
int lenOfOpen =246;
unsigned int openCode[246];
int pinOut= 28;
void setup()
{
pinMode(pinOut,OUTPUT);
Serial.begin(9600);
StringToArray();
}
void StringToArray()
{
int i;
char c;
for (i=0; i<lenOfOpen; i++)
{
c= strOpen[i];
//Serial.print(c);
//Serial.print('|');
if (c=='1')
openCode[i]=1;
else
openCode[i]=0;
//debug mode
//Serial.println(openCode[i]);
}
}
void loop()
{
int i;
for (i=0; i< lenOfOpen; i++)
{
digitalWrite(pinOut, openCode[i]);
delayMicroseconds(912);
//Serial.println(openCode[i]);
}
}
需要重新计算间隔时间。
2011年8月15日星期一
Arduino中digitalWrite的一点疑惑
做Blink试验时,就曾经有点疑惑,digitalWrite往某个pin写入HIGH或LOW之后,该pin的状态是如何维护的呢?用万用表量输出脚的电压时,HIGH状态时是4.90v,LOW状态时是0.00v,但是示波器查看到的波形却有点不一致:
从图上看出,状态设置为HIGH or LOW之后,该输出脚的状态处在一个中间值,而并不是一直处于HIGH or LOW,跟万用表量到的数据似乎有点矛盾。
源代码:
int P13=13;
boolean val=true;
void setup()
{
pinMode(P13,OUTPUT);
Serial.begin(96000);
}
void loop()
{
if (val)
digitalWrite(P13,HIGH);
else
digitalWrite(P13,LOW);
delay(1500);
val = !val;
//Serial.println(val);
}
![]() |
| pin13电压波形图 |
![]() |
| 采集到的电压峰值为正负0.3v,中间处于0v上下 |
源代码:
int P13=13;
boolean val=true;
void setup()
{
pinMode(P13,OUTPUT);
Serial.begin(96000);
}
void loop()
{
if (val)
digitalWrite(P13,HIGH);
else
digitalWrite(P13,LOW);
delay(1500);
val = !val;
//Serial.println(val);
}
2011年8月13日星期六
AUX立式空调遥控器红外线波形分析
在网上找了一个红外线逻辑分析电路,做了一个分析器,今天拿它捕捉了AUX遥控器的开机信号,波形图如下,第一个图是全部波形,由于太长,后面的放大图分成了多个。
高位之间的间隔为0.76ms
第一帧是宽度为9的低位信号,接着是一个宽度为4的高位,接着便是其它信号。
4,2,2,1,1,1,1,2,2,2,2,2,1,1,1,1,2,1,1,1,1,1,2,2,2,2,1,1,2,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,2,2,2,1,2,1,1,1,1,1,1,1,1,2,2,1,1,2
关机波形
声音信号
信号分析:
第一帧也是9个宽度的地位,紧接着是:(2*6表示6个2个宽度的高位)
4,2,2,1,1,1,1,2 * 5,1,1,2,1,2,2,2,1,1,1,2,2,2,1,2,1 * 12,2,1 * 14,2,1 * 31, 2 * 4, 1,2,1 * 7, 2,1,2,1,1,2
| 全部波形 |
高位之间的间隔为0.76ms
第一帧是宽度为9的低位信号,接着是一个宽度为4的高位,接着便是其它信号。
4,2,2,1,1,1,1,2,2,2,2,2,1,1,1,1,2,1,1,1,1,1,2,2,2,2,1,1,2,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,2,2,2,1,2,1,1,1,1,1,1,1,1,2,2,1,1,2
关机波形
| 关机信号方波 |
信号分析:
第一帧也是9个宽度的地位,紧接着是:(2*6表示6个2个宽度的高位)
4,2,2,1,1,1,1,2 * 5,1,1,2,1,2,2,2,1,1,1,2,2,2,1,2,1 * 12,2,1 * 14,2,1 * 31, 2 * 4, 1,2,1 * 7, 2,1,2,1,1,2
2011年8月11日星期四
常见三极管参数(转帖)
因为要经常用到下面的一些三极管,所以帖在此备查。原帖也是转来的,最早是谁的也无从知晓。下面的地址是离我最近的,呵呵
9011 NPN 30V 30mA 400mW 150MHz 放大倍数20-80
9012 PNP 50V 500mA 600mW 低频管 放大倍数30-90
9013 NPN 20V 625mA 500mW 低频管 放大倍数40-110
9014 NPN 45V 100mA 450mW 150MHz 放大倍数20-90
9015 PNP 45V 100mA 450mW 300MHz 放大倍数 几百
9016 NPN 20V 25mA 400mW 620MHz 放大倍数20-90
9018 NPN 15V 50mA 400mW 620MHz 放大倍数20-90
8050 NPN 25V 700mA 200mW 150MHz 放大倍数30-100
8550 PNP 40V 1500mA 1000mW 200MHz 放大倍数40-140
详情如下:
90系列三极管参数
90系列三极管大多是以90字为开头的,但也有以ST90、C或A90、S90、SS90、UTC90开头的,它们的特性及管脚排列都是一样的。
9011 结构:NPN
集电极-发射极电压 30V
集电极-基电压 50V
射极-基极电压 5V
集电极电流 0.03A
耗散功率 0.4W
结温 150℃
特怔频率 平均 370MHZ
放大倍数:D28-45 E39-60 F54-80 G72-108 H97-146 I132-198
9012 结构:PNP
集电极-发射极电压 -30V
集电极-基电压 -40V
射极-基极电压 -5V
集电极电流 0.5A
耗散功率 0.625W
结温 150℃
特怔频率 最小 150MHZ
放大倍数:D64-91 E78-112 F96-135 G122-166 H144-220 I190-300
9013 结构:NPN
集电极-发射极电压 25V
集电极-基电压 45V
射极-基极电压 5V
集电极电流 0.5A
耗散功率 0.625W
结温 150℃
特怔频率 最小 150MHZ
放大倍数:D64-91 E78-112 F96-135 G122-166 H144-220 I190-300
9014 结构:NPN
集电极-发射极电压 45V
集电极-基电压 50V
射极-基极电压 5V
集电极电流 0.1A
耗散功率 0.4W
结温 150℃
特怔频率 最小 150MHZ
放大倍数:A60-150 B100-300 C200-600 D400-1000
9015 结构:PNP
集电极-发射极电压 -45V
集电极-基电压 -50V
射极-基极电压 -5V
集电极电流 0.1A
耗散功率 0.45W
结温 150℃
特怔频率 平均 300MHZ
放大倍数:A60-150 B100-300 C200-600 D400-1000
9016 结构:NPN
集电极-发射极电压 20V
集电极-基电压 30V
射极-基极电压 5V
集电极电流 0.025A
耗散功率 0.4W
结温 150℃
特怔频率 平均 620MHZ
放大倍数:D28-45 E39-60 F54-80 G72-108 H97-146 I132-198
9018 结构:NPN
集电极-发射极电压 15V
集电极-基电压 30V
射极-基极电压 5V
集电极电流 0.05A
耗散功率 0.4W
结温 150℃
特怔频率 平均 620MHZ
放大倍数:D28-45 E39-60 F54-80 G72-108 H97-146 I132-198
三极管8550
8550是一种常用的普通三极管。
它是一种低电压,大电流,小信号的PNP型硅三极管
集电极-基极电压Vcbo:-40V
工作温度:-55℃ to +150℃
和8050(NPN)相对
主要用途: 开关应用,射频放大
三极管8050
8050是常用的NPN小功率三级管,下面是的8050引脚图参数资料。
8050三级管参数:类型:开关型; 极性:NPN; 材料:硅; 最大集存器电流(A):0.5 A; 直流电增益:10 to 60; 功耗:625 mW; 最大集存器发射电(VCEO):25; 频率:150 KHz
PE8050 硅 NPN 30V 1.5A 1.1W
3DG8050 硅 NPN 25V 1.5A FT=190 *K
2SC8050 硅 NPN 25V 1.5A FT=190 *K
MC8050 硅 NPN 25V 700mA 200mW 150MHz
CS8050 硅 NPN 25V 1.5A FT=190 *K
2011年8月5日星期五
声卡示波器
2011年7月31日星期日
C#与Arduino的通讯试验
这几天一直在搞PC机作为上位机,通过与Arduino单片机的通讯,来控制LED闪烁或者渐明渐暗。之前有一篇博客记录了试验过程中遇到的问题,不过之前的描述不怎么准确,这两天又重写了Arduino程序,并对C#上位机的程序也做了一些修改,终于可以达到预期功能。
功能需求:
PC机作为上位机,通过串口发送控制指令 F(ading) or B(link) 给Arduino,根据不同指令来实现LED闪烁或者渐明渐暗。
实现方式:
单片机选用Arduino MEGA 1280,PWM10脚作为输出口,接220欧限流电阻至高亮LED,再与GND脚共地。
上位机用C#作为编程语言,IDE选择VS2010,.Net版本选择了4.0,不过应该能够兼容其它版本的.net framework。之前上位机跟单片机通信时,传递的是字符串,方法是先将PWM值视为ASCII码,转换成对应的Char,然后将Char再转换成String类型。由于ANSI ASCII码表只支持128个字符,所以128-255之间的数在传递的时候就遇到难题,通过串口监视发现,超过127的ASCII发给arduino之后,都被修改为63,导致传输失效。
现在的方法改为直接传递byte类型的无符号数,解决了这个问题。
运行界面如下:
上位机源代码:
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)
{
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[0] =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();
}
}
}
Arduino程序源代码:
//COPYRIGHT DECLARATION
//THIS APPLICATION IS A DEMOSTRATION APPLICATON FOR EDUCATION PURPOSE ONLY. YOU CAN USE OR
//REDISTRIBUTE IT FREELY ON CONDITION THAT YOU WOULD NOT MAKE MONEY OF IT.
//THE DESKTOP APPLICATON WHICH IS PROGRAMMED IN C# WOULD SEND CONTROL CODE AND PARAMETERS, IF ANY,
//TO THE ARDUINO, THE MICROCONTROLLER WOULD MAKE THE LED FADING OR BLINKING IN ACCORDANCE
//WITH THE CONTROL CODE, THEN.
//SINCE THIS IS MY FIRST APPLICATION IN EITHER C# AND ARDUINO, THERE MIGHT BE SOME BUGS IN IT,
//IF YOU RUN INTO ANY EXCEPTIONS, PLEASE REPORT THEM TO ME AT JZOPEN@YEAH.NET.
//HISTORY
//VER 0.101 1:32 2011-7-31
//Add Fade function to the application
//VER 0.100 16:45 2011-7-30
//Add blink function to the application
char CMD; //command
int pwmValue; //PWM value
int PinOUT=10; //output pin
int Interval = 10;
void setup()
{
Serial.begin(9600);
pinMode(PinOUT, OUTPUT); //set the pin 10 as output pin�
CMD = 'F';
pwmValue = 50;
}
void loop()
{
if (Serial.available())
{
char PrevCMD;
PrevCMD = CMD;
CMD = Serial.read();
switch(CMD)
{
case 'B': //Blink
//read PWM value in readPWMValue routine
pwmValue = readPWMValue();
break ;
//any other CASE statement�
case 'F': //Fading
pwmValue = readPWMValue();
break;
default :
CMD = PrevCMD; //当没有按键或者控制指令无效时,继续执行原来的指令
break;
}
}
//if there is no chars income, then execute the last command
switch(CMD)
{
case 'B':
setPWM(pwmValue);
break;
case 'F':
ledFading(pwmValue);
break;
default:
break;
}
}
int readPWMValue()
{
int Value;
while (!Serial.available())
{
//wait for another incoming char�
}
Value=Serial.read();
Serial.print("Parameters received: ");
Serial.println(Value);
return Value;
}
void setPWM(int Value)
{
int i;
Serial.println(Value);
for (i=0; i<=100; i++)
{
//debug
Serial.print(i);
Serial.print(" / ");
if (i<= Value)
{
digitalWrite(PinOUT,HIGH);
//Debug
Serial.println("HIGH");
}
else
{
digitalWrite(PinOUT,LOW);
//DEBUG
Serial.println("LOW");
}
delay(Interval);
}
}
void ledFading(int Value)
{
Serial.print("Fading Value: ");
Serial.println(Value);
int i;
/*
if (Value>=255)
Value = 255;
else
if (Value<=0);
Value =0;
*/
//fade in
for (i=0; i<=Value; i++)
{
analogWrite(PinOUT, i);
Serial.println(i);
delay(Interval);
}
delay(500);
//fade out
for (i=Value; i>=0; i--)
{
analogWrite(PinOUT,i);
Serial.println(i);
delay(Interval);
}
delay(500);
}
当然上面的代码只是为了演示和学习需要,所以会很不完善甚至有错误的地方。
功能需求:
PC机作为上位机,通过串口发送控制指令 F(ading) or B(link) 给Arduino,根据不同指令来实现LED闪烁或者渐明渐暗。
实现方式:
单片机选用Arduino MEGA 1280,PWM10脚作为输出口,接220欧限流电阻至高亮LED,再与GND脚共地。
上位机用C#作为编程语言,IDE选择VS2010,.Net版本选择了4.0,不过应该能够兼容其它版本的.net framework。之前上位机跟单片机通信时,传递的是字符串,方法是先将PWM值视为ASCII码,转换成对应的Char,然后将Char再转换成String类型。由于ANSI ASCII码表只支持128个字符,所以128-255之间的数在传递的时候就遇到难题,通过串口监视发现,超过127的ASCII发给arduino之后,都被修改为63,导致传输失效。
现在的方法改为直接传递byte类型的无符号数,解决了这个问题。
运行界面如下:
上位机源代码:
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)
{
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[0] =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();
}
}
}
Arduino程序源代码:
//COPYRIGHT DECLARATION
//THIS APPLICATION IS A DEMOSTRATION APPLICATON FOR EDUCATION PURPOSE ONLY. YOU CAN USE OR
//REDISTRIBUTE IT FREELY ON CONDITION THAT YOU WOULD NOT MAKE MONEY OF IT.
//THE DESKTOP APPLICATON WHICH IS PROGRAMMED IN C# WOULD SEND CONTROL CODE AND PARAMETERS, IF ANY,
//TO THE ARDUINO, THE MICROCONTROLLER WOULD MAKE THE LED FADING OR BLINKING IN ACCORDANCE
//WITH THE CONTROL CODE, THEN.
//SINCE THIS IS MY FIRST APPLICATION IN EITHER C# AND ARDUINO, THERE MIGHT BE SOME BUGS IN IT,
//IF YOU RUN INTO ANY EXCEPTIONS, PLEASE REPORT THEM TO ME AT JZOPEN@YEAH.NET.
//HISTORY
//VER 0.101 1:32 2011-7-31
//Add Fade function to the application
//VER 0.100 16:45 2011-7-30
//Add blink function to the application
char CMD; //command
int pwmValue; //PWM value
int PinOUT=10; //output pin
int Interval = 10;
void setup()
{
Serial.begin(9600);
pinMode(PinOUT, OUTPUT); //set the pin 10 as output pin�
CMD = 'F';
pwmValue = 50;
}
void loop()
{
if (Serial.available())
{
char PrevCMD;
PrevCMD = CMD;
CMD = Serial.read();
switch(CMD)
{
case 'B': //Blink
//read PWM value in readPWMValue routine
pwmValue = readPWMValue();
break ;
//any other CASE statement�
case 'F': //Fading
pwmValue = readPWMValue();
break;
default :
CMD = PrevCMD; //当没有按键或者控制指令无效时,继续执行原来的指令
break;
}
}
//if there is no chars income, then execute the last command
switch(CMD)
{
case 'B':
setPWM(pwmValue);
break;
case 'F':
ledFading(pwmValue);
break;
default:
break;
}
}
int readPWMValue()
{
int Value;
while (!Serial.available())
{
//wait for another incoming char�
}
Value=Serial.read();
Serial.print("Parameters received: ");
Serial.println(Value);
return Value;
}
void setPWM(int Value)
{
int i;
Serial.println(Value);
for (i=0; i<=100; i++)
{
//debug
Serial.print(i);
Serial.print(" / ");
if (i<= Value)
{
digitalWrite(PinOUT,HIGH);
//Debug
Serial.println("HIGH");
}
else
{
digitalWrite(PinOUT,LOW);
//DEBUG
Serial.println("LOW");
}
delay(Interval);
}
}
void ledFading(int Value)
{
Serial.print("Fading Value: ");
Serial.println(Value);
int i;
/*
if (Value>=255)
Value = 255;
else
if (Value<=0);
Value =0;
*/
//fade in
for (i=0; i<=Value; i++)
{
analogWrite(PinOUT, i);
Serial.println(i);
delay(Interval);
}
delay(500);
//fade out
for (i=Value; i>=0; i--)
{
analogWrite(PinOUT,i);
Serial.println(i);
delay(Interval);
}
delay(500);
}
当然上面的代码只是为了演示和学习需要,所以会很不完善甚至有错误的地方。
订阅:
博文 (Atom)








