A
A
Albert2015-03-10 00:44:39
Programming
Albert, 2015-03-10 00:44:39

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;

Well, first of all, like the wise Vasya, I determine the available ports in the system and display them in the combobox.
private void Form1_Load(object sender, EventArgs e)
        {
            //чтение портов доступных в системе
            string[] ports = SerialPort.GetPortNames();
            //Очистка содержимого бокса
            comboBox1.Items.Clear();
            //Добавление найденных портов в бокс
            comboBox1.Items.AddRange(ports);
        }

Further, on the start button, I start reading the data coming from the device itself. This is where the dense forest begins for me.
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();
//тут я писал разного рода код для вывода полученных данных в текстовое поле но получал один бред.
        }

Now the question is:
As I understand this problem, the data transmitted by the device is written to the port, and I need to read them.
How can I wait until the beginning of the "0xFF,0xFF" packet so that after that I can receive the rest of the packet, or should the reception be started after receiving the end of the previous packet?
If someone has similar codes for processing waiting for the beginning or end of packets and there is no desire to explain, please throw off sections of the code and I will figure it out myself.
After the correct start of receiving packets, I need to sort them, I didn’t find anything better than putting the received packet into a byte sequence variable, more precisely, this can be said the only thing that settled down in my head.
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();
        }

But some kind of heresy comes to me ...
Do I understand this process of reading from the com-port correctly?
Please kick, poke, give a bream or help in solving this task to anyone as you like.
Who knows what to read specifically on this issue, where it is written or there are similar solutions, please throw off to read in order to better understand.
As long as it's like that. I would be grateful for any help, hint, piece of code.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
V
vitvov, 2015-03-10
@6ETuK

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 {}
        }
}

you need to use it like this:
var port = new MySerialPort();
port.Open("COM5");

This is prototype code, just a technique to help you.

V
Vladimir Martyanov, 2015-03-10
@vilgeforce

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 question

Ask a Question

731 491 924 answers to any question