VS C# 질문 (RS232 저울연동 프로그램 코딩 중 질문)

VS C# 질문 (RS232 저울연동 프로그램 코딩 중 질문)

작성일 2022.08.03댓글 2건
    게시물 수정 , 삭제는 로그인 필요

제가 비주얼스튜디오 C# 코딩 공부중에있습니다.

RS232 로 저울연결하여 HEX데이타를 받아오는데 

실행후 TEXT박스에 보여지는 결과가 ST,NT,??,     1.1 kg 이렇게 나옵니다

제가 원하는 값은 1.1kg 만 보여지게 하고싶은데 방법이 있을까요?

HEX값 : 53 54 2C 4E 54 2C 00 E4 2C 20 20 20 20 20 31 2E 34 20 6B 67 0D 0A
ASCII값 : ST,NT,??,     1.1 kg 

========================================================================
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;

namespace WindowsFormsApp1
{

    public partial class Form1 : Form
    {
        string InputData = String.Empty;
        delegate void SetTextCallback(string text);

        int n = 0;
        int forcount = 0;
        int listViewcount = 0;
        // 회원 검색 버튼 카운터, 회원 검색시 포문 카운터


        public Form1()
        {
            InitializeComponent();
            
            string[] ports = SerialPort.GetPortNames();// Nice methods to browse all available ports:

            
            foreach (string port in ports)// Add all port names to the combo box:
            {
                cmbComSelect.Items.Add(port);
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
        }

        private void button1_Click_1(object sender, EventArgs e)
        {
            string columnHeader1 = textBox1.Text;

            n++;

            ListViewItem item = new ListViewItem(n.ToString());

            item.SubItems.Add(textBox1.Text);
            item.SubItems.Add(textBox2.Text);
            item.SubItems.Add(textBox3.Text);
            item.SubItems.Add(textBox4.Text);
            item.SubItems.Add(textBox5.Text);
            item.SubItems.Add(textBox6.Text);
            item.SubItems.Add(textBox7.Text);
            item.SubItems.Add(textBox8.Text);


            listView1.Items.Add(item);

            textBox1.Text = "";
            textBox2.Text = "";
            textBox3.Text = "";
            textBox4.Text = "";
            textBox5.Text = "";
            textBox6.Text = "";
            textBox7.Text = "";
            textBox8.Text = "";

            textBox1.Focus();
        }

        private void listView1_SelectedIndexChanged_1(object sender, EventArgs e)
        {
            try
            {
                textBox1.Text = listView1.FocusedItem.SubItems[1].Text;
                textBox2.Text = listView1.FocusedItem.SubItems[2].Text;
                textBox3.Text = listView1.FocusedItem.SubItems[3].Text;
                textBox4.Text = listView1.FocusedItem.SubItems[4].Text;
                textBox5.Text = listView1.FocusedItem.SubItems[5].Text;
                textBox6.Text = listView1.FocusedItem.SubItems[6].Text;
                textBox7.Text = listView1.FocusedItem.SubItems[7].Text;
                textBox8.Text = listView1.FocusedItem.SubItems[8].Text;

            }
            catch { }
        }

        private void button2_Click_1(object sender, EventArgs e)
        {

            if (listView1.SelectedIndices.Count > 0)

            {

                for (int i = listView1.SelectedIndices.Count - 1; i >= 0; i--)

                    listView1.Items.RemoveAt(listView1.SelectedIndices[i]);

            }

            else

                MessageBox.Show("삭제할 항목을 선택해주세요.");

        }

        private void button3_Click_1(object sender, EventArgs e)
        {
            if (listView1.SelectedItems.Count > 0)

            {

                int n = listView1.SelectedItems[0].Index;

                listView1.Items[n].SubItems[1].Text = textBox1.Text;
                listView1.Items[n].SubItems[2].Text = textBox2.Text;
                listView1.Items[n].SubItems[3].Text = textBox3.Text;
                listView1.Items[n].SubItems[4].Text = textBox4.Text;
                listView1.Items[n].SubItems[5].Text = textBox5.Text;
                listView1.Items[n].SubItems[6].Text = textBox6.Text;
                listView1.Items[n].SubItems[7].Text = textBox7.Text;
                listView1.Items[n].SubItems[8].Text = textBox8.Text;
            }
        }

        private void button4_Click_1(object sender, EventArgs e)// 회원 검색 버튼
        {
            if (textBox9.Text == "")
            {
                MessageBox.Show("검색할 이름을 입력하세요!!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            else
            {
                int count = listView1.Items.Count;// 리스트뷰 항목 수 반환
                if (listViewcount > 0)// 멤버 카운트 버튼 한번 클릭했는지 여러번 클릭했는지 확인
                {
                    for (int i = forcount; i < count; i++)// 리스트 뷰 내에서 검색하는 포문
                    {
                        if (listView1.Items[i].SubItems[1].Text == textBox9.Text)
                        {
                            listView1.Items[i].Focused = true;
                            listView1.Items[i].Selected = true;// 리스트뷰 컨트롤에서 항목 선택 가능하도록 하는거
                            textBox1.Text = listView1.FocusedItem.SubItems[1].Text;
                            textBox2.Text = listView1.FocusedItem.SubItems[2].Text;
                            textBox3.Text = listView1.FocusedItem.SubItems[3].Text;
                            forcount++;
                            if (forcount == count)//포문을 끝까지 다 확인하고 나면
                            {
                                listViewcount = forcount = 0; //멤버 카운트,포문 카운트 초기화
                            }
                            break;
                        }
                        else
                        {
                            forcount++;
                            if (forcount == count) //포문을 끝까지 다 확인하고 나면
                            {
                                listViewcount = forcount = 0;
                            }
                        }
                    }
                }

                else
                {
                    for (int i = 0; i < count; i++) //리스트 뷰 내에서 검색하는 포문
                    {
                        if (listView1.Items[i].SubItems[1].Text == textBox9.Text)
                        {
                            listView1.Items[i].Focused = true;
                            listView1.Items[i].Selected = true;// 리스트뷰 컨트롤에서 항목 선택 가능하도록 하는거
                            textBox1.Text = listView1.FocusedItem.SubItems[1].Text;
                            textBox2.Text = listView1.FocusedItem.SubItems[2].Text;
                            textBox3.Text = listView1.FocusedItem.SubItems[3].Text;

                            forcount++;
                            listViewcount++;
                            break;
                        }
                        else
                        {
                            forcount++;
                        }
                    }
                }
            }

        }



        private void cmbComSelect_SelectionChangeCommitted(object sender, EventArgs e)
        {
            if (port.IsOpen) port.Close();
            port.PortName = cmbComSelect.SelectedItem.ToString();
            stsStatus.Text = port.PortName + ": 9600,8N1";

            // try to open the selected port:
            try
            {
                port.Open();
            }
            // give a message, if the port is not available:
            catch
            {
                MessageBox.Show(port.PortName + " 시리얼포트가 열리지 않았습니다!", "CASKOREA", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                cmbComSelect.SelectedText = "";
                stsStatus.Text = "Select serial port!";
            }
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            txtIn.Clear();
        }

        private void port_DataReceived_1(object sender, SerialDataReceivedEventArgs e)
        {
            InputData = port.ReadExisting();
            if (InputData != String.Empty)
            {
                //             txtIn.Text = InputData;   // because of different threads this does not work properly !!
                SetText(InputData);
            }
        }
        private void SetText(string text)
        {
            // InvokeRequired required compares the thread ID of the
            // calling thread to the thread ID of the creating thread.
            // If these threads are different, it returns true.
            if (this.txtIn.InvokeRequired)
            {
                SetTextCallback d = new SetTextCallback(SetText);
                this.Invoke(d, new object[] { text });
            }
            else this.txtIn.Text += text;
        }
    }
}



#vs c# #vs c# version #vs c# gitignore #vs c# .net #vs c# null #c++ vs c# #java vs c# #equals vs == c# #python vs c# #gdscript vs c#

profile_image 익명 작성일 -

전체 코드는 보지 못했습니다,

아래와 같은 형식에서 1.1 kg만 가져오는 방법입니다.

textBox1.Text = "ST,NT,??, 1.1 kg";

string[] s = textBox1.Text.Split(','); // 컴마로 분리합니다.

// s[3]에는 "1.1 kg" 문자열이 있습니다.

textBox1.Text = s[3]; // textBox1에 1.1kg가 출력됩니다.

profile_image 익명 작성일 -

RS232 는 통신 선로로서, 데이터가 드나드는 길일 뿐입니다.

데이터를 메모리에서 읽어 오든, 하드에서 읽어오든, 인터넷에서 읽어 오든 모든 데이터는 어떤 통신 선로를 거쳐 옵니다.

여기에서 중요한 점은 통신선로가 아니라 그 데이터를 "어떤 의미"로 해석하는가입니다.

예를 들어, 아래의 코드에서 메모리 a에 저장된 데이터(값)는 어떤 의미로 해석되어야 할까요?

int a = 50;

만약 나이를 의미한다면, 우리는 이 데이터를 정수 형태 그대로 사용해서, 나이에 관한 처리를 할 수 있습니다.

몸무게를 의미한다면, 다이어트나 의학정보에 관한 로직에 사용할 것입니다.

좀더 복잡하게, 앞에 5와 뒤의 0이 각각 다른 의미를 가진다면, 50에서 5와 0을 분리하는 가공을 한 후에, 용도에 맞게 사용해야 합니다.

이 데이터의 의미는 데이터를 저장한 사람, 혹은 생성한 사람이 결정합니다.

이와 동일하게, 저울이 보내는 데이터를 해석하는 방법과 데이터의 형태는 저울 프로그램을 작성한 사람이 결정하겠죠.

보통 232/485 처럼 시리얼 통신으로 주고 받는 데이터는 8비트 크기의 숫자(16진수 2자리)들로, 이들은 ASCII 문자표의 문자 번호(문자 코드)를 의미합니다. 문자코드는 문자 하나에 해당하기 때문에 이들을 합쳐 하나의 문자열에 저장하면, 가공하기 쉬운 형태가 될 것입니다. 아래의 코드가 이를 수행하고 있습니다.

private void port_DataReceived_1(object sender, SerialDataReceivedEventArgs e) { // 232로 들어 온 데이터를 문자열로 변환 후, InputData 메모리에 저장. InputData = port.ReadExisting(); ...

이 문자열은 미리 정해진 방법에 따라 구성되어 있는데, 그 방법을 보통 "데이터 프로토콜" 혹은 "패킷 프로토콜" 혹은 "패킷 구조" 등으로 불립니다.

예를 들어, 저울은 길이가 20인 문자열의 형태로 데이터를 보내는데, 데이터 프로토콜은 아래와 같을 수 있습니다.

참고: 문자 인코딩 방식: ASCII

첫 8 글자 : 저울 상태

3글자: 배터리 잔량.

2글자: 모드 0: Standard, 1: 영점 조정

3글자: reserved

그 다음 8글자 : 무게 데이터

3글자: 무게를 나타내는 정수

1글자: '.' 소숫점을 나타냄. 항상 고정.

1글자: 소숫점 첫째자리 숫자.

1글자: '0' => kg, '1'=> g

2글자: 공백 2칸.(고정)

그 다음 4글자

reserved.

우리는 이 프로토콜을 기반으로, 우리가 원하는 데이터를 선별할 수 있습니다.

private void port_DataReceived_1(object sender, SerialDataReceivedEventArgs e) { InputData = port.ReadExisting(); if (InputData != String.Empty) { if (InputData.Length != 20) MessageBox.Show("통신이상!!", "CASKOREA", MessageBoxButtons.OK, MessageBoxIcon.Warning); else { // 문자열 8번인덱스부터 5글자는 무게를 나타내는 문자열 var weight = new string(InputData[8..13]); // 13번인덱스 문자를 해석하여, 원하는 형태로 가공 var unit = InputData[13] == '0' ? "kg" : "g"; // 가공된 데이터를 표시. SetWeightLabel(weight + " " + unit + "."); } } }

만약 이 프로토콜을 무시하고, 일반적인 문자열 분리(Split) 기법 - 예를 들면, 공백을 구분자로 일괄적으로 분리를 수행한다면, 엉뚱한 의미로 파싱될 수 있습니다.

결론적으로, 저울의 제조사에게 패킷을 해석하는 문서를 요청해서, 데이터 프로토콜을 얻고 그에 준해서 데이터를 파싱하는 코드를 작성하는 것이 안전한 방법이고, 가장 일반적인 실무입니다.

2차 개발을 허용하는 제품이라면, 데이터 프로토콜을 회사 홈페이지의 개발자 페이지나 QnA 코너 등에 상시 게시해놓는게 보통입니다.

선별적으로 허용하는 제품이라면, 직접 문의해야 합니다.

비주얼 스튜디오 코드 C# 코드색상 및...

... 나오네요 VS Code참 편하죠? 저도 코딩하면서 맨날 쓰고... Visual Studio Code(VS Code)에서 C# 작업 시 문제가 발생하는 것으로 보아, 일단 사용 중인 확장 프로그램의 상태를...

프로그램밍 언어 C#과 .Net에 관련된...

... 질문이 많으니 아시는 것만 적어 주세요. 대충이라도 상관 없습니다. 1. C#과 C++의 차이점은 뭐죠? 2. Java와 C언어 요즘 대세는 어느 것이죠? 3. 프로그램밍 언어란...

C# 로그인질문

어제 질문을 했지만 잘 이해가 가지않아서... 이 프로그램을 가동중인 컴퓨터의 MAC주소와 동일한... view=vs-2017 그리고 C# 언어에서 mssql을 연동하는 구체적인 예는...

C# Access2007을 연동하며 이용할때...

안녕하세요 ㅠ_ㅠ C# 초보자입니다. 질문 올려봅니다...... 프로그램을 만들어보려고 하는데, 너무 막히는 부분이 많습니다 ㅠ 질문 들어가겠습니다. 제가 코딩을...

[초보질문] RS232, 포트의 수신 데이터...

... 보내고 프로그램에서 그 메세지핸들러를 이용하여 데이타가... 컴퓨터 vs 컴퓨터의 연결로 RS422/RS485를 쓰고자 한다면 [컴퓨터1] - [RS232] - [RS232->RS4**변환기] - [RS4...

C#.NET 관련 질문입니다...^^ 개념...

... 연습삼아 코딩도 해보고 그렇게 혼자 스터디하고... 0은 VS .NET 2002로 개발을 할 수 있었으며 C#, Smart Client... ㅎㅎ 질문자께서 내놓으신 프로그램 뿐만이 아니라...

국비지원 코딩교육 질문

... 그래서 내년에 국비 지원으로 코딩학원 다녀서 취업... 몰라서 연동을 못시킨다면 죽은 프로그램이나... 국비지원 수업도 종류가 다양하다보니 어떤 과정이 질문자님께...

노트북 맥북 VS MS 질문이여!

코딩 입문이랑 동영상 편집용 노트북 구매하려고 하는데 맥북이랑 일반 MS 체제... 하지만 가격이 비싸고 호환성이 낮아서 다른 기기나 프로그램연동하기 어렵습니다. - MS...