我编写了一个用c#连接PLC S7-200的程序.我使用dll Nmodbus。
我的目标:从PLC在线读取数据,并将数据写入PLC。我使用计时器从PLC在线读取数据。
问题:当我不止一次写数据时,我的程序挂起。
Button1_click:写数据
Button5_click:更新显示数据
public partial class Form1 : Form
{
System.Timers.Timer aTimer = new System.Timers.Timer(5000);
SerialPort sp = new SerialPort("COM10");
int count = 1;
void Update()
{
byte slaveId = 1;
ushort startAddress = 40001;
ushort numRegisters = 80;
// read five registers
IModbusSerialMaster master = ModbusSerialMaster.CreateRtu(sp);
ushort[] registers = master.ReadHoldingRegisters(1, 0, 80);
for (int i = 0; i < numRegisters; i++)
{
string temp = "Register[" + (startAddress + i) + "]=" + registers[i];
if (i == 36)
label10.Text = registers[i].ToString();
listBox1.Items.Add(temp);
}
}
private void OnTimedEvent(object source, ElapsedEventArgs e)
{
button5_Click(source, e);
label11.Text = sp.IsOpen.ToString();
// Update();
}
public Form1()
{
InitializeComponent();
//if (sp.IsOpen)
//{
// sp.Close();
//}
//Update();
sp.BaudRate = int.Parse(txtbaudrate.Text);
sp.DataBits = 8;
sp.Parity = Parity.None;
sp.StopBits = StopBits.One;
sp.Open();
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
aTimer.Interval = 1000;
aTimer.Enabled = true;
}
ushort i = 1;
int j = 1;
bool flag = false;
private void button1_Click(object sender, EventArgs e)
{
if (sp.IsOpen)
{
try
{
flag = true;
aTimer.Stop();
j++;
label11.Text = sp.IsOpen.ToString();
sp.Close();
sp.Open();
sp.BaudRate = int.Parse(txtbaudrate.Text);
sp.DataBits = 8;
sp.Parity = Parity.None;
sp.StopBits = StopBits.One;
ushort startAddress = 40036;
ushort numRegisters = 80;
byte slaveId = 1;
ushort[] registers;
if (j % 2 != 0)
{
registers = new ushort[] { 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50 };
}
else
{
registers = new ushort[] { 360, 370, 380, 390, 400, 410, 420, 430, 440, 450, 460, 470, 480, 490, 500 };
}
// read five registers
IModbusSerialMaster master = ModbusSerialMaster.CreateRtu(sp);
//ushort[] registers = master.ReadHoldingRegisters(1, 0, 5);
master.WriteMultipleRegisters(1, 36, registers);
//for (int i = 0; i < numRegisters; i++)
//{
// string temp = "Register[" + (startAddress + i) + "]=" + registers[i];
// listBox1.Items.Add(temp);
//}
sp.Close();
sp.Open();
aTimer.Start();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
sp.Close();
}
}
}
private void button5_Click(object sender, EventArgs e)
{
listBox1.Items.Clear();
Update();
}发布于 2013-11-02 19:52:32
每次尝试与远程设备通信时,您都会不断地打开和关闭串口,并创建新的Modbus主对象。此外,您不太可能需要/希望每次与设备对话时更改串行端口参数(波特率等)。
(关闭和打开端口可能会导致您丢失数据,虽然我不记得使用NModBus API的确切细节,因为我已经几年没有使用它们了,但这种类型的通信的通用使用模式可能包括为整个会话创建一个Master,而不是在会话期间创建多个Master-这些多个实例可能会在某种程度上发生冲突)
因此,我认为您应该做的第一件事是将通信分成三个不同的阶段:启动(创建表单时创建通信对象(串口和主))、交互(在计时器事件上尽可能多地与设备交谈)和关闭(关闭窗体时关闭主端口和串口)。
https://stackoverflow.com/questions/19739825
复制相似问题