Checking for Resume Circumstances from Halt.

Moderators: TomKerekes, dynomotion

Post Reply
xdmattz
Posts: 14
Joined: Wed Mar 14, 2018 1:06 pm

Checking for Resume Circumstances from Halt.

Post by xdmattz » Sun Nov 08, 2020 2:38 am

Tom,

For the past few months I have been working on writing a .Net application similar to your KMotionCNC. I started with the SimpleGCodeWPF example and it evolved from there.

I have been trying to copy a lot of the functionality of KMotionCNC and have so far been fairly successful. I can currently home my machine, Jog with buttons or my MPG, the Spindle responds to M3, M4, M5 and S commands and I can load and execute GCode. I have a manual G Code line working, and I can single step Feed hold, move forwards and backwards in feedhold (your solution for this is quite clever!) and can halt and resume.

But I am having a problem with the halt and resume. I re-implemented the section from KMotionCNC that checks to see if the position has changed since the interpreter was halted, trying to copy what was done in KMotionCNC. My CheckforResumeCircumstances method looks like this.

Code: Select all

private bool CheckforResumeCircumstances()
        {
            double cx, cy, cz, ca, cb, cc;  // current axis values
            cx = cy = cz = ca = cb = cc = 0;
            // trying to copy the functionality of KMotionCNC
            if(KM.CoordMotion.IsPreviouslyStopped == PREV_STOP_TYPE.Prev_Stopped_None)
            {
                //KM.CoordMotion.Interpreter.ReadAndSynchCurInterpreterPosition(ref cx, ref cy, ref cz, ref ca, ref cb, ref cc);
                //KM.CoordMotion.Interpreter.SetupParams.X_AxisPosition = cx;
                //KM.CoordMotion.Interpreter.SetupParams.Y_AxisPosition = cy;
                //KM.CoordMotion.Interpreter.SetupParams.Z_AxisPosition = cz;
                //KM.CoordMotion.Interpreter.SetupParams.A_AxisPosition = ca;
                //KM.CoordMotion.Interpreter.SetupParams.B_AxisPosition = cb;
                //KM.CoordMotion.Interpreter.SetupParams.C_AxisPosition = cc;
                MessageBox.Show("previously stopped");
                return false;
            }
            // read the current position
            KM.CoordMotion.UpdateCurrentPositionsABS(ref cx, ref cy, ref cz, ref ca, ref cb, ref cc, true);
            int dx, dy, dz, da, db, dc;
            dx = dy = dz = da = db = dc = 0;
            
            KM.CoordMotion.GetAxisDefinitions(ref dx, ref dy, ref dz, ref da, ref db, ref dc);
            //string msg;
            //msg = "check for movement\n";
            //msg += string.Format("X def:{0} {1:F7} {2:F7}\n", dx, round(cx), round(Stopped_X));
            //msg += string.Format("Y def:{0} {1:F7} {2:F7}\n", dy, round(cy), round(Stopped_Y));
            //msg += string.Format("Z def:{0} {1:F7} {2:F7}\n", dz, round(cz), round(Stopped_Z));
            //msg += string.Format("A def:{0} {1:F7} {2:F7}\n", da, round(ca), round(Stopped_A));
            //msg += string.Format("B def:{0} {1:F7} {2:F7}\n", db, round(cb), round(Stopped_B));
            //msg += string.Format("C def:{0} {1:F7} {2:F7}\n", dc, round(cc), round(Stopped_C));

            //MessageBox.Show(msg);

            // if the axis is enabled and hasn't moved...
            if (((dx < 0) || (round(cx) == round(Stopped_X))) &&
                ((dy < 0) || (round(cy) == round(Stopped_Y))) &&
                ((dz < 0) || (round(cz) == round(Stopped_Z))) &&
                ((da < 0) || (round(ca) == round(Stopped_A))) &&
                ((db < 0) || (round(cb) == round(Stopped_B))) &&
                ((dc < 0) || (round(cc) == round(Stopped_C))))
            {
                MessageBox.Show("No movement");
                return true; // return without modification
            }

            // show the resume dialog
            // if cancel then return false
            //    
            MessageBox.Show("Something moved!");
            ResumeDialog Resume = new ResumeDialog();

            Resume.SafeZ = KM.CoordMotion.Interpreter.InchesToUserUnits(m_Safe_Z);
            Resume.SafeRelAbs = m_SafeRelAbs;
            Resume.DoSafeZ = true;
            Resume.TraverseXY = true;
            Resume.Metric = KM.CoordMotion.Interpreter.SetupParams.LengthUnits == CANON_UNITS.CANON_UNITS_MM;
            Resume.SafeX = StoppedIX;
            Resume.SafeY = StoppedIY;

            if(StoppedSpindleDirection == CANON_DIRECTION.CANON_STOPPED)
            {
                Resume.SafeSpindleStart = false;
                Resume.SafeSpindleCWCCW = true;
            }
            else if(StoppedSpindleDirection == CANON_DIRECTION.CANON_CLOCKWISE)
            {
                Resume.SafeSpindleStart = true;
                Resume.SafeSpindleCWCCW = true;
            }
            else
            {
                Resume.SafeSpindleStart = true;
                Resume.SafeSpindleCWCCW = false;
            }
            Resume.SafeSpindleSpeed = StoppedSpindleSpeed;
            Resume.DoSafeFeedZ = true;
            Resume.SafeFeedZ = StoppedIZ;
            Resume.ResumeFeedRate = StoppedFeedrate;
            Resume.SafeFeedZRate = StoppedFeedrate;
            Resume.RestoreFeedRate = true;


            bool? ResumeResult = Resume.ShowDialog();
            if(ResumeResult == false)
            {
                MessageBox.Show("False");
                return false;
            } 
            else
            {
                MessageBox.Show("True!");
                // get the results back from the dialog box
                KM.CoordMotion.Interpreter.CanResume = true;
                KM.CoordMotion.Interpreter.ResumeFeedSafeZ = Resume.SafeZ;
                if(Resume.SafeRelAbs)
                { KM.CoordMotion.Interpreter.ResumeSafeRelAbs = 1; }
                else { KM.CoordMotion.Interpreter.ResumeSafeRelAbs = 0; }

                KM.CoordMotion.Interpreter.ResumeTraverseXY = Resume.TraverseXY;
                KM.CoordMotion.Interpreter.ResumeTraverseSafeX = Resume.SafeX;
                KM.CoordMotion.Interpreter.ResumeTraverseSafeY = Resume.SafeY;
                KM.CoordMotion.Interpreter.ResumeSafeStartSpindle = Resume.SafeSpindleStart;
                if (Resume.SafeSpindleCWCCW)    // this looks backwards - but it is correct.
                { KM.CoordMotion.Interpreter.ResumeSafeSpindleCWCCW = 0; }
                else { KM.CoordMotion.Interpreter.ResumeSafeSpindleCWCCW = 1; }

                // what about the spindle speed?
                KM.CoordMotion.Interpreter.ResumeMoveToSafeZ = Resume.DoSafeZ;
                KM.CoordMotion.Interpreter.ResumeDoSafeFeedZ = Resume.DoSafeFeedZ;
                KM.CoordMotion.Interpreter.ResumeFeedSafeZ = Resume.SafeFeedZ;
                KM.CoordMotion.Interpreter.ResumeZFeedRate = Resume.SafeFeedZRate;
                KM.CoordMotion.Interpreter.ResumeFeedRate = Resume.ResumeFeedRate;
                KM.CoordMotion.Interpreter.ResumeRestoreFeedRate = Resume.RestoreFeedRate;
            }

            return true;

        }
This mostly works. The problem that I am having is that when the Move to safe Z height is selected

Image

When I have Move to save Z height selected the interpreter halts again and gives a message that says "Soft Limit Z - Rapid Traverse Job Halted" It then resets interpreter back to the beginning of the GCode file.

Image

It doesn't seem to matter what number I put in for the safe z height or the state of ResumeSafeRelAbs, if the safe Z height is selected it gives me the error, if it is not selected everything else works.

When I try to do the same thing in KMotionCNC with the same KFLOP C code, ie run a small GCode program, halt, jog a bit and resume, KMotionCNC runs without a hitch.

Any help would be appreciated!

The entire code is available on my github page:
https://github.com/xdmattz/KFLOP_Test3

I'm using Visual Studio Community 2015. Everthing is in WPF - this is my first real project with WPF... I'm sure it's pretty ugly to real programmers.

The C code for the KFLOP board is at:
https://github.com/xdmattz/BP308/tree/m ... 20C%20Code

All the design files for the machine I'm working on are at:
https://github.com/xdmattz/BP308

you can see the current state of the machine here:


This is very much a work in progress but I'm having a good time with it.

Thanks

Dan Matthews

PS I'm having trouble getting images to show up in this post. Are there some instructions somewhere that show how to do it properly?

User avatar
TomKerekes
Posts: 2527
Joined: Mon Dec 04, 2017 1:49 am

Re: Checking for Resume Circumstances from Halt.

Post by TomKerekes » Sun Nov 08, 2020 5:21 pm

Hi Dan,

Thank you for sharing your code.

I would step into the code to see what Safe Z value is being applied. Visual Studio is really good at that. If you don't know how I can explain how to step into unmanaged code.

I was going to try but the github seems to be missing files:

[Failure] Could not find file 'C:\Users\tk\Downloads\KFLOP_Test3-master\KFLOP Test3\Fixtuers.cs'.
[Failure] Could not find file 'C:\Users\tk\Downloads\KFLOP_Test3-master\KFLOP Test3\ResumeDialog.xaml.cs'.

One issue might be in metric mode. I think I see a bug where the dialog shows the SafeZ in the appropriate units, but then uses the value always in inches. I think KMotionCNC might have the same bug.
Regards,

Tom Kerekes
Dynomotion, Inc.

xdmattz
Posts: 14
Joined: Wed Mar 14, 2018 1:06 pm

Re: Checking for Resume Circumstances from Halt.

Post by xdmattz » Wed Nov 11, 2020 1:39 am

Tom,

Thanks for the quick response,

Stepping through the code was a good suggestion.
As I was stepping through the code after the Resume Dialog returns it was getting reasonable numbers in the return values.
Then I noticed that I was setting the Interpreter.ResumeFeedSafeZ twice. Once from my Resume.SafeZ value and once from my Resume.SafeFeedZ.

I changed the first one to interpreter.ResumeSafeZ - and now it works!
The uninitialized value of the variable was something like -6xxxxxE+66 which is some huge number - that must have been what was triggering the soft limit.

I wonder if I can blame this on the auto complete and really long variable names?

I also added the missing files to github. (and the fixed main file)

I haven't checked to see how the safeZ works in metric. I did notice that KMotionCNC didn't behave how I liked when it was in metric mode. I have a G28 position that is not 0,0,0 because my machine homes to the extremes and I didn't want it moving to the side when it got a G28. In KMotionCNC the G28 position is assumed to be in what ever units the interpreter is currently in. To get around this when a gcode file is loaded I search through the first few lines (maybe 20) to find a G20 or G21 then I convert all the work offsets to the other coordinate system and save and reload. It seems to be working. I have two simple test gcode files that have the exact same path, one metric, one inch and they seem to behave exactly the same now.

I've still got a lot to do on this before it is finished, and I'm sure I'll have more questions for you in the near future.

Thanks again!

Dan Matthews

xdmattz
Posts: 14
Joined: Wed Mar 14, 2018 1:06 pm

Re: Checking for Resume Circumstances from Halt.

Post by xdmattz » Wed Nov 11, 2020 1:42 am

And if you wanted to show us how to step into unmanaged code that would be nice!

Dan M.

User avatar
TomKerekes
Posts: 2527
Joined: Mon Dec 04, 2017 1:49 am

Re: Checking for Resume Circumstances from Halt.

Post by TomKerekes » Wed Nov 11, 2020 5:38 pm

Hi Dan,

Still missing LED_Indicator.xaml and LED_Indicator.xaml.cs.

Also C Programs and others data/config files from your personal Dan folder.

With mods to \KFLOP Test3\bin\Debug1\Config\KTestConfig.json and others I was able to get it to run :)

DansGUI.png

And if you wanted to show us how to step into unmanaged code that would be nice!
See wiki article here.
Regards,

Tom Kerekes
Dynomotion, Inc.

xdmattz
Posts: 14
Joined: Wed Mar 14, 2018 1:06 pm

Re: Checking for Resume Circumstances from Halt.

Post by xdmattz » Thu Nov 12, 2020 12:22 am

Tom,

Looks like you got it to compile and run!
The KFLOP C code is in a different repository on GitHub.
https://github.com/xdmattz/BP308/tree/master/KFLOP
It is under KFLOP C Code. The BP308 Notes.txt file contains a minimal explanation.

The LED_Indicator.xaml and .cs files I didn't include because they don't work the way I wanted and the rest of the code doesn't reference them. I need to remove them from the project.

Your link to the wiki article doesn't point to the right place. Looks like you had something else in the paste buffer when you tried to cut and paste it in.

It is kind of cool to see that you took the time to compile and run the program. Now I have a bit more incentive to make the rest of it work.

As you can imagine I have spent some time trying to figure out the .net interface. The KMotion_dotNet.chm file has been indispensable.

All the design files for everything I've worked on for this machine are on GitHub. I ended up making several PCBs to interface different hardware. Everything was done with open-source /free tools. I used KiCAD for the schematics and layout. The Cypress PSoC processor for the micro controller boards, and a Lattice FPGA on the KFLOP interface board. All the FPGA (verilog) code was simulated on EDA Playground before it was put on the board. (I actually design hardware for a living so I'm a bit more comfortable with that side of it - software is just something you have to do to make the hardware work.)

My next goal is to get the automatic tool changer running. I already have the micro controller on that board (TLAUX board) programmed and communicating with the KFLOP over the serial bus, so it should only require some new functions in my Thread 2 C code, and to figure out how I want it to look in the .net app. If you are interested, I can keep you posted. And I'm sure it will generate a few more questions.

Dan M.

User avatar
TomKerekes
Posts: 2527
Joined: Mon Dec 04, 2017 1:49 am

Re: Checking for Resume Circumstances from Halt.

Post by TomKerekes » Thu Nov 12, 2020 2:39 pm

Hi Dan,

Thanks for the additional info.

Here is the corrected link to debugging into unmanaged code.
Regards,

Tom Kerekes
Dynomotion, Inc.

Post Reply