Написал программу на микроконтроллере которая в порт посылает данные(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);
}
}
В чем может быть проблема?
Проблема со странным выводом в данном случае связана с символом '\r', он же NEWLINE в рассматриваемом коде (что, кстати, запутывает, потому что обычно перенос строки — это всё-таки 10, а не 13).
Когда '\r' выводится в консоль — это переносит курсор в начало текущей строки. Поэтому в некоторых строчках вывода программы мы наблюдаем наложение нескольких строк из пакета, и они выглядят странно, как ?888d: 1337.
Шагом к исправлению проблемы будет замена Console.WriteLine(package) на Console.WriteLine(package.Replace("\r", "\n")). А ещё лучше на Console.Write(package.Replace("\r", "\n")), чтобы пакеты перестали иногда разрубаться в середине строки.
Принятые данные нужно складывать в одну строку - буфер.
Когда в буфере появился CR (NEW_LINE) - скопировать всё до него и вывести в нужном формате.
Удалить начало буфера, включая CR
P.S. DataChanged?.Invoke( обеспечивает синхронизацию обработчика события, которое выполняется в отдельном потоке, и Port_DataChanged?
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости