// Background reading
        private void ThreadWork()
        {
            while (run)
            {
                foreach (DataGridViewRow row in dataGridView1.Rows)
                {
                    if (row.Cells["address"].Value != null && row.Cells["IsValid"].Value.ToString() == "1")
                    {
                        // Read row
                        string idrow  = row.Cells["idrow"].Value.ToString();
                        string addr   = row.Cells["address"].Value.ToString();
                        string format = row.Cells["format"].Value.ToString();

                        string GraphName = addr;

                        // Raw byte from PLC
                        byte[] resbyte = _plc.GetValue(addr);
                        // Formated user output
                        string resvalue = "";
                        // Read in format
                        switch (format.ToUpper())
                        {
                        case "BOOL":
                            resvalue = _plc.GetBooltS(resbyte);
                            break;

                        case "DEC":
                            resvalue = _plc.GetDecS(resbyte);
                            break;

                        case "BIN":
                            resvalue = _plc.GetBinS(resbyte);
                            break;

                        case "FLOAT":
                            resvalue = _plc.GetFloatS(resbyte);
                            break;

                        case "CHAR":
                            resvalue = _plc.GetCharS(resbyte);
                            break;

                        default:
                            resvalue = "Data type error";
                            break;
                        }

                        // Update datagridview
                        SendResult dResult = new SendResult(ShowResult);
                        this.Invoke(dResult, idrow, resvalue);
                        if (Convert.ToBoolean(row.Cells["check"].Value))
                        {
                            // Insert into chart
                            if (format.ToUpper() != "BIN" & format.ToUpper() != "CHAR")
                            {
                                PlotResult dPlot = new PlotResult(InsertPlotPoint);
                                this.Invoke(dPlot, GraphName, resvalue, format.ToUpper());
                            }
                        }
                    }
                }
                Thread.Sleep(100);
                // Update chart
                UpdateChart dupdate = new UpdateChart(UpdateChartPoints);
                this.Invoke(dupdate);
            }
        }