Странное поведение при получении последовательных выходов от Arduino - PullRequest
1 голос
/ 07 марта 2020

Я сделал скрипт 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 я получаю хорошее поведение:

enter image description here

Но при использовании моего консольного приложения я иногда получаю пустые строки :

enter image description here

Есть идеи как его улучшить?

1 Ответ

0 голосов
/ 08 марта 2020

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 чтобы быть уверенным, что я получил всю строку перед печатью.

...