C#上位机处理大量PLC报警类型
上位机读取PLC的变量数据
在C#开发平台中安装S7netplus插件
创建一个DataGrid表格和两个按钮分别为连接PLC和断开PLC
在程序的开始进行实例化
public partial class Form1:Form
{
static string ipAddress = "192.168.165.56";
Plc plc = new Plc(CpuType.S71500,ipAddress,0,1);
bool[] alarmState = new bool[256];
BitArray bitArray; //在框架之前就初始一个空对象
DataTable dt = new DataTable(); //创建一个表格,让报警信息显示在上面
DataTable dtDisplay;
public Form1()
{
InitializeComponent();
bitArray = new BitArray(alarmState);
dt.Columns.Add("报警类型");
dt.Columns.Add("报警状态");
dt.Columns.Add("报警产生时间");
dt.Columns.Add("报警恢复时间");
//dataGridView1.DataSource=dt; //表格控件与表格对象绑定
Control.CheckForllegalCrossThreadCalls = false; //关闭控件的跨线程检测
}
private void button1_Click(object sender,EventArgs e)
{
if(!plc.IsConnected) //没有连接成功
{
plc.Open();
this.Text = "通讯成功";
Task.Run(()=>
{
while(true)
{
if(plc.IsConnected)
{
try
{
//读取DB7数据块,从0.2开始的256个位变量。
bitArray = (BitArray)plc.Read(DataType.DataBlock,7,2,VarType.Bit,256);
AdjustDataTable();
}
catch()
{
}
}
}
});
}
}
void AdjustDataTable()
{
for(int i=0; i<bitArray.Rows.Count; i++)
{
if(bitArray[i]==true) //有报警产生时
{
for(int j=0; j<dt.Rows.Count; j++)
{
//判断当前报警表格里是否有该报警,如果没有就添加;有就跳出循环,判断下一个报警类理
if(dt.Rows[j]["报警类型"].ToString()=="报警类型"+i.ToString() && dt.Rows[j]["报警状态"].ToString()=="已产生")
{
goto LabelA; //跳到最外层for循环,如果用continue就会跳到当前的上一层For循环中。
}
}
dt.Rows.Add("报警类型"+i.ToString(),"已产生",DateTime.Now.ToString(),"");
//让表格中的报警记录如果是刚产生的变成红色,如果已经恢复了变成绿色
for(int i=0; i<dataGridView1.Rows.Count; i++)
{
if(dataGridView1.Rows[i].Cells[1].Value.ToString()=="已产生")
dataGridView1.Rows[i].DefaultCellStyle.BackColor = Color.Red;
else if(dataGridView1.Rows[i].Cells[1].Value.ToString()=="已恢复")
dataGridView1.Rows[i].DefaultCellStyle.BackColor = Color.Green;
}
}
else if(bitArray[i]==false)//没有报警产生时,该报警已经恢复了
{
for(int j=0; j<dt.Rows.Count; j++)
{
//判断当前报警表格里是否有该报警被恢复,如果有该类型同时报警状诚是已产生,那么就改成已恢复,报警恢复时间为当前时间。
if(dt.Rows[j]["报警类型"].ToString()=="报警类型"+i.ToString() && dt.Rows[j]["报警状态"].ToString()=="已产生")
{
dt.Rows[j]["报警类型"]="已恢复";
dt.Rows[j]["报警恢复时间"]=DateTime.Now.ToString();
}
}
}
LabelA:continue;
}
dtDisplay = dt.Copy(); //将带有类似 报警类型1..N 显示成水温高,水压力低等类型信息的处理
for(int i=0; i<dt.Rows.Count; i++)
{
if(dtDisplay.Rows[i][0].ToString()=="报警类型0")
dtDisplay.Rows[i][0] = "水温高";
else if(dtDisplay.Rows[i][0].ToString()=="报警类型1")
dtDisplay.Rows[i][0] = "水压力低";
else if(dtDisplay.Rows[i][0].ToString()=="报警类型2")
dtDisplay.Rows[i][0] = "水流量低";
}
//表格的绑定操作要在主线程下才可以工作,因为当前是在子线程下工作的。
this.Invoke(new Action(()=>{dataGridView1.DataSource = dtDisplay;}));
}
private void button2_Click(object sender,EventArgs e)
{
if(plc.IsConnected) //连接成功
{
plc.Close();
}
}
}
此时运行中的PLC如果产生报警,就会同步显示在这个上位机软件上了。
让表格中的报警记录如果是刚产生的变成红色,如果已经恢复了变成绿色
将带有类似 报警类型1..N 显示成水温高,水压力低等类型信息的处理