586,103 active members*
3,827 visitors online*
Register for free
Login
IndustryArena Forum > Machine Controllers Software and Solutions > Dynomotion/Kflop/Kanalog > Preventing G-code execution in C, and problems evaluating while loop conditionals
Results 1 to 8 of 8
  1. #1
    Join Date
    May 2016
    Posts
    35

    Preventing G-code execution in C, and problems evaluating while loop conditionals

    Hi Tom,

    I have two questions, one following from the other. I have an axis with two motors on either side of the bed that needs to home them in case they were moved while the machine was off, usually just a small number of encoder counts. Each has a home sensor at the end of travel, and an index on the encoder. The procedure had been to drive the axes into the home sensors one at a time, then away from them into the respective indices, and the measured delta is compared to what it should be as measured with a test indicator and adjusted. Question 1 comes from accidentally commanding a G0 while the axes were still in motion (oops) and the G0 command moved only one motor until a following error fault occurred and the gantry was tweaked: is there a way in C to disable G code from executing even if the operator boneheads it in KmotionCNC before they should?

    Question 2 comes from trying to fix the misalignment caused above. Earlier the homing motion would be repeated twice, once for each axis, but this doesn't work with the large alignment error as one axis would overtravel before the other found the home sensor. So I tried to have both axes drive towards their home sensors as simultaneous independent motions, and each would stop once the respective home sensor is found:

    Jog(X0_AXIS,FAST_SPEED); // move towards sensor
    Jog(X1_AXIS,FAST_SPEED); // move towards sensor
    x0_moving = 1; //int defined above
    x1_moving = 1; //int defined above


    while(x0_moving || x1_moving) {
    //while(!ReadBit(X0_HOME_BIT) || !ReadBit(X1_HOME_BIT)){


    if (ReadBit(X0_HOME_BIT)) {
    Jog(X0_AXIS,0.0); // StopMotion
    home0 = chan[X0_AXIS].Position;
    x0_moving = 0;
    printf("Found x0 home sensor, stopping x0. Home at %f\n", home0);
    }
    if (ReadBit(X1_HOME_BIT)) {
    Jog(X1_AXIS,0.0); // StopMotion
    home1 = chan[X1_AXIS].Position;
    x1_moving = 0;
    printf("Found x1 home sensor, stopping x1. Home at %f\n", home1);
    }
    WaitNextTimeSlice();
    }
    printf("post loop %d %d\n", x0_moving, x1_moving);




    Without the WaitNextTimeSlice(); present it would immediately skip to the post loop printf without executing anything inside the while loop.
    Adding the WaitNextTimeSlice() seems to have it hang inside the loop, but it won't read the home sensors. (without any code running I can watch them change in the Kmotion Digital I/O screen as expected)
    If I instead use "while(!ReadBit(X0_HOME_BIT) || !ReadBit(X1_HOME_BIT)){" instead it seems to actually evaluate the inside of the while loop, except that that isn't actually the while condition I want it to be checking.

    I've been having a bunch of KFLOP crashes while debugging this as well.
    One of the errors produced a small hex dump in the console: "Aborti013500AE 00000029 00000168 00000168 0000016E 00000167 0000016E 00000168 00000169 00000000 00000000 00000000 00000000 00000000 00000000 00000000"
    And it often seems to hard crash the Kflop until I do a power cycle on it: "Kmotion present but not responding Correct problem and restart application"
    Once, in the combo of without the WaitNextTimeSlice and with the while(x0_moving || x1_moving) it also produced brief uncommanded motion in the Y and Z axes before crashing hard enough to kill servo power (unsure if the SWE pin or a Kanalog output, both of which are driving a SSR in the e-stop chain). After this I proceeded with the servo power off until done debugging.

    Update after further debugging attempts: I have a "supervisor" program in Thread 7 that loads axis/Kanalog/Konnect settings, and then starts a perpetual loop which watches coolant flow, checks for button presses, generate messages to display on KmotionCNC DROs, etc and is the first thing loaded when I power on. I had been having all the above problems while running the above code in thread 6, but the same code works fine if I run it in Threads 1-5, or if I kill thread 7 before running it in Thread 6. Is this a buffer overflow issue? If so how can I make sure I'm inside the memory space for each thread? I'm not using the TI compiler.

    Thanks,
    Andy

  2. #2
    Join Date
    May 2016
    Posts
    35

    Re: Preventing G-code execution in C, and problems evaluating while loop conditionals

    More updates: Tracked it down to a call in the Thread 7 supervisor that checks stuff on an infrequent time basis (coolant flow, temperatures, etc) and it's a bit of allocated memory for some chars to format the messages to the DRO. Put it as static and now the program works in Thread 6, but if I load KmotionCNC with it running in Thread 6 KmotionCNC gives an error about the DRO and it hangs, but if it runs in Threads 1-5 KmotionCNC works as expected. My prior C coding has all been on single thread microcontrollers so I'm a bit out of my element with knowing how to allocate memory in a multi-thread environment...

  3. #3
    Join Date
    May 2006
    Posts
    4045

    Re: Preventing G-code execution in C, and problems evaluating while loop conditionals

    Hi Andy,

    is there a way in C to disable G code from executing even if the operator boneheads it in KmotionCNC before they should?
    You might remove all Axes from the Coordinated Motion System with:

    DefineCoordSystem6(-1,-1,-1,-1,-1,-1);


    Question 2 comes from trying to fix the misalignment caused above. Earlier the homing motion would be repeated twice, once for each axis, but this doesn't work with the large alignment error as one axis would overtravel before the other found the home sensor. So I tried to have both axes drive towards their home sensors as simultaneous independent motions, and each would stop once the respective home sensor is found.

    Without the WaitNextTimeSlice(); present it would immediately skip to the post loop printf without executing anything inside the while loop.
    I can't explain this, but one possibility is there is noise on the inputs. Without the WaitNextTimeSlice the loop will sample the inputs hundreds of times faster increasing the chances of detecting any glitch.


    Another issue with the program is when the Home Bit is set the StopMotion is continuously called. It should only be stopped once. Computing a new blended trajectory to stop can be fairly complex and involve solving quartic equations and take some time.

    https://youtu.be/LdkyiH-v_9A

    Especially with many other things going on concurrently (multiple Threads multiple Servos, etc). So KFLOP computes the new trajectory beginning 4ms in the future and maintains the current trajectory until then. So continuously requesting a new trajectory causes problems. Actually I see now a printf in the loop which might slow it down enough to work, but will then flood the Console with messages. Please just command each axis to stop once by changing the 'if' statement to:

    if (ReadBit(X0_HOME_BIT) && x0_moving)

    There is a C Example HomeSlaved.c you might look at.

    Tracked it down to a call in the Thread 7 supervisor that checks stuff on an infrequent time basis (coolant flow, temperatures, etc) and it's a bit of allocated memory for some chars to format the messages to the DRO. Put it as static and now the program works in Thread 6
    The Stack space for each Thread is fairly small 2KBytes. So anything significant in size should be made global or static so it uses the 64KBytes of Thread memory or placed in the 8MByte gather_buffer space. Its not clear why the different behavior for different Threads but overflowing the Stack can be unpredictable.

    but if I load KMotionCNC with it running in Thread 6 KMotionCNC gives an error about the DRO and it hangs, but if it runs in Threads 1-5 KMotionCNC works as expected
    I can't think of why the Thread number would matter. Could you be running the program in more than one thread at the same time? KMotion shows a green bar on running Threads

    Sending Commands to KMotionCNC is not thread safe. Commands are sent and then a wait occurs until KMotionCNC indicates the command is complete. If during this process another Thread issues another command the results will be unpredictable.

    You might post your program so we can see them.
    TK
    http://dynomotion.com

  4. #4
    Join Date
    May 2016
    Posts
    35

    Re: Preventing G-code execution in C, and problems evaluating while loop conditionals

    Hi Tom,

    The homing code (as yet unmodified) is HomeX_with_index_autoalign (called in Threads 1-6 as a result of buttons in KmotionCNC), and the DRO updating one is service_time_insensitive (called from the Thread 7 perpetual loop something like once/sec).. I was able to run a dummy program with the behavior in Threads 1-5 simultaneously without issue (just printing a counter value when counter % 5000 == 0) but it would break in Thread 6 if KmotionCNC was running and work otherwise.

    If any command that communicates to KmotionCNC (I am using the DROlabel and set the Z axis based on a toolsetter input) needs to complete would it make sense to use a bit as a busy indicator across threads and have each communication check that it isn't set, set it and then clear it after the command finishes? As I have it set up none of the commands need realtime responses so if it has to wait until a different message cycle completes that seems like it would be fine? There are couple different places where messages would get sent that could be in different threads (toolsetting, spindle spinup/down, homing sequences).

    Thanks,
    Andy

  5. #5
    Join Date
    May 2006
    Posts
    4045

    Re: Preventing G-code execution in C, and problems evaluating while loop conditionals

    Hi Andy,

    The homing code (as yet unmodified) is HomeX_with_index_autoalign (called in Threads 1-6 as a result of buttons in KmotionCNC)
    I don't understand. Are you still executing code without the changes I requested? Please attach the files you are using.


    I was able to run a dummy program with the behavior in Threads 1-5 simultaneously without issue (just printing a counter value when counter % 5000 == 0) but it would break in Thread 6 if KmotionCNC was running and work otherwise.
    Unless there is a WaitNextTimeSlice() in the loop then the Console would be flooded with messages. With the WaitNextTimeSlice I can run such a loop in all 7 Threads and KMotionCNC without any problem. Please post the entire program you are running.

    Code:
    #include "KMotionDef.h"
    
    main()
    {
        int i=0;
        for (;;)
        {
            WaitNextTimeSlice();
            if (((i++) % 5000) == 0)
                printf("Count 7 = %d\n", i);
        }
    }
    What Version are you running?

    Maybe something to do with your custom Screen? Select a non-custom screen to see if it is related.


    If any command that communicates to KmotionCNC (I am using the DROlabel and set the Z axis based on a toolsetter input) needs to complete would it make sense to use a bit as a busy indicator across threads and have each communication check that it isn't set, set it and then clear it after the command finishes?
    There is a flaw in that method. If in the period between the reading the bit and setting the bit the Thread gets pre-empted and another Thread sets the bit things still get messed up.

    There is a test and set function defined in KMotionDef.h that solves this problem. You might use a persist variable for this that all Threads have easy access to.

    Code:
    // test a location and if zero, set
    // to value.  returns the original
    // value.  routine is atomic
    
    int TestAndSet(int *mutex, int value);
    //{
    //	register result = *mutex;
    //	if (result==0) *mutex=value;
    //	return result;
    //}
    Another approach is to have a single thread do all the communication and have other Threads request that Thread to do it. For example setting a bit.

    printf's to Console should only be used for diagnostics but it is designed to be Thread safe.
    TK
    http://dynomotion.com

  6. #6
    Join Date
    May 2016
    Posts
    35

    Re: Preventing G-code execution in C, and problems evaluating while loop conditionals

    Code post
    Attached Files Attached Files

  7. #7
    Join Date
    May 2016
    Posts
    35

    Re: Preventing G-code execution in C, and problems evaluating while loop conditionals

    Hi Tom,

    I think I have the fix implemented, where every command to the PC is bracketed e.g.:

    while(TestAndSet(&persist.UserData[COMMSMUTEXVAR], 1));
    DoPCFloat(PC_COMM_SET_X, 41.1424);
    persist.UserData[COMMSMUTEXVAR] = 0;

    The whole code is attached in the post above, I thought it did that with the previous reply but apparently not. I have a lot of different places DROlabels are set so it makes sense that if the communication behavior isn't threadsafe I would have been often having the requests collide and that would explain stuff like popup boxes occasionally being full of garbage characters.

    Thanks for the help,
    Andy

  8. #8
    Join Date
    May 2006
    Posts
    4045

    Re: Preventing G-code execution in C, and problems evaluating while loop conditionals

    Hi Andy,

    That should now be Threadsafe.

    Thanks for posting the code.
    TK
    http://dynomotion.com

Similar Threads

  1. Problems with Lichuan LCDA357H drives (closed loop steppers)
    By CaspianCmonster in forum Stepper Motors / Drives
    Replies: 2
    Last Post: 04-25-2021, 09:03 AM
  2. Simple G code loop needed!
    By gcodehelp in forum G-Code Programing
    Replies: 7
    Last Post: 08-13-2011, 07:45 PM
  3. Is it possible to loop a g-code program?
    By sul1 in forum G-Code Programing
    Replies: 4
    Last Post: 04-03-2009, 08:49 PM
  4. Loop/variable Problems
    By tonper in forum Fanuc
    Replies: 7
    Last Post: 10-17-2008, 06:25 AM
  5. Programming with conditionals and inputs/outputs (URGENT)
    By nilimpa in forum G-Code Programing
    Replies: 4
    Last Post: 09-22-2007, 04:43 PM

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •