Answer the question
In order to leave comments, you need to log in
C# com-port getting information, processing start-bit, stop-bit?
Good afternoon!
I ask for help in understanding, and maybe in resolving the issue that interests me.
First, I will outline the essence of the task set before me, I will immediately warn you that in programming I am, so to speak, very young and this is to some extent my first project that I want to implement on the visual studio platform.
Task:
There is a certain device that connects to a computer via RS-485 and transmits data at 38400 bps , the device can transmit packets with a resolution of 25 Hz or 50 Hz .
The command-information packet transmitted by the device consists of 6 blocks , at the beginning of each packet, the packet start marker "0xFF, 0xFF" is transmitted, then there are 6 blocks of data at the end of the packet, a 2-byte field is transmitted . At the end there is a parity bit (formed when performing the "Exclusive OR" operation, an even number of logical units in a byte must correspond to the parity bit 0) and 2 stop bits.
- The length of one packet is 52 bytes.
— Pause time between two packets is no more than 2 bits.
Characteristics of the data block:
— Length of the block is 8 bytes.
— Further 4 values on 2 bytes
Actually a question which interests me: how it is all correct to organize.
First of all, I rushed to look for how to work with the COM port, I came across a namespace:
using System.IO;
using System.IO.Ports;
private void Form1_Load(object sender, EventArgs e)
{
//чтение портов доступных в системе
string[] ports = SerialPort.GetPortNames();
//Очистка содержимого бокса
comboBox1.Items.Clear();
//Добавление найденных портов в бокс
comboBox1.Items.AddRange(ports);
}
private void button1_Click(object sender, EventArgs e)
{
//выбранный порт
Object selectedItem = comboBox1.SelectedItem;
//Создаю объект port1 с параметрами.
//selectedItem.ToString() - порт к которому подключено устройство.
//9600 скорость передачи данных в порт, как я понял 9600 бод - 38400 бит/сек.
//Parity.None бит четности установил в отсутствие так как пока не сильно понимаю что с ним делать об этом далее.
//416 бит данных т.е. 8*52 = 416.
//один стоп бит
SerialPort port1 = new SerialPort(selectedItem.ToString(), 9600, Parity.None, 416, StopBits.One);
//Открываю порт.
port1.Open();
//тут я писал разного рода код для вывода полученных данных в текстовое поле но получал один бред.
}
private void button1_Click(object sender, EventArgs e)
{
Object selectedItem = comboBox1.SelectedItem;
SerialPort port1 = new SerialPort(selectedItem.ToString(), 9600, Parity.None, 416, StopBits.One);
port1.Open();
//создаю массив размером 52 т.е на запись 52 байт переданного с устройства пакетов
byte[] data1 = new byte[52];
//Ну и запускаю команду чтения в массив data1
port.Read(data1, 0, data1.Length);
int databyte = port.ReadByte();
}
Answer the question
In order to leave comments, you need to log in
If I understand your question correctly, then your device sends data all the time and you only need to read.
All you need is to create a port connection and subscribe to the update event. When an event occurs, you will receive an array of data from the port, you save this array to a buffer or parse it on the fly (as you prefer). I'll write a small example for you:
// Наследуем наш клас от SerialPort для более красивого кода
public class MySerialPort : SerialPort
{
private const int DataSize = 54; // я так и не понял, какой размер данных нужен. Укажите правильное число в байтах
private readonly byte[] _bufer = new byte[DataSize];
private int _stepIndex;
private bool _startRead;
public MySerialPort(string port)
: base()
{
// все папаметры вы должны указать в соответствии с вашим устройством
//base.PortName = COM1;
base.BaudRate = 115200;
base.DataBits = 8;
base.StopBits = StopBits.Two;
base.Parity = Parity.None;
base.ReadTimeout = 1000;
// тут подписываемся на событие прихода данных в порт
// для вашей задачи это должно подойт идеально
base.DataReceived += SerialPort_DataReceived;
}
// открываем порт передав туда имя
public void Open(string portName)
{
if (base.IsOpen)
{
base.Close();
}
base.PortName = portName;
base.Open();
}
// эта функция вызвется каждый раз, когда в порт чтото будет передано от вашего устройства
void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
var port = (SerialPort)sender;
try
{
// узнаем сколько байт пришло
int buferSize = port.BytesToRead;
for (int i = 0; i < buferSize; ++i)
{
// читаем по одному байту
byte bt = (byte)port.ReadByte();
// если встретили начало кадра (0xFF) - начинаем запись в _bufer
if (0xFF == bt)
{
_stepIndex = 0;
_startRead = true;
// раскоментировать если надо сохранять этот байт
//_bufer[_stepIndex] = bt;
//++_stepIndex;
}
// дописываем в буфер все остальное
if (_startRead)
{
_bufer[_stepIndex] = bt;
++_stepIndex;
}
// когда буфер наполнлся данными
if (_stepIndex == DataSize && _startRead)
{
// по идее тут должны быть все ваши данные.
// .. что то делаем ...
// var item = _bufer[7];
_startRead = false;
}
}
}
catch {}
}
}
var port = new MySerialPort();
port.Open("COM5");
Read from the port until there is a start-of-packet marker. After that, read 52 bytes, check the sum and process. It's not gonna go?
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question