Hi Dan,
The code you posted would cause a Feedhold while the input was active and release feed hold continuously while the input was released. Were you aware of this?
Regards
Hi,
I don't like the length of time delay that occurs between hitting the feed hold button in Mach3 and the eventual stop of the machine. I've read that a hard wired FeedHold button into Kflop will make this almost instant, but there is no way for Mach3 to understand this Kflop direct Feed hold button, instead it will just be waiting and waiting until you release the physical feed hold button which i'm ok with.
My question is; what type of C-Code do I need? Something sinple or more complicated. Is there something that I need to include for Mach3?
I came up with this, but surprise, it isn't working for me.
Any suggestions would be appreciated.
Thanks,
Dan
Similar Threads:
Hi Dan,
The code you posted would cause a Feedhold while the input was active and release feed hold continuously while the input was released. Were you aware of this?
Regards
Regards
TK http://dynomotion.com
I keep running into issues where my code keeps continuously doing a function, how do i change my code to do it once and only once?
I've read some C code tutorials but haven't spent enough time to really learn any tricks yet.
When i tested the code with a input nothing happened but when i added a message prompt, the console screen was flooded so i knew it was doing something.
I was using Mach3 for run the coordinated motion, that shouldn't have played a factor in it not working right?
Thanks for the help.
Hi Dan,
A technique that can be used to do something only once is to keep track of the previous state and detect when the signal changes. Below is a modified version of your code that uses a Debounce function to detect when a signal changes and is stable. The code is taken from the ExternalButtons.c example. The code is also attached as a text file.
HTHCode:#include "KMotionDef.h" // function prototypes for compiler int Debounce(int n, int *cnt, int *last, int *lastsolid); // state variables for switch debouncing int flast=0,flastsolid=-1,fcount=0; main() { for (;;) // repeat forever { WaitNextTimeSlice(); // execute one loop per time slice // check if feed hold button has been pushed ( IOBit 21 goes high) // Handle FeedHold/Resume if (Debounce(ReadBit(21),&fcount,&flast,&flastsolid) == 1) { if (CS0_StoppingState == 0) StopCoordinatedMotion(); else ResumeCoordinatedMotion(); } } } // Debounce a bit // // return 1 one time when first debounced high // return 0 one time when first debounced low // return -1 otherwise #define DBTIME 300 int Debounce(int n, int *cnt, int *last, int *lastsolid) { int v = -1; if (n == *last) // same as last time? { if (*cnt == DBTIME-1) { if (n != *lastsolid) { v = *lastsolid = n; // return debounced value } } if (*cnt < DBTIME) (*cnt)++; } else { *cnt = 0; // reset count } *last = n; return v; }
Regards
Regards
TK http://dynomotion.com
Hoping for some guidance getting a Feed Hold button working (as well as Cycle Start and Stop). I have wired up buttons to my KFLOPs inputs and they are working correctly. I say this because I have configured the Ports and Pins Input Settings in Mach3 (Input #1, #2, #3) to the corresponding IOs (16, 17, 18) on the KFLOP. When I go to the Mach3 Diagnostics page the inputs reflect button pushes.
I tried the code below and configured the file in the KFLOP plugin in Mach3 as the Notify program. I also tried the file Tom posted. When running a gcode file with the machine moving when I press the button but KFLOP never halts motion. Does anyone have any idea what I am missing? Also if anyone has any examples of how they got Mach3 to know KFLOP is in a feed hold I would love to hear how you did it.
Thanks,
Adam
#include "KMotionDef.h"
main()
{
for (; // loop forever
{
WaitNextTimeSlice();
printf("Test msg");
if (ReadBit(16)==1) // Watch an external input switch
{
StopCoordinatedMotion(); //feedhold
}
}
}
Hi adamflyer,
Configuring as a Notify program wouldn't be appropriate because it would never run unless you code something in Mach3 to send a notification message to the Dynomotion Plugin.
Your code contains a printf in a tight loop that would generate thousands of messages. So that wouldn't be a good idea. It also would need a new line character at the end to be printed '\n'.
BTW whenever positing code use the cnczone #CODE option on the Advanced page so it formats better and is more readable for us.
As a first step try using the code posted in my previous post. Load and compile/download/run it in an unused Thread (ie #4) in KMotion.exe C Programs Screen. Be sure to change the IO bit to the one you are using (16?). There should be a green bar on Thread #4 showing it is actively running.
Test if the External Feedhold/Resume works and is instantaneous.
Once you prove that works we can show you how to include the loop in your Initialization C Program so it always runs automatically.
HTH
Regards
Regards
TK http://dynomotion.com
Thanks for your help Tom.
I was setting up a digitizing probe and it left me thinking that code needed to be in the notify program... I think I understand now.
I added your code to main and it works as it should. While your code works per design the resulting system behavior is less than desirable for me because Mach3 keeps going when KFLOP is stopped. So I changed the code by removing the debounce and called ResumeCoordinatedMotion() when pressing the new external Cycle Start button. I also configured Mach3 to enter a feed hold by configuring the KFLOP inputs to OEM Trigers (#1, #2, #3) and OEM Codes (1000-Cycle Start, 1005-Resume, 1003-Stop) respectively. Everything seems to be working but I have some observations/questions.
1. Is it a bad idea to handle the external button presses in main and in the first thread like I do?Code:#include "KMotionDef.h" int main() { //KFLOP external button press input for (;;) // loop forever { WaitNextTimeSlice(); if (ReadBit(17)==1) // Stop external input button depressed { StopCoordinatedMotion(); } if (ReadBit(18)==1) // Feed Hold external input button depressed { StopCoordinatedMotion(); } if (ReadBit(16)==1) // Cycle Start external input button depressed { ResumeCoordinatedMotion(); } } // Configure Gecko G320X Servo Drive double T0, LastX=0, LastY=0, LastZ=0, Tau; KStepPresent=TRUE; // enable KSTEP input multiplexing FPGA(KAN_TRIG_REG)=4; // Mux PWM0 to JP7 Pin5 IO 44 for KSTEP FPGA(STEP_PULSE_LENGTH_ADD) = 32 + 0x80; // set polarity and pulse length to 4us ch0->InputMode=NO_INPUT_MODE; ch0->OutputMode=STEP_DIR_MODE; ch1->Vel=80000; ch1->Accel=500000; ch0->Jerk=1000000; ch0->P=0; ch0->I=0.01; ch0->D=0; ch0->FFAccel=0; ch0->FFVel=0; ch0->MaxI=200; ch0->MaxErr=1e+006; ch0->MaxOutput=200; ch0->DeadBandGain=1; ch0->DeadBandRange=0; ch0->InputChan0=0; ch0->InputChan1=0; ch0->OutputChan0=8; ch0->OutputChan1=0; ch0->MasterAxis=-1; ch0->LimitSwitchOptions=0x100; ch0->LimitSwitchNegBit=0; ch0->LimitSwitchPosBit=0; ch0->SoftLimitPos=1e+009; ch0->SoftLimitNeg=-1e+009; ch0->InputGain0=1; ch0->InputGain1=1; ch0->InputOffset0=0; ch0->InputOffset1=0; ch0->OutputGain=-1; ch0->OutputOffset=0; ch0->SlaveGain=1; ch0->BacklashMode=BACKLASH_OFF; ch0->BacklashAmount=0; ch0->BacklashRate=0; ch0->invDistPerCycle=1; ch0->Lead=0; ch0->MaxFollowingError=1000000000; ch0->StepperAmplitude=1; ch0->iir[0].B0=1; ch0->iir[0].B1=0; ch0->iir[0].B2=0; ch0->iir[0].A1=0; ch0->iir[0].A2=0; ch0->iir[1].B0=1; ch0->iir[1].B1=0; ch0->iir[1].B2=0; ch0->iir[1].A1=0; ch0->iir[1].A2=0; ch0->iir[2].B0=0.000769; ch0->iir[2].B1=0.001538; ch0->iir[2].B2=0.000769; ch0->iir[2].A1=1.92076; ch0->iir[2].A2=-0.923833; EnableAxisDest(0,0); ch1->InputMode=NO_INPUT_MODE; ch1->OutputMode=STEP_DIR_MODE; ch1->Vel=4000; ch1->Accel=400000; ch1->Jerk=4e+006; ch1->P=0; ch1->I=0.01; ch1->D=0; ch1->FFAccel=0; ch1->FFVel=0; ch1->MaxI=200; ch1->MaxErr=1e+006; ch1->MaxOutput=200; ch1->DeadBandGain=1; ch1->DeadBandRange=0; ch1->InputChan0=1; ch1->InputChan1=0; ch1->OutputChan0=9; ch1->OutputChan1=0; ch1->MasterAxis=-1; ch1->LimitSwitchOptions=0x100; ch1->LimitSwitchNegBit=0; ch1->LimitSwitchPosBit=0; ch1->SoftLimitPos=1e+009; ch1->SoftLimitNeg=-1e+009; ch1->InputGain0=1; ch1->InputGain1=1; ch1->InputOffset0=0; ch1->InputOffset1=0; ch1->OutputGain=1; ch1->OutputOffset=0; ch1->SlaveGain=1; ch1->BacklashMode=BACKLASH_OFF; ch1->BacklashAmount=0; ch1->BacklashRate=0; ch1->invDistPerCycle=1; ch1->Lead=0; ch1->MaxFollowingError=1000000000; ch1->StepperAmplitude=20; ch1->iir[0].B0=1; ch1->iir[0].B1=0; ch1->iir[0].B2=0; ch1->iir[0].A1=0; ch1->iir[0].A2=0; ch1->iir[1].B0=1; ch1->iir[1].B1=0; ch1->iir[1].B2=0; ch1->iir[1].A1=0; ch1->iir[1].A2=0; ch1->iir[2].B0=0.000769; ch1->iir[2].B1=0.001538; ch1->iir[2].B2=0.000769; ch1->iir[2].A1=1.92081; ch1->iir[2].A2=-0.923885; EnableAxisDest(1,0); ch2->InputMode=NO_INPUT_MODE; ch2->OutputMode=STEP_DIR_MODE; ch2->Vel=4000; ch2->Accel=400000; ch2->Jerk=4e+006; ch2->P=0; ch2->I=0.01; ch2->D=0; ch2->FFAccel=0; ch2->FFVel=0; ch2->MaxI=200; ch2->MaxErr=1e+006; ch2->MaxOutput=200; ch2->DeadBandGain=1; ch2->DeadBandRange=0; ch2->InputChan0=2; ch2->InputChan1=0; ch2->OutputChan0=10; ch2->OutputChan1=0; ch2->MasterAxis=-1; ch2->LimitSwitchOptions=0x100; ch2->LimitSwitchNegBit=0; ch2->LimitSwitchPosBit=0; ch2->SoftLimitPos=1e+009; ch2->SoftLimitNeg=-1e+009; ch2->InputGain0=1; ch2->InputGain1=1; ch2->InputOffset0=0; ch2->InputOffset1=0; ch2->OutputGain=1; ch2->OutputOffset=0; ch2->SlaveGain=1; ch2->BacklashMode=BACKLASH_OFF; ch2->BacklashAmount=0; ch2->BacklashRate=0; ch2->invDistPerCycle=1; ch2->Lead=0; ch2->MaxFollowingError=1000000000; ch2->StepperAmplitude=20; ch2->iir[0].B0=1; ch2->iir[0].B1=0; ch2->iir[0].B2=0; ch2->iir[0].A1=0; ch2->iir[0].A2=0; ch2->iir[1].B0=1; ch2->iir[1].B1=0; ch2->iir[1].B2=0; ch2->iir[1].A1=0; ch2->iir[1].A2=0; ch2->iir[2].B0=0.000769; ch2->iir[2].B1=0.001538; ch2->iir[2].B2=0.000769; ch2->iir[2].A1=1.92081; ch2->iir[2].A2=-0.923885; EnableAxisDest(2,0); DefineCoordSystem(0,1,2,-1); SetBitDirection(45,1); // set Enable Signal as Output SetBit(45); // Enable the amplifiers // Add a small amount of Coordinated Motion Path smoothing if desired // Tau = 0.001; // seconds for Low Pass Filter Time Constant // KLP = exp(-TIMEBASE/Tau); KLP=0; // force to 0 to disable // printf("Tau=%f KLP=%f\n",Tau,KLP); for (;;) // loop forever { WaitNextTimeSlice(); // Service Amplifier disable after no activity for a while if (ch0->Dest != LastX || ch1->Dest != LastY || ch2->Dest != LastZ) { // we moved - enable KStep Amplifers SetBit(45); T0 = Time_sec(); // record the time and position of last motion LastX=ch0->Dest; LastY=ch1->Dest; LastZ=ch2->Dest; } else { if (Time_sec() > T0 + 10.0) ClearBit(45); } } return 0; }
2. Having the OEM code 1005-Resume triggered in Mach3 with the new external Feed Hold button press seems to work ok as I have it. However if I use 1001-Feed Hold OEM code instead when the new external button Cycle Start is pressed both Mach3 and KFLOP resume motion for about 3s and then stops for no apparent reason?? Pressing Cycle Start again resumes motion and everything seems to be ok. I guess I stay with what works but I would like to know if it is going to cause any problems and what is going on.
3. What is the best way to pass a Mach3 screen button press to KFLOP? To make the new physical external buttons work interchangeably with the Mach3 screen buttons for Cycle Start, Feed Hold, and Stop I want to call ResumeCoordinatedMotion() in KFLOP when Cycle Start is pressed on the Mach3 screen with a mouse.
Thanks,
Adam
Hi adamflyer,
You might read this to see if you can understand why it doesn't make sense to place a forever loop at the beginning of a program:
KFLOP C Programs - Dynomotion
Regarding Cycle Start and our Plugin: our plugin receives a Cycle Start notification from Mach3 and checks if a Hardware feedhold is in progress and if so it releases the hardware feed hold. Unfortunately Mach3 isn't ever aware that a hardware feed hold is in progress. It basically just assumes the motion it specified is taking a really long time to progress.
To pass a screen button press to KFLOP you must use the Mach3 Screen editor to create or modify and existing button to execute some Basic code to do a NotifyPlugins call. When our Plugin receives the notification it will invoke the Notify C Program and pass it the Notification Code. So you will need to add code to the Notify C Program to detect that specific Notification Code and do whatever you want to do.
HTH
Regards
Regards
TK http://dynomotion.com
Hello,
Here it is a much better feed hold for Mach3. The delay consist in only the Windows buffer ahead time from the Mach3 Plugin.
1. Install Mach3 screen. It has a custom VB Cycle start and Feed hold buttons.
2. Copy Mach3_feedHold.c to C:\KMotion433\C Programs or whatever you want and set the path from Mach3 plugin on Custom Notify user program.
If you hit Stop button you will need to go back few lines to match the actual position with the gcode since you cancel buffered gcode motions.
Give it a try and let me know how it is working.
Best regards,
Cris
Kflop ver. 4.33
Mach3 ver. R3.043.053
Mach3 plugin is from kmotion 434b.
Last edited by Cristm; 11-09-2017 at 06:17 PM.