最近做了一个小系统,麻雀虽小五脏俱全呀,用到各种线程控制,串口控制等技术。其中串口控制最麻烦,因为继电器的响应很快,根据不同的转接口,返回的数据质量是不一样的,所以不能直接wirte,然后马上read,这样经常得到的效应状态是错误的。因此需要用到backgroundworker不停地read,校验数据成功后再设置成功状态标志,最后让timer定时获取改标志,成功后立即控制程序界面上的按钮等控件。

public void openSerial()
{
try
{
foreach (GlobaConfig config in GlobaConfigInstance.Instance)
{
if ((!config.SerialPort.IsOpen))
{
config.SerialPort.Open();
config.SerialPort.DiscardInBuffer();
config.SerialPort.DiscardOutBuffer();
}
}
}
catch(Exception ex)
{
//MessageBox.Show("打开失败!" + ex.Message);
NotificationManager.Show(this, "打开失败!" + ex.Message,
Color.Gold, );
return;
}
} private void SendOpenDemand(byte port)
{
byte[] buffer = new byte[];
byte[] buffer2 = new byte[];
buffer[] = GlobaConfigInstance.Instance[kryptonNavigator1.SelectedIndex].Addr;
buffer[] = ;
buffer[] = ;
buffer[] = port;
buffer[] = 0xff;
buffer[] = ;
A101.GetCRC(buffer, , buffer2);
buffer[] = buffer2[];
buffer[] = buffer2[];
if (GlobaConfigInstance.Instance[kryptonNavigator1.SelectedIndex].SerialPort.IsOpen)
{
this.SerialSendFrame(buffer, , );
}
else
{
//MessageBox.Show("亲,你要先打开串口哦!");
}
} private void SendCloseDemand(byte port)
{
byte[] buffer = new byte[];
byte[] buffer2 = new byte[];
buffer[] = GlobaConfigInstance.Instance[kryptonNavigator1.SelectedIndex].Addr;
buffer[] = ;
buffer[] = ;
buffer[] = port;
buffer[] = ;
buffer[] = ;
A101.GetCRC(buffer, , buffer2);
buffer[] = buffer2[];
buffer[] = buffer2[];
if (GlobaConfigInstance.Instance[kryptonNavigator1.SelectedIndex].SerialPort.IsOpen)
{
this.SerialSendFrame(buffer, , );
}
else
{
//MessageBox.Show("亲,你要先打开串口哦!");
}
} private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
byte[] buffer;
while (true)
{
try
{ if (GlobaConfigInstance.Instance[kryptonNavigator1.SelectedIndex].SerialPort.IsOpen)
{
int bytesToRead = GlobaConfigInstance.Instance[kryptonNavigator1.SelectedIndex].SerialPort.BytesToRead;
buffer = new byte[0xff];
if (bytesToRead > )
{
int num2;
bytesToRead = 0x45;
GlobaConfigInstance.Instance[kryptonNavigator1.SelectedIndex].SerialPort.Read(buffer, , bytesToRead);
bool isValid = A101.ValidCRC(buffer, (byte)bytesToRead);
System.Diagnostics.Debug.WriteLine("isValid: " + isValid);
if (isValid)
{
for (num2 = ; num2 < bytesToRead; num2++)
{
this.SerialRecBuf[num2] = buffer[num2];
} this.SerialRecFlag = true;
}
else
this.SerialRecFlag = false; }
}
}
catch (Exception ex)
{ Console.WriteLine(ex);
}
Thread.Sleep();
}
} private void timer1_Tick(object sender, EventArgs e)
{
if (this.SerialRecFlag)
{
this.SerialRecFlag = false;
if (((this.SerialRecBuf[] == GlobaConfigInstance.Instance[kryptonNavigator1.SelectedIndex].Addr) && (this.SerialRecBuf[] == )) && (this.SerialRecBuf[] == ))
{
this.BtnSendFlag = false;
if (GlobaConfigInstance.Instance[kryptonNavigator1.SelectedIndex].SerialPort.IsOpen)
{
Control[] controls = this.kryptonNavigator1.SelectedPage.Controls.Find("btnRelay" + kryptonNavigator1.SelectedIndex + this.SerialRecBuf[], true);
if (controls.Length > )
{
KryptonCheckButton button = controls[] as KryptonCheckButton;
button.Checked = false;
button.Tag = "断开";
button.Enabled = true;
}
}
}
else if (((this.SerialRecBuf[] == GlobaConfigInstance.Instance[kryptonNavigator1.SelectedIndex].Addr) && (this.SerialRecBuf[] == )) && (this.SerialRecBuf[] == 0xff))
{
this.BtnSendFlag = false; if (GlobaConfigInstance.Instance[kryptonNavigator1.SelectedIndex].SerialPort.IsOpen)
{
Control[] controls = this.kryptonNavigator1.SelectedPage.Controls.Find("btnRelay" + kryptonNavigator1.SelectedIndex + this.SerialRecBuf[], true);
if (controls.Length > )
{
KryptonCheckButton button = controls[] as KryptonCheckButton;
button.Checked = true;
button.Tag = "闭合";
button.Enabled = true;
}
}
}
else if (((this.SerialRecBuf[] == GlobaConfigInstance.Instance[kryptonNavigator1.SelectedIndex].Addr) && (this.SerialRecBuf[] == )) && (this.SerialRecBuf[] == ))
{
uint[] numArray = new uint[];
uint resource = ;
numArray[] = this.SerialRecBuf[];
numArray[] = this.SerialRecBuf[];
numArray[] = this.SerialRecBuf[];
numArray[] = this.SerialRecBuf[];
resource = (((numArray[] << 0x18) | (numArray[] << 0x10)) | (numArray[] << )) | numArray[]; if (GlobaConfigInstance.Instance[kryptonNavigator1.SelectedIndex].SerialPort.IsOpen)
{
foreach (Control control in this.kryptonNavigator1.SelectedPage.Controls[].Controls)
{
KryptonCheckButton button = control as KryptonCheckButton;
if (this.GetRegBit(resource, (byte)control.TabIndex) == )
{
button.Checked = false;
button.Tag = "断开";
}
else
{
button.Checked = true;
button.Tag = "闭合";
}
button.Enabled = true;
}
}
} }
} private void timer2_Tick(object sender, EventArgs e)
{
if (!this.BtnSendFlag)
{
byte[] buffer = new byte[];
byte[] buffer2 = new byte[];
buffer[] = GlobaConfigInstance.Instance[kryptonNavigator1.SelectedIndex].Addr;
buffer[] = ;
buffer[] = ;
buffer[] = ;
buffer[] = ;
buffer[] = 0x1c;
A101.GetCRC(buffer, , buffer2);
buffer[] = buffer2[];
buffer[] = buffer2[];
System.Diagnostics.Debug.WriteLine(kryptonNavigator1.SelectedIndex + ":" + GlobaConfigInstance.Instance[kryptonNavigator1.SelectedIndex].SerialPort.IsOpen);
if (GlobaConfigInstance.Instance[kryptonNavigator1.SelectedIndex].SerialPort.IsOpen)
{
this.SerialSendFrame(buffer, , );
this.timer1.Start();
}
else
{
if (GlobaConfigInstance.Instance[kryptonNavigator1.SelectedIndex].IsValid == true)
{
GlobaConfigInstance.Instance[kryptonNavigator1.SelectedIndex].IsValid = false;
try
{
GlobaConfigInstance.Instance[kryptonNavigator1.SelectedIndex].SerialPort.Open();
//修復退出的線程
//this.timer1 = new System.Windows.Forms.Timer();
this.timer1.Start();
}
catch (Exception ex)
{
NotificationManager.Show(this, "主机" + (kryptonNavigator1.SelectedIndex + ) + "出现异常:" + ex.Message,
Color.Gold, );
//MessageBox.Show("主机" + (kryptonNavigator1.SelectedIndex + 1) + "出现异常:" + ex.Message);
}
}
}
}
}

C#SerialPort实现串口控制继电器的更多相关文章

  1. C# SerialPort自定义串口DCB

    C# SerialPort自定义串口DCBChange DCB fields from SerialPort instance CPS:中文DCB结构详解表 译自Change DCB fields f ...

  2. C#用SerialPort实现串口通讯

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  3. Nodejs 使用 SerialPort 调用串口

    工作经常使用串口读写数据,electron 想要替代原来的客户端,串口成了必须要突破的障碍. get -->  https://github.com/EmergingTechnologyAdvi ...

  4. C#SerialPort如何读取串口数据并显示在TextBox上

    SerialPort中串口数据的读取与写入有较大的不同.由于串口不知道数据何时到达,因此有两种方法可以实现串口数据的读取.一.线程实时读串口:二.事件触发方式实现. 由于线程实时读串口的效率不是十分高 ...

  5. c#实现串口操作 SerialPort

    命名空间:using System.IO.Ports;该类提供了同步 I/O 和事件驱动的 I/O.对管脚和中断状态的访问以及对串行驱动程序属性的访问. 操作类声明: SerialPort sp = ...

  6. System.IO.Ports.SerialPort串口通信接收完整数据

    C#中使用System.IO.Ports.SerialPort进行串口通信网上资料也很多,但都没有提及一些细节: 比如 串口有时候并不会一次性把你想要的数据全部传输给你,可能会分为1次,2次,3次分别 ...

  7. 树莓派4B 串口通信

    提前下载安装Glade图形编辑器 参考 树莓派4B安装netcore 环境部署.发布.执行操作 准备串口设备本文使用串口控制继电器设备 如图 1.发现串口 void GetSerialPort() { ...

  8. C#上位机制作之串口接受数据(利用接受事件)

    前面设计好了界面,现在就开始写代码了,首先定义一个串口对象.. SerialPort serialport = new SerialPort();//定义串口对象 添加串口扫描函数,扫描出来所有可用串 ...

  9. C#串口通讯实例

    本文参考<C#网络通信程序设计>(张晓明  编著) 程序界面如下图: 参数设置界面代码如下: using System; using System.Collections.Generic; ...

随机推荐

  1. VC++使用CImage PNG转BMP图片透明背景处理

    PNG格式的图片是支持透明通道的,BMP格式的图片是没有透明通道的,所以当PNG格式的图片转换为BMP格式时,对于PNG图片的透明背景就需要进行特别的处理. VC++中的HBITMAP是支持透明色的, ...

  2. 解读dbcp自动重连那些事

    转载自:http://agapple.iteye.com/blog/791943 可以后另一篇做对比:http://agapple.iteye.com/blog/772507 同样的内容,不同的描述方 ...

  3. es6+最佳入门实践(6)

    6.Symbol用法 6.1.什么是Symbol? Symbol是es6中一种新增加的数据类型,它表示独一无二的值.es5中我们把数据类型分为基本数据类型(字符串.数字.布尔.undefined.nu ...

  4. The NPF driver isn't running

    转自:http://blog.csdn.net/zhangkaihang/article/details/7470239 今天安装Wireshark软件时出现了如下图所示的错误,就搜索了一下解决方法, ...

  5. 转:A Painless Q-learning Tutorial (一个 Q-learning 算法的简明教程)

    demo 参见 MDP DEMO   本文是对 http://mnemstudio.org/path-finding-q-learning-tutorial.htm 的翻译,共分两部分,第一部分为中文 ...

  6. [Leetcode Week8]Edit Distance

    Edit Distance 题解 原创文章,拒绝转载 题目来源:https://leetcode.com/problems/edit-distance/description/ Description ...

  7. [Leetcode Week4]Merge Two Sorted Lists

    Merge Two Sorted Lists题解 原创文章,拒绝转载 题目来源:https://leetcode.com/problems/merge-two-sorted-lists/descrip ...

  8. 一.Select 函数详细介绍【转】

    转自:http://www.cnblogs.com/hjslovewcl/archive/2011/03/16/2314330.html Select在Socket编程中还是比较重要的,可是对于初学S ...

  9. 【linux】kill ;杀死某一用户下的所有进程

    [linux]kill :杀死某一用户下的所有进程 https://my.oschina.net/u/347414/blog/600854

  10. Android的简单应用(一)——PreferenceFragment实现应用的设置

    今天主要讲解怎么使用PreferenceFragment.PreferenceFragment它与默认的SharedPreferences文件相连接,不需要你再自己写代码去操作SharedPrefer ...