Вопрос по c# – Как отобразить вес из весов в текстовое поле через последовательный порт RS-232 или USB-конвертер?

3

Мне было назначено отображать вес из весов (CAS CI-201A) в текстовое поле с использованием C #. Вес будет отправлен через последовательный порт RS-232 или USB-конвертер. Шкала со мной, но я не знаю, с чего начать. Как я могу достичь своей цели?

Я бы начал с добавления ссылки на DDL, которая дает вам доступ к API шкалы ... и далее выглядит также актуально. Mr Shoubs
Попробуйте разбить проблему на маленькие кусочки. Можете ли вы отобразить текстовое поле и отобразить в нем значение? Как только вы сможете это сделать, подумайте, как получить значение из весов; сначала вы должны подключиться к весам, затем вы должны прочитать значение. Tim Croydon
где я могу найти DDL? извините, если мои вопросы кажутся глупыми, потому что я начинающий. user1398000
Что вызывает у вас проблемы? Часть RS232 или часть текстового поля? Что вы пробовали? Anders Lindahl
я не знаю с чего начать :( user1398000

Ваш Ответ

7   ответов
1

основываясь на предложении Адама, я преобразовал вывод в читаемый человеком формат (из ASCII в UTF8) я помещаю байты в массив байтов []

private void SerialPortOnDataReceived(object sender, SerialDataReceivedEventArgs serialDataReceivedEventArgs)
        {
            if (InvokeRequired)     //<-- Makes sure the function is invoked to work properly in the UI-Thread
                BeginInvoke(new Closure(() => { SerialPortOnDataReceived(sender, serialDataReceivedEventArgs); }));     //<-- Function invokes itself
            else
            {
                int dataLength = _serialPort.BytesToRead;
                byte[] data = new byte[dataLength];
                int nbrDataRead = _serialPort.Read(data, 0, dataLength);
                if (nbrDataRead == 0)
                    return;
                string str = System.Text.Encoding.UTF8.GetString(data);
                textBox1.Text = str.ToString();
            }
        }

вот полный рабочий код

using System;
using System.IO.Ports;          //<-- necessary to use "SerialPort"
using System.Windows.Forms;

namespace ComPortTests
{
    public partial class Form1 : Form
    {
        private SerialPort _serialPort;         //<-- declares a SerialPort Variable to be used throughout the form
        private const int BaudRate = 9600;      //<-- BaudRate Constant. 9600 seems to be the scale-units default value
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            string[] portNames = SerialPort.GetPortNames();     //<-- Reads all available comPorts
            foreach (var portName in portNames)
            {
                comboBox1.Items.Add(portName);                  //<-- Adds Ports to combobox
            }
            comboBox1.SelectedIndex = 0;                        //<-- Selects first entry (convenience purposes)
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //<-- This block ensures that no exceptions happen
            if(_serialPort != null && _serialPort.IsOpen)
                _serialPort.Close();
            if (_serialPort != null)
                _serialPort.Dispose();
            //<-- End of Block

            _serialPort = new SerialPort(comboBox1.Text, BaudRate, Parity.None, 8, StopBits.One);       //<-- Creates new SerialPort using the name selected in the combobox
            _serialPort.DataReceived += SerialPortOnDataReceived;       //<-- this event happens everytime when new data is received by the ComPort
            _serialPort.Open();     //<-- make the comport listen
            textBox1.Text = "Listening on " + _serialPort.PortName + "...\r\n";
        }

        private delegate void Closure();
        private void SerialPortOnDataReceived(object sender, SerialDataReceivedEventArgs serialDataReceivedEventArgs)
        {
            if (InvokeRequired)     //<-- Makes sure the function is invoked to work properly in the UI-Thread
                BeginInvoke(new Closure(() => { SerialPortOnDataReceived(sender, serialDataReceivedEventArgs); }));     //<-- Function invokes itself
            else
            {
                int dataLength = _serialPort.BytesToRead;
                byte[] data = new byte[dataLength];
                int nbrDataRead = _serialPort.Read(data, 0, dataLength);
                if (nbrDataRead == 0)
                    return;
                string str = System.Text.Encoding.UTF8.GetString(data);
                textBox1.Text = str.ToString();
            }
        }
}

если вы используете A & D EK V Калибровочная модель: AND EK-610V. вы используете BaudRate = 2400; и DataBits = 7

Примечание: если вы получаете вывод, как это enter image description here

Вы должны проверить BaudRate, DataBits (см. руководство к вашему весу) или проверить свой кабель

4

Основываясь на этом:

Listening on COM1... 30 30 33 33 20 49 44 5F 30 30 3A 20 20 20 31 30 2E 36 20 6B 67 20 0D 0A 0D 0A

Быть ASCII для этого:

0033 ID_00: 10.6 kg

Вы можете получить результат, обрезав полученную строку. Предполагая, что ваш слушатель помещает байты в массивbyte[] serialReceived :

string reading = System.Text.Encoding.UTF8.GetString(serialReceived);
textBox1.Text = reading.Substring(13);
Error: User Rate Limit Exceeded user1398000
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
5

Во-первых, прежде чем вы начнете что-то кодировать, я бы проверил, правильно ли вы используете кабель. Попробуйте открыть последовательный терминал по вашему выбору (HyperTerm, putty) и проверить, есть ли какие-либо данные вообще.

Обязательно настройте одинаковую скорость передачи, стоп-биты и четность как на весовой шкале, так и в вашей терминальной программе.

Если вы получаете данные (программа терминала должна хотя бы отображать мусор), вы можете перейти к кодированию. Если нет, проверьте, правильно ли вы используете кабель (nullmodem, он же перечеркнутый).

Когда вы так далеко, вы можете использоватьSerialPort класс C # http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.aspx

9

Вы уже пробовали что-нибудь?

Если вы хотите использовать последовательный порт, имеет смысл сначала дать пользователю способ выбрать, какой порт использовать. Это можно сделать легко, заполнив комбинированный список всеми доступными портами.

        private void Form1_Load(object sender, EventArgs e)
    {
        string[] portNames = SerialPort.GetPortNames();
        foreach (var portName in portNames)
        {
            comboBox1.Items.Add(portName);
        }
        comboBox1.SelectedIndex = 0;
    }

В этом коде используется форма со списком comboBox, которая называется «comboBox1». (По умолчанию). Вам нужно будет добавить:

using System.IO.Ports;

с использованием директив.

Затем добавьте кнопку (button1) и многострочное текстовое поле (textbox1) в форму и добавьте этот код:

        private void button1_Click(object sender, EventArgs e)
    {
        _serialPort = new SerialPort(comboBox1.Text, BaudRate, Parity.None, 8, StopBits.One);
        _serialPort.DataReceived += SerialPortOnDataReceived;
        _serialPort.Open();
        textBox1.Text = "Listening on " + comboBox1.Text + "...";
    }

    private void SerialPortOnDataReceived(object sender, SerialDataReceivedEventArgs serialDataReceivedEventArgs)
    {
        while(_serialPort.BytesToRead >0)
        {
            textBox1.Text += string.Format("{0:X2} ", _serialPort.ReadByte());
        }
    }

Это также требует, чтобы вы добавили:

    private SerialPort _serialPort;
    private const int BaudRate = 9600;

прямо под открывающими скобками

public partial class Form1 : Form

После нажатия кнопки все полученные данные с выбранного comPort будут отображаться в шестнадцатеричном виде в TextBox.

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Приведенный выше код не содержит обработки ошибок и будет выдавать ошибки, если на кнопку 1 нажимают несколько раз из-за того, что предыдущий экземпляр «SerialPort» quot; не закрывается должным образом. Пожалуйста, помните это при использовании этого примера.

С уважением Нико

Полный код:

using System;
using System.IO.Ports;          //<-- necessary to use "SerialPort"
using System.Windows.Forms;

namespace ComPortTests
{
    public partial class Form1 : Form
    {
        private SerialPort _serialPort;         //<-- declares a SerialPort Variable to be used throughout the form
        private const int BaudRate = 9600;      //<-- BaudRate Constant. 9600 seems to be the scale-units default value
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            string[] portNames = SerialPort.GetPortNames();     //<-- Reads all available comPorts
            foreach (var portName in portNames)
            {
                comboBox1.Items.Add(portName);                  //<-- Adds Ports to combobox
            }
            comboBox1.SelectedIndex = 0;                        //<-- Selects first entry (convenience purposes)
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //<-- This block ensures that no exceptions happen
            if(_serialPort != null && _serialPort.IsOpen)
                _serialPort.Close();
            if (_serialPort != null)
                _serialPort.Dispose();
            //<-- End of Block

            _serialPort = new SerialPort(comboBox1.Text, BaudRate, Parity.None, 8, StopBits.One);       //<-- Creates new SerialPort using the name selected in the combobox
            _serialPort.DataReceived += SerialPortOnDataReceived;       //<-- this event happens everytime when new data is received by the ComPort
            _serialPort.Open();     //<-- make the comport listen
            textBox1.Text = "Listening on " + _serialPort.PortName + "...\r\n";
        }

        private delegate void Closure();
        private void SerialPortOnDataReceived(object sender, SerialDataReceivedEventArgs serialDataReceivedEventArgs)
        {
            if (InvokeRequired)     //<-- Makes sure the function is invoked to work properly in the UI-Thread
                BeginInvoke(new Closure(() => { SerialPortOnDataReceived(sender, serialDataReceivedEventArgs); }));     //<-- Function invokes itself
            else
            {
                while (_serialPort.BytesToRead > 0) //<-- repeats until the In-Buffer is empty
                {
                    textBox1.Text += string.Format("{0:X2} ", _serialPort.ReadByte());
                        //<-- bytewise adds inbuffer to textbox
                }
            }
        }
    }
}
Error: User Rate Limit Exceeded user1398000
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded user1398000
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
0
using System;

using System.IO;

using System.IO.Ports;

namespace comport

{
    public partial class Form1 : Form

    {
        public Form1()

        {

            InitializeComponent();
        }

        private SerialPort _serialPort = null;

        private void Form1_Load(object sender, EventArgs e)
        {
            AppConfiguration.sConfigType = "default";

            _serialPort = new SerialPort("COM1", 9600, Parity.None, 8);

            _serialPort.DataReceived += new SerialDataReceivedEventHandler(_serialPort_DataReceived);

            _serialPort.Open();

        }

        void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            string data = _serialPort.ReadExisting();

            textBox2.Text = data;
        }
    }

}
-1
    using System;
    using System.IO.Ports;         
    using System.Windows.Forms;
    namespace ComPortTests
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
                private SerialPort _serialPort = null;
    private void Form1_Load(object sender, EventArgs e)
    {
     _serialPort = new SerialPort("COM1", 9600, Parity.None, 8);

     _serialPort.DataReceived += new SerialDataReceivedEventHandler(_serialPort_DataReceived);

     _serialPort.Open();
    }

    void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)

            {

                string data = _serialPort.ReadExisting();
                textBox2.Text = data;    
            }
    }
}
2

Я использовал код Anto sujesh, но у меня была проблема с тем, что некоторые значения, полученные из шкалы, были повреждены. Я решил это путем буферизации значений в файле кэша.

        private void SerialPortOnDataReceived(object sender, SerialDataReceivedEventArgs serialDataReceivedEventArgs)
    {

        if (InvokeRequired)     //<-- Makes sure the function is invoked to work properly in the UI-Thread
            BeginInvoke(new Closure(() => { SerialPortOnDataReceived(sender, serialDataReceivedEventArgs); }));     //<-- Function invokes itself
        else
        {
            int dataLength = _serialPort.BytesToRead;                

            byte[] data = new byte[dataLength];
            int nbrDataRead = _serialPort.Read(data, 0, dataLength);
            if (nbrDataRead == 0)
                return;
            string str = Encoding.UTF8.GetString(data);

            //Buffers values in a file
            File.AppendAllText("buffer1", str);

            //Read from buffer and write into "strnew" String
            string strnew = File.ReadLines("buffer1").Last();

            //Shows actual true value coming from scale
            textBox5.Text = strnew;

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