从 arduino 获取串行输出的奇怪行为
Strange behavior on getting serial outputs from arduino
我制作了一个 Arduino 脚本,用于在按下按钮时打印按键:
#include <Keypad.h>
//Buttons
const byte ROWS = 2;
const byte COLS = 2;
char keys[ROWS][COLS] = {
{'1','2'},
{'3','4'}
};
byte rowPins[ROWS] = {A0, A1};
byte colPins[COLS] = {30, 31};
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
void setup() {
Serial.begin(9600);
keypad.addEventListener(keypadEvent);
}
void loop() {
char key = keypad.getKey();
}
void keypadEvent(KeypadEvent key){
switch (keypad.getState()){
case PRESSED:
Serial.println(key);
break;
default:
break;
}
}
然后,我制作了一个 C# 代码,用于在调试控制台中打印它(在继续之前进行测试):
using System;
using System.Diagnostics;
using System.IO.Ports;
namespace ConsoleApplication1
{
class Program
{
public static void Main()
{
SerialPort SP = new SerialPort("COM3");
SP.BaudRate = 9600;
SP.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
SP.Open();
Console.WriteLine("Press any key to continue...");
Console.WriteLine();
Console.ReadKey();
SP.Close();
}
private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
SerialPort SP = (SerialPort)sender;
string msg = SP.ReadExisting();
Debug.Print($"Data Received: {msg}");
}
}
}
当使用 Arduino 的串行监视器时,我得到了良好的行为:
但是在使用我的控制台应用程序时,有时会出现空行:
关于如何改进它有什么想法吗?
Jasc24 让我上路了。
SerialPort.ReadExisting() 读取一个可能未完成的流,并且 SerialDataReceivedEventHandler 可以为一行触发多次。
我的解决方法如下:
class Program
{
static string line = string.Empty;
public static void Main()
{
SerialPort SP = new SerialPort("COM3");
SP.BaudRate = 9600;
SP.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
SP.Open();
Console.WriteLine("Press any key to continue...");
Console.WriteLine();
Console.ReadKey();
SP.Close();
}
private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
SerialPort SP = (SerialPort)sender;
line = $"{line}{SP.ReadExisting()}";
if (line.Contains(Environment.NewLine))
{
line = line.Replace(Environment.NewLine, string.Empty);
Debug.Print($"Data Received: {line}");
line = string.Empty;
}
}
}
等待 EOL 字符以确保在打印之前我得到了所有行。
我制作了一个 Arduino 脚本,用于在按下按钮时打印按键:
#include <Keypad.h>
//Buttons
const byte ROWS = 2;
const byte COLS = 2;
char keys[ROWS][COLS] = {
{'1','2'},
{'3','4'}
};
byte rowPins[ROWS] = {A0, A1};
byte colPins[COLS] = {30, 31};
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
void setup() {
Serial.begin(9600);
keypad.addEventListener(keypadEvent);
}
void loop() {
char key = keypad.getKey();
}
void keypadEvent(KeypadEvent key){
switch (keypad.getState()){
case PRESSED:
Serial.println(key);
break;
default:
break;
}
}
然后,我制作了一个 C# 代码,用于在调试控制台中打印它(在继续之前进行测试):
using System;
using System.Diagnostics;
using System.IO.Ports;
namespace ConsoleApplication1
{
class Program
{
public static void Main()
{
SerialPort SP = new SerialPort("COM3");
SP.BaudRate = 9600;
SP.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
SP.Open();
Console.WriteLine("Press any key to continue...");
Console.WriteLine();
Console.ReadKey();
SP.Close();
}
private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
SerialPort SP = (SerialPort)sender;
string msg = SP.ReadExisting();
Debug.Print($"Data Received: {msg}");
}
}
}
当使用 Arduino 的串行监视器时,我得到了良好的行为:
但是在使用我的控制台应用程序时,有时会出现空行:
关于如何改进它有什么想法吗?
Jasc24 让我上路了。 SerialPort.ReadExisting() 读取一个可能未完成的流,并且 SerialDataReceivedEventHandler 可以为一行触发多次。
我的解决方法如下:
class Program
{
static string line = string.Empty;
public static void Main()
{
SerialPort SP = new SerialPort("COM3");
SP.BaudRate = 9600;
SP.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
SP.Open();
Console.WriteLine("Press any key to continue...");
Console.WriteLine();
Console.ReadKey();
SP.Close();
}
private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
SerialPort SP = (SerialPort)sender;
line = $"{line}{SP.ReadExisting()}";
if (line.Contains(Environment.NewLine))
{
line = line.Replace(Environment.NewLine, string.Empty);
Debug.Print($"Data Received: {line}");
line = string.Empty;
}
}
}
等待 EOL 字符以确保在打印之前我得到了所有行。