如何获取RS232串口与本地笔记本电脑之间的历史命令?
How to have command history between RS232 Serial Port and local laptop?
我正在开发 C# Console app
来与 SAS 扩展卡上的固件交互。
卡已通过 RS232
端口连接。
我已经发送了命令并在控制台应用程序上得到了结果。
现在我想要一个记录命令的功能
当我使用PuTTY
发送命令时,
我发现当我按下 UpArrow
键时,它会显示最后一条命令。
这是PuTTY
的结果:
按下前UpArrow Key
→
按下后UpArrow Key
→
这是我的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;
using System.IO.Ports;
using System.Threading;
namespace ConsoleApp3
{
class Program
{
[STAThread]
static void Main()
{
SerialPort mySerialPort = new SerialPort("COM5");
mySerialPort.BaudRate = 115200;
mySerialPort.Parity = Parity.None;
mySerialPort.StopBits = StopBits.One;
mySerialPort.DataBits = 8;
mySerialPort.Handshake = Handshake.None;
mySerialPort.RtsEnable = true;
mySerialPort.DtrEnable = true;
mySerialPort.ReadTimeout = 2000;
mySerialPort.WriteTimeout = 1500;
mySerialPort.Open();
if (mySerialPort.IsOpen)
{
mySerialPort.Write("\r");
}
mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
while (true)
{
if (Console.KeyAvailable)
{
ConsoleKeyInfo userResponse = Console.ReadKey(true);
List<string> Command = new List<string>();
if (userResponse.KeyChar.ToString() == "s")
{
Command.Add("s");
mySerialPort.Write("s");
}
else if (userResponse.KeyChar.ToString() == "y")
{
Command.Add("y");
mySerialPort.Write("y");
}
else if (userResponse.Key == ConsoleKey.UpArrow)
{
for (int i = 0; i < Command.Count; i++)
{
Console.WriteLine(Command[i]);
}
Console.ReadLine();
Command.Clear();
}
else
{
mySerialPort.Write("\r");
}
}
}
}
private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string indata = sp.ReadExisting();
Console.Write(indata);
}
}
}
代码的结果是什么:
当我按UpArrow
键两次时,应用程序显示两个space进入。
那是图片中的第二个 bp1>
。
图片看起来像:
我按下enter
键后,又出现了bp1>
我开始发送 sys
命令,它没有得到响应,但出现 space 进入。
在我再次按下 Enter
和 UpArrow
键后,sys
命令出现。
我的代码有什么问题?
还有其他改进方法吗?
我的控制台应用程序正在使用 .Net Framework 4.7.2
。
更好的方法是使用mono/LineEditor,kunif在评论中怎么说的。另一种方式是这样的:
using System;
using System.Collections.Generic;
using System.IO.Ports;
namespace ConsoleApp3
{
class Program
{
static void Main()
{
SerialPort mySerialPort = new SerialPort("COM5");
mySerialPort.BaudRate = 115200;
mySerialPort.Parity = Parity.None;
mySerialPort.StopBits = StopBits.One;
mySerialPort.DataBits = 8;
mySerialPort.Handshake = Handshake.None;
mySerialPort.RtsEnable = true;
mySerialPort.DtrEnable = true;
mySerialPort.ReadTimeout = 2000;
mySerialPort.WriteTimeout = 1500;
// mySerialPort.NewLine = "\r"; // implement this if you use "string indata = sp.ReadLine();" in event handler
mySerialPort.Open();
//if (mySerialPort.IsOpen)
//{
// mySerialPort.Write("\r");
//}
List<string> Commands = new List<string>();
string command = "";
int counter = 0;
//mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
while (true)
{
ConsoleKeyInfo consoleInput = Console.ReadKey();
if (consoleInput.KeyChar == '\r')
{
Commands.Add(command);
counter = Commands.Count - 1;
//mySerialPort.Write(command + "\r");
ClearCurrentConsoleLine();
command = "";
}
else if (consoleInput.Key == ConsoleKey.UpArrow)
{
if ((counter >= 0) && (counter < Commands.Count))
{
ClearCurrentConsoleLine();
Console.Write(Commands[counter]);
}
if (counter > 0)
{
counter--;
}
else
{
counter = Commands.Count - 1;
}
}
else
{
command += consoleInput.KeyChar.ToString();
}
}
}
private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string indata = sp.ReadExisting(); // it might be better to use --> string indata = sp.ReadLine();
Console.Write(indata);
}
private static void ClearCurrentConsoleLine()
{
int currentLineCursor = Console.CursorTop;
Console.SetCursorPosition(0, Console.CursorTop);
Console.Write(new string(' ', Console.WindowWidth));
Console.SetCursorPosition(0, currentLineCursor);
}
}
}
我在没有串行通信的情况下测试了代码。如果您清除我的评论,串行通信应该可以正常工作。
我正在开发 C# Console app
来与 SAS 扩展卡上的固件交互。
卡已通过 RS232
端口连接。
我已经发送了命令并在控制台应用程序上得到了结果。
现在我想要一个记录命令的功能
当我使用PuTTY
发送命令时,
我发现当我按下 UpArrow
键时,它会显示最后一条命令。
这是PuTTY
的结果:
按下前UpArrow Key
→
按下后UpArrow Key
→
这是我的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;
using System.IO.Ports;
using System.Threading;
namespace ConsoleApp3
{
class Program
{
[STAThread]
static void Main()
{
SerialPort mySerialPort = new SerialPort("COM5");
mySerialPort.BaudRate = 115200;
mySerialPort.Parity = Parity.None;
mySerialPort.StopBits = StopBits.One;
mySerialPort.DataBits = 8;
mySerialPort.Handshake = Handshake.None;
mySerialPort.RtsEnable = true;
mySerialPort.DtrEnable = true;
mySerialPort.ReadTimeout = 2000;
mySerialPort.WriteTimeout = 1500;
mySerialPort.Open();
if (mySerialPort.IsOpen)
{
mySerialPort.Write("\r");
}
mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
while (true)
{
if (Console.KeyAvailable)
{
ConsoleKeyInfo userResponse = Console.ReadKey(true);
List<string> Command = new List<string>();
if (userResponse.KeyChar.ToString() == "s")
{
Command.Add("s");
mySerialPort.Write("s");
}
else if (userResponse.KeyChar.ToString() == "y")
{
Command.Add("y");
mySerialPort.Write("y");
}
else if (userResponse.Key == ConsoleKey.UpArrow)
{
for (int i = 0; i < Command.Count; i++)
{
Console.WriteLine(Command[i]);
}
Console.ReadLine();
Command.Clear();
}
else
{
mySerialPort.Write("\r");
}
}
}
}
private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string indata = sp.ReadExisting();
Console.Write(indata);
}
}
}
代码的结果是什么:
当我按UpArrow
键两次时,应用程序显示两个space进入。
那是图片中的第二个 bp1>
。
图片看起来像:
我按下enter
键后,又出现了bp1>
我开始发送 sys
命令,它没有得到响应,但出现 space 进入。
在我再次按下 Enter
和 UpArrow
键后,sys
命令出现。
我的代码有什么问题?
还有其他改进方法吗?
我的控制台应用程序正在使用 .Net Framework 4.7.2
。
更好的方法是使用mono/LineEditor,kunif在评论中怎么说的。另一种方式是这样的:
using System;
using System.Collections.Generic;
using System.IO.Ports;
namespace ConsoleApp3
{
class Program
{
static void Main()
{
SerialPort mySerialPort = new SerialPort("COM5");
mySerialPort.BaudRate = 115200;
mySerialPort.Parity = Parity.None;
mySerialPort.StopBits = StopBits.One;
mySerialPort.DataBits = 8;
mySerialPort.Handshake = Handshake.None;
mySerialPort.RtsEnable = true;
mySerialPort.DtrEnable = true;
mySerialPort.ReadTimeout = 2000;
mySerialPort.WriteTimeout = 1500;
// mySerialPort.NewLine = "\r"; // implement this if you use "string indata = sp.ReadLine();" in event handler
mySerialPort.Open();
//if (mySerialPort.IsOpen)
//{
// mySerialPort.Write("\r");
//}
List<string> Commands = new List<string>();
string command = "";
int counter = 0;
//mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
while (true)
{
ConsoleKeyInfo consoleInput = Console.ReadKey();
if (consoleInput.KeyChar == '\r')
{
Commands.Add(command);
counter = Commands.Count - 1;
//mySerialPort.Write(command + "\r");
ClearCurrentConsoleLine();
command = "";
}
else if (consoleInput.Key == ConsoleKey.UpArrow)
{
if ((counter >= 0) && (counter < Commands.Count))
{
ClearCurrentConsoleLine();
Console.Write(Commands[counter]);
}
if (counter > 0)
{
counter--;
}
else
{
counter = Commands.Count - 1;
}
}
else
{
command += consoleInput.KeyChar.ToString();
}
}
}
private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string indata = sp.ReadExisting(); // it might be better to use --> string indata = sp.ReadLine();
Console.Write(indata);
}
private static void ClearCurrentConsoleLine()
{
int currentLineCursor = Console.CursorTop;
Console.SetCursorPosition(0, Console.CursorTop);
Console.Write(new string(' ', Console.WindowWidth));
Console.SetCursorPosition(0, currentLineCursor);
}
}
}
我在没有串行通信的情况下测试了代码。如果您清除我的评论,串行通信应该可以正常工作。