G-code - what am I doing wrong here

hi trying to place codes and parameters, but the if statements seemes not to work

this is the line to split into code and parameter: String gkode= "G1 X45.676 Y97.404 F3600.000 E40.83666";

heres the code:

   delay(3000);
   // int j=1;
    j=0;
    int i=0;
    gkode.trim();
    lengde=gkode.length();
    gkode.toUpperCase();
    for (int i=0; i<lengde;i++)
    {
     curgkode[i]="";
    }
   
   for (int i=0; i<lengde;i++)
    {
     parameter[i]="";
    }
   
   
    for (int m = 0; m<lengde;m++)
    {         
            //  Serial.println(i);
            //  Serial.println(char(gkode.charAt(i)));
              if (gkode.charAt(m)==';') // ikke utfør kommentarer
             {
               i=lengde;           
             }
 //  Serial.println(int(gkode.charAt(i)));
 
  
              if ((int(gkode.charAt(i))>64 && int(gkode.charAt(i))<91))
                  {
                   curgkode[j]=curgkode[j]+(gkode.charAt(i));
                   j=j+1;
                  }

 
              if((int(gkode.charAt(i))>44 && int(gkode.charAt(i))<58))
                  {
                    parameter[j]=parameter[j]+gkode.charAt(i);  
                    
                  }
 Serial.println(j);
              
   } // end for i

There is no way to help you based on that snippet. We have no idea how those arrays are defined, whether they are the proper size, etc.

              if (gkode.charAt(m)==';') // ikke utfør kommentarer
             {
               i=lengde;           
             }

So, i is the index of the ; in the String. Or it is 0 if the String doesn't contain a ;.

              if ((int(gkode.charAt(i))>64 && int(gkode.charAt(i))<91))

Given that your String supposedly contains a ;, how it this useful? gkode.charAt(i) is a ;.

Why i as index when the loop variable is m (I think i just happens to have the variable left
over from a previous loop...)

Yes, post all the code and say what you think it should do, and what it does do....

hi Paul and Mark, thanks for reply

heres the definitions

int j=1; // number of commands in a g-kode line;
int k=0;
int lengde;
int teller;
int comlengde;
String kommando="";
String gkode= "G1 X45.676 Y97.404 F3600.000 E40.83666"; // inneholder eksempel textlinje lest fra .gcode fil
// String gkode= "; M104 S200 ;set temperature"; // test for kommentarer
// String gkode="";
String curgkode[]="";
String parameter[]="";
int paramlengde=0;

and program :

void loop() 
{ 
//  vent til programstart bryter er på
//  åpne slicer filen på SD-lageret i lese-modus
//  while not(EOF)
//  les linje fra tekstfil

//  parse tekstlinjen

  
    
//    parser(gkode);
   delay(3000);
   // int j=1;
    j=0;
    int i=0;
    gkode.trim();
    lengde=gkode.length();
    gkode.toUpperCase();
    for (int i=0; i<lengde;i++)
    {
     curgkode[i]="";
    }
   
   for (int i=0; i<lengde;i++)
    {
     parameter[i]="";
    }
   
   
    for (int m = 0; m<lengde;m++)
    {         
            //  Serial.println(i);
            //  Serial.println(char(gkode.charAt(i)));
              if (gkode.charAt(m)==';') // ikke utfør kommentarer
             {
               i=lengde;           
             }
 //  Serial.println(int(gkode.charAt(i)));
 
  
              if ((int(gkode.charAt(i))>64 && int(gkode.charAt(i))<91))
                  {
                   curgkode[j]=curgkode[j]+(gkode.charAt(i));
                   j=j+1;
                  }

 
              if((int(gkode.charAt(i))>44 && int(gkode.charAt(i))<58))
                  {
                    parameter[j]=parameter[j]+gkode.charAt(i);  
                    
                  }
 Serial.println(j);
              
   } // end for i

What I want to do is

  1. read a line (block) of g-code
  2. Find all gcodes ( G,X,Y,Z,M) and store them in an array named curgkode[j]
  3. Find all parameters, belonging to each gcode, and store them in an array named parameter[j]
    by reading teststring, gkode, one character at a time until end of line

The if test of ';' is to get rid of comments fields

thank You
regards

  1. read a line (block) of g-code

Nothing in that requirement indicates that a String is necessary. Big boys use strings - NULL terminated arrays of chars.

  1. Find all gcodes ( G,X,Y,Z,M) and store them in an array named curgekode[j]

curgekode[j] is not an array. It is an element of the array curgekode. strtok() would parse the data quite easily, if the data was a string.

  1. Find all parameters and store them in an array named parameter[j]

Same comments.

PaulS:

  1. read a line (block) of g-code

Nothing in that requirement indicates that a String is necessary. Big boys use strings - NULL terminated arrays of chars.

  1. Find all gcodes ( G,X,Y,Z,M) and store them in an array named curgekode[j]

curgekode[j] is not an array. It is an element of the array curgekode. strtok() would parse the data quite easily, if the data was a string.

  1. Find all parameters and store them in an array named parameter[j]

Same comments.

ad 1 : Do I understand You right saying suggesting I should work with array of chars instead of string object?
ad 2: Ah, too long since last working with array's. I suppose the strtok() works in Arduino.

regards and thanks

Out of personal curiosity, why are you doing this GCode stuff on an Arduino rather than a PC - where it would be trivial?

...R

Robin2:
Out of personal curiosity, why are you doing this GCode stuff on an Arduino rather than a PC - where it would be trivial?

...R

Thanks G you didnt tell I was reinventing the wheel :).
Im doing this cause Im curios and happens to own an Arduino M 2560

best regards

PaulS:

  1. read a line (block) of g-code

Nothing in that requirement indicates that a String is necessary. Big boys use strings - NULL terminated arrays of chars.

  1. Find all gcodes ( G,X,Y,Z,M) and store them in an array named curgekode[j]

curgekode[j] is not an array. It is an element of the array curgekode. strtok() would parse the data quite easily, if the data was a string.

  1. Find all parameters and store them in an array named parameter[j]

Same comments.

hm, there might be no delimitters in the g-code sentence

The sentence may be written i.e. like this: G1X45.676 Y97.404F3600.000E40.83666
regards

Case is, the program stores the 5 g-codes from the gkode sentence correctly in array. (G,X,Y,F,E)
However, the 2nd if statement, commented, regarding parameter array store theese values: (X,Y,F,E,SPACE) , where I should expect the parameters (numbers/minus sign/period)
The 2nd if statement regarding parameter array also messes up my curgkode array too.

I think Ive stearing at this too long, getting blinded.

Slightly modified code:

   delay(3000);
    j=0;
    i=0;
    gkode.trim();
    lengde=gkode.length();
    gkode.toUpperCase();
    
    for (int i=0; i<lengde;i++)
    {
     curgkode[i]="";
    }
   
   for (i=0; i<lengde;i++)
    {
     parameter[i]="";
    }
   
   
    for (i = 0; i<lengde;i++)
    {         
            //  Serial.println(i);
            //  Serial.println(char(gkode.charAt(i)));
              if (gkode.charAt(i)==';') // ikke utfør kommentarer
             {
               i=lengde;           
             }
 //  Serial.println(int(gkode.charAt(i)));
 
  
              if ((int(gkode.charAt(i))>64 && int(gkode.charAt(i))<91))
                  {
                   curgkode[j]+=gkode.charAt(i);
                  }


 /*             if((int(gkode.charAt(i))>44 && int(gkode.charAt(i))<58))
                  {
                    parameter[j]+=gkode.charAt(i);  
                    
                  }
 */                 
              if ((int(gkode.charAt(i))>64 && int(gkode.charAt(i))<91))
                  {
                   j=j+1;
                  }

              
   } // end for i
   
   
 
             for (int m=0; m<j;m++)
                  {
                  Serial.print("curgkode ");
                  Serial.print(m);
                  Serial.print(" = ");
                  Serial.println(curgkode[m]);
                  Serial.println(parameter[m]);

janeik:
Thanks G you didnt tell I was reinventing the wheel :).

I don't know if you have any use for your project apart from educating yourself ... but if you want to drive stepper motors with GCode there are several pieces of Arduino software such as Grbl and Sprinter.

However my question arose because I can't understand why the authors of those programs interpret GCode on the Arduino rather than on a PC - especially as the GCode is generated on a PC in the first place.

In this piece of code

    for (int m = 0; m<lengde;m++)
    {         
            //  Serial.println(i);
            //  Serial.println(char(gkode.charAt(i)));
              if (gkode.charAt(m)==';') // ikke utfør kommentarer
             {
               i=lengde;           
             }

you have "i = lengde". Perhaps it should be "i=m" to capture the position at which the ";" is found?

...R

Robin2:

janeik:
Thanks G you didnt tell I was reinventing the wheel :).

I don't know if you have any use for your project apart from educating yourself ... but if you want to drive stepper motors with GCode there are several pieces of Arduino software such as Grbl and Sprinter.

However my question arose because I can't understand why the authors of those programs interpret GCode on the Arduino rather than on a PC - especially as the GCode is generated on a PC in the first place.

...R

hi :slight_smile:
Thanks. Im aware of the Norwegian made Grbl which is the bottom of many nc/reprap firmwares. Its mainly for my curosity and trying to look into whats really happening below the surface.
Yes, its for driving steppermotor's , hopefully in a homemade cnc.
What I dont understand is why Norwegians did develope the structure of the Arduino and then SELLING IT AWAY :slight_smile:
(I asume they didnt give it away free).
regards

I am working on a system where my PC converts the GCode to a series of numbers representing the microseconds at which each motor should step plus the total time for the movement. That way the Arduino has little to do apart from figure out how many usecs have passed.

...R

Robin2:
I am working on a system where my PC converts the GCode to a series of numbers representing the microseconds at which each motor should step plus the total time for the movement. That way the Arduino has little to do apart from figure out how many usecs have passed.

...R

Im not yet sure if to use servoes or steppers. Ill have to try running steppers with controller and accellib first to get some experiences.
I have a feeling the controller Ive bought (big easy) isnt fast enough and if uC Mega 2560 is fast enough to control steppers in full 16 microsteps for x,y (and z axes).
So You solely rely on timing to move steppers around? No counting steps? (wonder if 1/16 ustepping and 1.8deg/step rotation is enough accuracy, moving steppers around).
Wish You luck with your project.
regards

Just to clarify...

I am counting steps. (Following numbers are just t illustrate the technique) Suppose a movement takes 2 seconds (due to whatever physical speed limits there may be). That's 2,000,000 microseconds (usecs). Suppose one motor needs to move 500 steps in the time. Then the interval between each step must be 4000 usecs. So if I give the numbers 2000000 and 4000 to the Arduino it will produce 500 steps in 2 secs. And obviously there would be other numbers equivalent to the 4000 which make the other motors do their thing in the same 2 secs.

The PC can take as long as it wants to create the "time" numbers and save them in a file to send to the Arduino later. But the Arduino must be able to move the motors in real time so it seems sensible to reduce its computational load to a minimum. Not to mention the greater ease of PC programming.

It's not your fault but it is very unfortunate that there are motors called "servos" for CNC machines which are entirely different (in function and price) from similarly named devices that are used, for example, to control flying model aircraft. I suspect most users of this forum would assume that "servo" means the model aircraft device.

...R

hey folks.
Would appreciate some help, pointing out why I dont get result I want.
Below is the attached code.
regards

String gkode= "G1 X45.676 Y97.404 F3600.000 E40.83666"; // inneholder eksempel textlinje lest fra .gcode fil
// String gkode= "; M104 S200 ;set temperature"; // test for kommentarer
// String gkode="";
String curgkode[]="";
String param[]="";
int i=0;
int j=0;
int k=0;
int lengde;
int teller;

void setup()
{
  Serial.begin(9600);
}


void loop() 
{ 
//  vent til programstart bryter er på
//  åpne slicer filen på SD-lageret i lese-modus
//  while not(EOF)
//  les linje fra tekstfil
//  parse tekstlinjen

   delay(3000);
    j=0;
    i=0;
    gkode.trim();
    lengde=gkode.length();
    gkode.toUpperCase();
    
    for (int i=0; i<lengde;i++)
    {
     curgkode[i]="";
    }
   
   for (i=0; i<lengde;i++)
    {
     param[i]="";
    }
   i=0;
  
    for (i = 0; i<lengde;i++)
    {         
/*            //  Serial.println(char(gkode.charAt(i)));
              if (gkode.charAt(i)==';') // ikke utfør kommentarer
             {
               i=lengde;           
             }
*/
              // look for letters)
              if ((int(gkode.charAt(i))>64 && int(gkode.charAt(i))<91))
                  {
                   curgkode[j]+=String(gkode.charAt(i));
                  }

             // look for numbers 0-9 . and + or - sign
             if((int(gkode.charAt(i))>44 && int(gkode.charAt(i))<58))
                  {
//                    Serial.println(gkode.charAt(i));
                    
                    param[j]=param[j]+String(gkode.charAt(i));
                    param[j].trim();
                    Serial.print(j);
                    Serial.print(" = ");
                    Serial.println(param[j]);
                    Serial.println(gkode.charAt(i));
                  }
                 
              if ((int(gkode.charAt(i))>64 && int(gkode.charAt(i))<91))
                  {
                   j=j+1;
                  }

              
   } // end for i
   
/*                 Everything seemes to work until I try to print elements in the param array and
                 prints this:
                             1Y
                             45.676F
                             97.404E
                             3600.000
*/

                //  Serial.println(curgkode[m]);
                  Serial.println(String(param[0]));
                  Serial.println(String(param[1]));
                  Serial.println(String(param[2]));
                  Serial.println(String(param[3]));
                  Serial.println(String(param[4]));
                 

//  sett parametre gitt i G-type instruksjoner
//    setparam(); 
}  // end of loop

I can't figure out what you are trying to do and the code you have posted has no setup() section so I can't get it to work.

...R

The OP, janeik, wants to go from a typical Gcode command line to two arrays, one that contains the command character and a corresponding array that contains the value. janeik still needs to make that a numric array, as the string values probably are of little use. The challnge is that this comes from a SD card so the Serial.parseFloat isnt possible - with it it's so easy.

I haven't played with the SD library, so I dont know if it has inherited the parseFloat via the Stream class....

I'm pretty sure the problem is that you have not defined a size for

String curgkode[]="";
String param[]="";

and later when you initialize those arrays the data overwrites all sorts of other stuff. Before you correct anything try printing the value of "lengde" immediately after it is created and again after the arrays are intitalized - the value will have disappeared.

You need to allocate enough space for the two arrays so that they can fit the biggest gkode. For example

String curgkode[50]="";
String param[50]="";

I noticed that you had little or no debugging "Serial.println()" stuff in your code. It's pretty hard to figure things out without it.

...R

Robin2:
I can't figure out what you are trying to do and the code you have posted has no setup() section so I can't get it to work.

...R

Sri, Ive added it now. (Serial.begin.....

regards