Sajith Nirmal
Sajith Nirmal

Reputation: 1

Read one line at a time

I am currently working on a project. But I am not very good at C#.What I need to do is, Open a G-code file and read data form it and send it via USB to a CNC machine. I can read data and send it. But now I want to read one line and send it via USB and then read the next line. below I have attached the codes which I used to read G-code file and other related data.

Open g-code file and read all data on to a textbox:

 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();


        }

Read X Y Z coordinates from the opened file:

  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);

}

Upvotes: 0

Views: 4914

Answers (4)

Chris Miller
Chris Miller

Reputation: 46

You can't read a gcode file line by line because: A) You can have multiple commands on a single line. B) One command may span multiple lines.

You can use my gcode parsing library at: https://github.com/chrismiller7/GCodeNet

And do something like:

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());
    }
}

Upvotes: 0

Steve
Steve

Reputation: 216273

A bit of refactoring will help to improve your code.
First extract the code from the button click and build a private method that receives a string and operates the commands present on the line. Then modify the method that opens the file to read one line at time and call for each line the extracted method...

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);
    ....
}

Of course, don't forget to call the new private method also from the button click to preserve the previous functionality.

private void button1_Click(object sender, EventArgs e)
{
     ExecuteLine(textBox1.Text);
}

Upvotes: 3

Nolonar
Nolonar

Reputation: 6122

Instead of

textBox1.Text = OpenFile.ReadToEnd();

You'll want

string line = OpenFile.ReadLine();
while (line != null)
{
    // do something with line
    line = OpenFile.ReadLine();
}

Upvotes: 1

Jasmine
Jasmine

Reputation: 4029

You're just reading the whole file at once. You can do that, and then read each line from your in-memory object, or you can simply read one line at a time directly from the file. The second method is more verbose, easier to understand, but it's prone to leaving the file open if you have an error or something happen in the middle.

Here is a demo program showing how to read lines one at a time... http://www.dotnetperls.com/file-readlines

Upvotes: 0

Related Questions