diff --git a/px-tcp1/ProtosXExercise/AnalogInputRead.cs b/px-tcp1/ProtosXExercise/AnalogInputRead.cs new file mode 100644 index 0000000..65c8ccc --- /dev/null +++ b/px-tcp1/ProtosXExercise/AnalogInputRead.cs @@ -0,0 +1,69 @@ +using System; +using Modbus.Device; +using static System.Console; + +namespace ProtosXdigitalDemo +{ + internal class RegisterReader + { + private readonly ModbusIpMaster _master; + + public RegisterReader(ModbusIpMaster master) + { + _master = master; + } + + public void ReadAll() + { + WriteLine("Reading all input registers…"); + try + { + // Read all input registers as ushorts + ushort[] registers = _master.ReadInputRegisters(0, ChannelCache.AnalogInputCount); + Display(registers); + + // Convert to bool[] and display + bool[] bits = ConvertRegistersToBools(registers); + Display(bits); + } + catch (Exception ex) + { + WriteLine($"[Error] Reading input registers failed → {ex.Message}"); + PromptKey("Press any key to continue…"); + } + } + + private void Display(ushort[] registers) + { + WriteLine("Input Registers (ushort):"); + for (int i = 0; i < registers.Length; i++) + { + WriteLine($" Register #{i + 1}: {registers[i]}"); + } + } + + private void Display(bool[] bits) + { + WriteLine("Flattened Bits:"); + for (int i = 0; i < bits.Length; i++) + { + WriteLine($" Bit #{i + 1}: {(bits[i] ? "On" : "Off")}"); + } + } + + // Map a ushort's bits to bools using AND operator + private bool[] ConvertRegistersToBools(ushort[] registers) + { + + return registers.SelectMany(r => Enumerable.Range(0, 16) + .Select(bit => ((r >> bit) & 1) == 1)) + .ToArray(); + } + + private void PromptKey(string prompt) + { + WriteLine(prompt); + ReadKey(intercept: true); + } + } +} \ No newline at end of file diff --git a/px-tcp1/ProtosXExercise/ChannelHandling.cs b/px-tcp1/ProtosXExercise/ChannelHandling.cs new file mode 100644 index 0000000..6e37259 --- /dev/null +++ b/px-tcp1/ProtosXExercise/ChannelHandling.cs @@ -0,0 +1,16 @@ +namespace ProtosXdigitalDemo +{ + internal static class ChannelCache + { + public static ushort DigitalInputCount { get; private set; } + public static ushort DigitalOutputCount { get; private set; } + public static ushort AnalogInputCount { get; private set; } + + public static void Initialize() + { + DigitalInputCount = (ushort)Data.MachineState.digitalInputChannels.Length; + DigitalOutputCount = (ushort)Data.MachineState.digitalOutputChannels.Length; + AnalogInputCount = (ushort)Data.MachineState.analogInputChannels.Length; + } + } +} \ No newline at end of file diff --git a/px-tcp1/ProtosXExercise/CommandLine.cs b/px-tcp1/ProtosXExercise/CommandLine.cs new file mode 100644 index 0000000..6364dda --- /dev/null +++ b/px-tcp1/ProtosXExercise/CommandLine.cs @@ -0,0 +1,35 @@ +using System; +using static System.Console; + +namespace ProtosXdigitalDemo +{ + internal class CommandLineParser + { + public string? RecipeName { get; } + public int TimesToRepeat { get; } + + private CommandLineParser(string? recipeName, int timesToRepeat) + { + RecipeName = recipeName; + TimesToRepeat = timesToRepeat; + } + + public static CommandLineParser Parse(string[] args) + { + return args.Length switch + { + 0 => new CommandLineParser(null, 0), + 1 => new CommandLineParser(args[0], 0), + 2 => new CommandLineParser(args[0], Convert.ToInt32(args[1])), + _ => ExitOnTooManyArgs() + }; + } + + private static CommandLineParser ExitOnTooManyArgs() + { + WriteLine("Too many command-line arguments; exiting."); + Environment.Exit(Data.MachineState.failureCode[2]); + throw new OperationCanceledException(); + } + } +} \ No newline at end of file diff --git a/px-tcp1/ProtosXExercise/ConsoleSetup.cs b/px-tcp1/ProtosXExercise/ConsoleSetup.cs new file mode 100644 index 0000000..76b030f --- /dev/null +++ b/px-tcp1/ProtosXExercise/ConsoleSetup.cs @@ -0,0 +1,17 @@ +using System; +using static System.Console; + +namespace ProtosXdigitalDemo +{ + internal static class ConsoleSetup + { + public static void ApplyDefaultAppearance() + { + WindowUtility.SetAppearanceOptions(); + WindowUtility.MoveWindowToCenter(); + BackgroundColor = ConsoleColor.DarkBlue; + ForegroundColor = ConsoleColor.White; + Clear(); + } + } +} \ No newline at end of file