Ejemplo n.º 1
0
        /// <summary>
        /// Обработчик принятых данных, после анализа посылка,
        /// в случае корректности запроса отвечает,но только по функции 0x04, адресу 0x20
        /// по всем адресам приборов 1-247
        /// </summary>
        /// <param name="sender">SerialPort</param>
        /// <param name="e"></param>
        private void SlavePort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            SerialPort serialPort = (sender as SerialPort);

            if (serialPort.BytesToRead == 0)
            {
                return;
            }
            byte[] buffer = new byte[256];
            int    count  = serialPort.Read(buffer, 0, serialPort.BytesToRead);

            if (count > 0 && buffer.IsCorrectCrc(count))
            {
                byte   slaveAddress    = buffer[0];
                byte   function        = buffer[1];
                UInt16 registerAddress = (UInt16)(buffer[2] << 8 | buffer[3]);
                UInt16 registerCount   = (UInt16)(buffer[4] << 8 | buffer[5]);

                if ((slaveAddress >= 1 && slaveAddress <= 247) &&
                    (function == 0x04) &&
                    (registerAddress == 0x20) &&
                    (registerCount == 0x01))
                {
                    UInt16 randomData = (UInt16)random.Next(0, 1000);
                    buffer[0] = slaveAddress;
                    buffer[1] = function;
                    buffer[2] = 0x02;
                    buffer[3] = (byte)(randomData >> 8);
                    buffer[4] = (byte)randomData;
                    buffer.AddModbusCrc(count: 5);
                    serialPort.BaseStream.Write(buffer, 0, count: 7);
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Запускает цикл асинхронного опроса одного из портов
        /// </summary>
        /// <param name="serialPort">Опрашиваемый порт</param>
        /// <param name="deviceAddressRange">Адресы опрошиваемых устройст</param>
        private static async void StartModbusPollAsync(SerialPort serialPort, List <byte> deviceAddressRange)
        {
            const byte function            = 0x04;
            const byte registerAddressHigh = 0x00;
            const byte registerAddressLow  = 0x20;
            const byte registerCountHigh   = 0x00;
            const byte registerCountLow    = 0x01;
            await Task.Factory.StartNew(() =>
            {
                /*Основной цикл опроса одного порта*/
                while (true)
                {
                    /*Ассинхронно запускаю алгоритм опроса, и сразу же начинаю засекать период*/
                    Task.Factory.StartNew(async() =>
                    {
                        await Task.Factory.StartNew(() =>
                        {
                            deviceAddressRange.ForEach(address =>
                            {
                                #region Формирую и отправляю запрос
                                byte[] buffer = new byte[256];
                                buffer[0]     = address;
                                buffer[1]     = function;
                                buffer[2]     = registerAddressHigh;
                                buffer[3]     = registerAddressLow;
                                buffer[4]     = registerCountHigh;
                                buffer[5]     = registerCountLow;

                                buffer.AddModbusCrc(count: 6);

                                string logMessage = $"{DateTime.Now.ToString("HH:mm:ss.fff")}:{serialPort.PortName}: TX: ";
                                logMessage       += buffer.ToStringHex(count: 8) + "\r\n";

                                serialPort.BaseStream.Write(buffer, 0, count: 8);
                                #endregion
                                #region Обрабатываю полученный ответ
                                Task <int> taskReader = serialPort.BaseStream.ReadAsync(buffer, 0, 256);
                                if (taskReader.Wait(250))
                                {
                                    buffer = buffer.Take(count: taskReader.Result).ToArray();
                                }
                                else
                                {
                                    Logger.Write($"\t\t{serialPort.PortName}:RX: TIMEOUT");
                                }

                                #endregion
                                #region Записываю историю
                                logMessage += $"{DateTime.Now.ToString("HH:mm:ss.fff")}:{serialPort.PortName}: RX: ";
                                logMessage += buffer.ToStringHex(count: taskReader.Result);
                                Logger.Write(logMessage);
                                #endregion
                            });
                        });
                    });
                    /*Период опроса*/
                    Task.Delay(1000).Wait();
                }
            }, TaskCreationOptions.LongRunning);
        }