Exemple #1
0
 public static float ReadFloat(IModbusMaster master, byte slaveId, ushort address)
 {
     ushort[] registers = master.ReadInputRegisters(slaveId, address, sizeof(float) / sizeof(ushort));
     var result = new byte[registers.Length * sizeof(ushort)];
     Buffer.BlockCopy(registers, 0, result, 0, result.Length);
     return BitConverter.ToSingle(result, 0);
 }
Exemple #2
0
 /// <summary>
 /// Проверка наличия измененеий в состоянии входов
 /// </summary>
 /// <param name="master">Транспорт</param>
 /// <returns>Список изменившихся входов</returns>
 public IEnumerable<int> UpdateAllInputState(IModbusMaster master)
 {
     var res = new List<int>();
     var answer = master.ReadHoldingRegisters(_address, RegisterStartInputs, CountRegistersInputs);
     if (_lastState == null)
     {
         _lastState = answer;
         for (int i = 0; i < (_lastState.Length * 16); i++)
             res.Add(i);
     }
     else
     {
         for(int i = 0; i< answer.Length; i++)
         {
             if(answer[i]==_lastState[i])
                 continue;
             for(int bit = 0; bit<16; bit++)
                 if (GetBitFromUShortArray(_lastState, (i * 16 + bit)) != GetBitFromUShortArray(answer, (i * 16 + bit)))
                     res.Add(i * 16 + bit);
         }
         _lastState = answer;
     }
     _lastStateTimestamp = DateTime.Now;
     return res;
 }
Exemple #3
0
        private ModbusResult ReadRegister(dynamic parameters)
        {
            var result = new ModbusResult();

            try
            {
                result.IpAddress    = parameters.ipaddress;
                result.StartAddress = parameters.start_address;
                bool ok = true;

                using (TcpClient client = new TcpClient(result.IpAddress, 502))
                {
                    client.SendTimeout = 1000;

                    var factory = new ModbusFactory();

                    IModbusMaster master = factory.CreateMaster(client);
                    master.Transport.Retries      = 0;
                    master.Transport.ReadTimeout  = 300;
                    master.Transport.WriteTimeout = 300;

                    //if (!client.ConnectAsync(result.IpAddress, 502).Wait(1000))
                    //{
                    //    // connection failure
                    //    ok = false;
                    //}

                    if (ok)
                    {
                        ushort startAddress = (ushort)result.StartAddress;
                        ushort numInputs    = (ushort)int.Parse(parameters.number_of_points);
                        bool[] inputs       = master.ReadInputs(0, startAddress, numInputs);

                        for (int i = 0; i < numInputs; i++)
                        {
                            result.data.Add(inputs[i]);

                            if (parameters.with_html == true)
                            {
                                result.ApiCall            = Request.Url.SiteBase + $"/api/modbus/{parameters.ipaddress}/{parameters.start_address}/{parameters.number_of_points}";
                                result.BitsStringForHtml += $"no {i} = {(inputs[i] ? "1" : "0")}<br />\r\n";
                            }

                            result.HasData = true;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                log.Error(ex);
                result.HasError     = true;
                result.ErrorMessage = ex.Message + Environment.NewLine + ex.StackTrace;
            }

            result.serverTime = DateTime.Now;
            return(result);
        }
Exemple #4
0
        public ModbusPlcConnection(string host, int port, byte unitId)
        {
            _host   = host;
            _port   = port;
            _unitId = unitId;

            TcpClient    = new TcpClient();
            ModbusMaster = new ModbusFactory().CreateMaster(TcpClient);
        }
        public static IModbusSlave CreateSlaveProxy(
            this IModbusFactory factory,
            byte unitId,
            IModbusMaster master)
        {
            var dataStore = new ProxyDataStore(unitId, master);

            return(factory.CreateSlave(unitId, dataStore));
        }
Exemple #6
0
 /// <summary>
 /// Scans in data from the IED and writes it
 /// </summary>
 /// <param name="master"></param>
 /// <returns></returns>
 private static void ScanIn(IModbusMaster master)
 {
     for (int i = 0; i < 272; i += 2)
     {
         ushort[] items = master.ReadInputRegisters(1, (ushort)i, 2);
         //float itemsFloat = BinaryToFloat(items); // Checks that the data is correct
         WriteValues(items, i);
     }
 }
Exemple #7
0
 internal Controller(string port)
 {
     //создаем порт
     ComPort = new SerialPort(port, 115200, Parity.Even, 7, StopBits.One);
     //открываем его
     ComPort.Open();
     //создаем modbus-устройство
     PLC = ModbusSerialMaster.CreateAscii(ComPort);
 }
Exemple #8
0
        /// <summary>
        /// Writes a single TimeSpan value to the KWLEC200.
        /// </summary>
        /// <param name="modbus">The Modbus master device.</param>
        /// <param name="slave">The slave ID of the Modbus device.</param>
        /// <param name="name">The Helios value name attribute.</param>
        /// <param name="size">The Helios value size attribute.</param>
        /// <param name="count">The Helios value count attribute.</param>
        /// <param name="data">The TimeSpan data item.</param>
        /// <returns></returns>
        public async Task WriteTimeDataAsync(IModbusMaster modbus, byte slave, string name, ushort size, ushort count, TimeSpan data)
        {
            string text = GetTimeData(name, size, count, data);

            if (!string.IsNullOrEmpty(text))
            {
                await modbus.WriteStringAsync(slave, OFFSET, text);
            }
        }
Exemple #9
0
 /// <inheritdoc/>
 public void Dispose()
 {
     _client?.Dispose();
     _client = null;
     _adapter?.Dispose();
     _adapter = null;
     _master?.Dispose();
     _master = null;
 }
Exemple #10
0
 /// <summary>
 /// Set state relay by index
 /// </summary>
 /// <param name="master">modbus transport</param>
 /// <param name="index">aim index relay</param>
 /// <param name="value">aim value relay</param>
 public void SetRelayState(IModbusMaster master, int index, bool value)
 {
     var answer = master.ReadHoldingRegisters(_address, RegisterStartRelays, CountRegistersRelays);
     Thread.Sleep(10);
     var state = SetBitToUShortArray(answer, index, value);
     master.WriteMultipleRegisters(_address, RegisterStartRelays, state);
     //answer = master.ReadHoldingRegisters(_address, RegisterStartRelays, CountRegistersRelays);
     //if (state != answer)
     //    throw new Exception(string.Format("Relay not setted(must by {0} but now {1})", state, answer));
 }
        internal async Task ConnectByTCPAsync(string address, int port)
        {
            tcpClient = new TcpClient(address, port);

            var factory = new ModbusFactory();

            master = factory.CreateMaster(tcpClient);

            await master.ReadInputRegistersAsync(SLAVE_ADDRESS, 0, 1);
        }
Exemple #12
0
		public static void ReadRegisters(IModbusMaster master)
		{
			var result = master.ReadHoldingRegisters(1, 0, 5);

			for (int i = 0; i < 5; i++)
			{
				if (result[i] != i + 1)
					throw new Exception();
			}
		}
Exemple #13
0
        private IModbusMaster GetModbusMaster(SerialPort port)
        {
            IModbusMaster master = ModbusSerialMaster.CreateRtu(port);

            master.Transport.ReadTimeout             = 1000; //读取数据超时1000ms
            master.Transport.WriteTimeout            = 1000; //写入数据超时100ms
            master.Transport.Retries                 = 3;    //重试次数
            master.Transport.WaitToRetryMilliseconds = 100;  //重试间隔
            return(master);
        }
Exemple #14
0
        public async Task TestInput()
        {
            var           factory = new ModbusFactory();
            IModbusMaster modbus  = factory.CreateMaster(_client);
            await _client.ConnectAsync(MODBUS_IP, MODBUS_PORT);

            bool[] data = await modbus.ReadInputsAsync(MODBUS_SLAVE, 0, 5);

            Assert.Equal(5, data.Length);
        }
 public DeviceController(IRedisConnectionFactory redisConnectionFactory,
                         IDataAccess mysql_dataAccess,
                         IModbusFactory modbusFactory, ILoggerFactory loggerFactory)
 {
     redis_ai      = redisConnectionFactory.Connection().GetDatabase(1);
     redis_di      = redisConnectionFactory.Connection().GetDatabase();
     modbus        = modbusFactory;
     modbus_master = modbus.GetModbusMaster();
     logger        = loggerFactory.CreateLogger <DeviceController>();
     dataAccess    = mysql_dataAccess;
 }
Exemple #16
0
 private void ReleaseConnection()
 {
     _modbusMaster?.Dispose();
     _modbusMaster = null;
     _tcpClient?.Dispose();
     _tcpClient = null;
     _udpClient?.Dispose();
     _udpClient = null;
     _serialPort?.Dispose();
     _serialPort = null;
 }
Exemple #17
0
        //
        // Zusammenfassung:
        //     Establish connection to Master device in case of Modbus TCP.
        public void Connect(string ipAddress, int port)
        {
            // create the master
            this.masterTcpClient = new TcpClient();
            Task task = this.masterTcpClient.ConnectAsync(ipAddress, port);

            task.Wait();

            var factory = new ModbusFactory();

            this.master = factory.CreateMaster(masterTcpClient);
        }
        public Machine(string portName, byte id)
        {
            this.ID = id;

            this.plcPort          = new SerialPort(portName);
            this.plcPort.BaudRate = 115200;
            this.plcPort.DataBits = 8;
            this.plcPort.StopBits = StopBits.One;
            this.plcPort.Parity   = Parity.Even;

            this.master = ModbusSerialMaster.CreateRtu(this.plcPort);
        }
 private void FormForcingCoilY000ON_Load(object sender, EventArgs e)
 {
     try
     {
         objIModbusMaster = new ModbusASCIIMaster("COM10", 9600, 7, System.IO.Ports.StopBits.One, System.IO.Ports.Parity.Even);
         objIModbusMaster.Connection();
     }
     catch (Exception ex)
     {
         MessageBox.Show(this, ex.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
     }
 }
 public void CreateClient()
 {
     try
     {
         tcp    = new TcpClient(Host, Port);
         master = new ModbusFactory().CreateMaster(tcp);
     }
     catch (Exception ex)
     {
         OnException?.Invoke(ex);
     }
 }
Exemple #21
0
 private void FormReadingContactY0ToY5FromSlaveDevice02_Load(object sender, EventArgs e)
 {
     try
     {
         objIModbusMaster = new ModbusASCIIMaster("COM20", 9600, 7, System.IO.Ports.StopBits.One, System.IO.Ports.Parity.Even);
         objIModbusMaster.Connection();
     }
     catch (Exception ex)
     {
         MessageBox.Show(this, ex.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
     }
 }
 private void FormWriteMultipleRegistersD0ToD15ToSlaveDevice02_Load(object sender, EventArgs e)
 {
     try
     {
         objIModbusMaster = new ModbusASCIIMaster("COM10", 9600, 7, System.IO.Ports.StopBits.One, System.IO.Ports.Parity.Even);
         objIModbusMaster.Connection();
     }
     catch (Exception ex)
     {
         MessageBox.Show(this, ex.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
     }
 }
Exemple #23
0
 private void Form1_Load(object sender, EventArgs e)
 {
     //初始化modbusmaster
     modbusFactory = new ModbusFactory();
     //在本地测试 所以使用回环地址,modbus协议规定端口号 502
     master = modbusFactory.CreateMaster(new TcpClient("127.0.0.1", 502));
     //设置读取超时时间
     master.Transport.ReadTimeout = 2000;
     master.Transport.Retries     = 2000;
     groupBox1.Enabled            = false;
     groupBox2.Enabled            = false;
 }
Exemple #24
0
    public static void ReadRegisters(IModbusMaster master)
    {
        ushort[]? result = master.ReadHoldingRegisters(1, 0, 5);

        for (int i = 0; i < 5; i++)
        {
            if (result[i] != i + 1)
            {
                throw new Exception();
            }
        }
    }
 public void Port_choised(string arg)
 {
     if (port.PortName != null)
     {
         try
         {
             if (port.PortName == arg)
             {
                 if (!port.IsOpen)
                 {
                     port.Open();
                 }
                 output += "Port " + port.PortName + " opened" + "\n";
                 RaisePropertyChanged("Terminal");
             }
             else
             {
                 if (port.IsOpen)
                 {
                     port.Close();
                 }
                 port.PortName = arg;
                 port.Open();
             }
             _port_state = port.PortName + " opened";
             if (baudrate != 0)
             {
                 port.BaudRate = baudrate;
             }
             port.Handshake = Handshake.None;
             adapter        = new SerialPortAdapter(port);
             factory        = new ModbusFactory();
             master         = factory.CreateRtuMaster(adapter);
             master.Transport.ReadTimeout  = 300;
             master.Transport.WriteTimeout = 1000;
             output += "Master created " + port.BaudRate.ToString() + "\n";
             RaisePropertyChanged("Terminal");
         }
         catch (System.IO.IOException)
         {
             Refresh_List();
             _port_state = arg + " was lost";
             output     += "Master create error: " + "\n";
             RaisePropertyChanged("Terminal");
         }
     }
     else
     {
         output += "Port not choised" + "\n";
         RaisePropertyChanged("Terminal");
     }
     RaisePropertyChanged("Port_state");
 }
        public Machine(string portName, byte id)
        {
            this.ID = id;

            this.plcPort = new SerialPort(portName);
            this.plcPort.BaudRate = 115200;
            this.plcPort.DataBits = 8;
            this.plcPort.StopBits = StopBits.One;
            this.plcPort.Parity = Parity.Even;

            this.master = ModbusSerialMaster.CreateRtu(this.plcPort);
        }
Exemple #27
0
        public static int[] LayDuLieuCOMHoldingRegisters(SerialPort serialPort, ushort quantityHoldingRegisters, ushort minAddressHoldingRegisters, ThietBiModel thietBiModel)
        {
            IModbusMaster master = ModbusSerialMaster.CreateRtu(serialPort);
            List <ushort> readHoldingRegistersUshortTpye = new List <ushort>();

            if (quantityHoldingRegisters != 0)
            {
                try
                {
                    byte slaveAddress    = 1;
                    int  soNguyenSauChia = quantityHoldingRegisters / DonViQuantityMoiLanDoc;
                    for (int i = 0; i <= soNguyenSauChia; i++)
                    {
                        if (i != soNguyenSauChia)
                        {
                            int startAddress = i * DonViQuantityMoiLanDoc + minAddressHoldingRegisters;
                            int quantity     = DonViQuantityMoiLanDoc - minAddressHoldingRegisters;
                            var temp         = master.ReadHoldingRegisters(slaveAddress, (ushort)startAddress, (ushort)(quantity));

                            readHoldingRegistersUshortTpye.AddRange(temp.ToList());
                        }
                        else if (i == soNguyenSauChia)
                        {
                            int startAddress = i * DonViQuantityMoiLanDoc + minAddressHoldingRegisters;
                            int quantity     = quantityHoldingRegisters % DonViQuantityMoiLanDoc - minAddressHoldingRegisters;
                            if (quantity != 0)
                            {
                                var temp = master.ReadHoldingRegisters(slaveAddress, (ushort)startAddress, (ushort)(quantity));
                                readHoldingRegistersUshortTpye.AddRange(temp.ToList());
                            }
                        }
                    }
                }
                catch (TimeoutException ex)
                {
                    ExceptionTimeOut(ex, thietBiModel);
                    throw;
                    //lỗi không đọc được dữ liệu
                }
                catch (Modbus.SlaveException ex)
                {
                    ExceptionErrorSlave(ex, thietBiModel);
                    throw;
                    //lỗi số bản ghi cần đọc vượt quá lượng bản ghi trả về
                }
                catch (Exception ex)
                {
                    throw;
                }
            }
            return(ConvertArrayUshortToIntArray(readHoldingRegistersUshortTpye));
        }
Exemple #28
0
        public bool Open(ref IModbusMaster master)
        {
            if (TcpClient == null || !TcpClient.Connected)
            {
                TcpClient                = new TcpClient();
                TcpClient.SendTimeout    = Timeout;
                TcpClient.ReceiveTimeout = Timeout;
                TcpClient.Connect(IPAddr, Port);

                master = ModbusIpMaster.CreateIp(TcpClient);
            }
            return(TcpClient.Connected);
        }
        /// <summary>
        /// 初始化modbus客户端
        /// </summary>
        public void CreateMaster()
        {
            var factory = new ModbusFactory();

            try
            {
                this.master = factory.CreateMaster(new TcpClient(hostIpAddr, modbusPort));
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message.ToString());
            }
        }
Exemple #30
0
 //
 // Zusammenfassung:
 //     Close connection to Master Device.
 public void Disconnect()
 {
     if (this.masterTcpClient != null)
     {
         this.masterTcpClient.Dispose();
         this.masterTcpClient = null;
     }
     if (this.master != null)
     {
         this.master.Dispose();
         this.master = null;
     }
 }
Exemple #31
0
        /// <summary>
        ///     Write a single 16 bit holding register.
        /// </summary>
        /// <param name="master">The Modbus master.</param>
        /// <param name="slaveAddress">Address of the device to write to.</param>
        /// <param name="registerAddress">Address to write.</param>
        /// <param name="value">Value to write.</param>
        public static void WriteSingleRegister32(
            this IModbusMaster master,
            byte slaveAddress,
            ushort registerAddress,
            uint value)
        {
            if (master == null)
            {
                throw new ArgumentNullException(nameof(master));
            }

            master.WriteMultipleRegisters32(slaveAddress, registerAddress, new[] { value });
        }
Exemple #32
0
        /// <summary>
        /// Reads a single Time value from the KWLEC200.
        /// </summary>
        /// <param name="modbus">The Modbus master device.</param>
        /// <param name="slave">The slave ID of the Modbus device.</param>
        /// <param name="name">The Helios value name attribute.</param>
        /// <param name="size">The Helios value size attribute.</param>
        /// <param name="count">The Helios value count attribute.</param>
        /// <returns>The Timespan value read from the KWLEC200.</returns>
        public (TimeSpan Data, DataStatus Status) ReadTimeData(IModbusMaster modbus, byte slave, string name, ushort size, ushort count)
        {
            var(result, status) = ReadRawData(modbus, slave, name, size, count);

            if (status.IsGood)
            {
                return(ParseTimeData(name, size, count, result));
            }
            else
            {
                return(new TimeSpan(), status);
            }
        }
Exemple #33
0
        /// <summary>
        /// Reads a string value from the KWLEC200.
        /// </summary>
        /// <param name="modbus">The Modbus master device.</param>
        /// <param name="slave">The slave ID of the Modbus device.</param>
        /// <param name="name">The Helios value name attribute.</param>
        /// <param name="size">The Helios value size attribute.</param>
        /// <param name="count">The Helios value count attribute.</param>
        /// <returns>The string value read from the KWLEC200.</returns>
        public (string Data, DataStatus Status) ReadStringData(IModbusMaster modbus, byte slave, string name, ushort size, ushort count)
        {
            var result = ReadRawData(modbus, slave, name, size, count);

            if (!string.IsNullOrEmpty(result.Data))
            {
                return(ParseStringData(name, size, count, result.Data));
            }
            else
            {
                return(string.Empty, BadUnknownResponse);
            }
        }
Exemple #34
0
        public static async Task SendBack(SerialPort port, ushort address)
        {
            var adapter = new SerialPortAdapter(port);
            // create modbus master
            var factory = new ModbusFactory();

            IModbusMaster master = factory.CreateRtuMaster(adapter);

            byte slaveId = 1;
            await master.WriteSingleCoilAsync(slaveId, address, true);

            await master.WriteSingleCoilAsync(slaveId, address, false);
        }
Exemple #35
0
        /// <summary>
        /// Reads a single integer value from the KWLEC200.
        /// </summary>
        /// <param name="modbus">The Modbus master device.</param>
        /// <param name="slave">The slave ID of the Modbus device.</param>
        /// <param name="name">The Helios value name attribute.</param>
        /// <param name="size">The Helios value size attribute.</param>
        /// <param name="count">The Helios value count attribute.</param>
        /// <returns>The integer value read from the KWLEC200.</returns>
        public (int Data, DataStatus Status) ReadIntegerData(IModbusMaster modbus, byte slave, string name, ushort size, ushort count)
        {
            var(result, status) = ReadRawData(modbus, slave, name, size, count);

            if (status.IsGood)
            {
                return(ParseIntegerData(name, size, count, result));
            }
            else
            {
                return(0, status);
            }
        }
Exemple #36
0
 /// <summary>
 /// Set state multiply relay by index
 /// </summary>
 /// <param name="master">modbus transport</param>
 /// <param name="values">aim values relays</param>
 public void SetRelayState(IModbusMaster master, IDictionary<int, bool> values)
 {
     var answer = master.ReadHoldingRegisters(_address, RegisterStartRelays, CountRegistersRelays);
     var state = answer;
     Thread.Sleep(10);
     foreach (var value in values)
     {
         state = SetBitToUShortArray(answer, value.Key, value.Value);
     }
     master.WriteMultipleRegisters(_address, RegisterStartRelays, state);
     _relays = state;
     //Thread.Sleep(50);
     //answer = master.ReadHoldingRegisters(_address, RegisterStartRelays, CountRegistersRelays);
     //if (state != answer)
     //    throw new Exception(string.Format("Relay not setted(must by {0} but now {1})", state, answer));
 }
 public IEnumerable<KeyValuePair<Tag, object>> Update(IModbusMaster master)
 {
     Parse(storage, master.ReadHoldingRegisters(addr, 0, nregs));
     return storage.ToList();
 }
Exemple #38
0
 /// <summary>
 /// Set state relay by index
 /// </summary>
 /// <param name="master">modbus transport</param>
 /// <param name="index">aim index relay</param>
 /// <param name="value">aim value relay</param>
 public void SetRelayState(IModbusMaster master, int index, bool value)
 {
     var answer = master.ReadInputRegisters(_address, RegisterStartRelays, CountRegistersRelays);
     var state = SetBitToUShortArray(answer, index, value);
     master.WriteMultipleRegisters(_address, RegisterStartRelays, state);
 }
Exemple #39
0
 /// <summary>
 /// Get state relay by index
 /// </summary>
 /// <param name="master">modbus transport</param>
 /// <param name="index">aim index</param>
 /// <returns>state relay</returns>
 public bool GetRelayState(IModbusMaster master, int index)
 {
     var answer = master.ReadInputRegisters(_address, RegisterStartRelays, CountRegistersRelays);
     return GetBitFromUShortArray(answer, index);
 }
Exemple #40
0
 /// <summary>
 /// Обновить состояние панели
 /// </summary>
 /// <param name="master">Транспорт</param>
 /// <returns>Список изменившихся входов</returns>
 public void UpdatePannelState(IModbusMaster master)
 {
     var res = new List<int>();
     var answer = master.ReadHoldingRegisters(_address, RegisterStar, CountRegisters);
     ParceFromUShortArray(answer);
     _lastStateTimestamp = DateTime.Now;
 }
Exemple #41
0
        /// <summary>
        /// Прочитать состояние одного дискретного входа 
        /// </summary>
        /// <param name="master">Транспорт</param>
        /// <param name="index">Индекс входа</param>
        /// <returns>Значение дискретного входа</returns>
        public bool GetInput(IModbusMaster master, int index)
        {
            var answer = master.ReadHoldingRegisters(_address, RegisterStartInputs, CountRegistersInputs);

            return GetBitFromUShortArray(answer, index);
        }
Exemple #42
0
 /// <summary>
 /// Read state all state relay
 /// </summary>
 /// <param name="master">Транспорт</param>
 /// <returns>Список изменившихся входов</returns>
 public void UpdateAllStateRelay(IModbusMaster master)
 {
     _relays = master.ReadHoldingRegisters(_address, RegisterStartRelays, CountRegistersRelays);
 }
Exemple #43
0
        /// <summary>
        /// Perform read registers command 
        /// </summary>
        /// <param name="master"></param>
        /// <returns></returns>
        internal static double CalculateAverage(IModbusMaster master)
        {
            ushort startAddress = 5;
            ushort numRegisters = 5;

            // JIT compile the IL
            master.ReadHoldingRegisters(SlaveAddress, startAddress, numRegisters);

            Stopwatch stopwatch = new Stopwatch();
            long sum = 0;
            double numberOfReads = 50;

            for (int i = 0; i < numberOfReads; i++)
            {
                stopwatch.Reset();
                stopwatch.Start();
                master.ReadHoldingRegisters(SlaveAddress, startAddress, numRegisters);
                stopwatch.Stop();
                log.DebugFormat("CalculateAverage read {0}", i + 1);

                checked
                {
                    sum += stopwatch.ElapsedMilliseconds;
                }
            }

            return sum / numberOfReads;
        }