我正在构建一个控制台应用程序,该应用程序将在Windows的任务计划程序中安排,以便在设定的每小时每天运行我的代码。总而言之,此应用程序将通过SerialPort
进行读写。当我向Arduino发送内容时,我需要从中收到一些内容以完成我发送的内容并执行命令。
换句话说,我会发送一些东西,看看门是否打开,如果是应用程序将运行代码关闭它。如果门已关闭,我将发送一串字符显示在Arduino Led Display中。
所以我开发了一个代码,但我不确定它是否完全正确,如果有可能帮助我改进它。我可以做出任何改变吗?
static void Main(string[] args)
{
SerialPort comport = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
comport.Open();
string start = "?";
string carriageReturn = "\r";
string text = string.Empty;
string mensage = "@" + "r" + "\r";
string mensage2 = "@" + "{" + texto + "\r";
try
{
while (true)
{
//Send to the Arduino
comport.Write(start+ "*" + carriageReturn);
//If the serial port have bytes to read
if (comport.BytesToRead > 0)
{
//Buffer with data
byte[] dados = HexStringToByteArray(mensage);
//Handle data
comport.Read(dados, 0, dados.Length);
//Send again to execute the the command
comport.Write(start + "*" + carriageReturn);
}
if (comport.BytesToRead > 0)
{
comport.Write(start + "*" + carriageReturn);
byte[] dados2 = HexStringToByteArray(mensage2);
comport.Read(dados2, 0, dados2.Length);
comport.Write(text);
}
comport.Close();
}
}
catch(Exception ex)
{
}
}
private static byte[] HexStringToByteArray(string s)
{
s = s.Replace(" ", "");
byte[] buffer = new byte[s.Length / 2];
for (int i = 0; i < s.Length; i += 2)
buffer[i / 2] = (byte)Convert.ToByte(s.Substring(i, 2), 16);
return buffer;
}
修改
我的基本输入输出映射/关系是:
我会将?*\r
发送给Arduino,然后我会等待回答。
如果,Arduino的答案为@r\r
,我会再次发送?*\r
。
如果来自Arduino的回答是@{/r
我将向他发送一个字符串。
答案 0 :(得分:0)
这是我修改的第一次尝试。
您应该考虑使用DataReceived
事件并使用退出策略。到目前为止,您的程序永远不会退出。
static void Main(string[] args)
{
SerialPort port = new SerialPort("COM1", 9600, Parity.Odd, 7, StopBits.One);
// register the event
port.DataReceived += Port_DataReceived;
//open the port
port.Open();
try
{
// start the communication
port.Write("?*\r");
Console.WriteLine("Waiting for response");
// Your manual exit strategy. Hit a kKeyboard-key to end this game
while (!Console.KeyAvailable)
{
}
}
catch (Exception ex)
{
Console.WriteLine("Writing failed! \nError: " + ex.Message);
}
}
一旦Arduino发送给你,DataReceived
事件就会被解雇。如果没有,您可以手动退出程序。
在活动中你可以完成整个逻辑。正如您已经发布了输入输出映射,您可以将其破解为固定代码,因为它是在您的帖子中编写的。如果仅有两种情况,您也可以使用开关/案例构造:
private static void Port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
SerialPort port = sender as SerialPort;
// read input
string incoming = port.ReadExisting();
switch (incoming)
{
case "@r\r":
// send the message back
port.Write("?*\r");
break;
case @"@{/r":
port.Write("Display this!");
break;
default:
Console.WriteLine("Unknown command from Arduino!\n Command: " + incoming);
break;
}
}
我希望它有所帮助
答案 1 :(得分:0)
如果我理解你的描述(关闭门将由arduino完成,对吧?),这就是任务:
你可以这么做:
"?" --> PC sends a trigger: Check door status and behave accordingly
然后PC等待回复:
"1" <-- Arduino response ( door was already closed )
"2" <-- or alternate response ( I closed the door )
Arduino可以发送任何其他内容来表示错误。 (随意发明就足够了)
此外,arduino可能根本没有回应。那么你的预定控制台应用程序会做什么呢?
您不需要发送/接收超过一个字节,以使Arduino和您的小型串行PC代码更简单。
PC代码没有用户界面,所以Arduino不需要立即响应,如果关闭门需要一段时间。