// Constructor public UI161() { InitializeComponent(); // Instantiate Modbus printer and register for log events MB = new Modbus(this); MB.Log += Modbus_Log; MB.Complete += P_Complete; // Instantiate the user pattern up = new UserPattern(this, MB, tabLogo); up.Log += Modbus_Log; // Start AsyncIO asyncIO = new AsyncIO(this, MB); asyncIO.Log += Modbus_Log; asyncIO.Complete += AsyncIO_Complete; doSubs = new DoSubs(this, MB, grpMain); doSubs.Subs = new Substitution[2]; //if (global.DefaultSubRules != null) { // doSubs.Subs[(int)DoSubs.Src.global] = global.DefaultSubRules.Copy(); //} //if (parent.msg != null && parent.msg.Substitution != null) { // doSubs.Subs[(int)DoSubs.Src.msg] = parent.msg.Substitution.Copy(); //} doSubs.BuildControls(prop); }
private void Connect() { try { Serial?.Close(); Thread.Sleep(50); Serial = new SerialPort(PortName) { BaudRate = 9600, DataBits = 8, Parity = Parity.None, StopBits = StopBits.One }; Serial.Open(); Modbus = ModbusSerialMaster.CreateRtu(Serial); Modbus.Transport.Retries = 2; Modbus.Transport.ReadTimeout = 100; Modbus.ReadInputRegisters(1, 0, 4); ModbusDeviceStates.Fire(TemperatureDeviceEdge.ConnectionValid); } catch { Serial?.Close(); Thread.Sleep(50); ModbusDeviceStates.Fire(TemperatureDeviceEdge.ConnectionInvalid); } }
internal CModbus(string IP) { try { m_Modbus = new Modbus(IPAddress.Parse(IP), 502); Thread thd = new Thread(Thd_PollMsg); thd.IsBackground = true; thd.Name = "Modbus轮询消息"; thd.Start(); m_Modbus.event_MessageText += new Modbus.dele_MessageText(m_Modbus_event_MessageText); } catch (Exception ex) { log.AddERRORLOG("IP地址:" + IP + "\r\nModbus初始化失败:" + ex.Message); if (IP.Contains("100")) { throw new Exception("连接上料机失败,IP地址:" + IP); } else if (IP.Contains("200")) { throw new Exception("连接下料机失败,IP地址:" + IP); } else { throw new Exception("连接上下料机失败,IP地址:" + IP); } } }
/*-------------------------------------------------------------------------------------------------- * Func: 生成ModBus数据报文 * Time: 2010-6-28 * Ver.: V1.0 * Note: * 本方法对于主机: 生成查询报文 * 本方法对于从机: 若TxMsg->CmdCode为读命令,则生成返回数据报文 * 若TxMsg->CmdCode为写命令,则生成应答报文 * 若收到非法不可执行命令,则生成错误码状态报文 * * 本方法根据Msg->DataLenth指定生成是否含Datas域 * Infor: DevAddr[1]+CmdCode[1]+StartReg[2]+RegCount[2]+CRC16[2] * Input: *Msg/报文结构 *Buffer/报文帧数据缓冲区 * --------------------------------------------------------------------------------------------------*/ public static int CreateTxMessage(ref Modbus CurModbus, ref byte[] TxBuffer) { int L = 0; TxBuffer[0] = (byte)CurModbus.TxMsg.DevAddr; //写入设备地址字节 TxBuffer[1] = (byte)CurModbus.TxMsg.CmdCode; //写入命令码字节 if (CurModbus.LocalMode == HostMode) { TxBuffer[2] = (byte)(CurModbus.TxMsg.RegStart >> 8); TxBuffer[3] = (byte)(CurModbus.TxMsg.RegStart); //写入起始地址 TxBuffer[4] = (byte)(CurModbus.TxMsg.RegCount >> 8); TxBuffer[5] = (byte)(CurModbus.TxMsg.RegCount); //写入寄存器个数 if (CurModbus.TxMsg.CmdCode == 0x03) { L = 6; } else { TxBuffer[6] = (byte)(CurModbus.TxMsg.DataLenth); //写入数据长度 L = 7; } for (int i = 0; i < CurModbus.TxMsg.DataLenth; i++) { TxBuffer[L + i] = CurModbus.TxMsg.DataBuffer[i]; //写入数据域 } L += CurModbus.TxMsg.DataLenth; } uint T = CheckTools.GetCrc16(TxBuffer, L); //求本帧数据校验码 TxBuffer[L] = (byte)(T); TxBuffer[L + 1] = (byte)(T >> 8); //写入CRC16到帧尾部 return(L + 2); //设定发送帧长度 }
/// <summary> /// Создать узел группы элементов /// </summary> private TreeNode NewElemGroupNode(Modbus.ElemGroup elemGroup) { string name = elemGroup.Name == "" ? KpPhrases.DefGrName : elemGroup.Name; TreeNode grNode = new TreeNode(name + " (" + Modbus.GetTableTypeName(elemGroup.TableType) + ")"); grNode.ImageKey = grNode.SelectedImageKey = "group.png"; grNode.Tag = elemGroup; ushort elemAddr = elemGroup.Address; int elemSig = elemGroup.StartKPTagInd + 1; foreach (Modbus.Elem elem in elemGroup.Elems) { ElemInfo elemInfo = new ElemInfo(); elemInfo.Elem = elem; elemInfo.ElemGroup = elemGroup; elemInfo.Address = elemAddr; elemInfo.Signal = elemSig++; grNode.Nodes.Add(NewElemNode(elemInfo)); elemAddr += (ushort)elem.Length; } return(grNode); }
/// <summary> /// 超时判断 /// </summary> /// <returns></returns> //public async Task<bool> TimeTask() //{ // var task = PrimeTask(); // int timeout = 1000; // if (await Task.WhenAny(task, Task.Delay(timeout)) == task) // { // return true; // } // return false; //} /// <summary> /// 调用Modbus的CRC校验处理 /// </summary> /// <param name="_data"></param> /// <returns></returns> public bool ModbusCRC(Data _data) { try { byte[] bt = _data.SendByList.ToArray(); if (bt == null || bt.Length == 0) { return(false); } if (!Modbus.ReceiveByteArray(bt)) { return(false); } _data.ModbusData = Modbus.double_data; return(true); } catch (Exception ex) { Log4netHelper.Error(ex); return(false); } }
public override Task <bool[]> PrectiVstupyNaZarizeni() { return(Task.Factory.StartNew(() => { var returnValue = Modbus.ReadDiscreteInputs(0, 6); return returnValue; })); }
/// <summary> /// 电量服务 /// </summary> /// <returns></returns> public bool ElectricService() { Modbus.MBConfig(0xFA, 9600); Modbus.MBAddRepeatCmd(0x1000, 0x03); BLECode.GetIntance.Write(Modbus.WBuff); return(true); }
// Get the length of the area in words (2 bytes per word) public static int GetSpan(Modbus MB, T start, T end) { AttrData startAttr = MB.GetAttrData(start); // Starting memory address (Words) AttrData endAttr = MB.GetAttrData(end); // Ending memory address Debug.Assert(startAttr.Val <= endAttr.Val); // Make sure they are in the correct order return(endAttr.Val - startAttr.Val + endAttr.Data.Len); // Be sure to include the last element }
public ModbusAdapterContext(DeviceBase canDevice, File modbusDevice) { CanDevice = new CAN(); CanDevice.NetworkId = canDevice.Network.NetworkId; CanDevice.NodeId = canDevice.NodeId; ModbusDevice = new Modbus(); ModbusDevice.FileNumber = modbusDevice.Number; }
public AsyncIO(Form parent, Modbus MB) { // this.parent = parent; this.MB = MB; t = new Thread(processTasks); t.Start(); }
private DateTime connectDT; // время установки TCP-соединения /// <summary> /// Конструктор /// </summary> public KpModbusLogic(int number) : base(number) { modbus = new Modbus(); tcpClient = null; netStream = null; connectDT = DateTime.MinValue; }
/// <summary> /// Обновить узел выбранной группы элементов /// </summary> private void UpdateElemGroupNode() { if (selElemGroup != null) { string name = selElemGroup.Name == "" ? KpPhrases.DefGrName : selElemGroup.Name; selNode.Text = name + " (" + Modbus.GetTableTypeName(selElemGroup.TableType) + ")"; } }
public MainViewModel() { ConnectCommand = ReactiveCommand.CreateFromTask(() => Connect()); DisconnectCommand = ReactiveCommand.CreateFromTask(() => Disconnect()); WriteCommand = ReactiveCommand.Create(() => Write()); ReadCommand = ReactiveCommand.Create(() => Read()); _client = Modbus.CreateClient("127.0.0.1", 502); }
/// <summary> /// Обновить узел выбранной команды /// </summary> private void UpdateCmdNode() { if (selCmd != null) { string name = selCmd.Name == "" ? KpPhrases.DefCmdName : selCmd.Name; selNode.Text = name + " (" + Modbus.GetTableTypeName(selCmd.TableType) + ", " + (selCmd.Address + 1) + ")"; } }
public Fl_termo_window(Modbus modbus_pered, Termo_correction termo_pered, Translation trans) { modbus = modbus_pered; //Termo = termo_pered; Points_table = new Points(); InitializeComponent(); currentTranslation = trans; }
private void Write() { var cmd = Modbus.Commands.NewWriteHoldingRegisters(4107, new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); var res = Modbus.CommandHandler(_client, cmd); if (res.IsError) { MessageBox.Show(res.ErrorValue); } }
/// <summary> /// Создать узел команды /// </summary> private TreeNode NewCmdNode(Modbus.Cmd cmd) { string name = cmd.Name == "" ? KpPhrases.DefCmdName : cmd.Name; TreeNode cmdNode = new TreeNode(name + " (" + Modbus.GetTableTypeName(cmd.TableType) + ", " + (cmd.Address + 1) + ")"); cmdNode.ImageKey = cmdNode.SelectedImageKey = "cmd.png"; cmdNode.Tag = cmd; return(cmdNode); }
// Обработка нажатия кнопки Записать private void CM_REG_WRITE_BTN_Click(object sender, EventArgs e) { byte[] Buffer = new byte[9]; byte reg_address = 0; uint reg_data = 0; reg_address = (byte)Convert.ToInt32(CM_REG_ADDRESS_BOX.Text, 16); reg_data = (uint)Convert.ToInt32(CM_REG_DATA_BOX.Text, 16); Buffer[0] = Modbus.NODE_ADDRESS; Buffer[1] = Modbus.WRITE_REGISTER; // Адрес первого регистра Buffer[2] = Modbus.GRUP_CM1K_REGISTER; Buffer[3] = reg_address; // Количество регистров для записи Buffer[4] = 0x01; // Данные для записи Buffer[5] = (byte)(reg_data >> 8); Buffer[6] = (byte)reg_data; // Вычисляем контрольную сумму uint crc = Modbus.CRC16(Buffer, (uint)Buffer.Length - 2); Buffer[7] = (byte)(crc); Buffer[8] = (byte)(crc >> 8); // Пытаемся отправить пакет try { serialPort1.Write(Buffer, 0, Buffer.Length); } catch (Exception ex) { serialPort1.Close(); MessageBox.Show("Error writing to serial port - " + ex.Message, "Error!"); return; } // Ждем секунду Wait(1); // Проверяем, есть ли пакет try { int sss = serialPort1.Read(Buffer, 0, Buffer.Length); if ((sss == 0) && (Buffer[0] != Modbus.NODE_ADDRESS)) { toolStripStatusLabel3.Text = "Data not write!"; } else { toolStripStatusLabel3.Text = "Data write!"; } } catch (Exception ex) { MessageBox.Show("Error reading from serial port - " + ex.Message, "Error!"); return; } }
//---------------------------------------------------------------------------- public void Read_IR_TypeOfDevice( ref Modbus.OSIModel.ApplicationLayer.Master.Device host, out OperationResult error, Byte addressSlave, out TYPE_NGK_DEVICE typeOfDevice) { Modbus.OSIModel.Message.Result result; UInt16[] registers; if (host == null) { typeOfDevice = TYPE_NGK_DEVICE.UNKNOWN_DEVICE; error = new OperationResult(OPERATION_RESULT.CONNECTION_ERROR, "Подключение к сети не создано"); } else { if (host.DataLinkObject.IsOpen()) { result = host.ReadInputRegisters(addressSlave, BI_ADDRESSES_OF_INPUTREGISTERS.TypeOfDevice, 1, out registers); if (result.Error == Modbus.OSIModel.ApplicationLayer.Error.NoError) { try { typeOfDevice = (TYPE_NGK_DEVICE)Enum.Parse(typeof(TYPE_NGK_DEVICE), registers[0].ToString()); error = new OperationResult(OPERATION_RESULT.OK, String.Empty); } catch { typeOfDevice = TYPE_NGK_DEVICE.UNKNOWN_DEVICE; error = new OperationResult(OPERATION_RESULT.UNKNOWN_DEVICE, String.Format( "Устройство вернуло код неизвестного типа устройства: {0}", registers[0].ToString())); } } else { typeOfDevice = TYPE_NGK_DEVICE.UNKNOWN_DEVICE; error = new OperationResult(OPERATION_RESULT.FAILURE, result.Description); } } else { typeOfDevice = TYPE_NGK_DEVICE.UNKNOWN_DEVICE; error = new OperationResult(OPERATION_RESULT.CONNECTION_ERROR, "Соeдинение создано, но не открыто"); } } return; }
/*-------------------------------------------------------------------------------------------------- * Func: 初始化MODBUS发送报文结构 * Time: 2010-6-29 * Ver.: V1.0 * Note: * --------------------------------------------------------------------------------------------------*/ public static void CreateTxHeader(ref Modbus CurModbus, int DevAddr, int CmdCode, int RegStart, int RegCount, byte[] DataBuffer, int DataLenth) { CurModbus.TxMsg.DevAddr = DevAddr; CurModbus.TxMsg.CmdCode = CmdCode; CurModbus.TxMsg.RegStart = RegStart; CurModbus.TxMsg.RegCount = RegCount; for (int i = 0; i < DataLenth; i++) { CurModbus.TxMsg.DataBuffer[i] = DataBuffer[i]; } CurModbus.TxMsg.DataLenth = DataLenth; }
/** * 发送所有数据的CRC校验码 * 请求:地址域 功能码 寄存器地址 所有数据的CRC校验码 CRC16校验 * 响应:地址域 功能码 寄存器地址 所有数据的校验码状态 CRC16校验 * 主机发送:FA 06 11 04 5C 66 61 96 * 从机返回:01 06 11 04 00 01 0C F7 * 注: 5C 66 ----所有数据的CRC校验码 * 00 01 ----校验码正确 00 00 ---- 错误 */ public static void sendDrviceUpdataDataCRC(byte[] datas) { if (datas == null || datas.Length == 0) { return; } //加入验证码 //CRC16校验:2字节,从地址域开始前面所有数据的CRC Modbus.MBAddCmd(0x1104, 0x06, 0, datas); BLECode.GetIntance.Write(Modbus.WBuff); }
//固件升级 private void FirmwareUpdata_InSetup(Object sender, EventArgs e) { Modbus.MBConfig(0xFA, 9600); Modbus.MBAddCmd(0x1000, 0x03); BLECode.GetIntance.Write(Modbus.WBuff); if (!_setupRepository.ReadChipId()) { _setupForm.ShowToast_InSetup("提示", "请检查蓝牙设备是否打开", 2); _setupForm.SetButtonUp(true); return; } }
/// <summary> /// Конструктор /// </summary> /// <param name="nameNetwork">Имя Modbus-сети</param> /// <param name="dataLinkObject">Объект уровня DataLink Layer</param> public Device(String nameNetwork, Modbus.OSIModel.DataLinkLayer.Master.IDataLinkLayer dataLinkObject) { // Задаём имя сервера _name = nameNetwork; // Задаём объект уровня DataLinkLayer _dataLinkObject = dataLinkObject; // Сервер находится в режиме простоя StopTransaction(); return; }
public override bool Disconnect() { try { Modbus?.Disconnect(); Status = Stav.Offline; return(true); } catch (Exception exception) { var zarizeniArgs = new ZarizeniArgs(Status, Ping, $"!CHYBA!", exception); OnStatusChanged(zarizeniArgs); return(false); } }
public FmMain() { InitializeComponent(); this.StartPosition = FormStartPosition.CenterScreen; this.WindowState = FormWindowState.Maximized; CheckForIllegalCrossThreadCalls = false; plc = new Functions.OPC_ToPLC(); Text = "[" + GlobalPara.PackageNo + "号]包装机系统 版本" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString(); pbInfo_Click(null, null); robotService = new RobotTaskService(); CreateOpcClinet(); modbus = new Modbus(); }
public async Task Connect() { var res = Modbus.Connect(_client); if (res.IsError) { MessageBox.Show(res.ErrorValue); } else { _client = res.ResultValue; MessageBox.Show("Connected"); } await Task.CompletedTask; }
public short ReadRegister(ushort reg) { Modbus link = new Modbus(); link.Open(port, 9600, 8, Parity.None, StopBits.Two); short[] val = new short[1]; bool ret = link.SendFc3(address, reg, 1, ref val); if (!ret) { throw new EngineMessageException( "Read from register 0x" + reg.ToString("x") + " failed: " + link.modbusStatus); } link.Close(); return(val[0]); }
public void WriteRegister(ushort reg, short value) { Modbus link = new Modbus(); link.Open(port, 9600, 8, Parity.None, StopBits.Two); short[] val = { value }; bool ret = link.SendFc3(address, reg, 1, ref val); if (!ret) { throw new EngineMessageException( "Writing 0x" + value.ToString("x") + " to register 0x" + reg.ToString("x") + " failed: " + link.modbusStatus); } link.Close(); }
private void Read() { var qry = Modbus.Queries.NewReadHoldingRegisters(4107, 10); var res = Modbus.QueryHandler(_client, qry); if (res.IsOk) { var regs = res.ResultValue; var str = regs.Aggregate(string.Empty, (current, reg) => current + $"{reg} "); MessageBox.Show(str); } else { MessageBox.Show(res.ErrorValue); } }
/// <summary> /// 测量 && 采集数据 /// </summary> /// <param name="data"></param> /// <returns></returns> public bool ReadComond(string name) { #region 深度档位选择 string sql = "select fet,gears from info where name = '" + name + "'"; DataTable dt = SQLiteHelper.ExecuteDataTable(sql, null); if (dt.Rows.Count == 0) { return(false); } string fet = dt.Rows[0].ItemArray[0].ToString(); string gears = dt.Rows[0].ItemArray[1].ToString(); int Index = -1; foreach (KeyValuePair <string, string[]> kvp in ComboxDSHelper.DepthMap) { if (kvp.Key.Equals(fet)) { for (int i = 0; i < kvp.Value.Length; i++) { if (kvp.Value[i].Equals(gears)) { Index = i; break; } } break; } } #endregion Modbus.MBConfig(0xFA, 9600); if (Index == 1) { Modbus.MBAddCmd(0x20, 0x04); } else if (Index == 2) { Modbus.MBAddCmd(0x22, 0x04); } else { Modbus.MBAddCmd(0x16, 0x04); } BLECode.GetIntance.Write(Modbus.WBuff); return(true); }
/*-------------------------------------------------------------------------------------------------- * Func: 截取请求报文中的数据段 * Time: 2010-6-28 * Ver.: V1.0 * Note: 本方法根据RegCount和Lenth自动判断是否有合适的Datas域 * Infor: DevAddr[1]+CmdCode[1]+StartReg[2]+RegCount[2]+Datas[RegCount*2]+CRC16[2] * Input: *Data/原如数据报文 Lenth/报文总长度 *Msg/返回的报文信息 * return: 0/报文信息提取成功 11/报文长度不足 12/报文数据校验错误 13/数据报分长度错误 0xFF/地址不匹配 * --------------------------------------------------------------------------------------------------*/ public static int ExpendRxMessage(ref Modbus CurModbus, byte[] RxBuffer, int RxLenth) { int T, P; if (CurModbus.LocalMode != HostMode) { if ((RxBuffer[0]) != CurModbus.LocalAddr) { return(0xFF); } } if (RxLenth < 5) { return(DataLenthError); //判断报文长度是否正常 } T = RxBuffer[RxLenth - 1]; T <<= 8; T |= (int)RxBuffer[RxLenth - 2]; P = (int)CheckTools.GetCrc16(RxBuffer, RxLenth - 2); //获取报文CRC16检验码 if (T != P) { return(CrcCheckError); //检验CRC16码是否正确 } CurModbus.RxMsg.DevAddr = RxBuffer[0]; //取设备地址 CurModbus.RxMsg.CmdCode = RxBuffer[1]; //取命令码 if (CurModbus.LocalMode == HostMode) { if (CurModbus.RxMsg.CmdCode == CmdCode_Read) { CurModbus.RxMsg.DataLenth = RxBuffer[2]; for (int i = 0; i < CurModbus.TxMsg.RegCount * 2; i++) { CurModbus.RxMsg.DataBuffer[i] = RxBuffer[i + 3]; } } else if ((CurModbus.RxMsg.CmdCode & 0x80) == 0x80) { CurModbus.RxMsg.DataLenth = 1; CurModbus.RxMsg.DataBuffer[0] = RxBuffer[2]; } else if (CurModbus.RxMsg.CmdCode == CmdCode_Write) { CurModbus.RxMsg.DataLenth = RxBuffer[2]; } } return(MsgSuccess); }
//---------------------------------------------------------------------------- public void Read_IR_BattaryVoltage( ref Modbus.OSIModel.ApplicationLayer.Master.Device host, out OperationResult error) { Modbus.OSIModel.Message.Result result; //String msg; UInt16[] registers; result = host.ReadInputRegisters(_AddressSlave, BI_ADDRESSES_OF_INPUTREGISTERS.BattaryVoltage, 1, out registers); if (result.Error == Modbus.OSIModel.ApplicationLayer.Error.NoError) { this.BattaryVoltage = (float)(ToValue(registers[0]) * 0.01); error = new OperationResult(OPERATION_RESULT.OK, String.Empty); } else { error = new OperationResult(OPERATION_RESULT.FAILURE, result.Description); } return; }
//---------------------------------------------------------------------------- public void Read_IR_SerialNumber( ref Modbus.OSIModel.ApplicationLayer.Master.Device host, out OperationResult error) { Modbus.OSIModel.Message.Result result; //String msg; UInt16[] registers; result = host.ReadInputRegisters(AddressSlave, BI_ADDRESSES_OF_INPUTREGISTERS.SerialNumber, 3, out registers); if (result.Error == Modbus.OSIModel.ApplicationLayer.Error.NoError) { UInt64 serialNumber; serialNumber = 0; serialNumber = registers[0]; // Upper serialNumber |= (serialNumber << 16); serialNumber |= registers[1]; // High serialNumber |= (serialNumber << 16); serialNumber |= registers[2]; // Low this.SerialNumber = serialNumber; error = new OperationResult(OPERATION_RESULT.OK, String.Empty); } else { error = new OperationResult(OPERATION_RESULT.FAILURE, result.Description); } return; }
//---------------------------------------------------------------------------- public void Read_HR_MeasuringPeriod( ref Modbus.OSIModel.ApplicationLayer.Master.Device host, out OperationResult error) { ushort[] registers; Modbus.OSIModel.Message.Result result; UInt32 period = 0; String msg; result = host.ReadHoldingRegisters(_AddressSlave, BI_ADDRESSES_OF_HOLDINGREGISTERS.MeasuringPeriod, 2, out registers); if (result.Error == Modbus.OSIModel.ApplicationLayer.Error.NoError) { if (registers.Length != 2) { msg = String.Format( "Ответ БИ содержит количесво прочитанных регистров {0}, должно быть 2", registers.Length); error = new OperationResult(OPERATION_RESULT.INCORRECT_ANSWER, msg); } else { period |= registers[0]; // high period = period << 16; period |= registers[1]; // low try { this.MeasuringPeriod = period; error = new OperationResult(OPERATION_RESULT.OK, String.Empty); } catch (Exception ex) { error = new OperationResult(OPERATION_RESULT.INCORRECT_ANSWER, ex.Message); } } } else { error = new OperationResult(OPERATION_RESULT.FAILURE, result.Description); } return; }
//------------------------------------------------------------------------------------------------------ /// <summary> /// Записывает серийный номер в устройство БИ при первоначальной инициализации /// </summary> /// <param name="host">Modbus master устройство</param> /// <param name="error">Результат выполнеия операции</param> /// <param name="addressSlave">Адрес подчинённого устройство</param> /// <param name="serialNumber">Серийный номер для записи в устройство</param> public static void Write_HR_SerialNumber(ref Modbus.OSIModel.ApplicationLayer.Master.Device host, out OperationResult error, Byte addressSlave ,UInt64 serialNumber) { // Записываем новое значение в устройство Modbus.OSIModel.Message.Result result; UInt16[] registers = new ushort[3] { 0, 0, 0 }; String msg; //this.Cursor = Cursors.WaitCursor; unchecked { registers[0] = (UInt16)serialNumber; registers[1] = (UInt16)(serialNumber >> 16); registers[2] = (UInt16)(serialNumber >> 32); } result = host.WriteMultipleRegisters( addressSlave, BI_ADDRESSES_OF_HOLDINGREGISTERS.SerialNumber, registers); if (result.Error != Modbus.OSIModel.ApplicationLayer.Error.NoError) { error = new OperationResult(OPERATION_RESULT.FAILURE, result.Description); } else { // Проверяем правильно ли записался параметр // Читаем записанный параметр result = host.ReadHoldingRegisters(addressSlave, BI_ADDRESSES_OF_HOLDINGREGISTERS.SerialNumber, 3, out registers); if (result.Error == Modbus.OSIModel.ApplicationLayer.Error.NoError) { if (registers.Length != 3) { msg = String.Format( "Ответ БИ содержит количество прочитанных регистров {0}, должно быть 3", registers.Length); error = new OperationResult(OPERATION_RESULT.FAILURE, msg); } else { UInt64 number_wr; number_wr = 0; number_wr = registers[2]; number_wr |= (number_wr << 16); number_wr |= registers[1]; number_wr |= (number_wr << 16); number_wr |= registers[0]; if (number_wr != serialNumber) { msg = String.Format( "Значение записанного прараметра {0} не совподает с прочитанным {1}", serialNumber, number_wr); error = new OperationResult(OPERATION_RESULT.FAILURE, msg); } else { error = new OperationResult(OPERATION_RESULT.OK, String.Empty); } } } else { error = new OperationResult(OPERATION_RESULT.FAILURE, result.Description); } } return; }
//------------------------------------------------------------------------------------------------------ /// <summary> /// Читает визитную карточку NGK-устройства /// </summary> /// <param name="host"></param> /// <param name="error"></param> /// <param name="addressSlave"></param> /// <param name="card"></param> public static void Read_IRs_CallingCard( ref Modbus.OSIModel.ApplicationLayer.Master.Device host, out OperationResult error, Byte addressSlave, out CallingCard card) { ushort[] registers; Modbus.OSIModel.Message.Result result; String msg; UInt16 startAddress = 0x0000; // Адрес начального входного регистра визитной карточки UInt16 length = 7; result = host.ReadInputRegisters(addressSlave, startAddress, length, out registers); if (result.Error == Modbus.OSIModel.ApplicationLayer.Error.NoError) { if (registers.Length != 7) { msg = String.Format( "Ответ БИ содержит количесво прочитанных регистров {0}, должно быть 7", registers.Length); card = null; error = new OperationResult(OPERATION_RESULT.FAILURE, msg); } else { // Рассчитываем контрольную сумму. List<Byte> arr = new List<Byte>(); // Получаем массив байт (без регистра с CRC16) for (int i = 0; i < (registers.Length - 1); i++) { arr.AddRange(Modbus.Convert.ConvertToBytes(registers[i])); } // Рассчитываем CRC16 и сравниваем с прочитанным Byte[] crc16calc_b = Modbus.OSIModel.DataLinkLayer.CRC16.CalcCRC16(arr.ToArray()); UInt16 crc16calc = 0; crc16calc = crc16calc_b[1]; // Hi_byte crc16 crc16calc = (UInt16)(crc16calc << 8); crc16calc |= crc16calc_b[0]; // Lo_byte crc16 // Проверяем контрольную сумму (прочитанную и рассчитаную) if (registers[registers.Length - 1] == crc16calc) { // Контрольная сумма сошлась, получаем данные визтной карты card = new CallingCard(); // Получаем тип устройства try { card.TypeOfDevice = (TYPE_NGK_DEVICE)Enum.Parse(typeof(TYPE_NGK_DEVICE), registers[0].ToString()); } catch { msg = String.Format( "Неизвестный тип устройства, код типа устройства: {0}", registers[0]); error = new OperationResult(OPERATION_RESULT.FAILURE, msg); return; } // Получаем версию ПО card.SofwareVersion = ((float)registers[1]) / 100; // Получаем версию Аппаратуры card.HardwareVersion = ((float)registers[2]) / 100; // Получаем серийный номер card.SerialNumber = 0; card.SerialNumber = registers[3]; card.SerialNumber |= (card.SerialNumber << 16); card.SerialNumber |= registers[4]; card.SerialNumber |= (card.SerialNumber << 16); card.SerialNumber |= registers[5]; error = new OperationResult(OPERATION_RESULT.OK, String.Empty); } else { msg = "Конрольная сумма визитной краточки не совпала с рассчётной"; card = null; error = new OperationResult(OPERATION_RESULT.FAILURE, msg); } } } else { // При выполнени чтения устройства возникли проблемы... card = null; error = new OperationResult(OPERATION_RESULT.FAILURE, result.Description); } return; }
//--------------------------------------------------------------------------- /// <summary> /// Отправляет сообщение с запросом /// </summary> /// <param name="requst">Запрос</param> /// <param name="answer">Ответ</param> /// <returns>Результат выполнения операции</returns> public RequestError SendMessage( Modbus.OSIModel.Message.Message requst, out Modbus.OSIModel.Message.Message answer) { RequestError error; Byte[] reply; Byte[] tempArray; error = SendMessage(requst.Address, requst.PDUFrame.Function, requst.PDUFrame.Data, out reply); if (error == RequestError.NoError) { tempArray = new Byte[reply.Length - 1]; Array.Copy(reply, 1, tempArray, 0, (reply.Length - 1)); answer = new Modbus.OSIModel.Message.Message(requst.Address, reply[0], tempArray); } else { answer = null; } return error; }
//---------------------------------------------------------------------------- /// <summary> /// Читает версию аппаратного обеспечения подключенного устройства, /// без созданного виртуального. /// </summary> /// <param name="host"></param> /// <param name="error"></param> /// <param name="addressSlave"></param> /// <param name="version"></param> public void Read_IR_HardWareVersion( ref Modbus.OSIModel.ApplicationLayer.Master.Device host, out OperationResult error, Byte addressSlave, out float version) { Modbus.OSIModel.Message.Result result; //String msg; UInt16[] registers; this.LockGUI(); if (host == null) { version = 0; error = new OperationResult(OPERATION_RESULT.CONNECTION_ERROR, "Подключение к сети не создано"); } else { if (host.DataLinkObject.IsOpen()) { result = host.ReadInputRegisters(addressSlave, BI_ADDRESSES_OF_INPUTREGISTERS.VersionHardware, 1, out registers); if (result.Error == Modbus.OSIModel.ApplicationLayer.Error.NoError) { version = ((float)registers[0]) / 100; error = new OperationResult(OPERATION_RESULT.OK, String.Empty); } else { version = 0; error = new OperationResult(OPERATION_RESULT.FAILURE, result.Description); } } else { version = 0; error = new OperationResult(OPERATION_RESULT.CONNECTION_ERROR, "Содениение создано, но порт закрыт"); } } this.UnLockGUI(); return; }
//---------------------------------------------------------------------------- public void Read_HR_DateTime( ref Modbus.OSIModel.ApplicationLayer.Master.Device host, out OperationResult error, out DateTime dataTime) { ushort[] registers; Modbus.OSIModel.Message.Result result; DateTime unixStartTime; UInt32 totalSeconds; String msg; dataTime = DateTime.Now; result = host.ReadHoldingRegisters(_AddressSlave, BI_ADDRESSES_OF_HOLDINGREGISTERS.DateTime, 2, out registers); if (result.Error == Modbus.OSIModel.ApplicationLayer.Error.NoError) { if (registers.Length != 2) { msg = String.Format( "Ответ БИ содержит количесво прочитанных регистров {0}, должно быть 2", registers.Length); error = new OperationResult(OPERATION_RESULT.INCORRECT_ANSWER, msg); } else { // Читать время необходимо из входного регистра. Через регистр // хранения время только записывается в устройство БИ //unixStartTime = DateTime.Parse("01/01/1970 00:00:00", // new System.Globalization.CultureInfo("ru-Ru", false)); unixStartTime = new System.DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); totalSeconds = 0; totalSeconds = registers[0]; // Hi_byte totalSeconds = (totalSeconds << 16); totalSeconds |= registers[1]; // Lo_byte dataTime = unixStartTime.AddSeconds(totalSeconds); this._DateTime = dataTime; error = new OperationResult(OPERATION_RESULT.OK, String.Empty); } } else { error = new OperationResult(OPERATION_RESULT.FAILURE, result.Description); } return; }
//---------------------------------------------------------------------------- public void Write_HR_DateTime( ref Modbus.OSIModel.ApplicationLayer.Master.Device host, out OperationResult error) { // Записываем новое значение в устройство Modbus.OSIModel.Message.Result result; UInt16[] registers = new ushort[2] { 0, 0 }; DateTime unixStartTime; DateTime dt = DateTime.Now; UInt32 totalSeconds; //String msg; TimeSpan ts; //unixStartTime = DateTime.Parse("01/01/1970 00:00:00", // new System.Globalization.CultureInfo("ru-Ru", false)); unixStartTime = new System.DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); ts = (DateTime.Now.ToUniversalTime()).Subtract(unixStartTime); totalSeconds = Convert.ToUInt32(ts.TotalSeconds); unchecked { registers[0] = (UInt16)(totalSeconds >> 16); // Hi_byte registers[1] = (UInt16)(totalSeconds); // Lo byte } result = host.WriteMultipleRegisters( _AddressSlave, BI_ADDRESSES_OF_HOLDINGREGISTERS.DateTime, registers); if (result.Error != Modbus.OSIModel.ApplicationLayer.Error.NoError) { error = new OperationResult(OPERATION_RESULT.FAILURE, result.Description); } else { error = new OperationResult(OPERATION_RESULT.OK, String.Empty); } // Проверку записанное осуществить невозможно, по причине хода часов!!! return; }
/// <summary> /// Конструктор /// </summary> /// <param name="address">Адрес ответившего устройства</param> /// <param name="frame">PDU-фрайм (код функции + данные)</param> public Message(byte address, Modbus.OSIModel.Message.PDU frame) { _Address = address; _PDU = frame; return; }
//------------------------------------------------------------------------------------------------------ /// <summary> /// Читаем серийный номер устройства. Если данный регистр не доступен, /// то устройство инициализировано. /// В противном случае, необходимо записать серийный номер. /// </summary> /// <param name="host"></param> /// <param name="serialNumber"></param> /// <param name="error"></param> public void Read_HR_SerialNumber( ref Modbus.OSIModel.ApplicationLayer.Master.Device host, out UInt64 serialNumber, out OperationResult error) { ushort[] registers; Modbus.OSIModel.Message.Result result; result = host.ReadHoldingRegisters(_AddressSlave, BI_ADDRESSES_OF_HOLDINGREGISTERS.SerialNumber, 3, out registers); switch (result.Error) { case Modbus.OSIModel.ApplicationLayer.Error.NoError: { if (registers.Length == 3) { serialNumber = 0; serialNumber = registers[0]; serialNumber = (serialNumber << 16); serialNumber |= registers[1]; serialNumber = (serialNumber << 16); serialNumber |= registers[2]; error = new OperationResult(OPERATION_RESULT.OK, String.Empty); } else { serialNumber = 0; error = new OperationResult(OPERATION_RESULT.INCORRECT_ANSWER, String.Format( "Устройство вернуло неверные данные. Количество регистров {0}, а должно быть 3", registers.Length)); } break; } case Modbus.OSIModel.ApplicationLayer.Error.IllegalDataAddress: { serialNumber = 0; error = new OperationResult(OPERATION_RESULT.IllegalDataAddress, result.Description); break; } default: { serialNumber = 0; error = new OperationResult(OPERATION_RESULT.FAILURE, result.Description); break; } } return; }
//---------------------------------------------------------------------------- public void Read_HR_PollingPeriodChannel2( ref Modbus.OSIModel.ApplicationLayer.Master.Device host, out OperationResult error) { ushort[] registers; Modbus.OSIModel.Message.Result result; result = host.ReadHoldingRegisters(_AddressSlave, BI_ADDRESSES_OF_HOLDINGREGISTERS.PollingPeriodChannel2_4_20, 1, out registers); if (result.Error == Modbus.OSIModel.ApplicationLayer.Error.NoError) { try { this.PollingPeriodChannel2 = (UInt32)(registers[0] * 10); error = new OperationResult(OPERATION_RESULT.OK, String.Empty); } catch (Exception ex) { error = new OperationResult(OPERATION_RESULT.FAILURE, ex.Message); } } else { error = new OperationResult(OPERATION_RESULT.FAILURE, result.Description); } return; }
//---------------------------------------------------------------------------- public void Write_HR_PollingPeriodChannel2( ref Modbus.OSIModel.ApplicationLayer.Master.Device host, out OperationResult error) { // Записываем новое значение в устройство Modbus.OSIModel.Message.Result result; UInt16 value = (UInt16)(this.PollingPeriodChannel2 / 10); String msg; result = host.WriteSingleRegister( _AddressSlave, BI_ADDRESSES_OF_HOLDINGREGISTERS.PollingPeriodChannel2_4_20, ref value); if (result.Error != Modbus.OSIModel.ApplicationLayer.Error.NoError) { error = new OperationResult(OPERATION_RESULT.FAILURE, result.Description); } else { if ((value * 10) != this.PollingPeriodChannel2) { msg = String.Format( "Параметр записан не верно: должно быть {0}, устройство вернуло {1}", this.PollingPeriodChannel2, value); error = new OperationResult(OPERATION_RESULT.INCORRECT_ANSWER, msg); } else { error = new OperationResult(OPERATION_RESULT.OK, String.Empty); } } return; }
//---------------------------------------------------------------------------- public void Write_HR_MeasuringVoltagePeriod( ref Modbus.OSIModel.ApplicationLayer.Master.Device host, out OperationResult error) { ushort[] registers; Modbus.OSIModel.Message.Result result; String msg; UInt16 period = this._MeasuringVoltagePeriod; registers = new ushort[] { period }; result = host.WriteMultipleRegisters(_AddressSlave, BI_ADDRESSES_OF_HOLDINGREGISTERS.MeasuringSupplyVoltagePeriod, registers); if (result.Error == Modbus.OSIModel.ApplicationLayer.Error.NoError) { if (registers.Length != 1) { msg = String.Format( "Ответ БИ содержит количесво прочитанных регистров {0}, должен быть 1", registers.Length); error = new OperationResult(OPERATION_RESULT.INCORRECT_ANSWER, msg); } else { // Проверяем записанное и прочитанное result = host.ReadHoldingRegisters(_AddressSlave, BI_ADDRESSES_OF_HOLDINGREGISTERS.MeasuringSupplyVoltagePeriod, 1, out registers); if (result.Error == Modbus.OSIModel.ApplicationLayer.Error.NoError) { if (registers.Length != 1) { msg = String.Format( "Ответ БИ содержит количесво прочитанных регистров {0}, должен быть 1", registers.Length); error = new OperationResult(OPERATION_RESULT.INCORRECT_ANSWER, msg); } else { period = registers[0]; if (this.MeasuringVoltagePeriod != period) { msg = String.Format( "Значение записанного прараметра {0} не совподает с прочитанным {1}", this.MeasuringPeriod, period); error = new OperationResult(OPERATION_RESULT.INCORRECT_ANSWER, msg); } else { error = new OperationResult(OPERATION_RESULT.OK, String.Empty); } } } else { error = new OperationResult(OPERATION_RESULT.FAILURE, result.Description); } } } else { error = new OperationResult(OPERATION_RESULT.FAILURE, result.Description); } return; }
//---------------------------------------------------------------------------- public void Read_IR_InternalTemperatureSensor( ref Modbus.OSIModel.ApplicationLayer.Master.Device host, out OperationResult error) { //throw new InvalidOperationException("Операция неподдреживается в БИ(У)-00"); error = new OperationResult(OPERATION_RESULT.INVALID_OPERATION, "Операция неподдреживается в БИ(У)-00"); //Modbus.OSIModel.Message.Result result; ////String msg; //UInt16[] registers; //result = host.ReadInputRegisters(_AddressSlave, // BI_ADDRESSES_OF_INPUTREGISTERS.InternalTemperatureSensor, // 1, out registers); //if (result.Error == Modbus.OSIModel.ApplicationLayer.Error.NoError) //{ // this.InternalTemperatureSensor = // (Int16)(ToValue(registers[0])); // error = new OperationResult(true, String.Empty); //} //else //{ // error = new OperationResult(false, result.Description); //} return; }
//---------------------------------------------------------------------------- public void Read_IR_ReferenceElectrodeACCurrent( ref Modbus.OSIModel.ApplicationLayer.Master.Device host, out OperationResult error) { Modbus.OSIModel.Message.Result result; //String msg; UInt16[] registers; result = host.ReadInputRegisters(_AddressSlave, BI_ADDRESSES_OF_INPUTREGISTERS.ReferenceElectrodeAcCurrent, 1, out registers); //if (result.Error == Modbus.OSIModel.ApplicationLayer.Error.NoError) //{ // this._ReferenceElectrodeAcСurrent = // (float)((registers[0]) * 0.01); // error = new OperationResult(OPERATION_RESULT.OK, String.Empty); //} //else //{ // error = new OperationResult(OPERATION_RESULT.FAILURE, result.Description); //} switch (result.Error) { case Modbus.OSIModel.ApplicationLayer.Error.NoError: { this._ReferenceElectrodeAcСurrent = (float)((registers[0]) * 0.01); error = new OperationResult(OPERATION_RESULT.OK, String.Empty); break; } case Modbus.OSIModel.ApplicationLayer.Error.IllegalDataAddress: { // Если возвращается исключение 0x2 (регистр не доступен для чтения) // это является нормальной ситуацией. // См. протокол: При чтении Input Register, определённого в Coil как // неактивный канал измерения возвращать исключение 0х02. this._ReferenceElectrodeAcСurrent = 0; error = new OperationResult(OPERATION_RESULT.OK, String.Empty); break; } default: { error = new OperationResult(OPERATION_RESULT.FAILURE, result.Description); break; } } return; }
//---------------------------------------------------------------------------- public void Read_CL_AcCurrentRefereceElectrodeEn( ref Modbus.OSIModel.ApplicationLayer.Master.Device host, out OperationResult error) { Modbus.OSIModel.Message.Result result; //String msg; Modbus.State[] coils; result = host.ReadCoils(_AddressSlave, BI_ADDRESSES_OF_COILS.AcCurrentRefereceElectrodeEn, 1, out coils); if (result.Error == Modbus.OSIModel.ApplicationLayer.Error.NoError) { this.AcCurrentRefereceElectrodeEn = Modbus.Convert.ToBoolean(coils[0]); error = new OperationResult(OPERATION_RESULT.OK, String.Empty); } else { error = new OperationResult(OPERATION_RESULT.FAILURE, result.Description); } }
//---------------------------------------------------------------------------- public void Write_CL_AcCurrentRefereceElectrodeEn( ref Modbus.OSIModel.ApplicationLayer.Master.Device host, out OperationResult error) { Modbus.OSIModel.Message.Result result; String msg; Modbus.State coil; coil = Modbus.Convert.ToState(this.AcCurrentRefereceElectrodeEn); result = host.WriteSingleCoil(_AddressSlave, BI_ADDRESSES_OF_COILS.AcCurrentRefereceElectrodeEn, ref coil); if (result.Error == Modbus.OSIModel.ApplicationLayer.Error.NoError) { // Проверяем записанные данные if (this.AcCurrentRefereceElectrodeEn != Modbus.Convert.ToBoolean(coil)) { msg = String.Format( "Параметр записан не верно: должно быть {0}, устройство вернуло {1}", this.AcCurrentRefereceElectrodeEn, coil); error = new OperationResult(OPERATION_RESULT.INCORRECT_ANSWER, msg); } else { error = new OperationResult(OPERATION_RESULT.OK, String.Empty); } } else { error = new OperationResult(OPERATION_RESULT.FAILURE, result.Description); } return; }
//---------------------------------------------------------------------------- public void Read_DI_CorrosionSensor3( ref Modbus.OSIModel.ApplicationLayer.Master.Device host, out OperationResult error) { Modbus.OSIModel.Message.Result result; //String msg; Modbus.State[] discreteInputs; result = host.ReadDiscreteInputs(_AddressSlave, BI_ADDRESSES_OF_DISCRETESINPUTS.CorrosionSensor3, 1, out discreteInputs); if (result.Error == Modbus.OSIModel.ApplicationLayer.Error.NoError) { this.CorrosionSensor3 = Modbus.Convert.ToBoolean(discreteInputs[0]); error = new OperationResult(OPERATION_RESULT.OK, String.Empty); } else { error = new OperationResult(OPERATION_RESULT.FAILURE, result.Description); } return; }
//---------------------------------------------------------------------------- /// <summary> /// Устанавливает режим транзакции запрос-ответ /// </summary> private void StartTransaction( Modbus.OSIModel.Transaction.TransactionType type) { if (_transaction == TransactionType.Undefined) { if ((_MaskOfMessageLog & TypeOfMessageLog.Information) == TypeOfMessageLog.Information) { Trace.TraceInformation("{0}: Поток ID: {1} : Старт транзакции", DateTime.Now.ToLongTimeString(), Thread.CurrentThread.ManagedThreadId); } //_incomingBuffer.Clear(); _serialPort.DiscardInBuffer(); _serialPort.DiscardOutBuffer(); _transaction = type; _error = RequestError.NoError; } else { if ((_MaskOfMessageLog & TypeOfMessageLog.Information) == TypeOfMessageLog.Information) { Trace.TraceError("{0}: Поток ID: {1} : Попытка начать новую транзакцию во время текущей транзакции", DateTime.Now.ToLongTimeString(), Thread.CurrentThread.ManagedThreadId); } throw new Exception("Попытка начать новую транзакцию во время текущей транзакции"); } return; }
//---------------------------------------------------------------------------- public void Read_IR_TypeOfDevice( ref Modbus.OSIModel.ApplicationLayer.Master.Device host, out OperationResult error, out TYPE_NGK_DEVICE typeOfDevice) { Modbus.OSIModel.Message.Result result; //String msg; UInt16[] registers; result = host.ReadInputRegisters(AddressSlave, BI_ADDRESSES_OF_INPUTREGISTERS.TypeOfDevice, 1, out registers); if (result.Error == Modbus.OSIModel.ApplicationLayer.Error.NoError) { try { typeOfDevice = (TYPE_NGK_DEVICE)Enum.Parse(typeof(TYPE_NGK_DEVICE), registers[0].ToString()); error = new OperationResult(OPERATION_RESULT.OK, String.Empty); } catch { typeOfDevice = TYPE_NGK_DEVICE.UNKNOWN_DEVICE; error = new OperationResult(OPERATION_RESULT.UNKNOWN_DEVICE, String.Format( "Устройство вернуло код неизвестного типа устройства: {0}", registers[0].ToString())); } } else { typeOfDevice = TYPE_NGK_DEVICE.UNKNOWN_DEVICE; error = new OperationResult(OPERATION_RESULT.FAILURE, result.Description); } return; }
//---------------------------------------------------------------------------- /// <summary> /// Читает серийный номер в устройство БИ при первоначальной инициализации /// </summary> /// <param name="host">Modbus master устройство</param> /// <param name="error">Результат выполнеия операции</param> /// <param name="addressSlave">Адрес подчинённого устройство</param> /// <param name="serialNumber">Серийный номер для записи в устройство</param> public static void Read_HR_SerialNumber(ref Modbus.OSIModel.ApplicationLayer.Master.Device host, out OperationResult error, Byte addressSlave, out UInt64 serialNumber) { ushort[] registers; Modbus.OSIModel.Message.Result result; String msg; serialNumber = 0; result = host.ReadHoldingRegisters(addressSlave, BI_ADDRESSES_OF_HOLDINGREGISTERS.SerialNumber, 3, out registers); if (result.Error == Modbus.OSIModel.ApplicationLayer.Error.NoError) { if (registers.Length != 3) { msg = String.Format( "Ответ БИ содержит количесво прочитанных регистров {0}, должно быть 3", registers.Length); error = new OperationResult(OPERATION_RESULT.FAILURE, msg); } else { serialNumber = 0; serialNumber = registers[2]; serialNumber |= (serialNumber << 16); serialNumber |= registers[1]; serialNumber |= (serialNumber << 16); serialNumber |= registers[0]; error = new OperationResult(OPERATION_RESULT.OK, String.Empty); } } else { error = new OperationResult(OPERATION_RESULT.FAILURE, String.Empty); } return; }
//---------------------------------------------------------------------------- public void Read_IR_HardWareVersion( ref Modbus.OSIModel.ApplicationLayer.Master.Device host, out OperationResult error) { Modbus.OSIModel.Message.Result result; //String msg; UInt16[] registers; result = host.ReadInputRegisters(AddressSlave, BI_ADDRESSES_OF_INPUTREGISTERS.VersionHardware, 1, out registers); if (result.Error == Modbus.OSIModel.ApplicationLayer.Error.NoError) { this.HardwareVersion = ((float)registers[0]) / 100; error = new OperationResult(OPERATION_RESULT.OK, String.Empty); } else { error = new OperationResult(OPERATION_RESULT.FAILURE, result.Description); } return; }
//---------------------------------------------------------------------------- public void Write_HR_CurrentShuntValue( ref Modbus.OSIModel.ApplicationLayer.Master.Device host, out OperationResult error) { // Записываем новое значение в устройство Modbus.OSIModel.Message.Result result; UInt16 value = (UInt16)this.CurrentShuntValue; String msg; result = host.WriteSingleRegister( _AddressSlave, BI_ADDRESSES_OF_HOLDINGREGISTERS.CurrentShuntValue, ref value); if (result.Error != Modbus.OSIModel.ApplicationLayer.Error.NoError) { error = new OperationResult(OPERATION_RESULT.FAILURE, result.Description); } else { // Читаем записаное и сверяем результаты if ((UInt16)this.CurrentShuntValue != value) { msg = String.Format( "Значение записанного прараметра {0} не совподает с прочитанным {1}", this.CurrentShuntValue, value); error = new OperationResult(OPERATION_RESULT.INCORRECT_ANSWER, msg); } else { error = new OperationResult(OPERATION_RESULT.OK, String.Empty); } } return; }
//------------------------------------------------------------------------------------------------------ public void Write_HR_SerialNumber( ref Modbus.OSIModel.ApplicationLayer.Master.Device host, UInt64 serialNumber, out OperationResult error) { // Записываем новое значение в устройство Modbus.OSIModel.Message.Result result; UInt64 sn; UInt16[] value; //String msg; value = new ushort[3]; value[2] = (UInt16)serialNumber; // Low value[1] = (UInt16)(serialNumber >> 16); // High value[0] = (UInt16)(serialNumber >> 32); // Upper result = host.WriteMultipleRegisters( _AddressSlave, BI_ADDRESSES_OF_HOLDINGREGISTERS.SerialNumber, value); if (result.Error != Modbus.OSIModel.ApplicationLayer.Error.NoError) { // При операции записи произошла ошибка error = new OperationResult(OPERATION_RESULT.FAILURE, result.Description); } else { // После записи данный регистр становиться не доступен // Проверяем записанные данные this.Read_HR_SerialNumber(ref host, out sn, out error); switch (error.Result) { case OPERATION_RESULT.IllegalDataAddress: { // // Чтение выполено успешно, проверяем данные // if (sn == serialNumber) // { // error = new OperationResult(OPERATION_RESULT.OK, String.Empty); // } // else // { // msg = String.Format( // "Ошибка записи серийного номера устройства. Не совпал записанное {0} и прочитанное значение {1}", // serialNumber, sn); // error = new OperationResult(OPERATION_RESULT.INCORRECT_ANSWER, msg); // } error = new OperationResult(OPERATION_RESULT.OK, String.Empty); break; } case OPERATION_RESULT.OK: { // При выполнении операции чтения произошла ошибка error = new OperationResult(OPERATION_RESULT.FAILURE, "Ошибка: После инициализации устройсвта регистр хранения остался доступен"); break; } default: { error = new OperationResult(OPERATION_RESULT.FAILURE, error.Message); break; } } } return; }
//------------------------------------------------------------------------------------------------------ #region NetworksCommands //------------------------------------------------------------------------------------------------------ /// <summary> /// Проверяет инициализировано устройство или нет. /// </summary> /// <param name="host">Master-устройство</param> /// <param name="init">TRUE-устройство иницилизировано</param> /// <param name="error">Результат выполнения операции</param> public void Read_HR_VerifyInitDevice( ref Modbus.OSIModel.ApplicationLayer.Master.Device host, out Boolean init, out OperationResult error) { Modbus.OSIModel.Message.Result result; UInt16[] registers; result = host.ReadHoldingRegisters( _AddressSlave, BI_ADDRESSES_OF_HOLDINGREGISTERS.SerialNumber, 3, out registers); switch (result.Error) { case Modbus.OSIModel.ApplicationLayer.Error.NoError: { // Регистры доступны и значит устройство не инициализировано init = false; error = new OperationResult(OPERATION_RESULT.OK, String.Empty); break; } case Modbus.OSIModel.ApplicationLayer.Error.IllegalDataAddress: { // Регистры не доступны значит устройство инициализировано init = true; error = new OperationResult(OPERATION_RESULT.OK, String.Empty); break; } default: { init = false; String msg = String.Format( "Ошибка выполнения чтения устройства. Устройство венуло ошибку: {0}", result.Description); error = new OperationResult(OPERATION_RESULT.FAILURE, msg); break; } } }
//---------------------------------------------------------------------------- public void Read_HR_CurrentShuntValue( ref Modbus.OSIModel.ApplicationLayer.Master.Device host, out OperationResult error) { ushort[] registers; Modbus.OSIModel.Message.Result result; CurrentShuntValues shunt; result = host.ReadHoldingRegisters(_AddressSlave, BI_ADDRESSES_OF_HOLDINGREGISTERS.CurrentShuntValue, 1, out registers); if (result.Error == Modbus.OSIModel.ApplicationLayer.Error.NoError) { try { shunt = (CurrentShuntValues)Enum.ToObject(typeof(CurrentShuntValues), registers[0]); this.CurrentShuntValue = shunt; error = new OperationResult(OPERATION_RESULT.OK, String.Empty); } catch (Exception ex) { error = new OperationResult(OPERATION_RESULT.FAILURE, ex.Message); } } else { error = new OperationResult(OPERATION_RESULT.FAILURE, result.Description); } return; }