This is an old revision of the document!
Table of Contents
PLC Examples
Spindle Speed control for DAC
- SPN.plc
#define command var00 #define parameter var01 //set Spindle speed control via DAC channel #1 //Spindle Speed is given in **eparam** register main() { value=eparam; if (value>0xFFF) {value=0xFFF;}; //fix if given value is out of range 0...0xfff if (value<0) {value=0;}; dac01=value; //setup DAC value //**Set Spindle Speed** is asynchronous operation. //It's better to inform myCNC Software New Spindle Speed applied. //Send information about new Spindle Speed to myCNC Software message=PLCCMD_REPLY_TO_MYCNC; //Command code to send to myCNC software command=PLC_MESSAGE_SPINDLE_SPEED_CHANGED; //Message code parameter=eparam; //New Spindle Speed information timeout=timer+10; do { timer++; } while (timer<timeout); //Delay to push the Message to myCNC Software gvarset(7371,eparam); //myCNC register #7371 contains actual Spindle Speed. //Another way to inform myCNC software about new Spindle Speed //(to display on it DRO for example) exit(99); //normal exit. };
Spindle Control through Triggers
In this case, a couple of lines are added to standard M03 (spindle ON), M05 (spindle OFF) and M02 (End program) PLCs, typically to allow the system to interpret some spindle feedback signal. Spindle control is done through a trigger, with the trigger flag indicating whether the trigger is ON or OFF. If the spindle is ON and the trigger is activated, then the program will be stopped.
The following code can be used to enable the trigger:
message=PLCCMD_TRIGGER1_ON; timer=10;do{timer--;}while(timer>0);
The following code can be used to disable the trigger:
message=PLCCMD_TRIGGER1_OFF; timer=10;do{timer--;}while(timer>0);
The code to enable the trigger should be inserted into M03, while the code to disable the trigger should be inserted into M05 and M02. The full resultant PLC procedure code can be found below:
Click to expand the M02 code |
#include pins.h #include vars.h // g0moveA - start motion: // flags - // bit 0 - absolute programming // bit 1 - machine coordinates // bit 7 - delayed start. // axes mask // bit 0 - X axis; bit 1 - Y axis;bit 2 - Z axis;bit 3 - A axis;bit 4 - B axis;bit 5 - C axis lift_up() { if (proc==plc_proc_spindle) { z1=gvarget(17003); timer=10; do{timer--;}while (timer>0);//wait till motion started z2=gvarget(7020); z2=z2*100; if (absolute==0) { z2=z1+z2; }; z1=z1+100; //add 1mm gap if (z2>z1) { //position coordinate in given axis in 0.01 units (mm) gvarset(7080,speed_z); //set speed g0moveA(1,0x4,z2); //absolute programming; Z axis; timer=300; do{timer--;}while (timer>0); //wait motion started //wait motion stopped do { ex=0; code=gvarget(6060); if (code==0x4d) {ex=1;}; if (code==0x57) {ex=1;}; } while(ex==0); }; }; }; main() { message=PLCCMD_TRIGGER4_ON; timer=2;do{timer--;}while(timer>0); if (absolute!=0) { absolute=1; }; portclr(OUTPUT_MIST); portclr(OUTPUT_FLOOD); gvarset(7372,0);//Reset Mist State timer=30;do{timer--;}while(timer>0); gvarset(7373,0);//Reset Flood State timer=30;do{timer--;}while(timer>0); lift_up(); dac01=0x0; //off DAC output portclr(OUTPUT_SPINDLE); portclr(OUTPUT_CCW_SPINDLE); gvarset(7370,0);//Spindle State gvarset(7371,0);//Spindle Speed Mirror register message=PLCCMD_TRIGGER1_OFF; timer=10;do{timer--;}while(timer>0); proc=plc_proc_idle; exit(99); };
- M240.plc
#define OUTPUT_FILL 13 #define OUTPUT_DRAIN 12 main() { o=gvarget(7184); //read OUTPUT PORT 0 state (pins 0...31) drain_state=o&(1<<OUTPUT_DRAIN); fill_state=o&(1<<13); if (eparam==0) //toggle drain { if (drain_state==0) { portset(OUTPUT_DRAIN); portclr(OUTPUT_FILL); //to prevent both are open }else { portclr(OUTPUT_DRAIN); }; }else //toggle fill { if (fill_state==0) { portset(OUTPUT_FILL); portclr(OUTPUT_DRAIN); //to prevent both are open }else { portclr(OUTPUT_FILL); }; }; exit(99); };
=== Eliminating tangential knife spin at the start of the program (M212) === Because of how the system records angles, the software shows angles larger than 360 degrees (one full revolution) if a number of turns in the same direction have been taken by the knife. For example, if the knife has turned around its axis from 0 degrees twice in the positive direction, the angle now will be recorded as 720 degrees (2 full revolutions). After the program completes, and the angle is left at this number, the next time the program starts, the knife will rotate back until the angle is equal to zero. This behaviour is not ideal for some users, as it can extend the cutting process time. The M212 PLC exists to remove this positive/negative degree turn that is larger than 360 degrees at the program start. This is useful if the user wants to stop the knife from spinning back multiple times to its 0 position on the c-axis as the program is starting (however, this will still allow the knife to rotate an angle less than a full revolution in order to align itself properly). This PLC is provided with the myCNC software, and looks as follows:
main() { c=gvarget(17006); //get C-position in PLC units (0.01 degree) m=18000; //180 degree in PLC units (0.01 degree) if (c>m) { do{ c=c-36000; }while (c>m); //remove the whole positive turns }; m=0-m; //-180 degree in PLC units (0.01 degree) if (c<m) { do{ c=c+36000; }while (c<m); //remove the whole negative turns }; gvarset(7080,1000); //set speed 3000 degree/s; timer=10;do{timer--;}while(timer>0); g0moveA(0x0,0x20,0-c); //C axis, move to C=0 timer=200;do{timer--;}while(timer>0); do { code=gvarget(6060); }while(code!=0x4d);//wait till motion finished timer=100;do{timer--;}while(timer>0); //delay for any case exit(99); };
This PLC can be added to the DXF footer in Settings > Config > DXF Import Settings to run every time when the program generated from an imported DXF file finishes running. ==== Gantry Alignment Procedure (with Homing) ====
- M132
G10 L80 P5521 Q1 G10 L80 P5525 Q1 M146 P0 L1028 M88 L0 P5(Soft stop when sensor triggered) G91 G0 Y -300.0000 F 600.00 G04 P0.1 M89 L1 P5(Quick stop when sensor triggered) G91 G0 Y 300.0000 F 30.00 G04 P0.1 M135
- M135
G10 L80 P5521 Q1 G10 L80 P5525 Q1 M146 P0 L1028 M144 G91 G0 Y100 F30 G04 P0.1 G90 G10 L70 P0 Y0 G04 P0.1 M145 P0 L1028 G90 G10 L193 P97 Q5531 debug #98 G90 G10 L192 P98 Q7525 debug #98 debug #97 G90 G10 L190 P97 Q98 debug #97 G90 G28.9 Y97 F200 M146 P0 L1028 G90 G10 L70 P0 Y0 G90 G10 L80 P5521 Q0 G90 G10 L80 P5525 Q0 G90 G10 L80 P7395 Q0 (Homing Flag)
- M144.plc
//Look after input1 & input2 sensors, remember position, when triggered main() { timer=0; message=PLCCMD_MOTION_CONTINUE; texit=timer+2;do{timer++;}while(timer<texit); ready=0; state1=0; state2=0; e9000=portget(13);//gvarget(9000); e9001=portget(14);//gvarget(9001); state0=0; m1=0; m2=0; do { timer++; if (state0==0) { a=portget(13);//gvarget(9000); if (a!=e9000) { m1=1; position1=gvarget(5021+1); //Machine Y state0=1; }; a=portget(14);//gvarget(9100); if (a!=e9001) { m1=2; position1=gvarget(5021+1); //Machine Y state0=1; }; }else { if (m1==2) { a=portget(13);//gvarget(9000); if (a!=e9000) { m2=1; position2=gvarget(5021+1); //Machine Y state0=2; }; }else { a=portget(14);//gvarget(9100); if (a!=e9001) { m2=2; position2=gvarget(5021+1); //Machine Y state0=2; }; }; }; }while(state0<2); b=position1-position2; if (b>25000) { b=50000-b; }; c=0-25000; if (b<c) { b=50000+b; }; gvarset(97,b); texit=timer+30;do{timer++;}while(timer<texit); gvarset(7230,m1); if (m1==1) { gvarset(98,1);} else { x=0-1; gvarset(98,x);}; message=PLCCMD_MOTION_SKIP; //message=PLCCMD_MOTION_SOFT_SKIP; texit=timer+2;do{timer++;}while(timer<texit); exit(99); };
- M145.plc
#define var_address var00 #define var_value var01 main() { timer=0; lparam=eparam>>16; axis=1; // n=gvarget(7230); channel=0xff; if (n==1) {channel=0;}; if (n==2) {channel=1;}; if (n==4) {channel=2;}; if (n==8) {channel=3;}; if (channel>8) { message=PLCCMD_MOTION_ABORT; texit=timer+2;do{timer++;}while(timer<texit); exit(99); }; var_value=15; var_address=112+channel;//channel turn off message=PLCCMD_SET_CNC_VAR; texit=timer+2;do{timer++;}while(timer<texit); exit(99); };
- M146.plc
#define var_address var00 #define var_value var01 main() { timer=0; dir=0; axis=1; channel=0; var_address=112+channel;//channel 0 set up var_value=axis; if (dir!=0) { var_value=16+axis; }; message=PLCCMD_SET_CNC_VAR; texit=timer+10;do{timer++;}while(timer<texit); channel=1; var_address=112+channel;//channel 0 set up var_value=axis; if (dir!=0) { var_value=16+axis; }; message=PLCCMD_SET_CNC_VAR; texit=timer+10;do{timer++;}while(timer<texit); gvarset(7230,1); exit(99); };