简体   繁体   English

如何统一从串口接收数据?

[英]how can in receive data from serial port in unity?

I want to establish a full duplex connection between the microcontroller(ARM Stm32F4) and the program made by Unity software via c#.我想在微控制器(ARM Stm32F4)Unity 软件通过 c# 制作的程序之间建立全双工连接 This connection must be made through the serial port.此连接必须通过串行端口进行。 I need a two-way connection between these two parts.我需要这两个部分之间的双向连接。 At first the sent data from the program (made in unity software) can send command to the microcontroller(ARM Stm32F4), then the microcontroller must check the received data and verifying finishing commands to the Unity software If the data is correct, send the next data to the program.首先从程序(用unity软件制作)发送的数据可以发送命令到微控制器(ARM Stm32F4),然后微控制器必须检查接收到的数据并验证完成命令给Unity软件如果数据正确,发送下一个数据到程序。 My problem is that my program, which is made by the unity, does not receive finished data that sent from the microcontroller.我的问题是我的统一程序制作的程序没有收到从微控制器发送的完成数据。

How can I have full duplex connection?如何进行全双工连接?

*
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.IO.Ports;
using System.IO;
using UnityEditor;
using SerialPortUtility;
using System;
public class gcode : MonoBehaviour
{
    string str;
    string str1;
    public SerialPort sina;
    public InputField sendgcode;
    public InputField plusoffset;
    public InputField minusoffset;
    public InputField lenghtoffset;
    public InputField counter;
    public Button plus_inc;
    public Button plus_dec;
    public Button minus_inc;
    public Button minus_dec;
    public Button lenght_inc;
    public Button lenght_dec;
    string board;
    
    Array[] inserial;
    //int resend = 0;
    // Start is called before the first frame update
    void Start()
    {
        sina = new SerialPort("com1", 115200);
        sina.ReadTimeout = 100;
        
        sina.Open();
        sina.DtrEnable = true;
    }
    // Update is called once per frame
    void Update()
    {
        //sina.Close();
            //str = sina.ReadLine();
            //sendgcode.text = str;
        
    }
    public void sendserial()
    {
        
        str = sendgcode.text;
        TextWriter a40 = new StreamWriter("c:\\1.txt");
        a40.WriteLine(str);
        a40.Close();
        str = "";
        TextWriter a41 = new StreamWriter("c:\\2.txt");
        TextWriter a43 = new StreamWriter("c:\\3.txt");
        TextWriter a22 = new StreamWriter("c:\\22.txt");
        TextWriter plus = new StreamWriter("c:\\p.txt");
        TextWriter minus = new StreamWriter("c:\\m.txt");
        TextWriter lenght = new StreamWriter("c:\\t.txt");
        System.IO.StreamReader file = new System.IO.StreamReader("c:\\1.txt");
        while ((str = file.ReadLine()) != null)
        {
            str1 = str.Replace(" ", "");
            str1 = str1.Replace("L", "\r\n");
            str1 = str1.Replace("A", "\r\n");
            str1 = str1.Replace("S", "");
            a41.WriteLine(str1);
        }
        a41.WriteLine("S");
        a41.Close();
        file.Close();
        System.IO.StreamReader file22 = new System.IO.StreamReader("c:\\2.txt");
        while ((str = file22.ReadLine()) != "S")
        {
            if (str.Length >= 1) { a22.WriteLine(str); }
        }
        a22.WriteLine("S");
        a22.Close();
        file22.Close();
        System.IO.StreamReader file1 = new System.IO.StreamReader("c:\\22.txt");
        while ((str = file1.ReadLine()) != "S")
        {
            int idx = str.IndexOf('-');
            if (idx >= 0)
            {
                if (str.Length == 2)
                {
                    str = str.Replace("-", "-00");
                    a43.WriteLine(str);
                }
                else if (str.Length == 3)
                {
                    str = str.Replace("-", "-0");
                    a43.WriteLine(str);
                }
                else
                {
                    a43.WriteLine(str);
                }
            }
            else if (str.Length == 1)
            {
                a43.WriteLine("00" + str);
            }
            else if (str.Length == 2)
            {
                a43.WriteLine("0" + str);
            }
            else
            {
                a43.WriteLine(str);
            }
        }
        a43.WriteLine("S");
        a43.Close();
        file1.Close();
        str1 = null;
        int c = 0;
        System.IO.StreamReader file2 = new System.IO.StreamReader("c:\\3.txt");
        while ((str = file2.ReadLine()) != "S")
        {
            if (str.Length > 2)
            {
                str1 = str1 + str;                          //read line by line to 4 line
            }
            c++;
            if (c == 4)                                     //end read 4 lines
            {
                c = 0;
                int n = 0;
                str1 = "#" + str1;
                int sp;
                
                do
                {
                    sina.WriteLine(str1);
                    board = sina.ReadExisting();
                    Debug.Log(board);               
                }
                while (board != str1);
                sina.WriteLine("$");
                str1 = null;
            }
             
            
        }
        /*
        System.Threading.Thread.Sleep(1000);
        sina.WriteLine(str1);                               //send last line of gcode     
        file2.Close();
        System.Threading.Thread.Sleep(1000);
        sina.WriteLine("p" + plusoffset.text);
        System.Threading.Thread.Sleep(1000);
        sina.WriteLine("m" + minusoffset.text);
        System.Threading.Thread.Sleep(1000);
        sina.WriteLine("t" + lenghtoffset.text);
        System.Threading.Thread.Sleep(1000);
        System.IO.StreamReader filecrc = new System.IO.StreamReader("c:\\3.txt");
        int crc = 0;
        int s1;
        int Poffset = 0;
        int Moffset = 0;
        int Toffset = 0;
        int Ecount = 0;
        while ((str = filecrc.ReadLine()) != "S")
        {
            int.TryParse(str, out s1);
            crc = crc + s1;
        }
        filecrc.Close();
        int.TryParse(plusoffset.text, out Poffset);
        int.TryParse(minusoffset.text, out Moffset);
        int.TryParse(lenghtoffset.text, out Toffset);
        int.TryParse(counter.text, out Ecount);
        crc = crc + Poffset;
        crc = crc + Moffset;
        crc = crc + Toffset;
        crc = crc + Ecount;
        System.Threading.Thread.Sleep(1000);
        sina.WriteLine("M" + crc.ToString());
        System.Threading.Thread.Sleep(1000);
        sina.WriteLine("E" + counter.text);
        plus.WriteLine(plusoffset.text); plus.Close();
        minus.WriteLine(minusoffset.text); minus.Close();
        lenght.WriteLine(lenghtoffset.text); lenght.Close();
        */
    }
    public void plusinc()
    {
        int value;
        int.TryParse(plusoffset.text, out value);
        value++;
        plusoffset.text = value.ToString();
    }
    public void plusdec()
    {
        int value;
        int.TryParse(plusoffset.text, out value);
        value--;
        plusoffset.text = value.ToString();
    }
    public void minusinc()
    {
        int value;
        int.TryParse(minusoffset.text, out value);
        value++;
        minusoffset.text = value.ToString();
    }
    public void minusdec()
    {
        int value;
        int.TryParse(minusoffset.text, out value);
        value--;
        minusoffset.text = value.ToString();
    }
    public void lenghtinc()
    {
        int value;
        int.TryParse(lenghtoffset.text, out value);
        value++;
        lenghtoffset.text = value.ToString();
    }
    public void lenghtdec()
    {
        int value;
        int.TryParse(lenghtoffset.text, out value);
        value--;
        lenghtoffset.text = value.ToString();
    }
    public void load_offest()
    {
        System.Threading.Thread.Sleep(500);
        System.IO.StreamReader offset = new System.IO.StreamReader("c:\\offset.txt");
        string stroffset;
        stroffset = offset.ReadLine();
        plusoffset.text = stroffset;
        stroffset = offset.ReadLine();
        minusoffset.text = stroffset;
        stroffset = offset.ReadLine();
        lenghtoffset.text = stroffset;
    }
    public void clear()
    {
        sendgcode.text = "";
        plusoffset.text = "";
        minusoffset.text = "";
        lenghtoffset.text = "";
    }
    void OnSerialLine(string line)
    {
        Debug.Log("Got a line: " + line);
    }
}*```

In your do - while loop you constantly keep writing the string str1 .在您的do - while循环中,您不断地编写字符串str1 This looks already quite odd.这看起来已经很奇怪了。

And then you do board = sina.ReadExisting() which returns all currently available stream and buffer content.然后您执行board = sina.ReadExisting() ,它返回所有当前可用的 stream 和缓冲区内容。

Reads all immediately available bytes, based on the encoding, in both the stream and the input buffer of the SerialPort object.根据编码读取 stream 和 SerialPort object 的输入缓冲区中的所有立即可用字节。

Since this is a stream and there is no sich concept as "messages" might be multiple lines/messages or also only a part of one => pretty unlikely that this matches exactly with what you have sent immediately.由于这是一个stream并且没有 sich 概念,因为“消息”可能是多行/消息,或者也只是一个的一部分 => 这不太可能与您立即发送的内容完全匹配。

You would need to come up with a proper protocol like eg using a special separator character between messages.您需要提出一个适当的协议,例如在消息之间使用特殊的分隔符。

Rather use ReadLine which reads until the next encounter of the configured NewLine character (by default \n ) or use ReadTo(string) for a string pattern.而是使用ReadLine读取直到下一次遇到配置的NewLine字符(默认情况下\n )或使用ReadTo(string)作为string模式。

Both will "freeze" until according character is received making sure the entire message is fully received before continuing in your code.两者都将“冻结”,直到收到相应的字符,确保在继续您的代码之前完全收到整个消息。

So instead of所以而不是

do
{
    sina.WriteLine(str1);
    board = sina.ReadExisting();
    Debug.Log(board);               
}
while (board != str1);
sina.WriteLine("$");

you would probably rather do something like eg你可能宁愿做类似的事情

sina.WriteLine(str1);
do
{
    board = sina.ReadLine();
    Debug.Log(board);               
}
while (board != str1);
sina.WriteLine("$");

IF a loop is what you want to use at all.如果一个循环是你想要使用的。


In general I would always use two separate threads for sending and receiving.一般来说,我总是使用两个单独的线程来发送和接收。 Except you have a clear protocol where you only need to be able to receive in certain slots in the logic.除非您有一个明确的协议,您只需要能够在逻辑中的某些插槽中接收。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM