Newbie PID advice on a retrofit BenchmanXT - Page 2


Page 2 of 3 FirstFirst 123 LastLast
Results 21 to 40 of 56

Thread: PID advice on a retrofit BenchmanXT

  1. #21
    Member TomKerekes's Avatar
    Join Date
    May 2006
    Location
    USA
    Posts
    4043
    Downloads
    0
    Uploads
    0

    Default Re: PID advice on a retrofit BenchmanXT

    Hi Steve,

    the fact is I'd rather use closed loop but I couldn't find any information on how to do that. My X,Y,and Z work perfect but they are seeking a position not a velocity, so I didn't think it was the same. How do you configure closed loop for velocity? I'd much rather use that!
    The Spindle is to be configured exactly the same as your XYZ (if you were to command your X axis to Jog forever at 100,000 counts/sec it could be used as a spindle).

    Also every Axis can function fully open loop by relying totally on FF to drive the DAC/motor and use no PID+Filter feedback. Or it can operate fully closed loop by relying on PID+Filter feedback and no FF. Or a mixture of both for optimal results. However one difference is when any closed loop is used then the units of commanded velocity/position must match the units of the measured velocity/position.


    I currently have the spindle in channel 7, No input, DAC Zero PID, 0.5 V, 1 A, 5 J , Feed Forward 2047V and 0A. My Factor is .002 and I am using the Jog programs for M3,M4,M5.
    Stating channel 7 is ambiguous. I'm guessing you mean Axis Channel 7? If so, what encoder channel is the spindle wired to? Do you have that configured as the InputChan0? Is the Position changing on the KMotion Axis Screen?

    We have the most difficult time explaining what should be a simple concept. Let me try this: Imagine you have 8 people in a room and 8 encoder counters. Person #7 is told to watch encoder counter #5. Encoder counter #5 is wired to the Spindle Encoder. Person #7 is then asked what his encoder is doing.

    Regards

    Regards
    TK http://dynomotion.com


  2. #22
    Registered
    Join Date
    Aug 2012
    Location
    United States
    Posts
    32
    Downloads
    0
    Uploads
    0

    Default Re: PID advice on a retrofit BenchmanXT

    Tom,
    Ok I might understand. The difference between seeking a position and a velocity is the command. When seeking a velocity you use the "jog" command. I always configure the axis channel and the encoder channel to the same number. So Axis 7 uses encoder 7. 7 was chosen because I may want to later add an A and possibly a B axis. Having the Spindle at 7 protects it from confusing it with a position VS a velocity system and/or overwriting it with a future A or B. So far, I haven't had any luck with configuring the Spindle as a PID controlled drive. I guess I wasn't sure it was possible and since open looped was relatively easy, it made sense to set that up first. I will experiment tomorrow. With luck that will be all I need to start making chips!
    I suppose there is a way to have the Step Response use a Jog instead of a Move? Is that automatic? As always. I really appreciate your help!

    Steve



  3. #23
    Member TomKerekes's Avatar
    Join Date
    May 2006
    Location
    USA
    Posts
    4043
    Downloads
    0
    Uploads
    0

    Default Re: PID advice on a retrofit BenchmanXT

    Hi Steve,

    Check if the #7 Position on the KMotion Axis Screen is changing with the Spindle Motion - 3rd request

    I think your problems with trying to tune the Spindle Servo was due to too high FF values. Set them to zero.

    To test the Spindle using the Step Response Screen just make a large move. There is also a Velocity Plot Mode.

    HTH
    Regards

    Regards
    TK http://dynomotion.com


  4. #24
    Registered
    Join Date
    Aug 2012
    Location
    United States
    Posts
    32
    Downloads
    0
    Uploads
    0

    Default Re: PID advice on a retrofit BenchmanXT

    Oh, sorry Tom,

    Yes the #7 position does track with the Spindle motion. I took your advice and zero'd FF and then used a large move, I think I got it. Need to work on the tuning. It kind of washing machines back and forth looking for Zero. I'll work with it and see where I get.

    Thanks
    Steve



  5. #25
    Member TomKerekes's Avatar
    Join Date
    May 2006
    Location
    USA
    Posts
    4043
    Downloads
    0
    Uploads
    0

    Default Re: PID advice on a retrofit BenchmanXT

    Hi Steve,

    Sounds like you are getting close. I think the main difference from a spindle drive and a normal servo drive is that the Spindle Drives often have slow response. So open loop FF becomes more important. The FF can handle the bulk of the control so that the feedback only has to make small corrections.

    Good luck,
    Regards

    Regards
    TK http://dynomotion.com


  6. #26
    Registered
    Join Date
    Aug 2012
    Location
    United States
    Posts
    32
    Downloads
    0
    Uploads
    0

    Default Re: PID advice on a retrofit BenchmanXT

    Tom,

    Great news. I configured the spindle for closed loop and tuned the PID to a reasonable setting. I even went so far as to run a test cut on Delrin . Looks fantastic! Might need to do a bit more tuning but I cannot complain about the accuracy. My numbers were really odd so I think my counts per rotation must be something other than I was told. The results are consistent so I believe I just need to throw a scope on it and have a look. I was also able to setup and use a switch. I'll be working on the potentiometers soon. Next question though; How do I control the threads? I know I have 1-7 to work with but I don't see an explanation on which threads actually run. I looked at the treads that are there in KMotion and I saw that I had accidentally duplicated my axis thread, which is on thread #1, on thread #3. I don't need two of the same threads running but I don't see a way to clear it or a way to tell it to run or not to run. Additionally there is a Probe thread I don't need and while none of this hurts anything, I should probably just delete anything I don't need. As always in an attempt to answer my own questions, I did a search but after reading a bunch of on line discussions, I didn't find anything I could use for my particular question. Just waiting for some replacement switches but a very exciting time indeed! I hadn't mentioned but this is a device at a boy's high school for their robotics program. They always show me respect but I could tell they were wondering just what I thought I was doing as I have spent so many hours behind this machine with wires everywhere. They finally saw it move as I was trying another test cut. Feels good to be back in the driver's seat. They are anxious to do some CADing and giving it a try. Exactly what I was hoping!

    Thanks for the great advice!
    Steve



  7. #27
    Member TomKerekes's Avatar
    Join Date
    May 2006
    Location
    USA
    Posts
    4043
    Downloads
    0
    Uploads
    0

    Default Re: PID advice on a retrofit BenchmanXT

    Hi Steve,

    That is great to hear.

    Regarding the C Programs Screen in KMotion those are more like notepad editors. What they show is not necessarily what is in KFLOP.

    The C Programs Screen will show a green bar on the Threads that are running.

    After your C Program(s) are developed you won't need KMotion.exe anymore. You can just assign the program to a Button or M Code in KMotionCNC and specify what Thread they should execute in.

    HTH
    Regards

    Regards
    TK http://dynomotion.com


  8. #28
    Registered
    Join Date
    Aug 2012
    Location
    United States
    Posts
    32
    Downloads
    0
    Uploads
    0

    Default Re: PID advice on a retrofit BenchmanXT

    Tom,

    I've made great progress and even cut a few test pieces. Resolution is great and good enough to reliably mill a bearing press fit hole. Very impressive. However, I have a problem. I wired the e-stop button and the pots. The programs work in KMotion and I can run them manually. How do I get KMotionCNC to run these threads automatically? I selected them in Config and Flash under the Launch On Power Up menu in KMotion, but they just don't run in KMotionCNC unless I first manually run them in KMotion. I'm sure this is a simple fix but nothing I've tried works. What am I missing?

    EDIT: Hang on... you have to disconnect the USB... I haven't been doing that. I'll give that a try. That may be the issue.


    Ok Frustrating time, No luck today. I selected threads 1,2,3,4 to run on power up and flashed them to memory. I disconnected the main drive to the mill so it wouldn't run wild, disconnected the USB and then disconnected power to the KFlop/Kanalog. When I power it all up and look at KMotion, I see threads 2,3,4 running. I assume thread 1 ran and configured everything. When I try the same thing with KMotionCNC. It doesn't seem to run all the threads. I don't see a consistent pattern but I didn't have a whole lot of time today to do a lot of tests. One other thing I have happening is when I stop and re init the unit in KMotionCNC, the spindle doesn't run. If I halt the program, restart the GCode and init, the spindle will work every time. So something is happening and I suppose the system thinks the spindle is enabled but the jog command doesn't do anything.
    SO I seem to be able to tell KMotion to run threads, but that information is not being passed on to KMotionCNC. And KMotionCNC doesn't re-enable the spindle.
    Any advice?



    Thanks

    Steve

    Last edited by steve_alaniz; 09-18-2016 at 02:44 PM. Reason: Additional info


  9. #29
    Member TomKerekes's Avatar
    Join Date
    May 2006
    Location
    USA
    Posts
    4043
    Downloads
    0
    Uploads
    0

    Default Re: PID advice on a retrofit BenchmanXT

    Hi Steve,

    It isn't clear why that doesn't work, except it isn't clear if you compiled and downloaded the programs into KFLOP before Flashing KFLOP. You seem to have a misunderstanding that the programs exist in KMotion or KMotionCNC rather than in KFLOP.

    But taking a step back it would be better to combine all the functionality of all your programs into the Init Program so you don't need any other Threads. This is the preferred method so nothing ever needs to be Flashed into KFLOP. The idea is to add one loop at the end of the main() function in your init program that services all your devices. See:

    KFLOP C Programs - Dynomotion

    Regards

    Regards
    TK http://dynomotion.com


  10. #30
    Registered
    Join Date
    Aug 2012
    Location
    United States
    Posts
    32
    Downloads
    0
    Uploads
    0

    Default Re: PID advice on a retrofit BenchmanXT

    Tom,

    I actually never considered where the program goes. I only assumed that it should be used by both KMotion and KMotionCNC. I couldn't understand why it seemed to work sometimes but not always. I Finally see what is happening but I don't know why. The Kflop rightly runs all the threads on powerup. I can see that in KMotion and it seems to behave well there. Even when I launch KMotionCNC the programs are running. I was verifying a switch and my ESTOP button on the unit. They both worked until I ran a tap file in KMotionCNC. It halts the program I had that programed the action for those switches. Since I need it to control my ESTOP button, I guess I have to try to figure out why its doing that. I don't think writing those into my INIT file will help but I could be wrong. I thought I read that thread 7 continues to run so is that where I need to place those definitions?

    Thanks
    Steve



  11. #31
    Member TomKerekes's Avatar
    Join Date
    May 2006
    Location
    USA
    Posts
    4043
    Downloads
    0
    Uploads
    0

    Default Re: PID advice on a retrofit BenchmanXT

    Hi Steve,

    If you have a program running in a KFLOP Thread space and you then run a different program in that KFLOP Thread space then the first program will be killed and overwritten by the new program.

    I suspect you have some M Codes in KMotionCNC configured to run in some Threads that you are expecting to be left alone. Make sure that whatever M Codes are configured use Thread spaces that are available.

    Again the recommended method is to just put everything in your Init Program and only use one Thread (besides anything that executes temporarily like Spindle Control, Tool Change, Probe, etc...)

    Regards

    Regards
    TK http://dynomotion.com


  12. #32
    Registered
    Join Date
    Aug 2012
    Location
    United States
    Posts
    32
    Downloads
    0
    Uploads
    0

    Default Re: PID advice on a retrofit BenchmanXT

    Tom,

    I did as you suggested and converted the FRO ans SSO programs into functions and added them to the init file. Now that I look at the way the unit works I see that I was always going to have to do this. I think I was under the impression that the threads continued to work as long as the unit was powered but I can now see that It needs to be restated anytime I initialize the system. It's all just part of learning how this all works. So I have a handle on making this work the way I hoped.
    My next question is about limiting the effect of the SSO. It makes the spindle increase or decrease speed just like I want except when I overdrive the spindle with the pot and send it a command to run faster than it can, then it accumulates errors and I lose control of it until it "catches up" and then it might actually go into oscillation, so I want to avoid ever commanding it to go faster than it can. I need to set a limit that the pot cannot exceed. I'm thinking I need to do that in JogCW and set a maximum value for Speed after this statement.

    float speed = *(float *)&persist.UserData[SPEEDVAR]; // value stored is actually a float

    Is Speed encoder counts?

    Thanks for the help

    Steve



  13. #33
    Member TomKerekes's Avatar
    Join Date
    May 2006
    Location
    USA
    Posts
    4043
    Downloads
    0
    Uploads
    0

    Default Re: PID advice on a retrofit BenchmanXT

    Hi Steve,

    You should probably approach this in two parts. #1 set a reasonable Following Error Limit such that if the speed is ever commanded too fast it will immediately disable. #2 prevent it for being commanded too fast.

    At that point in the code the speed is in RPM. So you might limit it with something like:

    if (speed > 5000.0f) speed = 5000.0f; // Limit the speed to 5000RPM

    HTH
    Regards

    Regards
    TK http://dynomotion.com


  14. #34
    Registered
    Join Date
    Aug 2012
    Location
    United States
    Posts
    32
    Downloads
    0
    Uploads
    0

    Default Re: PID advice on a retrofit BenchmanXT

    Tom,

    OK I've been feeling pretty good about MOST of what I'm doing. Have not yet found a way to control the maximum speed when using the Speed Pot. It seems to override everything I'm not finding where the SSO is read and combined with the speed from the g-code S command. I would like to solve that but it is not the biggest item yet. I am continuing to re-wire this beast and still making good progress. I AM at the point of cutting test pieces out of aluminum and getting excellent results. I will be doing press fitting of bearings so the accuracy is pretty important and so far it's looking good. PID advice on a retrofit BenchmanXT-idlerplate-1-jpg

    However, I was attempting a much more complicated piece and the mill ran for awhile and then inexplicably quit. It seemed to work after a restart but then did it again. I opened up KMotion and opened up the console. It happened again and I got the message Pos Soft Limit Exceeded. I looked at the Axis and saw that it had reach it's "Maximum Distance". So it has counted it's rotations and acting like it is a linear axis that has traveled to the limit of it's travel. OK THAT'S not right. I'm using the JOG programs and I thought that prevented this from being a problem. I'm sure this is a really simple problem, but again, I am stumped. Can I be saved?

    Thanks
    Steve



  15. #35
    Registered
    Join Date
    Aug 2012
    Location
    United States
    Posts
    32
    Downloads
    0
    Uploads
    0

    Default Re: PID advice on a retrofit BenchmanXT

    OOOOooooh! The system is ignoring the G-Code "S" command and ONLY reading the SSO Value! Ok I have something really weird going on. Not sure how I got to this place but it probably isn't a good idea. I THOUGHT SSO was combined with the S value and adjusted it. This kind of explain why the spindle doesn't always spin up. If I move th speed pot after the "S" code is executed, then I get movement. It's ok if I am running the machine but I need to get this thing going for everyone. New question, can I configure the spindle for an open loop but still have threading ability?



  16. #36
    Member TomKerekes's Avatar
    Join Date
    May 2006
    Location
    USA
    Posts
    4043
    Downloads
    0
    Uploads
    0

    Default Re: PID advice on a retrofit BenchmanXT

    Hi Steve,

    The SSO (Spindle Speed Override) adjusts the speed relative to the current setting. So for example if the Speed is commanded with an S3000 to 3000RPM and then the SSO is set to 1.1 then the Actual Speed should be 3300. You will also need to turn the Spindle on with an M3 command.

    How are you expecting it to work?

    Regards

    Regards
    TK http://dynomotion.com


  17. #37
    Registered
    Join Date
    Aug 2012
    Location
    United States
    Posts
    32
    Downloads
    0
    Uploads
    0

    Default Re: PID advice on a retrofit BenchmanXT

    Tom,

    I understood how the SSO worked but whenever I launched a g-code file, the spindle wouldn't start up. If I slightly turned the SSO pot, the spindle would suddenly start and spin at speed. I finally came up with a work around if not the actual solution. I'm using SheetCAM and the EMC post processor seems to give me everything the way KMotionCNC needs to run. The code issues" M03 S2000" and then does a Z down and X and Y movement. So I'm ordering clockwise spindle rotation at 2000 RPM. It turns out that I have to issue an additional M03. So my code is M03 S2000 and the next line is M03 and then the program continues. This works so I'm not going to argue with it. I modified the Post Processor so this shouldn't be a problem again.
    I still have the issue of overrunning the spindle speed. I have yet to find where the SSO is actually applied to the Speed as a multiplier. I also still have the issue of the axis treating the spindle rotation as if it is going to a destination and eventually running out of space as if it has found it's travel limit. I need to solve these problems but at least for the moment, neither is preventing me from cutting test pieces. My first thought on the spindle travel problem is to increase the travel limit somehow. Any thought on either of these two problems?

    Thanks again

    Steve



  18. #38
    Member TomKerekes's Avatar
    Join Date
    May 2006
    Location
    USA
    Posts
    4043
    Downloads
    0
    Uploads
    0

    Default Re: PID advice on a retrofit BenchmanXT

    Hi Steve,

    So my code is M03 S2000 and the next line is M03 and then the program continues. This works so I'm not going to argue with it. I modified the Post Processor so this shouldn't be a problem again.
    Strange

    I still have the issue of overrunning the spindle speed. I have yet to find where the SSO is actually applied to the Speed as a multiplier.
    Please post your current Init Program (with the SSO stuff), S Program, and M3 programs so we can review them.

    I also still have the issue of the axis treating the spindle rotation as if it is going to a destination and eventually running out of space as if it has found it's travel limit.
    Not sure what you mean by this. It might be that you need to set the SoftLimits to infinity (ie +1e30 and -1e30).

    Regards

    Regards
    TK http://dynomotion.com


  19. #39
    Registered
    Join Date
    Aug 2012
    Location
    United States
    Posts
    32
    Downloads
    0
    Uploads
    0

    Default Re: PID advice on a retrofit BenchmanXT

    Tom,

    Here are the files : The Init

    #include "KMotionDef.h"


    #define POWERON 142
    #define POWEROFF 143
    #define ESTOP 136
    #define HALTBIT 137
    //#define RESTARTBIT 28
    //#define ZEROALLBIT 29
    #define TMP 10 // which spare persist to use to transfer data
    #include "KflopToKMotionCNCFunctions.c"

    #define CHANGE_TOL 0.02 // only update if change is more than this
    #define CHANGE_TIME 0.05 // don't update more often then this time


    ClearBit(144); //disable power


    // function prototypes for compiler
    int DoPC(int cmd);
    int DoPCFloat(int cmd, float f);
    int Debounce(int n, int *cnt, int *last, int *lastsolid);

    // state variables for switch debouncing
    int flast=0,flastsolid=-1,fcount=0;
    int clast=0,clastsolid=-1,ccount=0;
    int elast=0,elastsolid=-1,ecount=0;
    int hlast=0,hlastsolid=-1,hcount=0;
    //int rlast=0,rlastsolid=-1,rcount=0;
    //int zlast=0,zlastsolid=-1,zcount=0;
    double LastFRO=-1;
    double LastFROTime=0;

    double LastSSO = -1;
    double LastSSOTime = 0;
    double SSO = 1.000000;
    double T;




    void ButtonService(void);
    void PotService(void);


    main()
    {
    int BitA,Change1=0,Change2=0, DiffX2;
    int PosNoWrap, NewPos, Pos=0, wraps;

    //SetBit(152);
    //SetBit(157);
    //SetBit(158);

    ClearBit(159); //disable spindle

    ch0->InputMode=ENCODER_MODE;
    ch0->OutputMode=DAC_SERVO_MODE;
    ch0->Vel=272500;
    ch0->Accel=460000;
    ch0->Jerk=7.5e+006;
    ch0->P=13;
    ch0->I=0.01;
    ch0->D=90;
    ch0->FFAccel=0;
    ch0->FFVel=0;
    ch0->MaxI=2000;
    ch0->MaxErr=1e+006;
    ch0->MaxOutput=2000;
    ch0->DeadBandGain=1;
    ch0->DeadBandRange=0;
    ch0->InputChan0=0;
    ch0->InputChan1=0;
    ch0->OutputChan0=0;
    ch0->OutputChan1=1;
    ch0->MasterAxis=-1;
    ch0->LimitSwitchOptions=0x100;
    ch0->LimitSwitchNegBit=0;
    ch0->LimitSwitchPosBit=0;
    ch0->SoftLimitPos=1e+030;
    ch0->SoftLimitNeg=-1e+030;
    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=20;

    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.056605;
    ch0->iir[2].B1=0.11321;
    ch0->iir[2].B2=0.056605;
    ch0->iir[2].A1=1.22804;
    ch0->iir[2].A2=-0.454462;

    ch1->InputMode=ENCODER_MODE;
    ch1->OutputMode=DAC_SERVO_MODE;
    ch1->Vel=272500;
    ch1->Accel=460000;
    ch1->Jerk=7.5e+006;
    ch1->P=13;
    ch1->I=0.006;
    ch1->D=110;
    ch1->FFAccel=0;
    ch1->FFVel=0;
    ch1->MaxI=20;
    ch1->MaxErr=1e+006;
    ch1->MaxOutput=2400;
    ch1->DeadBandGain=1;
    ch1->DeadBandRange=0;
    ch1->InputChan0=1;
    ch1->InputChan1=0;
    ch1->OutputChan0=1;
    ch1->OutputChan1=0;
    ch1->MasterAxis=-1;
    ch1->LimitSwitchOptions=0x100;
    ch1->LimitSwitchNegBit=0;
    ch1->LimitSwitchPosBit=0;
    ch1->SoftLimitPos=1e+030;
    ch1->SoftLimitNeg=-1e+030;
    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.056605;
    ch1->iir[2].B1=0.11321;
    ch1->iir[2].B2=0.056605;
    ch1->iir[2].A1=1.22804;
    ch1->iir[2].A2=-0.454462;

    ch2->InputMode=ENCODER_MODE;
    ch2->OutputMode=DAC_SERVO_MODE;
    ch2->Vel=200000;
    ch2->Accel=600000;
    ch2->Jerk=500000;
    ch2->P=17;
    ch2->I=0.001;
    ch2->D=140;
    ch2->FFAccel=0;
    ch2->FFVel=0;
    ch2->MaxI=2000;
    ch2->MaxErr=1e+006;
    ch2->MaxOutput=2000;
    ch2->DeadBandGain=1;
    ch2->DeadBandRange=0;
    ch2->InputChan0=2;
    ch2->InputChan1=0;
    ch2->OutputChan0=2;
    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.056605;
    ch2->iir[2].B1=0.11321;
    ch2->iir[2].B2=0.056605;
    ch2->iir[2].A1=1.22804;
    ch2->iir[2].A2=-0.454462;

    ch7->InputMode=ENCODER_MODE;
    ch7->OutputMode=DAC_SERVO_MODE;
    ch7->Vel=1e+006;
    ch7->Accel=250000;
    ch7->Jerk=7e+006;
    ch7->P=6;
    ch7->I=0.0015;
    ch7->D=800;
    ch7->FFAccel=0;
    ch7->FFVel=0;
    ch7->MaxI=1000;
    ch7->MaxErr=1e+010;
    ch7->MaxOutput=2047;
    ch7->DeadBandGain=1;
    ch7->DeadBandRange=0;
    ch7->InputChan0=7;
    ch7->InputChan1=1;
    ch7->OutputChan0=7;
    ch7->OutputChan1=1;
    ch7->MasterAxis=-1;
    ch7->LimitSwitchOptions=0x100;
    ch7->LimitSwitchNegBit=0;
    ch7->LimitSwitchPosBit=0;
    ch7->SoftLimitPos=1e+030;
    ch7->SoftLimitNeg=-1e+030;
    ch7->InputGain0=1;
    ch7->InputGain1=1;
    ch7->InputOffset0=0;
    ch7->InputOffset1=0;
    ch7->OutputGain=1;
    ch7->OutputOffset=0;
    ch7->SlaveGain=1;
    ch7->BacklashMode=BACKLASH_OFF;
    ch7->BacklashAmount=0;
    ch7->BacklashRate=0;
    ch7->invDistPerCycle=1;
    ch7->Lead=0;
    ch7->MaxFollowingError=10000000;
    ch7->StepperAmplitude=250;

    ch7->iir[0].B0=1;
    ch7->iir[0].B1=0;
    ch7->iir[0].B2=0;
    ch7->iir[0].A1=0;
    ch7->iir[0].A2=0;

    ch7->iir[1].B0=1;
    ch7->iir[1].B1=0;
    ch7->iir[1].B2=0;
    ch7->iir[1].A1=0;
    ch7->iir[1].A2=0;

    ch7->iir[2].B0=1;
    ch7->iir[2].B1=0;
    ch7->iir[2].B2=0;
    ch7->iir[2].A1=0;
    ch7->iir[2].A2=0;


    EnableAxis(0);
    EnableAxis(1);
    EnableAxis(2);
    EnableAxis(7);


    SetBit(158); // release z axis brake
    SetBit(159); //enable VFD spindle contoller


    DefineCoordSystem(0,1,2,-1);

    T = WaitNextTimeSlice();
    DoPCFloat(PC_COMM_SET_SSO,SSO);
    LastSSO=SSO;
    //printf("SSO = %f\n",SSO);
    LastSSOTime=T;

    for (; // loop forever

    {
    ButtonService();
    PotService();
    }


    }



    void ButtonService()

    {
    int result;


    {


    // Handle Power On Button
    result = Debounce(ReadBit(POWERON),&fcount,&flast,&flastsol id);
    if (result == 1)
    {
    SetBit (144);
    }



    // Handle Power off Button
    result = Debounce(ReadBit(POWEROFF),&ccount,&clast,&clastso lid);
    if (result == 0)
    {

    ClearBit(144); //disable power
    }



    // Handle ESTOP
    result = Debounce(ReadBit(ESTOP),&ecount,&elast,&elastsolid );
    if (result == 0)
    {
    if (ch0->Enable) DisableAxis(0); // axis still enabled? - Disable it
    if (ch1->Enable) DisableAxis(1); // axis still enabled? - Disable it
    if (ch2->Enable) DisableAxis(2); // axis still enabled? - Disable it
    if (ch7->Enable) DisableAxis(7); // axis still enabled? - Disable it
    ClearBit(158);

    //DoPC(PC_COMM_ESTOP);
    }

    // Handle HALT
    result = Debounce(ReadBit(HALTBIT),&hcount,&hlast,&hlastsol id);
    if (result == 1)
    {
    //DoPC(PC_COMM_HALT);
    SetBit(155);
    }
    else if (result == 0)
    {
    ClearBit(155);
    }

    /*
    // Handle RESTART
    result = Debounce(ReadBit(RESTARTBIT),&rcount,&rlast,&rlast solid);
    if (result == 1)
    {
    DoPC(PC_COMM_RESTART);
    }


    */
    /*
    // Handle ZERO ALL
    result = Debounce(ReadBit(ZEROALLBIT),&zcount,&zlast,&zlast solid);
    if (result == 1)
    {
    DoPCFloat(PC_COMM_SET_X,0.0);
    DoPCFloat(PC_COMM_SET_Y,0.0);
    DoPCFloat(PC_COMM_SET_Z,0.0);
    }

    */
    }
    }

    // Put a Float as a parameter and pass the command to the App
    int DoPCFloat(int cmd, float f)
    {
    int result;
    persist.UserData[PC_COMM_PERSIST+1] = *(int*)&f;
    return DoPC(cmd);
    }


    // Pass a command to the PC and wait for it to handshake
    // that it was received by either clearing the command
    // or changing it to a negative error code
    int DoPC(int cmd)
    {
    int result;

    persist.UserData[PC_COMM_PERSIST]=cmd;

    do
    {
    WaitNextTimeSlice();
    }while (result=persist.UserData[PC_COMM_PERSIST]>0);

    printf("Result = %d\n",result);

    return result;
    }




    // 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;
    }


    PotService(void)
    {

    double Factor=0;
    double Pot,Pot1,FRO,SSO,T;


    T = WaitNextTimeSlice();


    // assume 5V range where 2.5V is nominal FRO
    Pot=KANALOG_CONVERT_ADC_TO_VOLTS(ADC(0)) - 2.5;
    Pot1=KANALOG_CONVERT_ADC_TO_VOLTS(ADC(1)) - 2.5;
    FRO = Pot*0.5+1.0;
    SSO = Pot1*0.5+1.0;

    // send message to KMotionCNC if the pot changed significantly
    // and it has been a while since the last message
    if ((FRO > LastFRO+CHANGE_TOL || FRO < LastFRO-CHANGE_TOL) &&
    T > LastFROTime+CHANGE_TIME)
    {
    // printf("FRO = %f\n",FRO);
    DoPCFloat(PC_COMM_SET_FRO,FRO);
    LastFRO=FRO;
    LastFROTime=T;
    }
    if ((SSO > LastSSO+CHANGE_TOL || SSO < LastSSO-CHANGE_TOL) &&
    T > LastSSOTime+CHANGE_TIME)
    {
    // printf("SSO = %f\n",SSO);
    DoPCFloat(PC_COMM_SET_SSO,SSO);
    LastSSO=SSO;
    LastSSOTime=T;
    }
    }


    The S file :


    #include "KMotionDef.h"

    #include "MySpindleDefs.h"

    int *css_mode = &persist.UserData[PC_COMM_CSS_MODE]; // Mode 1=Normal RPM mode. 2=CSS

    // desired speed is passed from KMotionCNC in variable KMVAR
    // save in user variable STATEVAR whether it was off, CW, or CCW (0,1,-1)
    // save in user variable SPEEDVAR the last desired speed

    main()
    {
    float speed = *(float *)&persist.UserData[KMVAR]; // value stored is actually a float
    float LastState = persist.UserData[STATEVAR]; // get last state

    persist.UserData[SPEEDVAR] = persist.UserData[KMVAR]; // Always save the last desired speed

    if (LastState==0 || *css_mode == 2)
    {
    // if spindle is off (or CSS mode) and User Changes the speed
    // just save the desired speed

    return 0;
    }

    // spindle is already on, so ramp to new speed
    if (USE_POS_NEG_VOLTAGE)
    Jog(SPINDLEAXIS,speed * FACTOR * LastState);
    else
    Jog(SPINDLEAXIS,speed * FACTOR);

    printf("Jogging Spindle %f counts/sec\n",speed * FACTOR);
    }

    The Jog File... It's unaltered as is the spindlejog file :


    #include "KMotionDef.h"

    #include "MySpindleDefs.h"

    int *css_mode = &persist.UserData[PC_COMM_CSS_MODE]; // Mode 1=Normal RPM mode. 2=CSS

    // desired speed is passed from KMotionCNC in variable KMVAR
    // save in user variable STATEVAR whether it was off, CW, or CCW (0,1,-1)
    // save in user variable SPEEDVAR the last desired speed

    main()
    {
    float speed = *(float *)&persist.UserData[SPEEDVAR]; // value stored is actually a float
    float LastState = persist.UserData[STATEVAR]; // get last state

    if (LastState==-1)
    {
    // if spindle was CCW now we want CW
    // spin down

    //ClearBit(SPINDLECW_BIT);
    //ClearBit(SPINDLECCW_BIT);
    Jog(SPINDLEAXIS,0);
    while (!CheckDone(SPINDLEAXIS)) ;
    }

    // turn spindle on CW and ramp to new speed
    SetBit(SPINDLECW_BIT);

    if (*css_mode != 2)
    {
    // spindle is already on, so ramp to new speed
    if (USE_POS_NEG_VOLTAGE)
    Jog(SPINDLEAXIS,speed * FACTOR * LastState);
    else
    Jog(SPINDLEAXIS,speed * FACTOR);
    printf("Jogging Spindle %f counts/sec\n",speed * FACTOR);
    }
    persist.UserData[STATEVAR] = 1; // remember we are CW
    }

    Steve



  20. #40
    Member TomKerekes's Avatar
    Join Date
    May 2006
    Location
    USA
    Posts
    4043
    Downloads
    0
    Uploads
    0

    Default Re: PID advice on a retrofit BenchmanXT

    Hi Steve,

    I don't see anything obvious.

    In the future pleas attach the programs as files (with a .c.txt extension). Pasting in causes all the formatting to be lost and parenthesis change to smiley faces.

    More questions :

    #1 Please include your modified MySpindelDef.h file.

    #2 Please tell us where each of the 4 files are located on your system.

    #3 Include a screen shot of your Tool Setup | M0-M30 page so we can see how the data for these programs is being passed.

    #4 did you change the Spindle Soft Limits to 1e30 and -1e30? Or were they that way before? Are you still getting Soft Limit Errors on the Spindle Axis 7?

    #5 how does your Spindle work? Is there a CW CCW control? Is there an Enable? Is it controlled with a +/-Voltage? Or with Speed and Direction?

    Regards

    Regards
    TK http://dynomotion.com


Page 2 of 3 FirstFirst 123 LastLast

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
  •  


About CNCzone.com

    We are the largest and most active discussion forum for manufacturing industry. The site is 100% free to join and use, so join today!

Follow us on


Our Brands

PID advice on a retrofit BenchmanXT

PID advice on a retrofit BenchmanXT