How to display weight from weighing scale into a textbox via serial port RS-232 or usb converter?
Asked Answered
J

8

6

I've been assigned to display weight from weighing scale (CAS CI-201A) into a textbox using C#. The weight will be sent via serial port RS-232 or USB converter. The scale is with me but I don't know where to start. How can I achieve my goal?

Jayjaycee answered 16/5, 2012 at 7:59 Comment(5)
What is causing you problems? The RS232 part or the textbox part? What have you tried?Meniscus
i don't know where to start :(Jayjaycee
I'd start by adding a reference to the DDL that gives you access to the API of the scale... Page 73 onwards looks relevant as well.Solarium
Try breaking the problem down into small chunks. Can you display a text box and display a value in it? Once you can do that, think about how to get the value from the scales; first you must connect to the scales, then you must read the value.Catchpenny
where can i find the DDL? sorry if my questions onwards seems silly because i'm a complete beginner.Jayjaycee
N
11

Have you tried anything yet?

If you want to use the serial port it makes sense to first give the user a way to select which port to use. This can be done easily, by filling a combobox with all available ports.

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

This code uses a form with a comboBox on it, called "comboBox1" (Default). You will need to add:

using System.IO.Ports;

to the using directives.

Then add a button (button1) and a multiline textbox (textbox1) to the form and add this code:

        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());
        }
    }

This also requires you to add:

    private SerialPort _serialPort;
    private const int BaudRate = 9600;

right below the opening brackets of

public partial class Form1 : Form

After clicking the button, all received data from the selected comPort will be displayed as hex values in the TextBox.

DISCLAIMER: The above code contains NO error-handling and will produce errors if button1 is clicked multiple times, due to the fact that the previous instance of "SerialPort" is not closed properly. Please remember this when using this example.

Regards Nico

Complete Code:

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
                }
            }
        }
    }
}
Niobic answered 16/5, 2012 at 8:27 Comment(6)
i've tried ur code. however nothing displayed in textBox1 after i click the button once. if click multiple times unhandled exc occured Access to the port "COM1" is denied.Jayjaycee
That probably means there is no incoming communication on the port or you have the wrong port. Please ensure that the scale is actually sending something, before worrying about writing a software. Khôi gave some suggestions as to how to do that.Niobic
Also, changed the event handler using invocation to run in the UI thread. This is necessary because the event and the UI Updates are not happening in the same thread. Plus, I tested the code. Works as intended. So it is really very probable, that you have no incoming communication.Niobic
hi.. after playing around with the scale, i manage to get this output [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] after press print button on it.. what the output means & what to do next?Jayjaycee
Well, those hex values are ASCII for the following string: "0033 ID_00: 10.6 kg" There's your weight.Double
How did you manage to get that? I am trying to get the ports listed but getting nothing. I have not connected to the scale yet but I have tried connecting other USB devices and nothing shows up in the list of portNames.Pulitzer
D
8

Based on this:

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

Being the ASCII for this:

0033 ID_00: 10.6 kg

You can get the result by trimming the received string. Assuming your listener puts the bytes into an array byte[] serialReceived :

string reading = System.Text.Encoding.UTF8.GetString(serialReceived);
textBox1.Text = reading.Substring(13);
Double answered 18/5, 2012 at 16:52 Comment(4)
thanks guys especially Nicolas & Adam Casey.. problem solved! =)Jayjaycee
You may want to upvote answers that were helpful and accept an answer for future readers of this question.Double
What if your pre data is shorter than 13 digits? and u are using several scalers with different pre line data sizes?Aggrieve
@Aggrieve You can change that 13 to what ever your byte length is, like textBox1.Text = reading.Substring(reading.length-(Your Length));Pyrope
C
5

Firstly, before you start to code anything, I would check whether you're using the right cable. Try open a serial terminal of your choice (HyperTerm, putty) and check whether there is any data at all.

Be sure to configure the same baudrate, stopbits and parity on both the weight scale and your terminal program.

If you receive data (the terminal program should at least display some garbage), then you can move on to coding. If not, check if you're using the right cable (nullmodem aka crossed-over).

When you're this far, then you may use the SerialPort class of C# http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.aspx

Cogitative answered 16/5, 2012 at 8:11 Comment(0)
C
2

based on adam suggestion i converted the output to human readable format ( from ASCII to UTF8 ) i puts the bytes into an array byte[]

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();
            }
        }

here is the full working code

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();
            }
        }
}

if your are using A&D EK V Calibration Model : AND EK-610V. you have use BaudRate = 2400; and DataBits = 7

Note : if you get output like this enter image description here

you have to check the BaudRate,DataBits (refer your weighing machine manual ) or check your cable

Christine answered 30/10, 2016 at 11:52 Comment(0)
H
2

I was using Anto sujesh's Code, but I had the problem that some of the values I got from the scale were corrupted. I solved it by buffering the values in a cache file.

        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;
Hauptmann answered 23/3, 2017 at 15:23 Comment(0)
S
0
    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;    
            }
    }
}
Seismic answered 23/3, 2017 at 5:18 Comment(0)
S
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;
        }
    }

}
Seismic answered 23/3, 2017 at 5:31 Comment(0)
W
0

I am using yaohua xk3190-a9 Weighing Scale indicator connected to my serial port. And after trying lots of codes, follwing code finally worked for me. I am pasting the code here so that if anybody is using the same device can get help.

    private SerialPort _serialPort;
    private const int BaudRate = 2400;
    private void Form1_Load(object sender, EventArgs e)
    {
        string[] portNames = SerialPort.GetPortNames();
        foreach (var portName in portNames)
        {
            comboBox1.Items.Add(portName);
        }
        comboBox1.SelectedIndex = 0;
        //<-- 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, 7, 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
    
    }
    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
        {
            string data = _serialPort.ReadExisting();
            if (data != null)
            {
                if (data.ToString() != "")
                {
                    if (data.Length > 6)
                    {
                        var result = data.Substring(data.Length - 5);
                        textBox1.Text = result.ToString().TrimStart(new Char[] { '0' });
                    }
                }
            }
          
        }
    }
Wendellwendi answered 31/7, 2020 at 17:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.