public bool WriteRegister(ushort reg, short value) { modbus link = new modbus(); bool ret = link.Open(port, 9600, 8, Parity.None, StopBits.Two); if (!ret) { throw EngineMessageException.offline( "Opening port " + port + " failed: " + link.modbusStatus); } short[] val = { value }; Logger.log( "Writing 0x" + value.ToString("x") + " to register 0x" + reg.ToString("x") + " to address 0x" + address.ToString("x")); ret = link.SendFc16(address, reg, 1, val); if (!ret) { throw new EngineMessageException( "Writing 0x" + value.ToString("x") + " to register 0x" + reg.ToString("x") + " failed: " + link.modbusStatus); } link.Close(); return(ret); }
private string FetchValueFromPlc(WebSocketSession session, string e) { HashMap obj = JsonConvert.DeserializeObject <HashMap>(e); int slaveMachineID = obj.GetValue <int>("SlaveID"); byte address = (byte)slaveMachineID; ushort start = obj.GetValue <ushort>("start"); ushort registers = obj.GetValue <ushort>("registers"); short[] values = new short[registers]; int waitTime = obj.GetValue <int>("waitTime"); String subscribe = obj.GetValue <String>("SubscribeWay"); modbus.SubscribeWay = subscribe; modbus.WaitTime = waitTime; modbus md = new modbus(); md.SendFc3NewVersion(address, start, registers, ref values); if (!String.IsNullOrEmpty(subscribe) && subscribe == "发送之后阻塞直到获取返回") { md.Close(); } return(values.ToString()); }
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]); }
/// <summary> /// 모드버스 에러 읽기 /// </summary> private DataRow readError(SerialPort master, string bmsId, byte slaveId) { // 읽기 주소 ushort startAddress = 0x8100; // 읽을 사이즈 ushort numRegisters = 0x08; byte readType = 0x04; ushort[] registers = new ushort[numRegisters]; byte[] buildPacket = new byte[7]; // read protocol size string recvBuffer = ""; byte[] checkBuffer = null; bool success = false; try { // modbus 레지스터 읽기 Utils util = new Utils(); modbus modbusUtil = new modbus(); // 전송 패킷 생성 modbusUtil.BuildModbusAsciiMessage(slaveId, readType, startAddress, numRegisters, ref buildPacket); // 헥사 스트링으로 변환 string convert = util.ByteArrayToHexString(buildPacket); // 공백문자제거 convert = convert.Replace(" ", ""); // STX, CR/LF 추가 string sendMessage = string.Format(":{0}\r\n", convert); // 전송 success = modbusUtil.SendFc4(master, sendMessage, ref recvBuffer); if (success) { checkBuffer = util.HexStringToByteArray(recvBuffer.Substring(1, recvBuffer.Length - 1)); if (!modbusUtil.CheckLRCResponse(checkBuffer)) { return(null); } } else { return(null); } //Return requested register values: for (int i = 0; i < (checkBuffer.Length - 4) / 2; i++) { registers[i] = checkBuffer[2 * i + 3]; registers[i] <<= 8; registers[i] += checkBuffer[2 * i + 4]; } // 에러 발생 시간 string dateTime = string.Format("{0:D4}/{1:D2}/{2:D2} {3:D2}:{4:D2}:{5:D2}", registers[0], registers[1], registers[2], registers[3], registers[4], registers[5] ); if (registers[0] == 0) { return(null); } int errStatus = 0x01 & (registers[6] >> 7); int errCode = 0x0F & (registers[6] >> 0); DataRow errorName = mDataTable.Rows.Find(string.Format("0x{0:D2}", slaveId)); string code = getErrorCode(errStatus, errCode, errorName["Contact1"].ToString(), errorName["Contact2"].ToString(), errorName["Contact3"].ToString(), errorName["Contact4"].ToString()); DataRow row = mCommTable.Rows.Find(string.Format("0x{0:D2}", slaveId)); if (row != null) { // 에러 히스토리 기록을 위해 발생정보 테이블에 넣기 mErrorListTable.Rows.Add(dateTime, mLineName, row["Name"], code, registers[7]); } DataTable copyDataTable; copyDataTable = mErrorListTable.Copy(); //copyDataTable.Columns.Remove("Error Value"); DataRow dw; dw = copyDataTable.NewRow(); dw["Error Time"] = dateTime; dw["COM"] = mLineName; dw["BMS ID"] = row["Name"]; dw["Error Code"] = code; int errorValue = registers[7]; if (errorValue > 0xF000) { errorValue -= 65536; } // 온도 일 경우 10나누기 if (3 <= errCode && errCode <= 8) { dw["Error Value"] = errorValue / 10.0; } else { dw["Error Value"] = errorValue; } return(dw); } catch (Exception ex) { Console.WriteLine(ex.ToString()); DataRow dw = null; return(dw); } }
/// <summary> /// Modbus serial ASCII master write input registers. /// </summary> public int setTimeSync(SerialPort master) { // 읽기 주소 ushort startAddress = 0x6002; ushort[] registers = new ushort[6]; byte[] buildPacket = new byte[20]; // read protocol size int offset = 0; registers[offset++] = Convert.ToUInt16(DateTime.Now.Year); registers[offset++] = Convert.ToUInt16(DateTime.Now.Month); registers[offset++] = Convert.ToUInt16(DateTime.Now.Day); registers[offset++] = Convert.ToUInt16(DateTime.Now.Hour); registers[offset++] = Convert.ToUInt16(DateTime.Now.Minute); registers[offset++] = Convert.ToUInt16(DateTime.Now.Second); offset = 0; try { Utils util = new Utils(); modbus modbusUtil = new modbus(); buildPacket[offset++] = 0x00; // 브로드캐스트 buildPacket[offset++] = 0x10; // SET buildPacket[offset++] = Convert.ToByte(0xff & (startAddress >> 8)); buildPacket[offset++] = Convert.ToByte(0xff & (startAddress >> 0)); buildPacket[offset++] = 0x00; buildPacket[offset++] = 0x06; buildPacket[offset++] = 0x0C; for (int i = 0; i < 6; i++) { buildPacket[offset++] = Convert.ToByte(0xff & (registers[i] >> 8)); buildPacket[offset++] = Convert.ToByte(0xff & (registers[i] >> 0)); } buildPacket[offset] = modbusUtil.GetLRC(buildPacket, offset); // 헥사 스트링으로 변환 string convert = util.ByteArrayToHexString(buildPacket); // 공백문자제거 convert = convert.Replace(" ", ""); // STX, CR/LF 추가 string sendMessage = string.Format(":{0}\r\n", convert); // 전송 modbusUtil.SendTimeSync(master, sendMessage); } catch (Exception e) { return(-1); } return(1); }
/// <summary> /// 실시간 데이터 읽기 /// </summary> /// public int ModbusSerialAsciiMasterReadRegisters(SerialPort master, string bmsId, byte slaveId, int rowIndex) { // 에러 발생 int err = 0; // 읽기 주소 ushort startAddress = 0x8000; // 읽을 사이즈 ushort numRegisters = 0x32; // 레지스터 offset int regOffset = 16; // voltage offset byte readType = 4; // 그래프 출력 변수 Vars curValue = new Vars(); //if (master == null || master.Transport == null || mComport.IsOpen != true) // return 0; string eventLog = ""; int errorCheck = 0; DateTime Logfatchtime; byte[] buildPacket = new byte[7]; // read protocol size string recvBuffer = ""; ushort[] registers = new ushort[50]; byte[] checkBuffer = null; bool success = false; try { //3A30323034383030303030333234380D0A //3A 3032 3034 3830 3030 3030 3332 3438 0D 0A Utils util = new Utils(); modbus modbusUtil = new modbus(); // 전송 패킷 생성 modbusUtil.BuildModbusAsciiMessage(slaveId, readType, startAddress, numRegisters, ref buildPacket); // 헥사 스트링으로 변환 string convert = util.ByteArrayToHexString(buildPacket); // 공백문자제거 convert = convert.Replace(" ", ""); // STX, CR/LF 추가 string sendMessage = string.Format(":{0}\r\n", convert); // 전송 success = modbusUtil.SendFc4(master, sendMessage, ref recvBuffer); if (success) { checkBuffer = util.HexStringToByteArray(recvBuffer.Substring(1, recvBuffer.Length - 1)); if (!modbusUtil.CheckLRCResponse(checkBuffer)) { return(-2); } } else { // 이벤트 전달 //TimeoutEventArgs timeoutPort = new TimeoutEventArgs(this.mLineName); //OnTimeoutChanged(timeoutPort); return(-1); } //Return requested register values: for (int i = 0; i < (checkBuffer.Length - 4) / 2; i++) { registers[i] = checkBuffer[2 * i + 3]; registers[i] <<= 8; registers[i] += checkBuffer[2 * i + 4]; } // BMS 리스트 테이블에 수신한 ID 찾기 DataRow foundRow = mCommTable.Rows.Find(string.Format("0x{0:D2}", slaveId)); DataRow foundErrRow = mErrorTable.Rows.Find(string.Format("0x{0:D2}", slaveId)); // 있다면 업데이트 if (foundRow != null) { int index = mCommTable.Rows.IndexOf(foundRow); // 전압 값 int voltage = registers[regOffset++]; if (voltage > 0xF000) { voltage -= 65536; } curValue.Data[0] = (voltage / 10.0); //curValue.Data[0] = (registers[regOffset++] / 10.0); foundRow["VOLT"] = string.Format("{0:F1}", curValue.Data[0]); // 에러체크 errorCheck = setDataTableErrorSet(foundRow["ID"].ToString(), "VOLT", curValue.Data[0]); if (foundErrRow["VOLT"].ToString() != errorCheck.ToString()) { // 에러가 발생되었다면 이벤트를 보냄 if (errorCheck == 1) { ErrorEventSender(bmsId, "Voltage Error(SW)", curValue.Data[0].ToString()); } else { ErrorEventSender(bmsId, "Voltage Error Cancel(SW)", curValue.Data[0].ToString()); } foundErrRow["VOLT"] = errorCheck; errorCheck = 0; } regOffset += 3; // 전류 값 int current = registers[regOffset++]; if (current > 0xF000) { current -= 65536; } curValue.Data[1] = current; foundRow["CURRENT"] = string.Format("{0}", curValue.Data[1]); errorCheck = setDataTableErrorSet(foundRow["ID"].ToString(), "CURRENT", curValue.Data[1]); if (foundErrRow["CURRENT"].ToString() != errorCheck.ToString()) { // 에러가 발생되었다면 이벤트를 보냄 if (errorCheck == 1) { ErrorEventSender(bmsId, "Current Error(SW)", curValue.Data[1].ToString()); } else { ErrorEventSender(bmsId, "Current Error Cancel(SW)", curValue.Data[1].ToString()); } foundErrRow["CURRENT"] = errorCheck; errorCheck = 0; } regOffset += 3; // 온도 값 for (int i = 2; i < 8; i++) { int temperature = registers[regOffset++]; if (temperature > 0xF000) { temperature -= 65536; } curValue.Data[i] = temperature / 10.0; foundRow[i + 2] = string.Format("{0:F1}", curValue.Data[i]); // 온도 에러 체크 설정상태 errorCheck = setDataTableErrorSet(foundRow["ID"].ToString(), ("TEMP" + (i - 1)), curValue.Data[i]); if (foundErrRow[i + 2].ToString() != errorCheck.ToString()) { // 에러가 발생되었다면 이벤트를 보냄 if (errorCheck == 1) { ErrorEventSender(bmsId, "Temp" + (i - 1) + " Error(SW)", curValue.Data[i].ToString()); } else { ErrorEventSender(bmsId, "Temp" + (i - 1) + " Error Cancel(SW)", curValue.Data[i].ToString()); } foundErrRow[i + 2] = errorCheck; errorCheck = 0; } regOffset += 3; } // 접점 상태 읽기 ( 4포트 ) int[] contact = new int[4]; for (int i = 0; i < 4; i++) { // 접점 읽기 contact[i] = 0x01 & (registers[regOffset] >> i); foundRow[i + 10] = contact[i]; // 에러 읽기 errorCheck = 0x01 & (registers[regOffset] >> i + 8); if (foundErrRow[i + 10].ToString() != errorCheck.ToString()) { DataRow errorName = mDataTable.Rows.Find(string.Format("0x{0:D2}", slaveId)); // 에러가 발생되었다면 이벤트를 보냄 //if (errorCheck == 1) // ErrorEventSender(bmsId, errorName[i + 3] + " Error(SW)", contact[i].ToString()); //else // ErrorEventSender(bmsId, errorName[i + 3] + " Error Cancel(SW)", contact[i].ToString()); foundErrRow[i + 10] = errorCheck; errorCheck = 0; } } string fileDay = DateTime.Now.ToString("yyyyMMdd"); IniFileHandle log = new IniFileHandle(Properties.Settings.Default.BackupDir + "\\Log" + "\\" + mLineName + "\\" + foundRow["Name"].ToString() + "\\" + fileDay + ".Log"); Logfatchtime = DateTime.Now; eventLog += (eventLog.Length == 0 ? "" : "\r\n") + string.Format("{0}\t\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}\t{8}\t{9}\t{10}\t{11}\t{12}", Logfatchtime.ToString("yyyy-MM-dd HH:mm:ss"), foundRow["VOLT"].ToString(), foundRow["CURRENT"].ToString(), foundRow["TEMP1"].ToString(), foundRow["TEMP2"].ToString(), foundRow["TEMP3"].ToString(), foundRow["TEMP4"].ToString(), foundRow["TEMP5"].ToString(), foundRow["TEMP6"].ToString(), foundRow["Contact1"].ToString(), foundRow["Contact2"].ToString(), foundRow["Contact3"].ToString(), foundRow["Contact4"].ToString()); log.FileWrite(eventLog); curValue.Datetime = DateTime.Now; mGraphData[rowIndex].Add(curValue); if (mGraphData[rowIndex].Count > 20) { mGraphData[rowIndex].RemoveAt(0); } } } catch (Exception e) { Console.WriteLine(e.Message); } return(0); }