73
px-tcp1/ProtosXExercise/Data.cs
Normal file
73
px-tcp1/ProtosXExercise/Data.cs
Normal file
@@ -0,0 +1,73 @@
|
||||
namespace ProtosXdigitalDemo
|
||||
{
|
||||
public static class Data
|
||||
{
|
||||
public static class MachineState
|
||||
{
|
||||
|
||||
public static bool[] digitalInputChannels { get; } = new bool[16];
|
||||
public static bool[] digitalOutputChannels { get; } = new bool[16];
|
||||
|
||||
|
||||
public static double[] analogInputChannels { get; } = new double[8];
|
||||
|
||||
|
||||
public static byte[] failureCode { get; } = new byte[256];
|
||||
|
||||
|
||||
public static ushort digitalInputCount { get; private set; }
|
||||
public static ushort digitalOutputCount { get; private set; }
|
||||
public static ushort analogInputCount { get; private set; }
|
||||
|
||||
public static void InitializeCounts()
|
||||
{
|
||||
digitalInputCount = (ushort)digitalInputChannels.Length;
|
||||
digitalOutputCount = (ushort)digitalOutputChannels.Length;
|
||||
analogInputCount = (ushort)analogInputChannels.Length;
|
||||
}
|
||||
}
|
||||
internal enum digitalInputChannels
|
||||
{
|
||||
DigitalInput0,
|
||||
DigitalInput1,
|
||||
DigitalInput2,
|
||||
DigitalInput3,
|
||||
DigitalInput4,
|
||||
DigitalInput5,
|
||||
DigitalInput6,
|
||||
DigitalInput7,
|
||||
DigitalInput8,
|
||||
DigitalInput9,
|
||||
DigitalInput10,
|
||||
DigitalInput11,
|
||||
DigitalInput12,
|
||||
DigitalInput13,
|
||||
DigitalInput14,
|
||||
DigitalInput15
|
||||
}
|
||||
internal enum digitalOutputChannels
|
||||
{
|
||||
KitchenLight1,
|
||||
KitchenLight2,
|
||||
KitchenLight3,
|
||||
PorchLight1,
|
||||
Porchlight2,
|
||||
OutsideFloodlight1,
|
||||
OutsideFloodlight2,
|
||||
PantryLight1,
|
||||
FrontRoomLight1,
|
||||
FrontRoomLight2,
|
||||
FrontRoomLight3,
|
||||
Radio,
|
||||
LandingLight1,
|
||||
ServerRoomLights,
|
||||
HallLight1,
|
||||
HallLight2
|
||||
}
|
||||
internal enum analogInputChannels
|
||||
{
|
||||
TemperatureSensor1,
|
||||
TemperatureSensor2
|
||||
}
|
||||
}
|
||||
}
|
||||
47
px-tcp1/ProtosXExercise/DigitalInputread.cs
Normal file
47
px-tcp1/ProtosXExercise/DigitalInputread.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using Modbus.Device;
|
||||
using static System.Console;
|
||||
|
||||
namespace ProtosXdigitalDemo
|
||||
{
|
||||
internal class InputReader
|
||||
{
|
||||
private readonly ModbusIpMaster _master;
|
||||
|
||||
public InputReader(ModbusIpMaster master)
|
||||
{
|
||||
_master = master;
|
||||
}
|
||||
|
||||
public void ReadAll()
|
||||
{
|
||||
WriteLine("Reading all discrete inputs…");
|
||||
try
|
||||
{
|
||||
bool[] inputs = _master.ReadInputs(0, ChannelCache.DigitalInputCount);
|
||||
Display(inputs);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
WriteLine($"[Error] Reading inputs failed → {ex.Message}");
|
||||
PromptKey("Press any key to continue…");
|
||||
}
|
||||
}
|
||||
|
||||
private void Display(bool[] inputs)
|
||||
{
|
||||
WriteLine("Discrete Inputs:");
|
||||
for (int i = 0; i < inputs.Length; i++)
|
||||
{
|
||||
string state = inputs[i] ? "On" : "Off";
|
||||
WriteLine($" Input #{i + 1}: {state}");
|
||||
}
|
||||
}
|
||||
|
||||
private void PromptKey(string prompt)
|
||||
{
|
||||
WriteLine(prompt);
|
||||
ReadKey(intercept: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
14
px-tcp1/ProtosXExercise/LoadFailureCodes.cs
Normal file
14
px-tcp1/ProtosXExercise/LoadFailureCodes.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
|
||||
namespace ProtosXdigitalDemo
|
||||
{
|
||||
internal class LoadFailureCodes
|
||||
{
|
||||
public static void FailureCodeValues()
|
||||
{
|
||||
Data.MachineState.failureCode[0] = 0; // success
|
||||
Data.MachineState.failureCode[1] = 1; // digital write error from hardware
|
||||
Data.MachineState.failureCode[2] = 2; // too many CLI parameters
|
||||
Data.MachineState.failureCode[255] = 255; // other error
|
||||
}
|
||||
}
|
||||
}
|
||||
59
px-tcp1/ProtosXExercise/OutputWriter.cs
Normal file
59
px-tcp1/ProtosXExercise/OutputWriter.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using Modbus.Device;
|
||||
using static System.Console;
|
||||
|
||||
namespace ProtosXdigitalDemo
|
||||
{
|
||||
internal class OutputExerciser
|
||||
{
|
||||
private readonly ModbusIpMaster _master;
|
||||
|
||||
public OutputExerciser(ModbusIpMaster master)
|
||||
{
|
||||
_master = master;
|
||||
}
|
||||
|
||||
public void RunSequence()
|
||||
{
|
||||
SetAllOutputs(false, "Turning all outputs OFF…");
|
||||
WaitForKey("Press any key to turn outputs ON…");
|
||||
|
||||
SetAllOutputs(true, "Turning all outputs ON…");
|
||||
WaitForKey("Press any key to turn outputs OFF and finish…");
|
||||
|
||||
SetAllOutputs(false, "Turning all outputs OFF…");
|
||||
}
|
||||
|
||||
private void SetAllOutputs(bool state, string message)
|
||||
{
|
||||
WriteLine(message);
|
||||
UpdateMachineState(state);
|
||||
|
||||
int result = WriteMachineDigitalStateToIO.WriteMachineStateToIO(_master, 0);
|
||||
if (result == Data.MachineState.failureCode[0])
|
||||
{
|
||||
WriteLine($"All digital outputs are now {(state ? "ON" : "OFF")}");
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteLine("[Error] Writing machine-state failed");
|
||||
WaitForKey("Press any key to exit…");
|
||||
Environment.Exit(Data.MachineState.failureCode[1]);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateMachineState(bool state)
|
||||
{
|
||||
for (int i = 0; i < Data.MachineState.digitalOutputChannels.Length; i++)
|
||||
{
|
||||
Data.MachineState.digitalOutputChannels[i] = state;
|
||||
}
|
||||
}
|
||||
|
||||
private void WaitForKey(string prompt)
|
||||
{
|
||||
WriteLine(prompt);
|
||||
ReadKey(intercept: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
41
px-tcp1/ProtosXExercise/Program.cs
Normal file
41
px-tcp1/ProtosXExercise/Program.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using System.Net.Sockets;
|
||||
using Modbus.Device;
|
||||
using static System.Console;
|
||||
|
||||
namespace ProtosXdigitalDemo
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
private const string IpAddress = "10.10.1.1";
|
||||
private const int Port = 502;
|
||||
|
||||
public static int Main(string[] args)
|
||||
{
|
||||
//ConsoleSetup.ApplyDefaultAppearance();
|
||||
var cmd = CommandLineParser.Parse(args); // still available
|
||||
LoadFailureCodes.FailureCodeValues(); // assumed static initializer
|
||||
|
||||
try
|
||||
{
|
||||
using var tcpClient = new TcpClientConnector(IpAddress, Port).Connect();
|
||||
var master = ModbusIpMaster.CreateIp(tcpClient);
|
||||
|
||||
ChannelCache.Initialize();
|
||||
new InputReader(master).ReadAll();
|
||||
new OutputExerciser(master).RunSequence();
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
// an Exit was requested
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
WriteLine($"[Fatal] {ex}");
|
||||
return Data.MachineState.failureCode[1];
|
||||
}
|
||||
|
||||
return Data.MachineState.failureCode[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user