New C# Method Request

If you have a question about the software please ask it here.

Re: New C# Method Request

Postby beefy » Sat Aug 12, 2017 8:20 pm

Hi Balazs,

thanks for that, hope you are keeping well.

It was NET 4 something, (VS Community 2015 I think) so I changed it to NET 2.0

Got rid of a couple of the "using........." lines at the top (including Linq) and still debugging good.

It's killing me having to divert my attention to studying for my truck driver test. This programming stuff is dangerous, once you start working on a program it's hard to stop until you get it completed. It can make you miss appointments, not see to other responsibilities, etc. I can be at the shopping centre and I'm trying to figure out how to crack it :shock:

Can't imagine what it's like for you guys with the projects you work on.

Keith.
beefy
 
Posts: 449
Joined: Mon Sep 05, 2016 10:34 am

Re: New C# Method Request

Postby Robertspark » Sat Aug 12, 2017 9:03 pm

Yes it is immersive.... That's why I enjoy it... Doesn't matter where I am I have a notepad and a pencil scribbling ideas down
... Wish I could see a business in it from my perspective (too risk averse)
Robertspark
 
Posts: 1892
Joined: Sat Sep 03, 2016 4:27 pm

Re: New C# Method Request

Postby Robertspark » Mon Aug 14, 2017 2:30 pm

Stepping back to that "Regex" method of extacting the g-code information from a line of code.....

I've come up with the following (note it's a work in progress piece of code..... it works but does not quite extract the data into the array rows in the way it's needed to (the pattern needs sorting / understanding a little more) But the bare bones is there for a bit more development.

Note, you need to load a g-code file first or it will throw up an exception (not worried about that at present, as I can deal with that later).

Like Keith, Regex was bugging me and I needed to understand it a little more.

The pattern switches are a bit to get your head around as there are a load of options available:
https://docs.microsoft.com/en-us/dotnet ... -reference


Code: Select all
// get gcode line
string strGcode = AS3.Getfield(866); // read the current [active] gcode line number
string strCurrGcodeFilename = exec.Getgcodefilename(); // Get  path + filename of current loaded gcode file

MessageBox.Show(strGcode + "\n" + strCurrGcodeFilename);

int myLineNumber = Convert.ToInt32(strGcode);

string line = null;

using( System.IO.Stream fileStream = System.IO.File.Open(strCurrGcodeFilename, System.IO.FileMode.Open) )
{
using (System.IO.StreamReader reader = new System.IO.StreamReader(fileStream) )
    {
       
        for( int i = 0; i < myLineNumber; ++i )
        {
            line = reader.ReadLine();
         
        }
      
      MessageBox.Show(line);
    }
}

string pattern;
    pattern = @"([abcdefhijklpqrsxyz]?\s*[+-]?([0-9]+([\.,][0-9]*)?|[\.,][0-9]+)\s*)|";
    pattern += @"([g]\s*\d+([\.][0-9])*\s*)|";
    pattern += @"(m\s*\d+\s*{\s*)|";
    pattern += @"(}\s*)|";
    pattern += @"([mnot]\s*\d+\s*)|";
    pattern += @"([abcdefhijklpqrstxyz]\s*#\s*\d+\s*)|";
    pattern += @"([abcdefhijklpqrstxyz]\s*##\s*\d+\s*)|";
    pattern += @"(#\s*\d+\s*=)|";
    pattern += @"(@)|";
    pattern += @"(\(.*\))\s*";

   string[] digits = System.Text.RegularExpressions.Regex.Split(line, pattern);
   
   int length = digits.GetLength(0);
   MessageBox.Show("Array Rows " + Convert.ToString(length));

   for( int i = 0; i < length; ++i )
        {
            MessageBox.Show(digits[i]);
         
        }
   
Robertspark
 
Posts: 1892
Joined: Sat Sep 03, 2016 4:27 pm

Re: New C# Method Request

Postby dezsoe » Mon Aug 14, 2017 6:16 pm

Robertspark wrote:does not quite extract the data into the array rows in the way it's needed to (the pattern needs sorting / understanding a little more)

With what kind of code did you get problems? I use this regex in my QuickView plugin and as I know I had no trouble with it. But if there is any, then I would like to know, so I could fix it in the plugin.
dezsoe
 
Posts: 2093
Joined: Sun Mar 12, 2017 4:41 pm
Location: Csörög, Hungary

Re: New C# Method Request

Postby Robertspark » Mon Aug 14, 2017 6:43 pm

It's more than likley me + user error on my part...

I copied the code you kindly provided (as it was) and placed it in a macro and it failed to run

I then modified it as it appeared to not like the initial bracket at the front of the string "("

It also did not seem to like the long pattern string and the way it was joined with "+" for whatever reason... Hence I used =+ instead which should do the same thing

It would not split the gcode line as it appeared to not like recognise the upper case alpabetic letters hence I added a question mark after the first string of characters

Code: Select all
...]?...


Which seems to now work ... A bit in that it splits the gcode string into alphabetic and numeric.

Note I was using the "brackets.tap" file within the examples folder and just picked a random line of gcode

I'm not in front of my pc at present but may be in a few hours
Robertspark
 
Posts: 1892
Joined: Sat Sep 03, 2016 4:27 pm

Re: New C# Method Request

Postby dezsoe » Mon Aug 14, 2017 9:09 pm

OK, I see. The problem was not with you and not with the code but me: I forgot to say that it's in Visual Basic. I'm not a big fan of C#, I use it when I have to, but will never be in love with any kind of C. :) (No matter with Visual Basic: it compiles - theoretically - to the same .Net object code as C#.) I also did not mention that no need to change the regex expression to handle uppercase letters, just tell regex to ignore case. Here is the code snippet for getting whole words of code (also in Visual Basic):

Code: Select all
            Dim sWork As String = ""
            Dim iStart As Integer = 0
            Dim iNext As Integer = 0

            If Strings.Left(sInput, 1) = "%" Then
                sInput = "(" + Strings.Mid(sInput, 2) + ")"
            End If

            sInput += "@"

            Dim cWords As New Collection

            Dim tag As String = ""
            Try
                Dim mMatch As Match = Regex.Match(sInput, sControlsPattern, RegexOptions.IgnoreCase Or RegexOptions.Compiled)
                Do While mMatch.Success
                    sWork = mMatch.Groups(1).Value
                    iStart = mMatch.Groups(1).Index
                    If iStart <> iNext Then
                        tag = Mid(sInput, iNext + 1, iStart - iNext)
                        tag = Trim(tag.ToUpper)
                        cWords.Add(tag)
                    End If
                    iNext = iStart + mMatch.Groups(1).Length
                    '
                    tag = Trim(sWork.ToUpper)
                    cWords.Add(tag)
                    '
                    mMatch = mMatch.NextMatch()
                Loop
            Catch ex As TimeoutException
                tbStatusText.AppendText("Oops!" + vbCrLf)
            End Try

Some remarks. The "@" is added to the line to always have at least one match: faster and easier code. "%" is changed to brackets to have only one kind of remarks in code. (My code interpreter reads not only UCCNC compatible codes.) The trick with iStart and iNext is for collecting the "unmatched" characters which can be either useful or garbage, but I need all of them.
dezsoe
 
Posts: 2093
Joined: Sun Mar 12, 2017 4:41 pm
Location: Csörög, Hungary

Re: New C# Method Request

Postby Robertspark » Tue Aug 15, 2017 12:22 am

Dezsoe, thanks very much, you had me there with that code, if I'd have seen the "Dim" I would have realised it was VB.....

Can you mix C# with VB in a uccnc macro? or do I need to change the rest of the code [not much of it] to be in VB?

I was trying to implement this as a screenset button code (although at the moment for ease, I'm just running it as a MDI macro, which is why you see all the messagebox methods as I'm just testing the flow / returns as it's easier to visually see what the code is throwing up as it progresses).
_______________________________________________________________________________________________

What's wrong with C#?
Must abmit that VB is syntax easier (no missing off the ";" and it also reads easier). But I thought it was on its way out except for some use within Microsoft legacy products [excel probably one of the major ones I've used it for automation (single task repitition) via button click] Other than a few attemps with it over the years and Mach3 + Cypress VB I've not used it much (what with C, C++, C#, LUA, and arduino & processing variations on C.... I'm kind of stuck with C.... don't want to be learning yet another languague as a hobby user or I'd end up chasing yet another load of syntax issues [I've done Diesel and lisp in autocad too along the way on + off]
Robertspark
 
Posts: 1892
Joined: Sat Sep 03, 2016 4:27 pm

Re: New C# Method Request

Postby Robertspark » Tue Aug 15, 2017 3:02 am

This bit of code seems to work ok for me [it is still work in progress and not a completed macro]

In order to run it you will need to have a gcode file loaded, and select a random line
It will then display the current line of code
It will split the line of code in Alpha AND numeric+decimal+numeric AND neumeic
It will then join the line of code back into Alpha + numeric(regardless of decimal or negative value)

You can uncomment the messagebox if you wish to view the data being created as the macro progresses

Code: Select all
// get gcode line
string strGcode = AS3.Getfield(866); // read the current [active] gcode line number
string strCurrGcodeFilename = exec.Getgcodefilename(); // Get  path + filename of current loaded gcode file

MessageBox.Show(strGcode + "\n" + strCurrGcodeFilename);

int myLineNumber = Convert.ToInt32(strGcode);

string line = null;

using( System.IO.Stream fileStream = System.IO.File.Open(strCurrGcodeFilename, System.IO.FileMode.Open) )
{
using (System.IO.StreamReader reader = new System.IO.StreamReader(fileStream) )
    {
       
        for( int i = 0; i < myLineNumber; ++i )
        {
            line = reader.ReadLine();
         
        }
     
      MessageBox.Show(line);
    }
}


string pattern;
   pattern = @"(\D+)|(-?\d+\.\d+)|(-?\d+\.)|(-?\d+)";

   
System.Text.RegularExpressions.MatchCollection matches = System.Text.RegularExpressions.Regex.Matches(line, pattern);
string[] digits = new string[matches.Count];
for (int i = 0; i < matches.Count; i++)
{
    digits[i] = matches[i].Value;
}


int length = digits.GetLength(0);
   MessageBox.Show("Array Rows " + Convert.ToString(length));

  // for( int i = 0; i < length; ++i )
  //      {
  //          MessageBox.Show(digits[i]);
  //       
  //      }
int length2 = length / 2;
string[] gcodeStrings =  new string [length2];
int j = 0;
   for( int i = 0; i < length2; ++i )
   {
   gcodeStrings [i] = string.Concat(digits[j], digits[j+1]);
   j+=2;   
   }
   
   //Array.Sort(gcodeStrings);

for( int i = 0; i < length2; ++i )
        {
            MessageBox.Show(gcodeStrings[i]);
         
        }

Robertspark
 
Posts: 1892
Joined: Sat Sep 03, 2016 4:27 pm

Re: New C# Method Request

Postby dezsoe » Tue Aug 15, 2017 9:52 pm

Hi Rob,

Can you mix C# with VB in a uccnc macro?

No, UCCNC works only with C# macros. The code snippet is from a plugin (and also a desktop application). Since VB compiles to standard .Net object code, you can write plugins also in VB or any other .Net language.

What's wrong with C#?

Nothing. Just C# is not my favorite, I prefer VB.
dezsoe
 
Posts: 2093
Joined: Sun Mar 12, 2017 4:41 pm
Location: Csörög, Hungary

Re: New C# Method Request

Postby Robertspark » Wed Aug 16, 2017 9:20 pm

A bit of an updated working (work in progress) code snippet for reading the currently active gcode line
(I took another look at dezsoe's Regular Expression and found a regular expression viewer to understand the info I was given)
http://regexstorm.net/tester

This code gets the currently active line number
Reads the line with StreamReader
splits the string up into a 2 column array [number of rows is dependant upon the gcode split]
And stores the Alpha code [G,A,B,C,X,Y,Z,I,J,K,S,F,etc] in column [i,0] and the split gcode [G1,G2,G3,X123.234,Y-123.456 etc] in column [i,1]

The message box bits are just to display the stored values as the mocro progresses so that you can see what values are obtained and where they are located

You may ask why do you need the "alpha code" well the plan is to use a switch statement to assign the gcode snippets into a 26 position array, that way they can always be recovered and tested for (they could also be put into #Vars..... similar to Macro B.... although depends what you want to use them for...

Code: Select all
// get gcode line
string strGcode = AS3.Getfield(866); // read the current [active] gcode line number
string strCurrGcodeFilename = exec.Getgcodefilename(); // Get  path + filename of current loaded gcode file

MessageBox.Show(strGcode + "\n" + strCurrGcodeFilename);

int myLineNumber = Convert.ToInt32(strGcode);

string line = null;

using( System.IO.Stream fileStream = System.IO.File.Open(strCurrGcodeFilename, System.IO.FileMode.Open) )
{
using (System.IO.StreamReader reader = new System.IO.StreamReader(fileStream) )
    {
        for( int i = 0; i < myLineNumber; ++i )
        {
            line = reader.ReadLine();
        }
      MessageBox.Show(line);
    }
}

string pattern1;
   pattern1 = @"([abcdefghijklpqrsxyz]\s*)";

   
System.Text.RegularExpressions.MatchCollection matches1 = System.Text.RegularExpressions.Regex.Matches(line, pattern1, System.Text.RegularExpressions.RegexOptions.IgnoreCase);
string[,] gCode = new string[matches1.Count,2];
for (int i = 0; i < matches1.Count; i++)
{
    gCode[i,0] = matches1[i].Value;
}

int length1 = gCode.GetLength(0);
   MessageBox.Show("Array Rows " + Convert.ToString(length1));

for( int i = 0; i < length1; ++i )
    {
      MessageBox.Show(gCode[i,0]);
    }

string pattern;
   pattern = @"([abcdefhijklpqrsxyz]\s*[+-]?([0-9]+([\.,][0-9]*)?|[\.,][0-9]+)\s*)|([g]\s*\d+([\.][0-9])*\s*)";
   
System.Text.RegularExpressions.MatchCollection matches = System.Text.RegularExpressions.Regex.Matches(line, pattern, System.Text.RegularExpressions.RegexOptions.IgnoreCase);

for (int i = 0; i < matches.Count; i++)
{
    gCode[i,1] = matches[i].Value;
}

for( int i = 0; i < length1; ++i )
    {
      MessageBox.Show(gCode[i,1]);
    }

for( int i = 0; i < length1; ++i )
    {
   MessageBox.Show("Row " + i + "   "  + gCode[i,0] + "   " + gCode [i,1]);
   }


A suggestion is to try this on a number of gcode files / formats as some do not repeat the modal commands like G1, G2 and G3, or the feedrate (or spindle speed) hence you'll just recover the X,Y,Z,I,J,K,A,B,C accordingly and you may need to use other uccnc fields to establish what the current modal commands actually are, current stored feed rate (or spindle speed) should you want to change and reset these later. As discussed earlier you'll also need to check out if the machine is in absolute or incremental mode { actualdistancemode } before moving it back to another location .

Useful fields will therefore be:
Field # 877 Activemodal
Field # 867 Setfeedrate
Field # 869 Setspindlespeed [if required .... not for plasma obviously .... unless used for THC voltage / set cut ampage via RS485 interface maybe??]
Robertspark
 
Posts: 1892
Joined: Sat Sep 03, 2016 4:27 pm

PreviousNext

Return to Ask a question from support here

Who is online

Users browsing this forum: No registered users and 12 guests