mirror of
https://github.com/fasteddy516/SimplySerial.git
synced 2024-11-24 10:04:35 +00:00
auto-(re)connect functionality added
This commit is contained in:
parent
545ed8411d
commit
fa65b51a41
@ -10,12 +10,13 @@ namespace SimplySerial
|
|||||||
{
|
{
|
||||||
class SimplySerial
|
class SimplySerial
|
||||||
{
|
{
|
||||||
enum AutoConnect { NONE, ONE, ANY };
|
static readonly string version = "0.3.0";
|
||||||
|
static List<ComPort> availablePorts;
|
||||||
static SerialPort serialPort;
|
static SerialPort serialPort;
|
||||||
|
|
||||||
|
enum AutoConnect { NONE, ONE, ANY };
|
||||||
|
|
||||||
// default comspec values and application settings set here will be overridden by values passed through command-line arguments
|
// default comspec values and application settings set here will be overridden by values passed through command-line arguments
|
||||||
static readonly string version = "0.2.0";
|
|
||||||
static bool Quiet = false;
|
static bool Quiet = false;
|
||||||
static bool NoWait = false;
|
static bool NoWait = false;
|
||||||
static AutoConnect autoConnect = AutoConnect.ONE;
|
static AutoConnect autoConnect = AutoConnect.ONE;
|
||||||
@ -30,17 +31,17 @@ namespace SimplySerial
|
|||||||
// process all command-line arguments
|
// process all command-line arguments
|
||||||
ProcessArguments(args);
|
ProcessArguments(args);
|
||||||
|
|
||||||
// set up keyboard input for program control and relay to serial port
|
// set up keyboard input for program control / relay to serial port
|
||||||
ConsoleKeyInfo keyInfo = new ConsoleKeyInfo();
|
ConsoleKeyInfo keyInfo = new ConsoleKeyInfo();
|
||||||
Console.TreatControlCAsInput = true; // we need to use CTRL-C to activate the REPL in CircuitPython, so it can't be used to exit the application
|
Console.TreatControlCAsInput = true; // we need to use CTRL-C to activate the REPL in CircuitPython, so it can't be used to exit the application
|
||||||
|
|
||||||
// this is where data read from the serial port will be temporarily stored
|
// this is where data read from the serial port will be temporarily stored
|
||||||
string received = string.Empty;
|
string received = string.Empty;
|
||||||
|
|
||||||
//main loop - keep this up until instructed otherwise
|
//main loop - keep this up until user presses CTRL-X or an exception takes us down
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
// exit the program if CTRL-X was pressed
|
// first things first, check for (and respect) a request to exit the program via CTRL-X
|
||||||
if (Console.KeyAvailable)
|
if (Console.KeyAvailable)
|
||||||
{
|
{
|
||||||
keyInfo = Console.ReadKey(intercept: true);
|
keyInfo = Console.ReadKey(intercept: true);
|
||||||
@ -51,7 +52,59 @@ namespace SimplySerial
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// set up the serial port
|
// get a list of available ports
|
||||||
|
availablePorts = (SimplySerial.GetSerialPorts()).OrderBy(p => p.num).ToList();
|
||||||
|
|
||||||
|
// if no port was specified/selected, pick one automatically
|
||||||
|
if (port.name == String.Empty)
|
||||||
|
{
|
||||||
|
// if there are com ports available, pick one
|
||||||
|
if (availablePorts.Count() >= 1)
|
||||||
|
{
|
||||||
|
// first, try to default to something that we assume is running CircuitPython
|
||||||
|
SimplySerial.port = availablePorts.Find(p => p.board.isCircuitPython == true);
|
||||||
|
|
||||||
|
// if that doesn't work out, just default to the first available COM port
|
||||||
|
if (SimplySerial.port.name == null)
|
||||||
|
SimplySerial.port = availablePorts[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// if there are no com ports available, exit or try again depending on autoconnect setting
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (autoConnect == AutoConnect.NONE)
|
||||||
|
ExitProgram("No COM ports detected.", exitCode: -1);
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if a specific port has been selected, try to match it with one that actually exists
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool portMatched = false;
|
||||||
|
|
||||||
|
foreach (ComPort p in availablePorts)
|
||||||
|
{
|
||||||
|
if (p.name == port.name)
|
||||||
|
{
|
||||||
|
portMatched = true;
|
||||||
|
port = p;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the specified port is not available, exit or try again depending on autoconnect setting
|
||||||
|
if (!portMatched)
|
||||||
|
{
|
||||||
|
if (autoConnect == AutoConnect.NONE)
|
||||||
|
ExitProgram(("Invalid port specified <" + port.name + ">"), exitCode: -1);
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we get this far, it should be safe to set up the specified/selected serial port
|
||||||
serialPort = new SerialPort(port.name, baud, parity, dataBits, stopBits)
|
serialPort = new SerialPort(port.name, baud, parity, dataBits, stopBits)
|
||||||
{
|
{
|
||||||
Handshake = Handshake.None, // we don't need to support any handshaking at this point
|
Handshake = Handshake.None, // we don't need to support any handshaking at this point
|
||||||
@ -61,23 +114,38 @@ namespace SimplySerial
|
|||||||
RtsEnable = true // without this we don't ever receive any data
|
RtsEnable = true // without this we don't ever receive any data
|
||||||
};
|
};
|
||||||
|
|
||||||
// attempt to open the serial port, terminate on error
|
// attempt to open the serial port, deal with failures
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
serialPort.Open();
|
serialPort.Open();
|
||||||
}
|
}
|
||||||
catch (System.UnauthorizedAccessException uae)
|
|
||||||
{
|
|
||||||
Output(uae.GetType() + " occurred while attempting to open " + port.name + ". Is this port already in use in another application?");
|
|
||||||
serialPort.Dispose();
|
|
||||||
Thread.Sleep(1000);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Output(e.GetType() + " occurred while attempting to open " + port.name + ".");
|
// if auto-connect is disabled than any exception should result in program termination
|
||||||
|
if (autoConnect == AutoConnect.NONE)
|
||||||
|
{
|
||||||
|
if (e is UnauthorizedAccessException)
|
||||||
|
ExitProgram((e.GetType() + " occurred while attempting to open " + port.name + ". Is this port already in use in another application?"), exitCode: -1);
|
||||||
|
else
|
||||||
|
ExitProgram((e.GetType() + " occurred while attempting to open " + port.name + "."), exitCode: -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if auto-connect is enabled, prepare to try again
|
||||||
serialPort.Dispose();
|
serialPort.Dispose();
|
||||||
Thread.Sleep(1000);
|
Thread.Sleep(1000); // putting a delay here to avoid gobbling tons of resources thruogh constant high-speed re-connect attempts
|
||||||
|
/*
|
||||||
|
if (autoConnect == AutoConnect.ANY)
|
||||||
|
{
|
||||||
|
port.name = String.Empty;
|
||||||
|
Console.Clear();
|
||||||
|
Output("<<< Attemping to connect to any avaiable COM port. Use CTRL-X to cancel >>>");
|
||||||
|
}
|
||||||
|
else if (autoConnect == AutoConnect.ONE)
|
||||||
|
{
|
||||||
|
Console.Clear();
|
||||||
|
Output("<<< Attempting to re-connect to " + port.name + ". Use CTRL-X to cancel >>>");
|
||||||
|
}
|
||||||
|
*/
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,16 +218,30 @@ namespace SimplySerial
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Output(e.GetType() + " occurred while attempting to read/write to/from " + port.name + ".");
|
if (autoConnect == AutoConnect.NONE)
|
||||||
|
ExitProgram((e.GetType() + " occurred while attempting to read/write to/from " + port.name + "."), exitCode: -1);
|
||||||
|
else
|
||||||
|
Output("\n<<< Communications Interrupted >>>\n");
|
||||||
serialPort.Dispose();
|
serialPort.Dispose();
|
||||||
Thread.Sleep(1000);
|
Thread.Sleep(2000); // sort-of arbitrary delay - should be long enough to read the "interrupted" message
|
||||||
|
Console.Clear();
|
||||||
|
if (autoConnect == AutoConnect.ANY)
|
||||||
|
{
|
||||||
|
port.name = String.Empty;
|
||||||
|
Output("<<< Attemping to connect to any avaiable COM port. Use CTRL-X to cancel >>>");
|
||||||
|
}
|
||||||
|
else if (autoConnect == AutoConnect.ONE)
|
||||||
|
{
|
||||||
|
Console.Clear();
|
||||||
|
Output("<<< Attempting to re-connect to " + port.name + ". Use CTRL-X to cancel >>>");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (autoConnect > AutoConnect.NONE);
|
} while (autoConnect > AutoConnect.NONE);
|
||||||
|
|
||||||
// the program should have ended gracefully before now - there is no good reason for us to be here!
|
// if we get to this point, we should be exiting gracefully
|
||||||
ExitProgram("<<< SimplySerial session terminated >>>", exitCode: -1);
|
ExitProgram("<<< SimplySerial session terminated >>>", exitCode: 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -169,12 +251,6 @@ namespace SimplySerial
|
|||||||
/// <param name="args">Command-line parameters</param>
|
/// <param name="args">Command-line parameters</param>
|
||||||
static void ProcessArguments(string[] args)
|
static void ProcessArguments(string[] args)
|
||||||
{
|
{
|
||||||
// get a list of all available ports
|
|
||||||
List<ComPort> availablePorts = (SimplySerial.GetSerialPorts()).OrderBy(p => p.num).ToList();
|
|
||||||
//List<ComPort> availablePorts = SimplySerial.GetSerialPorts();
|
|
||||||
//availablePorts = (availablePorts.OrderBy(p => p.board.pid)).ToList();
|
|
||||||
|
|
||||||
// set default port information
|
|
||||||
port.name = String.Empty;
|
port.name = String.Empty;
|
||||||
|
|
||||||
// switch to lower case and remove '/', '--' and '-' from beginning of arguments - we can process correctly without them
|
// switch to lower case and remove '/', '--' and '-' from beginning of arguments - we can process correctly without them
|
||||||
@ -200,6 +276,9 @@ namespace SimplySerial
|
|||||||
// list available ports
|
// list available ports
|
||||||
else if (argument[0].StartsWith("l"))
|
else if (argument[0].StartsWith("l"))
|
||||||
{
|
{
|
||||||
|
// get a list of all available ports
|
||||||
|
availablePorts = (SimplySerial.GetSerialPorts()).OrderBy(p => p.num).ToList();
|
||||||
|
|
||||||
if (availablePorts.Count >= 1)
|
if (availablePorts.Count >= 1)
|
||||||
{
|
{
|
||||||
Console.WriteLine("\nPORT\tVID\tPID\tDESCRIPTION");
|
Console.WriteLine("\nPORT\tVID\tPID\tDESCRIPTION");
|
||||||
@ -327,38 +406,18 @@ namespace SimplySerial
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if no port was specified, default to the first/only available com port, exit with error if no ports are available
|
Console.Clear();
|
||||||
if (port.name == String.Empty)
|
if (autoConnect == AutoConnect.ANY)
|
||||||
{
|
{
|
||||||
if (availablePorts.Count() >= 1)
|
Output("<<< Attemping to connect to any avaiable COM port. Use CTRL-X to cancel >>>");
|
||||||
{
|
|
||||||
// first, try to default to something that we assume is running CircuitPython
|
|
||||||
SimplySerial.port = availablePorts.Find(p => p.board.isCircuitPython == true);
|
|
||||||
|
|
||||||
// if that doesn't work out, just default to the first available COM port
|
|
||||||
if (SimplySerial.port.name == null)
|
|
||||||
SimplySerial.port = availablePorts[0];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ExitProgram("No COM ports detected.", exitCode: -1);
|
|
||||||
}
|
}
|
||||||
|
else if (autoConnect == AutoConnect.ONE)
|
||||||
// if a port name was specified, try to match it with one that actually exists and fail if it doesn't
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
bool portMatched = false;
|
Console.Clear();
|
||||||
|
if (port.name == String.Empty)
|
||||||
foreach (ComPort p in availablePorts)
|
Output("<<< Attempting to connect to first available COM port. Use CTRL-X to cancel >>>");
|
||||||
{
|
else
|
||||||
if (p.name == port.name)
|
Output("<<< Attempting to connect to " + port.name + ". Use CTRL-X to concel >>>");
|
||||||
{
|
|
||||||
portMatched = true;
|
|
||||||
port = p;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!portMatched)
|
|
||||||
ExitProgram(("Invalid port specified <" + port.name + ">"), exitCode: -1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we made it this far, everything has been processed and we're ready to proceed!
|
// if we made it this far, everything has been processed and we're ready to proceed!
|
||||||
|
Loading…
Reference in New Issue
Block a user