向串口发送正确的Gcode字符串?

4
我正在尝试通过线路 port.Write("g28");向我的RepRap 3D打印机发送Gcode g28。程序已连接到正确的串行端口,但是当我尝试将信息作为字符串发送时,访问com端口被拒绝。这很奇怪,因为在向其发送Gcode之前,串行端口是开放的,甚至发送了一些数据。问题出在哪里?如何解决?
以下是我使用的代码行。 gcode命令列表可在此页面上找到。
我尝试在字符串末尾添加"\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");
        }

    }

当以前没有出现这种情况时,对 com 端口的访问被拒绝了。在这之前是什么情况?您尝试过使用大写字母 "G" 吗? - sawdust
@sawdust 在将Gcode发送到串口之前,我刚刚更新了问题。非常感谢。 - Arthur Mamou-Mani
1
“port.Write(“g28”)”- “g28”甚至不在有效操作列表中,您要执行哪个操作? “G”或“M”必须大写,并且需要使用“\n”终止该行代码。 “它甚至发送了一些数据回来。” - 那个消息是什么? - sawdust
1
我假设SolveInstance只被调用了一次,否则串口将会被锁定,因为在第一次调用时创建了Com Port。 - Mark Hall
1
@ArthurMamou-Mani 请在您的方法末尾放置一个port.Close()。 - Mark Hall
显示剩余3条评论
1个回答

3
通常,当我创建一个Com端口时,它是一个类级别的对象,在启动期间初始化一次。我建议您将初始化代码从方法中移出,并放到构造函数或启动期间可以调用的方法中。这样可以防止您尝试多次打开它,但仍然使其可用于响应接收到的数据。
我不确定您的架构,看起来您可能计划拥有多个端口,但为了回答您在评论中提出的问题,您所做的一切都是为了创建SerialPort。至少,SerialPort的声明应该是一个类级变量。您可以检查它是否为空,并在第一次创建它。
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.

使用类级别的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");
    }

}   

非常感谢,您会在上面的代码中包含什么“初始化代码”? - Arthur Mamou-Mani
抱歉,如果我从 SolveInstance 中移除所有的 if 语句,那么我怎么能够从我的程序中访问它们,因为 SolveInstance() 方法是我可以向其分配数据的地方?非常感谢。 - Arthur Mamou-Mani
@ArthurMamou-Mani 看看第二个选项,主要是要避免创建多个SerialPorts。 - Mark Hall
非常感谢@MarkHall,使用第二个选项时,当我打开HomeAll时出现错误:Error: Solution exception: A device attached to the system is not functioning。然后,当我打开其他命令并且端口应该连接时,我会得到:Error:Solution exception: The port is closed. 当所有命令都为false时,错误就消失了。我只想连接一个设备。即使多次打开和关闭ConnecttoDevice按钮,我也不再收到access denied消息,这是一件好事。 - Arthur Mamou-Mani
更新:感谢您的回复,我成功发送了G代码并且机器做出了正确的反应(所以这是正确的答案),但我不再收到反馈。我会继续努力解决这个问题。 - Arthur Mamou-Mani
@ArthurMamou-Mani 很高兴能提供一些帮助。 - Mark Hall

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接