modbus getPortByStationId(int stationAddress) { modbus mb = null; //Проверяем есть ли ком порта соответсвующий stationId string[] ports = SerialPort.GetPortNames(); bool _portFound = false; foreach (string p in ports) { if (p == "COM" + stationAddress.ToString()) { _portFound = true; } } //Порт соответсвующий stationId найден if (_portFound) { if (deviceList.ContainsKey(stationAddress)) { mb = (deviceList.SingleOrDefault(d => d.Key == stationAddress).Value); } else { mb = new modbus(); } //Порт не открыт после создания и после его закрытия вследствии нажантия на кнопку стоп if (!mb.isOpen) { if (mb.Open("COM" + stationAddress, DataRate, DataBits, DataParity, DataStopBit)) { deviceList.Add(stationAddress, mb); this.BeginInvoke(new SetTextCallback(SetText), new object[] { "Порт для StationId " + stationAddress + " успешно открыт. MBStatus: " + mb.modbusStatus, msgStatus.Success }); } else { throw new Exception("Не удалось открыть порт. " + mb.modbusStatus); } } } else { this.BeginInvoke(new SetTextCallback(SetText), new object[] { "Com port соответсвующий StationId не найден stationId: " + stationAddress, msgStatus.Common }); } return(mb); }
byte[] GetResponsMessage(byte[] request) { byte stationAddress = 0; List <byte> _response = null; //Возможна ошибка выхода за приделы массива, в этом случае вернем null try { //разбирваем запрос что бы получить stationId stationAddress = request[6]; //Ответ _response = new List <byte>(); //Переписываем заголовок запроса в ответ for (int i = 0; i < 5; i++) { _response.Add(request[i]); } } catch (Exception e) { return(null); } try { //проверяем есть ли данный компорт в списке устройств //если он есть. значит он был добавлен в предыдущих обработках //если порт еще не существует в списке, создаем порт, и добовляем его туда // modbus mb; modbus mb = getPortByStationId(stationAddress); //если нет соответсвуещего порта if (mb == null) { return(errorReturn(request)); } //Если порт открыт //Определить какую modbus функцию использовать byte _functionCode = request[7]; bool successFlag = false; //--------------------------------------- //Перед выполнением запросов к порту проверим открыт ли он if (!mb.isOpen) { throw new Exception("Порт закрыт не возможно производить операции чтения и записи stationId: " + stationAddress); } //функция записи // if (_functionCode == 6) { //Получаем стартовый адресс byte[] _start = { request[9], request[8] }; //Получаем значение для записи byte[] _value = { request[11], request[10] }; Int16 strt = BitConverter.ToInt16(_start, 0); Int16 val = BitConverter.ToInt16(_value, 0); successFlag = mb.SendFc6(1, (ushort)strt, (ushort)val); if (!successFlag) { throw new Exception("ModBus функция выполнена с ошибкой запрос " + Logger.BytePrinter(request) + " FC " + _functionCode + " stationId: " + stationAddress); } return(request); } //f-ции чтения if ((_functionCode == 3) || (_functionCode == 4)) { List <byte> resp = new List <byte> (); //Получаем стартовый адресс byte[] _start = { request[9], request[8] }; //Получаем количество регистров byte[] _regcount = { request[11], request[10] }; Int16 regcount = BitConverter.ToInt16(_regcount, 0); Int16 start = BitConverter.ToInt16(_start, 0); //Так как ТРД10 воспринимает запросы не более чем для 10 регистов //Приходится разбивать запросы по максимум 10 регистров //Выходной массив значений short[] values = new short[regcount]; //Массив значений для подзапроса short[] values10 = new short[10]; //Алгоритм следующий //В цикле делаем запросы по 10 регстров максимум, количество итераций цикал подсчитывется так: //Если остаток от деления исходного количества регистров на 10 больше 0, то есть будет //N Итераций по 10 и еще одна итерация по остатку, всего получается N+1 иетрация //В последней этерации будет использоватся массив не из 10 а из остатка регистров //Если же остаток от деления равен 0 //Ток тогда количество итераций N int _counter = 0; int _maxcount = 0; if (regcount % 10 > 0) { _maxcount = regcount / 10; _maxcount += 1; } else { _maxcount = regcount / 10; } while (_counter < _maxcount) { int _lastNum = 10; //Последняя итерация, проверяем если с остатоком деление значит на последней этерации массив не 10 а из остатка if ((_counter == _maxcount - 1) && (regcount % 10 > 0)) { _lastNum = regcount % 10; values10 = new short[_lastNum]; } if (_functionCode == 3) { //successFlag = mb.SendFc3(1, (ushort)start, (ushort)regcount, ref values, ref resp); successFlag = mb.SendFc3(1, (ushort)(start + 10 * _counter), (ushort)_lastNum, ref values10, ref resp); } if (_functionCode == 4) { //successFlag = mb.SendFc4(1, (ushort)start, (ushort)regcount, ref values, ref resp); successFlag = mb.SendFc4(1, (ushort)(start + 10 * _counter), (ushort)_lastNum, ref values10, ref resp); } if (!successFlag) { throw new Exception(@"ModBus функция выполнена с ошибкой" + "\n" + "Запрос: " + Logger.BytePrinter(request) + "\n" + "Ответ устройства на итерации: " + _counter + ": " + Logger.BytePrinter(resp.ToArray()) + "\n" + " FC " + _functionCode + " stationId: " + stationAddress + "modbus status: " + mb.modbusStatus); } for (int i = 0; i < _lastNum; i++) { values[i + 10 * _counter] = values10[i]; } _counter++; successFlag = false; } //Формируем массив значений для полного ответа List <byte> valuesResponse = new List <byte>(); for (int i = 0; i < regcount; i++) { valuesResponse.AddRange(BitConverter.GetBytes(values[i]).Reverse()); } //Получем длину ответа byte valuesLen = (byte)valuesResponse.Count; byte allLen = (byte)(valuesLen + 3); //Формируем полный ответ, он включает в себя заголовок. злинну, адресс, длну значений, и полученые значения _response.Add(allLen); _response.Add(stationAddress); _response.Add(_functionCode); _response.Add(valuesLen); foreach (byte b in valuesResponse) { _response.Add(b); } } } //есил исключение то отправляем ответ с кодом ошибки 131 3 catch (Exception excap) { this.BeginInvoke(new SetTextCallback(SetText), new object[] { excap.Message, msgStatus.Error }); _response.Add(request[7]); _response.Add(request[6]); _response.Add(131); _response.Add(3); } return(_response.ToArray()); }
modbus getPortByStationId(int stationAddress) { modbus mb = null; //Проверяем есть ли ком порта соответсвующий stationId string[] ports = SerialPort.GetPortNames(); bool _portFound = false; foreach (string p in ports) { if (p == "COM" + stationAddress.ToString()) { _portFound = true; } } //Порт соответсвующий stationId найден if (_portFound) { if (deviceList.ContainsKey(stationAddress)) { mb = (deviceList.SingleOrDefault(d => d.Key == stationAddress).Value); } else { mb = new modbus(); } //Порт не открыт после создания и после его закрытия вследствии нажантия на кнопку стоп if (!mb.isOpen) { if (mb.Open("COM" + stationAddress, DataRate, DataBits, DataParity, DataStopBit)) { deviceList.Add(stationAddress, mb); this.BeginInvoke(new SetTextCallback(SetText), new object[] { "Порт для StationId " + stationAddress + " успешно открыт. MBStatus: " + mb.modbusStatus, msgStatus.Success }); } else { throw new Exception("Не удалось открыть порт. " + mb.modbusStatus); } } } else { this.BeginInvoke(new SetTextCallback(SetText), new object[] {"Com port соответсвующий StationId не найден stationId: " + stationAddress, msgStatus.Common }); } return mb; }