Задать вопрос
@d_vorozhbit
Студент

Как принять массив hex и вывести в textbox?

На микроконтроллер посылаю посылку вида byte [] writestring = {0x10, 0x03, 0x00, 0x04, 0x00, 0x04, 0x06, 0x89}
Должен принять ответ и вывести в текст бокс, ответ должен быть следующим 10 03 08 14 00 3D 00 66 00 8F 00 BB 4.

Проблема в следующем, иногда ответ приходит корректный, а иногда в ответную посылку замешиваются непонятные нули. Т.е. иногда ответ нормальный приходит, иногда нет. Зависимости не нашел, думаю может это из-за конвертации. Подскажите пожалуйста, из-за чего это может быть.
<code lang="cs">
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.Threading;
using System.IO;
using System.Xml;
using System.Xml.Linq;

namespace Terminal
{
    public partial class Form1 : Form
    {

        int date;
        delegate void SetTextCallback(string text);

        public Form1()

        {
            InitializeComponent();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            serialPort1.DiscardInBuffer();
            serialPort1.DiscardOutBuffer();

            byte[] writestring = { 0x10, 0x03, 0x00, 0x04, 0x00, 0x04, 0x06, 0x89 };

            try
            {
                serialPort1.Write(writestring, 0, writestring.Length);
                textBox2.Clear();
            }
            catch (TimeoutException)
            {
            }
        }
        private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
        byte[] readstring = new byte[13];
        serialPort1.Read(readstring, 0, readstring.Length);
        string stringMessage = BitConverter.ToString(readstring);
        textBox1.AppendText(stringMessage + "\r\n\r\n");
    }
       }
        }    
</code>
<img src="https://habrastorage.org/files/f45/753/449/f45753449924495db9a2267f4ff5a292.JPG" alt="image"/>
  • Вопрос задан
  • 1559 просмотров
Подписаться 1 Оценить Комментировать
Решения вопроса 1
@dark_Kelvin
Событие DataReceived возникает в момент опроса порта (которое вероятно происходит каждый тик), если в буфере есть данные. Данные же в буфер пишутся асинхронно (по мере поступления).
Поэтому, когда возникает событие DataReceived, в буфер могут ещё не успеть записаться все байты, для решения этой проблемы я делал так:
Класс "ComPort" http://pastie.org/10814442
private void ComPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            byte[] inBuf = new byte[256];
            int rxCount = _comPort.Read(ref inBuf, 2); //Максимальное время между байтами одной посылки 
            if (rxCount < 5) return; //Не наше

//Обрабатываем массив inBuf 
        } 

private ComPort _comPort = new ComPort();
private void LoadPortSettings() //Повесить на загрузку формы
        {
            _comPort.DataReceived += ComPort_DataReceived;

            cmbPort.Items.Clear();
            cmbPort.Items.AddRange(_comPort.PortNames());
            cmbBaudRate.Items.Clear();
            cmbBaudRate.Items.AddRange(_comPort.BaudRates());

            cmbPort.SelectedItem = Properties.Settings.Default.Port;
            cmbBaudRate.SelectedItem = Properties.Settings.Default.BaudRate;
        }

private void UpdatePortSettings() //Повесить на изменение комбобоксов cmbPort и cmbBaudRate
        {
            int cpi = cmbPort.SelectedIndex;
            int bri = cmbBaudRate.SelectedIndex;
            if (cpi >= 0 && bri >= 0)
            {
                string port = cmbPort.Items[cpi].ToString();
                string baudRate = cmbBaudRate.Items[bri].ToString();
                if (!string.IsNullOrWhiteSpace(port) && !string.IsNullOrWhiteSpace(baudRate) 
                    && _comPort.isPortChange(port,baudRate))
                {
                    _comPort.Open(port, baudRate);
                }
            }
        }
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
a_volkov1987
@a_volkov1987
Инженер-схемотехник
А почему вы уверены, что DataReceived всегда отработает ровно тогда, когда в буфере порта сложится 13 байт? Я могу сказать, что микроконтроллер даже три байта может вам отправить как 2+ 1 или 1+1+1 или 1+2. То есть DataReceived у вас отработает за время передачи 2 или 3 раза.
Самое оптимальное, как мне кажется - вычитывать все доступное из буфера порта и искать в результате чтения начало и конец ответа от микроконтроллера.
В моем случае от контроллера приходило 4 типа ответа: XX, F0 XX, Е0 XX и E0 F0 XX, то есть стандартные скан-коды клавиатуры (если не брать в расчёт клавиши break и print screen, там многобайтовых посылка).
Я просто читал содержимое буфера порта и если там было только XX, то данные уходили дальше, если только E0 или F0, то в мой буфер писалось E0 и ставился флаг продолжения чтения. Ну и так далее. Таким образом я гарантированно правильно читал данные от контроллера. Если есть необходимость - могу завтра с работы скопипастить сюда свой код.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы