通过串口采集来自多个仪表的数据,协议是Modbus,仪表并接在RS485总线上,通过转接口连接到电脑USB接口
我现在用了一个计时器timer1,是System.Windows.Forms.Timer类型的,间隔一秒钟触发timer1_Tick函数
主要的代码是这样的:
private void timer1_Tick_1(object sender, EventArgs e)
{
try
{
System.Threading.Thread timerThread = new System.Threading.Thread(new System.Threading.ThreadStart(TimerMethod));
timerThread.Start();
//周期性将临时数据存入历史数据库
}
catch (Exception exp)
{
timer1.Stop();
}
}
public void TimerMethod()
{
try
{
//清除临时数据
using (SerialPort port = new SerialPort())
{
//设置串口
port.Open();
//从串口读数据
port.Close();
if (con.State == ConnectionState.Open)
{
//将实时数据写入数据库
//***********显示实时数值
// ************刷新控件状态
//************判断是否报警
}
}
}
catch (Exception exp)
{
timer1.Stop();
System.Threading.Thread.CurrentThread.Abort();
}
}
在运行了一小段时间之后就会出现“对COM1的访问被拒绝”这样的错误,但是有时候又会一直运行下去很长时间才出错,我是第一次尝试写多线程的代码,希望有朋友帮我看一下我这样的方式是否可行,另外帮我分析下出现这个错误的可能原因是什么。
PS:因为TimerMethod代码太长所以只贴了说明文字,如果需要我选取详细的代码再贴上来
我现在用了一个计时器timer1,是System.Windows.Forms.Timer类型的,间隔一秒钟触发timer1_Tick函数
主要的代码是这样的:
private void timer1_Tick_1(object sender, EventArgs e)
{
try
{
System.Threading.Thread timerThread = new System.Threading.Thread(new System.Threading.ThreadStart(TimerMethod));
timerThread.Start();
//周期性将临时数据存入历史数据库
}
catch (Exception exp)
{
timer1.Stop();
}
}
public void TimerMethod()
{
try
{
//清除临时数据
using (SerialPort port = new SerialPort())
{
//设置串口
port.Open();
//从串口读数据
port.Close();
if (con.State == ConnectionState.Open)
{
//将实时数据写入数据库
//***********显示实时数值
// ************刷新控件状态
//************判断是否报警
}
}
}
catch (Exception exp)
{
timer1.Stop();
System.Threading.Thread.CurrentThread.Abort();
}
}
在运行了一小段时间之后就会出现“对COM1的访问被拒绝”这样的错误,但是有时候又会一直运行下去很长时间才出错,我是第一次尝试写多线程的代码,希望有朋友帮我看一下我这样的方式是否可行,另外帮我分析下出现这个错误的可能原因是什么。
PS:因为TimerMethod代码太长所以只贴了说明文字,如果需要我选取详细的代码再贴上来
我这个是写一个命令,他会返回一些数据!
如果只是读数据的话只是读一个串口的数据是没有必要用多线程
可以使用timer或起动一个后台线程就可以了!
我这个也是用timer实现的每5Min读一次!测试效果还很稳定
SerialPort这个类中有一个datareceive(不知道是不是这样子拼的)这个事件
也可以在这个事件里完成的!
public string WriteCommand(byte[] bCommand)
{
StringBuilder sb = new StringBuilder();
bool bRead = true;
try
{
ss_port.DiscardInBuffer();
ss_port.Write(bCommand,0,bCommand.Length);
Thread.Sleep(1500);
while (bRead)
{
_ReadBuffer = new byte[ss_port.BytesToRead];
ss_port.Read(_ReadBuffer, 0, _ReadBuffer.Length);
sb.Append(Encoding.ASCII.GetString(_ReadBuffer));
Thread.Sleep(500);
if (ss_port.BytesToRead <= 0)
{
bRead = false;
}
}
if (sb.ToString().Length == 0)
{
nReadCount++;
} if (nReadCount == 3)
{
nReadCount = 0;
throw new Exception("设置不正确或没有联接设备!");
}
}
catch (Exception ex)
{
throw new Exception("从设备获取数据失败!\r\n错误信息:" + ex.Message);
}
return sb.ToString();
}
另外,我设置好串口之后读数据不是用的SerialPort的DataReceived事件,因为仪表采用的是Modbus协议,所以我找了一个Modbus控件来帮助读取数据,里面有ReadHoldingRegisters()这样的函数可供使用
在一个新线程里面:
while(true)
{
读数据。
Thread.Sleep(1000); }