代码拉取完成,页面将自动刷新
using MiniExcelLibs;
using NLog.Targets;
using S7.Net.Types;
using CommunicationTools.Model;
using ScottPlot;
using ScottPlot.Plottable;
using Sunny.UI;
using CommunicationTools;
using System.Data;
using System.Diagnostics;
using System.IO;
namespace CommunicationTools
{
public partial class S7NetDemo : UIPage
{
S7Helper S7Helper;
private bool _isVerture = false;
//指示灯
bool Status;
List<DataGetModel> dataModels = new List<DataGetModel>();
DataGetModel _dataGetModel;
Random rand = new Random();
double[] liveData = new double[400];
DataGen.Electrocardiogram ecg = new DataGen.Electrocardiogram();
Stopwatch sw = Stopwatch.StartNew();
VLine vline;
int nextValueIndex = -1;
//两个线程,一个刷新数据,一个插入数据
Task _InsertDataTask;
Task _UpdateScottPlotTask;
Task _WriteDataToPlcTask;
Task _ReadDataFormPlcTask;
//控制线程
private CancellationTokenSource _ctsInsert;
private CancellationTokenSource _ctsUpdate;
private CancellationTokenSource _ctsWrite;
private CancellationTokenSource _ctsRead;
public S7NetDemo()
{
InitializeComponent();
InitData();
InitDataTask();
InitScottPlot();
}
private void PlottThread()
{
_UpdateScottPlotTask = Task.Run(() => UpdateData(_ctsUpdate.Token), _ctsUpdate.Token);
_InsertDataTask = Task.Run(() => RefreshData(_ctsInsert.Token), _ctsInsert.Token);
}
//插入数据
private async Task UpdateData(CancellationToken ct)
{
while (!ct.IsCancellationRequested)
{
//double nextValue = ecg.GetVoltage(sw.Elapsed.TotalSeconds);
double nextValue = S7Helper.ReadSingleData_Float(1, 4, 4, PlcDataType.Float);
if (PlottRoll.Checked)
{
// "roll" new values over old values like a traditional ECG machine
nextValueIndex = (nextValueIndex < liveData.Length - 1) ? nextValueIndex + 1 : 0;
liveData[nextValueIndex] = nextValue;
vline.IsVisible = true;
vline.X = nextValueIndex;
}
else
{
// "scroll" the whole chart to the left
Array.Copy(liveData, 1, liveData, 0, liveData.Length - 1);
liveData[liveData.Length - 1] = nextValue;
vline.IsVisible = false;
}
await Task.Delay(500, ct);
}
}
//刷新 UI
private async Task RefreshData(CancellationToken ct)
{
while (!ct.IsCancellationRequested)
{
Invoke(new Action(() =>
{
formsPlot1.Refresh();
}));
await Task.Delay(500, ct);
}
}
//写入模拟数据到plc
private async Task WriteDataToPlc(CancellationToken ct)
{
while (!ct.IsCancellationRequested)
{
float nextValue = (float)ecg.GetVoltage(sw.Elapsed.TotalSeconds);
if (S7Helper != null && S7Helper.Connected)
{
try
{
//db块,地址,数据,,,
S7Helper.WriteSingleData_Float(1, _dataGetModel.Address.ToInt(), nextValue, 4, PlcDataType.Float);
}
catch (Exception)
{
}
}
await Task.Delay(1000, ct);
}
}
private void InitScottPlot()
{
// plot the data array only once and we can updates its values later
formsPlot1.Plot.AddSignal(liveData);
formsPlot1.Plot.AxisAutoX(margin: 0);
formsPlot1.Plot.SetAxisLimits(yMin: -1, yMax: 2.5);
// plot a red vertical line and save it so we can move it later
vline = formsPlot1.Plot.AddVerticalLine(0, Color.Red, 2);
// customize styling
formsPlot1.Plot.Title("Electrocardiogram Strip Chart");
formsPlot1.Plot.YLabel("Potential (mV)");
formsPlot1.Plot.XLabel("Time (seconds)");
formsPlot1.Plot.Grid(false);
Closed += (sender, args) =>
{
/*timerUpdateData?.Stop();
timerRender?.Stop();*/
};
}
//多线程监控温度,状态
private void InitDataTask()
{
Task task = Task.Run(() =>
{
while (true)
{
try
{
if (this.S7Helper != null && this.S7Helper.Connected)
{
var temperature = S7Helper.ReadSingleData_Float(1, 4, 4, PlcDataType.Float);
//对ui控件操作放在ui线程上
Invoke(new Action(() =>
{
uiLedLabel1.Text = temperature.ToString();
uiLight1.State = Status ? UILightState.On : UILightState.Off;
}));
}
else
{
uiLight1.State = Status ? UILightState.On : UILightState.Off;
Invoke(new Action(() =>
{
uiLedLabel1.Text = 0.00.ToString();
}));
}
}
catch (Exception)
{
}
Task.Delay(500);
}
});
}
private void InitData()
{
var FilePath = AppDomain.CurrentDomain.BaseDirectory + "Config.ini";
IniFile ini = new IniFile(FilePath);
string DataGet = ini.ReadString("Setup", "DataGetPath", "DataGet.xlsx");
string DataSet = ini.ReadString("Setup", "DataSetPath", "DataSet.xlsx");
// query加上泛型可以把查找的值一一对应!!!
dataModels = MiniExcel.Query<DataGetModel>(AppDomain.CurrentDomain.BaseDirectory + DataGet).ToList();
DataGridViewMiniExcell.DataSource = dataModels;
}
//开关
private void uiSwitch1_ValueChanged(object sender, bool value)
{
if (uiSwitch1.Active)
{
try
{
S7Helper = new S7Helper("S71200", s7IP.Text);
Status = S7Helper.ConnectPLC(S7Port.Value, (short)S7Rack.Value, (short)S7Slot.Value);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
else
{
S7Helper.DisconnectPLC();
Status = false;
}
}
//====================华丽分割线=================================================
private void plottRun_CheckedChanged(object sender, EventArgs e)
{
if (plottRun.Checked)
{
sw.Start();
//点击run开启两个线程来刷新和插入值
_ctsInsert = new CancellationTokenSource();
_ctsUpdate = new CancellationTokenSource();
PlottThread();
}
else
{
sw.Stop();
_ctsInsert?.Cancel();
_ctsUpdate?.Cancel();
}
}
private void PlottRoll_CheckedChanged(object sender, EventArgs e)
{
// clear old data values
for (int i = 0; i < liveData.Length; i++)
liveData[i] = 0;
}
//模拟数据写到plc
private void btn_Moni_Click(object sender, EventArgs e)
{
_isVerture = !_isVerture;
if (_isVerture && S7Helper != null && S7Helper.Connected)
{
if (DataGridViewMiniExcell.SelectedRows.Count > 0)
{
_dataGetModel = DataGridViewMiniExcell.SelectedRows[0].DataBoundItem as DataGetModel;
if (_dataGetModel == null)
{
MessageBox.Show("选择无效,数据为空");
}
_ctsWrite = new CancellationTokenSource();
_WriteDataToPlcTask = Task.Run(() => WriteDataToPlc(_ctsWrite.Token), _ctsWrite.Token);
}
else
{
_isVerture = !_isVerture;
MessageBox.Show("请选择一行!");
}
}
else
{
_ctsWrite?.Cancel();
_ctsRead?.Cancel();
}
}
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。