Чтение данных из COM порта C# .Net

147
23 февраля 2019, 19:00

Написал программу на микроконтроллере которая в порт посылает данные(4 константных значения типа int) через функцию sprintf, sprintf переводит интовое число в строку. Строка состоит из байт символов ascii которые отсылает usart.

printf("+------- Pakage sending --------+");
sprintf(altitude,"alt: %d", ALT);
/* Send data to USART; */
timerDelayMs(300);
send_Uart_str(altitude);
send_Uart(NEW_LINE);
/* и тд. */

Открываю терминал и получаю следующую картину:

NEW_LINE - это символ каретки в ASCII = 13;

На стороне ПК мне необходимо каждую строку записывать в отдельный буфер или переменные. Вот не могу понять как по каретке разделить. Набросал примитивное консольное приложение. Пока читаю по событию все содержимое из порта, но при рендеринге в консоли то же проблема:

Хотя при отладке в мониторе данные приходят нормальные, не битые. Собственно класс порта:

 public class CustomSerialPort : SerialPort
{
    public event DataRecievedEventHandler DataChanged;
    public delegate void DataRecievedEventHandler(object sender, string package);
    public CustomSerialPort(string port)
        : base()
    {
        //base.PortName = COM1;
        base.BaudRate = 38400;
        base.DataBits = 8;
        base.StopBits = StopBits.One;
        base.Parity = Parity.None;
        base.ReadTimeout = 300;
        base.DataReceived += CustomSerialPort_DataReceived; ;
    }
    public void Open(string portName)
    {
        if (base.IsOpen)
        {
            base.Close();
        }
        base.PortName = portName;
        base.Open();
    }
    private void CustomSerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        var port = (SerialPort) sender;
        try
        {
            DataChanged?.Invoke(sender, port.ReadExisting());
        }
        catch (Exception exception)
        {
            Debug.WriteLine(exception);
        }
    }
}

Основная программа:

 class Program
   {
    static void Main(string[] args)
    {
        var port = new CustomSerialPort("COM3");
        port.Open("COM3");
        port.DataChanged += Port_DataChanged;
        Console.ReadKey();
    }
    private static void Port_DataChanged(object sender, string package)
    {
        Console.WriteLine(package);
    }
}

В чем может быть проблема?

Answer 1

Проблема со странным выводом в данном случае связана с символом '\r', он же NEWLINE в рассматриваемом коде (что, кстати, запутывает, потому что обычно перенос строки — это всё-таки 10, а не 13).

Когда '\r' выводится в консоль — это переносит курсор в начало текущей строки. Поэтому в некоторых строчках вывода программы мы наблюдаем наложение нескольких строк из пакета, и они выглядят странно, как ?888d: 1337.

Шагом к исправлению проблемы будет замена Console.WriteLine(package) на Console.WriteLine(package.Replace("\r", "\n")). А ещё лучше на Console.Write(package.Replace("\r", "\n")), чтобы пакеты перестали иногда разрубаться в середине строки.

Answer 2

Принятые данные нужно складывать в одну строку - буфер.
Когда в буфере появился CR (NEW_LINE) - скопировать всё до него и вывести в нужном формате.
Удалить начало буфера, включая CR

P.S. DataChanged?.Invoke( обеспечивает синхронизацию обработчика события, которое выполняется в отдельном потоке, и Port_DataChanged?

READ ALSO
Как перевести текст HTML-страницы?

Как перевести текст HTML-страницы?

Приложение выполняет парсинг HTML страницыHTML страница имеет текст, картинки, таблицы и другое содержание

163
symfony 3 вывод в форму ChoiceType (select) из базы данных

symfony 3 вывод в форму ChoiceType (select) из базы данных

Помогите, пожалуйстаДелаю скрипт, в котором можно добавлять пользователя, каждый пользователь имеет свою должность (таблица в базе positions)

170
Вывод вложенных списков из БД с помощью PHP

Вывод вложенных списков из БД с помощью PHP

Подскажите, пожалуйста, как можно решить следующую задачуЕсть таблица Категории товаров

174
Opencart, ocmod, как заменить несколько строк?

Opencart, ocmod, как заменить несколько строк?

Допустим есть такой код в файле theme/default/common/headerphp:

198