[solved] infinite loop in GcodeCNCDemo…V2

Home Forum Everything Else [solved] infinite loop in GcodeCNCDemo…V2

  • This topic is empty.
Viewing 9 posts - 1 through 9 (of 9 total)
  • Author
    Posts
  • #6069
    AvatarAnonymous
    Inactive

    Hello,

    I am presently testing the GcodeCNCDemo sketches.(arduino due, version 1.5.8 ,windows 8.1) It does run one time and move the stepper motors when entering e.g.
    G00 X100 F300; in the serial monitor. It will not accept a second command. To see what is happening, I added some print commands and learned that it is not leaving the while loop in function parse number:

    float parsenumber(char code,float val) {
    char *ptr=buffer;

    while(ptr && *ptr && ptr Serial.print(“a ptr : “); Serial.println(ptr);
    Serial.print(“a *ptr : “); Serial.println(*ptr);
    Serial.print(“a buffer :”);Serial.println( buffer);
    Serial.print(“a buffer+sofar :”); Serial.println( buffer+sofar);
    Serial.print(“sofar :”); Serial.println(sofar);

    if(*ptr==code) {
    return atof(ptr+1);
    }
    ptr=strchr(ptr,’ ‘)+1;

    Serial.print(“b ptr : “); Serial.println(ptr);
    Serial.print(“b *ptr : “); Serial.println(*ptr);
    Serial.print(“b buffer :”);Serial.println( buffer);
    Serial.print(“b buffer+sofar :”); Serial.println( buffer+sofar);

    }
    return val;
    }

    This gives the following output in the serial monitor, processing the commands until it runs into the semicolon :

    codeCNCDemo6AxisV2 2
    Commands:
    G00/G01 [X/Y/Z/U/V/W(steps)] [F(feedrate)]; – linear move
    G04 P[seconds]; – delay
    G90; – absolute mode
    G91; – relative mode
    G92 [X/Y/Z/U/V/W(steps)]; – change logical position
    M18; – disable motors
    M100; – this help message
    M114; – report position and feedrate
    >G00 X100 F300;G00 X100 F300;

    sofar :14
    ptr : G00 X100 F300;
    *ptr : G
    buffer :G00 X100 F300;
    buffer+sofar :
    in while
    a ptr : G00 X100 F300;
    a *ptr : G
    a buffer :G00 X100 F300;
    a buffer+sofar :
    sofar :14
    sofar :14
    ptr : G00 X100 F300;
    *ptr : G
    buffer :G00 X100 F300;
    buffer+sofar :
    in while
    a ptr : G00 X100 F300;
    a *ptr : G
    a buffer :G00 X100 F300;
    a buffer+sofar :
    sofar :14
    b ptr : X100 F300;
    b *ptr : X
    b buffer :G00 X100 F300;
    b buffer+sofar :
    in while
    a ptr : X100 F300;
    a *ptr : X
    a buffer :G00 X100 F300;
    a buffer+sofar :
    sofar :14
    b ptr : F300;
    b *ptr : F
    b buffer :G00 X100 F300;
    b buffer+sofar :
    in while
    a ptr : F300;
    a *ptr : F
    a buffer :G00 X100 F300;
    a buffer+sofar :
    sofar :14
    sofar :14
    ptr : G00 X100 F300;
    *ptr : G
    buffer :G00 X100 F300;
    buffer+sofar :
    in while
    a ptr : G00 X100 F300;
    a *ptr : G
    a buffer :G00 X100 F300;
    a buffer+sofar :
    sofar :14
    b ptr : X100 F300;
    b *ptr : X
    b buffer :G00 X100 F300;
    b buffer+sofar :
    in while
    a ptr : X100 F300;
    a *ptr : X
    a buffer :G00 X100 F300;
    a buffer+sofar :
    sofar :14
    sofar :14
    ptr : G00 X100 F300;
    *ptr : G
    buffer :G00 X100 F300;
    buffer+sofar :
    in while
    a ptr : G00 X100 F300;
    a *ptr : G
    a buffer :G00 X100 F300;
    a buffer+sofar :
    sofar :14
    b ptr : X100 F300;
    b *ptr : X
    b buffer :G00 X100 F300;
    b buffer+sofar :
    in while
    a ptr : X100 F300;
    a *ptr : X
    a buffer :G00 X100 F300;
    a buffer+sofar :
    sofar :14
    b ptr : F300;
    b *ptr : F
    b buffer :G00 X100 F300;
    b buffer+sofar :
    in while
    a ptr : F300;
    a *ptr : F
    a buffer :G00 X100 F300;
    a buffer+sofar :
    sofar :14
    b ptr : € µ
    b *ptr : €
    b buffer :G00 X100 F300;
    b buffer+sofar :
    in while
    a ptr : € µ
    a *ptr : €
    a buffer :G00 X100 F300;
    a buffer+sofar :
    sofar :14

    and so on…..

    ( I selected no line end at the bottom of the serial monitor)

    The questions that arise to me particularly concern the while condition : buffer+sofar – a character array is added to an integer value. What is the value this expression should contain and where is it correctly (re)set ?

    After the pointer *ptr reaches the end of the string (;), its contents seem undefined and not reset.

    Furthermore, in void loop function buffer[sofar]=0; an element of an array of character is assigned an integer value.

    Obviously, several ( implicit ) type conversions in my case do not work correctly and I would appreciate and I would appreciate advice for better understanding of the code and make it more robust.

    Thank you very much

    #6896
    AvatarAnonymous
    Inactive

    send newline. the latest firmware doesn’t start to process a command until it gets the ‘n’ newline character.

    /**
    * Look for character /code/ in the buffer and read the float that immediately follows it.
    * @return the value found. If nothing is found, /val/ is returned.
    * @input code the character to look for.
    * @input val the return value if /code/ is not found.
    **/
    float parsenumber(char code,float val) {
    char *ptr=buffer; // start at the beginning of buffer
    while(ptr && *ptr && ptr<buffer+sofar) { // walk to the end
    if(*ptr==code) { // if you find code on your walk,
    return atof(ptr+1); // convert the digits that follow into a float and return it
    }
    ptr=strchr(ptr,' ')+1; // take a step from here to the letter after the next space
    }
    return val; // end reached, nothing found, return default val.
    }

    I will update the code with these comments for everyone else.

    Please feel free to submit a pull request with your improvements to the code.

    #6897
    AvatarAnonymous
    Inactive

    Hi

    I tested your advice using all three options (newline, carriage return and both CR and NL) Furthermore, I did not mention that I already tested the functions atof(ptr+1) and strchr(ptr,’ ‘+1), and seen them to work right. Same is true for the condition *ptr == code. parsenumber returns, giving the correct number as it should.

    In order to keep output clutter to a minimum I restricted the print commands to the while condition as posted. The problem remains. I cannot control the value of ( ptr && *ptr && ptr<buffer+sofar). The output shows that he indeed does “walk to the end”, but misses it. Pointers and strings are not correctly reset and the expression buffer+sofar neither is printed by the Serial command nor is it clear to me what it is supposed to contain.

    #6898
    AvatarAnonymous
    Inactive

    buffer is the address of a block of data. Over time it is filled with characters received from the serial line.
    sofar is a count of the number of bytes received from the serial line and stored starting at address buffer. In other words, buffer[sofar-1] is the last character received from the serial line and buffer+sofar is the address in memory of the last character received. When the system is ready to receive a new instruction, it sets sofar=0;

    ptr is an address. *ptr is the value at that address. char *ptr=buffer means “create a pointer called ptr and set the address to be the same as the address of buffer.”

    Strings in C are usually terminated with a null (number 0) character. String functions like strchr() and atof() agree to this standard. *ptr == 0 is true when ptr is pointing at the end of the string of characters. When the data is being read in from serial, *ptr is set to the new character and *(ptr+1) is set to zero, every time. The value is implicitely typecast to (char)0. That way the string is never unfinished.

    strchr() returns null (0) when it cannot find the character it seeks. At the end of the string ptr=strchr(ptr,’ ‘)+1 would set ptr equal to buffer+sofar+1, which would end the while() loop.

    #6899
    AvatarAnonymous
    Inactive

    In the meanwhile, I tested things a bit using an arduino uno and version 1.0.6. instead of 1.5.8 and due. This works so far in my case. Commands printing *ptr and ptr then do not print anything in the serial monitor and the while loop in parsenumber is exited. I presume but cannot verify some subtle difference in subjacent c/c++ compilers used.

    #6900
    AvatarAnonymous
    Inactive

    Interesting. I wonder what happens if you run 1.0.6 and a due. Thanks for the update!

    #6901
    AvatarAnonymous
    Inactive

    The table summarizes the results of the tests I did

    Version / Line Ending? / Due / Mega2560 / Uno
    106 / no line end / n.a. / ok / ok
    106 / newline / n.a. / once / once
    158 / no line end / once / ok / ok
    158 / newline / once / once / once

    Due board is not listed in tools-board in version 106.

    G00 X400 Y 400 Z400 U400 V400 W400 F300;
    G0 X300;
    G0 Y300;
    G0 Z300;
    G0 U300;
    G0 V300;
    G0 W300;

    Sending all commands at once to a Mega or Uno , they are completely executed with newline and no line end under both 158 and 106.
    Once means only the first line is executed.
    OK means I sent the first line, waited for the steppers to stop, then sent one of the short lines and saw the corresponding stepper motor move again.

    #6902
    AvatarAnonymous
    Inactive

    There’s no Duemilanove in v1.0.6? Due was their first board. Is your version maybe missing a file?

    #6903
    AvatarAnonymous
    Inactive

    There is. I simply did not get the idea to try since they are not completely the same boards. Fails to upload ( in 106 ) at the moment.
    (avrdude: stk500_getsync() : not in sync: resp=0x00).
    When I found out whats the current problem I will test.

Viewing 9 posts - 1 through 9 (of 9 total)
  • You must be logged in to reply to this topic.