2025-06-07 12:49:56 -04:00

123 lines
5.1 KiB
C#

// This program connects to a Sealevel type 463E-OEM I/O processor https://www.sealevel.com/seai-o-463e-oem/
// Note: this program cannot be started until at least five seconds after powering up the I/O processor
// Note: if the program is interrupted and does not terminate normally, a power reset is required on the 463E
using Modbus.Device;
using System.Net.Sockets;
using static System.Console;
namespace ModbusReadRegisters
{
internal class ModbusProgram
{
private const string IPaddress = "10.10.10.110"; // Modbus device IP
private const int Port = 502; // Default Modbus TCP port
private const byte SlaveID = 247; // Modbus slave ID
private const ushort RegisterStartAddress = 0; // Starting address to read
private const ushort NumRegisters = 9; // Number of registers to read
private const ushort CoilStartAddress = 0; // Starting address to write coils
private static void Main(string[] args)
{
WriteLine("ModbusProgram begins here...\n\n");
try
{
using TcpClient client = new(IPaddress, Port);
// Build a client
ModbusIpMaster master = ModbusIpMaster.CreateIp(client);
WriteLine("CreateIp done\n");
// Read register values
ushort[] registers = master.ReadHoldingRegisters(SlaveID, RegisterStartAddress, NumRegisters);
WriteLine("ReadHoldingRegisters done\n");
DisplayRegisters(registers, RegisterStartAddress);
WriteLine("\nDisplayRegisters done\n");
// Set all channels as outputs
master.WriteSingleRegister(SlaveID, 2, 0);
WriteLine("WriteSingleRegister done.");
// Write to specific outputs
WriteIndividualCoils(master, registers, CoilStartAddress);
WriteLine("WriteIndividualCoils done\n");
// Write to groups of eight outputs at a time
WriteAllOutputs(SlaveID, master);
WriteLine("WriteAllOutputs done\n");
ShutDown(SlaveID, master);
}
catch (Exception ex)
{
WriteLine("An error occurred:\n\n" + ex.Message);
}
finally
{
WriteLine("\nModbusProgram ends here.\n");
_ = ReadKey(true);
}
}
// Print registers we found and their values
private static void DisplayRegisters(ushort[] registers, ushort startAddress)
{
WriteLine($"Read {registers.Length} registers starting at address {startAddress}:");
for (int i = 0; i < registers.Length; i++)
{
WriteLine($"Register {startAddress + i}: {registers[i]}");
}
}
// Exercise two racks, eight points at a time
private static void WriteAllOutputs(ushort slaveID, ModbusIpMaster master)
{
bool[] valueArrayON = [true, false, true, false, true, false, true, false];
bool[] valueArrayOFF = [false, true, false, true, false, true, false, true];
WriteLine("Writing to two boards at once:\n");
for (ushort j = 0; j < 4; j++)
{
for (ushort i = 0; i < 6; i++)
{
master.WriteMultipleCoils((byte)slaveID, (ushort)(i * 8), valueArrayON);
}
Thread.Sleep(150);
for (ushort i = 0; i < 6; i++)
{
master.WriteMultipleCoils((byte)slaveID, (ushort)(i * 8), valueArrayOFF);
}
}
}
// Execise individual outputs
private static void WriteIndividualCoils(ModbusIpMaster master, ushort[] registers, ushort coilStartAddress)
{
WriteLine("The value of 'coilStartAddress' is {0}", coilStartAddress);
for (int i = 0; i < registers.Length; i++)
{
WriteLine(registers[i]);
}
DisplayRegisters(registers, RegisterStartAddress);
for (ushort j = 0; j < 4; j++)
{
WriteLine("Turning the outputs ON.");
for (ushort i = 0; i < 48; i++)
{
master.WriteSingleCoil(SlaveID, i, true);
}
for (ushort i = 0; i < 48; i++)
{
master.WriteSingleCoil(SlaveID, i, false);
}
}
WriteLine("\nDone writing individual outputs!\n\n");
}
// Shut off all outputs
private static void ShutDown(ushort slaveID, ModbusIpMaster master)
{
bool[] valueArrayOFF = [false, false, false, false, false, false, false, false];
for (ushort i = 0; i < 6; i++)
{
master.WriteMultipleCoils((byte)slaveID, (ushort)(i * 8), valueArrayOFF);
}
}
}
}