将正确的Gcode字符串发送到串行端口?

时间:2012-10-14 21:46:28

标签: c# serial-port grasshopper g-code

我正在尝试通过第g28行将gcode port.Write("g28");发送到我的RepRap 3D打印机。

我的程序连接到正确的串行端口但是当我尝试以字符串形式发送信息时,对com端口的访问被拒绝。 这很奇怪,因为在将Gcode发送给它之前串口是打开的。它甚至还发回了一些数据。有什么问题,我该怎么办?

以下是我正在使用的代码行。 gcode命令列表可在此page上找到。

我尝试在字符串的末尾添加"\n",但它不起作用。

    //Fields
    List<string> myReceivedLines = new List<string>();


    //subscriber method for the port.DataReceived Event
    private void DataReceivedHandler(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
    {
        SerialPort sp = (SerialPort)sender;
        while (sp.BytesToRead > 0)
        {
            try
            {
                myReceivedLines.Add(sp.ReadLine());
            }
            catch (TimeoutException)
            {
                break;
            }
        }
    }


    protected override void SolveInstance(IGH_DataAccess DA)
    {

        string selectedportname = default(string);
        DA.GetData(1, ref selectedportname);
        int selectedbaudrate = default(int);
        DA.GetData(2, ref selectedbaudrate);
        bool connecttodevice = default(bool);
        DA.GetData(3, ref connecttodevice);
        bool homeall = default(bool);
        DA.GetData(5, ref homeall);

        SerialPort port = new SerialPort(selectedportname, selectedbaudrate, Parity.None, 8, StopBits.One); 

        port.DtrEnable = true;   
        port.Open();             

        if (connecttodevice == true)
        {
            port.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
            DA.SetDataList(0, myReceivedLines);
        }

        if (homeall == true)
        {
            port.Write("g28");
        }

    }

1 个答案:

答案 0 :(得分:3)

通常当我创建一个Com Port时,它是一个Class级别的对象,我在启动期间初始化一次。我会将您的初始化代码移出您的方法并进入构造函数或在启动期间可以调用一次的方法。这样可以防止您尝试多次打开它并仍然可以响应已接收的数据。


我不确定您的架构看起来您可能计划拥有多个端口但是 在评论中回答您的问题,以及您为创建SerialPort所做的一切。至少,SerialPort的声明应该是Class Level变量。然后,您可以检查它是否为零,并在第一次创建它。

string selectedportname = default(string); 
DA.GetData(1, ref selectedportname); 
int selectedbaudrate = default(int); 
DA.GetData(2, ref selectedbaudrate); 
bool connecttodevice = default(bool); 
DA.GetData(3, ref connecttodevice); 

SerialPort port = new SerialPort(selectedportname, selectedbaudrate, Parity.None, 8, StopBits.One);   
port.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);

DA.SetDataList(0, myReceivedLines);   

port.Open();  // optional  I usually open it at the time that I initialize it. you can check `port.IsOpen()`
              // and Open it if it is false.

使用Class Level SerialPort的第二个选项尝试这样的事情:

protected override void SolveInstance(IGH_DataAccess DA)
{
    if(port == null)
    {
        string selectedportname = default(string);
        DA.GetData(1, ref selectedportname);
        int selectedbaudrate = default(int);
        DA.GetData(2, ref selectedbaudrate);
        bool connecttodevice = default(bool);
        DA.GetData(3, ref connecttodevice);
        port = new SerialPort(selectedportname, selectedbaudrate, Parity.None, 8, StopBits.One);
        if (connecttodevice == true)
        {
            port.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
            DA.SetDataList(0, myReceivedLines);
        }

        port.DtrEnable = true;
        port.Open();
    }


    bool homeall = default(bool);
    DA.GetData(5, ref homeall);

    if (homeall == true)
    {
        port.Write("g28");
    }

}