Example #1
0
        public Data()
            : base()
        {
            //// The following lines initialize the local PLC specific members using the
            //// different PLC types to generate the dynamic members of the PLC Object.
            //// While the PlcByte, PlcInt16, etc. are initialized with a dynamically
            //// created PLC address which uses a static member to identify the number
            //// of the DataBlock to address within the new instance.

            // DBx.DBB 2
            this.byteValue = new PlcByte(new PlcAddress(
                                             PlcOperand.DataBlock(Data.dataBlockNumber), PlcRawType.Byte, 2));

            this.Members.Add("ByteValue", this.byteValue);

            // DBx.DBW 4
            this.int16Value = new PlcInt16(new PlcAddress(
                                               PlcOperand.DataBlock(Data.dataBlockNumber), PlcRawType.Word, 4));
            this.Members.Add("Int16Value", this.int16Value);

            // DBx.DBD 6
            this.int32Value = new PlcInt32(new PlcAddress(
                                               PlcOperand.DataBlock(Data.dataBlockNumber), PlcRawType.DWord, 6));
            this.Members.Add("Int32Value", this.int32Value);

            // DBx.DBD 10
            this.realValue = new PlcReal(new PlcAddress(
                                             PlcOperand.DataBlock(Data.dataBlockNumber), PlcRawType.DWord, 10));
            this.Members.Add("RealValue", this.realValue);

            // DBx.DBB 20
            this.stringValue = new PlcString(new PlcAddress(
                                                 PlcOperand.DataBlock(Data.dataBlockNumber), PlcRawType.Byte, 20), 16);
            this.Members.Add("StringValue", this.stringValue);
        }
Example #2
0
        public static void Main(string[] args)
        {
            SimaticDevice device = new SimaticDevice("192.168.0.80", SimaticDeviceType.S7300_400);

            PlcDeviceConnection connection = device.CreateConnection();

            connection.Open();

            SQLiteConnectionStringBuilder builder = new SQLiteConnectionStringBuilder();

            builder.DataSource = @".\Database.db";

            SQLiteConnection sqlConnection = new SQLiteConnection(
                builder.ToString(),
                parseViaFramework: true);

            SQLiteCommand command = sqlConnection.CreateCommand();

            command.CommandText = "select * from Data";

            SQLiteDataReader dataReader = command.ExecuteReader();

            DataTable table = new DataTable();

            table.Load(dataReader);

            #region 1. Way: Sequential Write.
            {
                //// Either use the primitive low level methods of the PLC device connection to
                //// sequential write the data.

                foreach (DataRow row in table.Rows)
                {
                    connection.WriteByte("DB111.DBB 2", Convert.ToByte(row["NumberOfPages"]));      // Number of pages.
                    connection.WriteInt16("DB111.DBW 4", Convert.ToInt16(row["Resolution"]));       // Resolution in dpi.
                    connection.WriteInt32("DB111.DBD 6", Convert.ToInt32(row["LineHeight"]));       // Line Height in pixels.
                    connection.WriteReal("DB111.DBD 10", Convert.ToSingle(row["Price"]));           // Price.
                    connection.WriteString("DB111.DBB 20", Convert.ToString(row["ArticleNumber"])); // Article Number.

                    connection.WriteBoolean("DB111.DBX 1.0", true);

                    // Wait while printing.
                    while (connection.ReadBoolean("E 1.0"))
                    {
                        Thread.Sleep(TimeSpan.FromMilliseconds(100));
                    }
                }
            }
            #endregion

            #region 2. Way: Bulk write (with variables).
            {
                //// Or use the higher level methods of the PLC device connection to write a whole
                //// set of variables at once. While this way would be much faster than the
                //// previous one, because the values are write within one transaction instead of
                //// processing each value within a transaction for each action.

                PlcByte   numberOfPages = new PlcByte("DB111.DBB 2");
                PlcInt16  resolution    = new PlcInt16("DB111.DBW 4");
                PlcInt32  lineHeight    = new PlcInt32("DB111.DBD 6");
                PlcReal   price         = new PlcReal("DB111.DBD 10");
                PlcString articleNumber = new PlcString("DB111.DBB 20", 16);

                PlcBoolean startPrint = new PlcBoolean("DB111.DBX 1.0", true);

                foreach (DataRow row in table.Rows)
                {
                    numberOfPages.Value = Convert.ToByte(row["NumberOfPages"]);     // Number of pages.
                    resolution.Value    = Convert.ToInt16(row["Resolution"]);       // Resolution in dpi.
                    lineHeight.Value    = Convert.ToInt32(row["LineHeight"]);       // Line Height in pixels.
                    price.Value         = Convert.ToSingle(row["Price"]);           // Price.
                    articleNumber.Value = Convert.ToString(row["ArticleNumber"]);   // Article Number.

                    connection.WriteValues(numberOfPages, resolution, lineHeight, price, articleNumber, startPrint);

                    // Wait while printing.
                    while (connection.ReadBoolean("E 1.0"))
                    {
                        Thread.Sleep(TimeSpan.FromMilliseconds(100));
                    }
                }
            }
            #endregion

            #region 3. Way: Bulk write (with object).
            {
                //// Or use the methods of the PLC device connection at the highest abstraction
                //// layer to write the whole PLC data at once from a user defined PLC object.

                foreach (DataRow row in table.Rows)
                {
                    PrintJobData data = new PrintJobData();

                    data.NumberOfPages = Convert.ToByte(row["NumberOfPages"]);     // Number of pages.
                    data.Resolution    = Convert.ToInt16(row["Resolution"]);       // Resolution in dpi.
                    data.LineHeight    = Convert.ToInt32(row["LineHeight"]);       // Line Height in pixels.
                    data.Price         = Convert.ToSingle(row["Price"]);           // Price.
                    data.ArticleNumber = Convert.ToString(row["ArticleNumber"]);   // Article Number.

                    connection.WriteObject(data);

                    // Wait while printing.
                    while (connection.ReadBoolean("E 1.0"))
                    {
                        Thread.Sleep(TimeSpan.FromMilliseconds(100));
                    }
                }
            }
            #endregion

            sqlConnection.Close();
            connection.Close();
        }
        public static void Main(string[] args)
        {
            SimaticDevice device = new SimaticDevice("192.168.0.80", SimaticDeviceType.S7300_400);

            PlcDeviceConnection connection = device.CreateConnection();

            connection.Open();

            #region 1. Way: Sequential Write.
            {
                //// Either use the primitive low level methods of the PLC device connection to
                //// sequential write the data.

                foreach (string line in File.ReadAllLines(@".\Data.csv"))
                {
                    string[] values = line.Split(';');

                    connection.WriteByte("DB111.DBB 2", Convert.ToByte(values[0]));     // Number of pages.
                    connection.WriteInt16("DB111.DBW 4", Convert.ToInt16(values[1]));   // Resolution in dpi.
                    connection.WriteInt32("DB111.DBD 6", Convert.ToInt32(values[2]));   // Line Height in pixels.
                    connection.WriteReal("DB111.DBD 10", Convert.ToSingle(values[3]));  // Price.
                    connection.WriteString("DB111.DBB 20", values[4]);                  // Article Number.

                    connection.WriteBoolean("DB111.DBX 1.0", true);

                    // Wait while printing.
                    while (connection.ReadBoolean("E 1.0"))
                    {
                        Thread.Sleep(TimeSpan.FromMilliseconds(100));
                    }
                }
            }
            #endregion

            #region 2. Way: Bulk write (with variables).
            {
                //// Or use the higher level methods of the PLC device connection to write a whole
                //// set of variables at once. While this way would be much faster than the
                //// previous one, because the values are write within one transaction instead of
                //// processing each value within a transaction for each action.

                PlcByte   numberOfPages = new PlcByte("DB111.DBB 2");
                PlcInt16  resolution    = new PlcInt16("DB111.DBW 4");
                PlcInt32  lineHeight    = new PlcInt32("DB111.DBD 6");
                PlcReal   price         = new PlcReal("DB111.DBD 10");
                PlcString articleNumber = new PlcString("DB111.DBB 20", 16);

                PlcBoolean startPrint = new PlcBoolean("DB111.DBX 1.0", true);

                foreach (string line in File.ReadAllLines(@".\Data.csv"))
                {
                    string[] values = line.Split(';');

                    numberOfPages.Value = Convert.ToByte(values[0]);     // Number of pages.
                    resolution.Value    = Convert.ToInt16(values[1]);    // Resolution in dpi.
                    lineHeight.Value    = Convert.ToInt32(values[2]);    // Line Height in pixels.
                    price.Value         = Convert.ToSingle(values[3]);   // Price.
                    articleNumber.Value = Convert.ToString(values[4]);   // Article Number.

                    connection.WriteValues(numberOfPages, resolution, lineHeight, price, articleNumber, startPrint);

                    // Wait while printing.
                    while (connection.ReadBoolean("E 1.0"))
                    {
                        Thread.Sleep(TimeSpan.FromMilliseconds(100));
                    }
                }
            }
            #endregion

            #region 3. Way: Bulk write (with object).
            {
                //// Or use the methods of the PLC device connection at the highest abstraction
                //// layer to write the whole PLC data at once from a user defined PLC object.

                foreach (string line in File.ReadAllLines(@".\Data.csv"))
                {
                    string[]     values = line.Split(';');
                    PrintJobData data   = new PrintJobData();

                    data.NumberOfPages = Convert.ToByte(values[0]);     // Number of pages.
                    data.Resolution    = Convert.ToInt16(values[1]);    // Resolution in dpi.
                    data.LineHeight    = Convert.ToInt32(values[2]);    // Line Height in pixels.
                    data.Price         = Convert.ToSingle(values[3]);   // Price.
                    data.ArticleNumber = Convert.ToString(values[4]);   // Article Number.

                    connection.WriteObject(data);

                    // Wait while printing.
                    while (connection.ReadBoolean("E 1.0"))
                    {
                        Thread.Sleep(TimeSpan.FromMilliseconds(100));
                    }
                }
            }
            #endregion

            connection.Close();
        }
        public static void Main(string[] args)
        {
            SimaticDevice device = new SimaticDevice("192.168.0.80", SimaticDeviceType.S7300_400);

            PlcDeviceConnection connection = device.CreateConnection();

            connection.Open();

            SQLiteConnectionStringBuilder builder = new SQLiteConnectionStringBuilder();

            builder.DataSource = @".\Database.db";

            SQLiteConnection sqlConnection = new SQLiteConnection(
                builder.ToString(),
                parseViaFramework: true);

            sqlConnection.Open();

            SQLiteCommand command = sqlConnection.CreateCommand();

            command.CommandText
                = "insert into Data (ChanceOfRain, WindSpeed, Pressure, Temperature, Forecast) "
                  + "values (@chanceOfRain, @windSpeed, @pressure, @temperature, @forecast)";

            SQLiteParameter sqlChanceOfRain = command.Parameters.Add("@chanceOfRain", DbType.Int16);
            SQLiteParameter sqlWindSpeed    = command.Parameters.Add("@windSpeed", DbType.Int16);
            SQLiteParameter sqlPressure     = command.Parameters.Add("@pressure", DbType.Int16);
            SQLiteParameter sqlTemperature  = command.Parameters.Add("@temperature", DbType.Single);
            SQLiteParameter sqlForecast     = command.Parameters.Add("@forecast", DbType.String);

            #region 1. Way: Sequential Read.
            {
                //// Either use the primitive low level methods of the PLC device connection to
                //// sequential read the desired data areas.

                // Is the weather station online.
                while (connection.ReadBoolean("E 1.0"))
                {
                    sqlChanceOfRain.Value = connection.ReadByte("DB111.DBB 2");        // Chance of rain.
                    sqlWindSpeed.Value    = connection.ReadInt16("DB111.DBW 4");       // Wind speed.
                    sqlPressure.Value     = connection.ReadInt32("DB111.DBD 6");       // Pressure.
                    sqlTemperature.Value  = connection.ReadReal("DB111.DBD 10");       // Temperature.
                    sqlForecast.Value     = connection.ReadString("DB111.DBB 20", 16); // Forecast.

                    command.ExecuteNonQuery();
                    Thread.Sleep(TimeSpan.FromMinutes(30));
                }
            }
            #endregion

            #region 2. Way: Bulk read (with variables).
            {
                //// Or use the higher level methods of the PLC device connection to read a whole
                //// set of variables at once. While this way would be much faster than the previous
                //// one, because the values are read within one transaction instead of querying
                //// each value within a transaction for each request.

                PlcByte   chanceOfRain = new PlcByte("DB111.DBB 2");
                PlcInt16  windSpeed    = new PlcInt16("DB111.DBW 4");
                PlcInt32  pressure     = new PlcInt32("DB111.DBD 6");
                PlcReal   temperature  = new PlcReal("DB111.DBD 10");
                PlcString forecast     = new PlcString("DB111.DBB 20", 16);

                // Is the weather station online.
                while (connection.ReadBoolean("E 1.0"))
                {
                    connection.ReadValues(chanceOfRain, windSpeed, pressure, temperature, forecast);

                    sqlChanceOfRain.Value = chanceOfRain.Value; // Chance of rain.
                    sqlWindSpeed.Value    = windSpeed.Value;    // Wind speed.
                    sqlPressure.Value     = pressure.Value;     // Pressure.
                    sqlTemperature.Value  = temperature.Value;  // Temperature.
                    sqlForecast.Value     = forecast.Value;     // Forecast.

                    command.ExecuteNonQuery();
                    Thread.Sleep(TimeSpan.FromMinutes(30));
                }
            }
            #endregion

            #region 3. Way: Bulk read (with object).
            {
                //// Or use the methods of the PLC device connection at the highest abstraction
                //// layer to read the whole PLC data at once into a user defined PLC object.

                // Is the weather station online.
                while (connection.ReadBoolean("E 1.0"))
                {
                    WeatherData data = connection.ReadObject <WeatherData>();

                    sqlChanceOfRain.Value = data.ChanceOfRain; // Chance of rain.
                    sqlWindSpeed.Value    = data.WindSpeed;    // Wind speed.
                    sqlPressure.Value     = data.Pressure;     // Pressure.
                    sqlTemperature.Value  = data.Temperature;  // Temperature.
                    sqlForecast.Value     = data.Forecast;     // Forecast.

                    command.ExecuteNonQuery();
                    Thread.Sleep(TimeSpan.FromMinutes(30));
                }
            }
            #endregion

            sqlConnection.Close();
            connection.Close();
        }
Example #5
0
        public static void Main(string[] args)
        {
            SimaticDevice device = new SimaticDevice("192.168.0.80", SimaticDeviceType.S7300_400);

            PlcDeviceConnection connection = device.CreateConnection();

            connection.Open();

            string[]     values = new string[5];
            StreamWriter writer = File.AppendText(@".\Data.csv");

            #region 1. Way: Sequential Read.
            {
                //// Either use the primitive low level methods of the PLC device connection to
                //// sequential read the desired data areas.

                // Is the weather station online.
                while (connection.ReadBoolean("E 1.0"))
                {
                    values[0] = connection.ReadByte("DB111.DBB 2").ToString();  // Chance of rain.
                    values[1] = connection.ReadInt16("DB111.DBW 4").ToString(); // Wind speed.
                    values[2] = connection.ReadInt32("DB111.DBD 6").ToString(); // Pressure.
                    values[3] = connection.ReadReal("DB111.DBD 10").ToString(); // Temperature.
                    values[4] = connection.ReadString("DB111.DBB 20", 16);      // Forecast.

                    writer.WriteLine(string.Join(";", values));
                    writer.Flush();

                    Thread.Sleep(TimeSpan.FromMinutes(30));
                }
            }
            #endregion

            #region 2. Way: Bulk read (with variables).
            {
                //// Or use the higher level methods of the PLC device connection to read a whole
                //// set of variables at once. While this way would be much faster than the
                //// previous one, because the values are read within one transaction instead of
                //// querying each value within a transaction for each request.

                PlcByte   chanceOfRain = new PlcByte("DB111.DBB 2");
                PlcInt16  windSpeed    = new PlcInt16("DB111.DBW 4");
                PlcInt32  pressure     = new PlcInt32("DB111.DBD 6");
                PlcReal   temperature  = new PlcReal("DB111.DBD 10");
                PlcString forecast     = new PlcString("DB111.DBB 20", 16);

                // Is the weather station online.
                while (connection.ReadBoolean("E 1.0"))
                {
                    connection.ReadValues(chanceOfRain, windSpeed, pressure, temperature, forecast);

                    values[0] = chanceOfRain.Value.ToString();  // Chance of rain.
                    values[1] = windSpeed.Value.ToString();     // Wind speed.
                    values[2] = pressure.Value.ToString();      // Pressure.
                    values[3] = temperature.Value.ToString();   // Temperature.
                    values[4] = forecast.Value.ToString();      // Forecast.

                    writer.WriteLine(string.Join(";", values));
                    writer.Flush();

                    Thread.Sleep(TimeSpan.FromMinutes(30));
                }
            }
            #endregion

            #region 3. Way: Bulk read (with object).
            {
                //// Or use the methods of the PLC device connection at the highest abstraction
                //// layer to read the whole PLC data at once into a user defined PLC object.

                // Is the weather station online.
                while (connection.ReadBoolean("E 1.0"))
                {
                    WeatherData data = connection.ReadObject <WeatherData>();

                    values[0] = data.ChanceOfRain.ToString();  // Chance of rain.
                    values[1] = data.WindSpeed.ToString();     // Wind speed.
                    values[2] = data.Pressure.ToString();      // Pressure.
                    values[3] = data.Temperature.ToString();   // Temperature.
                    values[4] = data.Forecast.ToString();      // Forecast.

                    writer.WriteLine(string.Join(";", values));
                    writer.Flush();

                    Thread.Sleep(TimeSpan.FromMinutes(30));
                }
            }
            #endregion

            writer.Close();
            connection.Close();
        }
Example #6
0
        public static void Main(string[] args)
        {
            SimaticDevice device = new SimaticDevice("192.168.0.80", SimaticDeviceType.S7300_400);

            PlcDeviceConnection connection = device.CreateConnection();

            connection.Open();

            // NOTE
            // To access XLS files using OLEDB you will need to install
            // "Microsoft Access Database Engine 2010 Redistributable"
            // https://www.microsoft.com/en-us/download/details.aspx?id=13255
            OleDbConnection excelConnection = new OleDbConnection(
                "Provider=Microsoft.ACE.OLEDB.12.0;"
                + @"Data Source=.\Data.xls;"
                + "Extended Properties=Excel 12.0");

            excelConnection.Open();

            // 'Data' represents the Excel Worksheet to write.
            OleDbCommand command = excelConnection.CreateCommand();

            command.CommandText = "insert into [Data$] values (?, ?, ?, ?, ?)";

            OleDbParameter excelChanceOfRain = command.Parameters.Add("@chanceOfRain", OleDbType.UnsignedTinyInt);
            OleDbParameter excelWindSpeed    = command.Parameters.Add("@windSpeed", OleDbType.SmallInt);
            OleDbParameter excelPressure     = command.Parameters.Add("@pressure", OleDbType.Integer);
            OleDbParameter excelTemperature  = command.Parameters.Add("@temperature", OleDbType.Single);
            OleDbParameter excelForecast     = command.Parameters.Add("@forecast", OleDbType.BSTR);

            #region 1. Way: Sequential Read.
            {
                //// Either use the primitive low level methods of the PLC device connection to
                //// sequential read the desired data areas.

                // Is the weather station online.
                while (connection.ReadBoolean("E 1.0"))
                {
                    excelChanceOfRain.Value = connection.ReadByte("DB111.DBB 2");        // Chance of rain.
                    excelWindSpeed.Value    = connection.ReadInt16("DB111.DBW 4");       // Wind speed.
                    excelPressure.Value     = connection.ReadInt32("DB111.DBD 6");       // Pressure.
                    excelTemperature.Value  = connection.ReadReal("DB111.DBD 10");       // Temperature.
                    excelForecast.Value     = connection.ReadString("DB111.DBB 20", 16); // Forecast.

                    command.ExecuteNonQuery();
                    Thread.Sleep(TimeSpan.FromMinutes(30));
                }
            }
            #endregion

            #region 2. Way: Bulk read (with variables).
            {
                //// Or use the higher level methods of the PLC device connection to read a whole
                //// set of variables at once. While this way would be much faster than the previous
                //// one, because the values are read within one transaction instead of querying
                //// each value within a transaction for each request.

                PlcByte   chanceOfRain = new PlcByte("DB111.DBB 2");
                PlcInt16  windSpeed    = new PlcInt16("DB111.DBW 4");
                PlcInt32  pressure     = new PlcInt32("DB111.DBD 6");
                PlcReal   temperature  = new PlcReal("DB111.DBD 10");
                PlcString forecast     = new PlcString("DB111.DBB 20", 16);

                // Is the weather station online.
                while (connection.ReadBoolean("E 1.0"))
                {
                    connection.ReadValues(chanceOfRain, windSpeed, pressure, temperature, forecast);

                    excelChanceOfRain.Value = chanceOfRain.Value; // Chance of rain.
                    excelWindSpeed.Value    = windSpeed.Value;    // Wind speed.
                    excelPressure.Value     = pressure.Value;     // Pressure.
                    excelTemperature.Value  = temperature.Value;  // Temperature.
                    excelForecast.Value     = forecast.Value;     // Forecast.

                    command.ExecuteNonQuery();
                    Thread.Sleep(TimeSpan.FromMinutes(30));
                }
            }
            #endregion

            #region 3. Way: Bulk read (with object).
            {
                //// Or use the methods of the PLC device connection at the highest abstraction
                //// layer to read the whole PLC data at once into a user defined PLC object.

                // Is the weather station online.
                while (connection.ReadBoolean("E 1.0"))
                {
                    WeatherData data = connection.ReadObject <WeatherData>();

                    excelChanceOfRain.Value = data.ChanceOfRain; // Chance of rain.
                    excelWindSpeed.Value    = data.WindSpeed;    // Wind speed.
                    excelPressure.Value     = data.Pressure;     // Pressure.
                    excelTemperature.Value  = data.Temperature;  // Temperature.
                    excelForecast.Value     = data.Forecast;     // Forecast.

                    command.ExecuteNonQuery();
                    Thread.Sleep(TimeSpan.FromMinutes(30));
                }
            }
            #endregion

            excelConnection.Close();
            connection.Close();
        }
        public static void Main(string[] args)
        {
            SimaticDevice device = new SimaticDevice("192.168.0.80", SimaticDeviceType.S7300_400);

            PlcDeviceConnection connection = device.CreateConnection();

            connection.Open();

            // NOTE
            // To access XLS files using OLEDB you will need to install
            // "Microsoft Access Database Engine 2010 Redistributable"
            // https://www.microsoft.com/en-us/download/details.aspx?id=13255
            OleDbConnection excelConnection = new OleDbConnection(
                "Provider=Microsoft.ACE.OLEDB.12.0;"
                + @"Data Source=.\Data.xls;"
                + "Extended Properties=Excel 12.0");

            excelConnection.Open();

            // 'Data' represents the Excel Worksheet to read.
            OleDbCommand command = excelConnection.CreateCommand();

            command.CommandText = "select * from [Data$]";

            OleDbDataReader dataReader = command.ExecuteReader();

            DataTable table = new DataTable();

            table.Load(dataReader);

            #region 1. Way: Sequential Write.
            {
                //// Either use the primitive low level methods of the PLC device connection to
                //// sequential write the data.

                foreach (DataRow row in table.Rows)
                {
                    connection.WriteByte("DB111.DBB 2", Convert.ToByte(row[0]));        // Number of pages.
                    connection.WriteInt16("DB111.DBW 4", Convert.ToInt16(row[1]));      // Resolution in dpi.
                    connection.WriteInt32("DB111.DBD 6", Convert.ToInt32(row[2]));      // Line Height in pixels.
                    connection.WriteReal("DB111.DBD 10", Convert.ToSingle(row[3]));     // Price.
                    connection.WriteString("DB111.DBB 20", Convert.ToString(row[4]));   // Article Number.

                    connection.WriteBoolean("DB111.DBX 1.0", true);

                    // Wait while printing.
                    while (connection.ReadBoolean("E 1.0"))
                    {
                        Thread.Sleep(TimeSpan.FromMilliseconds(100));
                    }
                }
            }
            #endregion

            #region 2. Way: Bulk write (with variables).
            {
                //// Or use the higher level methods of the PLC device connection to write a whole
                //// set of variables at once. While this way would be much faster than the
                //// previous one, because the values are write within one transaction instead of
                //// processing each value within a transaction for each action.

                PlcByte   numberOfPages = new PlcByte("DB111.DBB 2");
                PlcInt16  resolution    = new PlcInt16("DB111.DBW 4");
                PlcInt32  lineHeight    = new PlcInt32("DB111.DBD 6");
                PlcReal   price         = new PlcReal("DB111.DBD 10");
                PlcString articleNumber = new PlcString("DB111.DBB 20", 16);

                PlcBoolean startPrint = new PlcBoolean("DB111.DBX 1.0", true);

                foreach (DataRow row in table.Rows)
                {
                    numberOfPages.Value = Convert.ToByte(row["NumberOfPages"]);     // Number of pages.
                    resolution.Value    = Convert.ToInt16(row["Resolution"]);       // Resolution in dpi.
                    lineHeight.Value    = Convert.ToInt32(row["LineHeight"]);       // Line Height in pixels.
                    price.Value         = Convert.ToSingle(row["Price"]);           // Price.
                    articleNumber.Value = Convert.ToString(row["ArticleNumber"]);   // Article Number.

                    connection.WriteValues(numberOfPages, resolution, lineHeight, price, articleNumber, startPrint);

                    // Wait while printing.
                    while (connection.ReadBoolean("E 1.0"))
                    {
                        Thread.Sleep(TimeSpan.FromMilliseconds(100));
                    }
                }
            }
            #endregion

            #region 3. Way: Bulk write (with object).
            {
                //// Or use the methods of the PLC device connection at the highest abstraction
                //// layer to write the whole PLC data at once from a user defined PLC object.

                foreach (DataRow row in table.Rows)
                {
                    PrintJobData data = new PrintJobData();

                    data.NumberOfPages = Convert.ToByte(row["NumberOfPages"]);     // Number of pages.
                    data.Resolution    = Convert.ToInt16(row["Resolution"]);       // Resolution in dpi.
                    data.LineHeight    = Convert.ToInt32(row["LineHeight"]);       // Line Height in pixels.
                    data.Price         = Convert.ToSingle(row["Price"]);           // Price.
                    data.ArticleNumber = Convert.ToString(row["ArticleNumber"]);   // Article Number.

                    connection.WriteObject(data);

                    // Wait while printing.
                    while (connection.ReadBoolean("E 1.0"))
                    {
                        Thread.Sleep(TimeSpan.FromMilliseconds(100));
                    }
                }
            }
            #endregion

            excelConnection.Close();
            connection.Close();
        }