0

我目前正在做一个项目。但我不太擅长 C#。我需要做的是,打开一个 G 代码文件并从中读取数据,然后通过 USB 将其发送到 CNC 机器。我可以读取数据并发送它。但现在我想读取一行并通过 USB 发送,然后读取下一行。下面我附上了我用来读取 G 代码文件和其他相关数据的代码。

打开 g 代码文件并将所有数据读入文本框:

 private void btnopen_Click(object sender, EventArgs e)
    {
        //OpenFileDialog1.ShowDialog();
        OpenFileDialog file = new OpenFileDialog();
        file.FileName = "";
        file.Title = "Open A Text document.";
        file.Filter = "(*.gc)|*.gc|(*.etf)|*.etf|(*.txt)|*.txt|(*.GC)|*.GC|(*.tap)|*.tap";
        DialogResult result = file.ShowDialog();
        if (result == DialogResult.OK)
        {
            System.IO.StreamReader OpenFile = new System.IO.StreamReader(file.FileName);


            textBox1.Text = OpenFile.ReadToEnd();

            OpenFile.Close();


        }

从打开的文件中读取 XYZ 坐标:

  private void button1_Click(object sender, EventArgs e)
    {


        Regex Gcode = new Regex("[ngxyzf][+-]?[0-9]*\\.?[0-9]*", RegexOptions.IgnoreCase);
        MatchCollection m = Gcode.Matches(this.textBox1.Text);


        double X, Y, Z, F;


        int g_code = 0;
        int x_code = 0, y_code = 0, z_code = 0;
        float x = 0, y = 0, z = 0;


        foreach (Match n in m)
        {

            if (n.Value.StartsWith("G"))
            {
                g_code = Convert.ToInt32(ExtractNumbers(n.Value));
            }

            if (n.Value.StartsWith("X"))
            {
                x = float.Parse(ExtractNumbers(n.Value));
                x = x * 1000;
                x_code = Convert.ToInt32(x);

            }

            if (n.Value.StartsWith("Y"))
            {
                y = float.Parse(ExtractNumbers(n.Value));
                y = y * 1000;
                y_code = Convert.ToInt32(y);

            }

            if (n.Value.StartsWith("Z"))
            {
                z = float.Parse(ExtractNumbers(n.Value));
                z = z * 1000;
                z_code = Convert.ToInt32(z);
            }
        }


        ExchangeInputAndOutputReports(g_code,x_code, y_code,z_code);

}

4

4 回答 4

3

一些重构将有助于改进您的代码。
首先从按钮单击中提取代码并构建一个私有方法,该方法接收一个字符串并操作该行上存在的命令。然后修改打开文件的方法,每次读取一行,并为每一行调用提取的方法...

using(StreamReader OpenFile = new System.IO.StreamReader(file.FileName))
{
    string textLine = string.Empty;
    // Loop until the end of file and call the operation for the line
    while((textLine = OpenFile.ReadLine()) != null)
        ExecuteLine(textLine);
}

private void ExecuteLine(string line)
{
    Regex Gcode = new Regex("[ngxyzf][+-]?[0-9]*\\.?[0-9]*", RegexOptions.IgnoreCase);
    MatchCollection m = Gcode.Matches(line);
    ....
}

当然,不要忘记从按钮单击中调用新的私有方法以保留以前的功能。

private void button1_Click(object sender, EventArgs e)
{
     ExecuteLine(textBox1.Text);
}
于 2013-06-19T16:14:20.157 回答
1

代替

textBox1.Text = OpenFile.ReadToEnd();

你会想要

string line = OpenFile.ReadLine();
while (line != null)
{
    // do something with line
    line = OpenFile.ReadLine();
}
于 2013-06-19T16:12:11.103 回答
0

您只是一次阅读整个文件。您可以这样做,然后从内存对象中读取每一行,或者您可以直接从文件中一次读取一行。第二种方法更冗长,更易于理解,但如果您有错误或中间发生某些事情,它很容易使文件保持打开状态。

这是一个演示程序,展示了如何一次读取一行... http://www.dotnetperls.com/file-readlines

于 2013-06-19T16:11:25.940 回答
0

您不能逐行读取 gcode 文件,因为: A) 您可以在一行中有多个命令。B) 一个命令可能跨越多行。

您可以在以下位置使用我的 gcode 解析库:https ://github.com/chrismiller7/GCodeNet

并执行以下操作:

var gcodeFile = new GCodeFile(File.ReadAllText("file.gcode"));
foreach (var cmd in gcodeFile.Commands)
{
    if (cmd.CommandType == CommandType.G)
    {
        var X = cmd.GetParameterValue(ParameterType.X)*1000;
        var Y = cmd.GetParameterValue(ParameterType.Y)*1000;
        var Z = cmd.GetParameterValue(ParameterType.Z)*1000;

        cmd.SetParameterValue(ParameterType.X, X);
        cmd.SetParameterValue(ParameterType.Y, Y);
        cmd.SetParameterValue(ParameterType.Z, Z);
        ExchangeInputAndOutputReports(cmd.ToGCode());
    }
}
于 2016-10-26T15:00:38.340 回答