User Tools

Site Tools


plc:plc_examples

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
plc:plc_examples [2019/07/12 12:51] ivanplc:plc_examples [2024/02/21 13:59] (current) ivan
Line 1: Line 1:
 ==== PLC Examples ==== ==== PLC Examples ====
 +
 +//**NOTE**: The myCNC team recommends utilizing the examples provided in this manual (as well as other manuals in this documentation) as a starting point for your machine setup. When possible (and applicable), it is recommended to keep changes to a mininum. In general, using these examples as the basis for your PLCs/macro commands allows for an easier setup process.//
  
   * [[plc:M07 Mist Coolant ON]]   * [[plc:M07 Mist Coolant ON]]
Line 43: Line 45:
 </code> </code>
  
 +===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: 
 +<code>
 +  message=PLCCMD_TRIGGER1_ON;
 +  timer=10;do{timer--;}while(timer>0);
 +</code>
 +
 +The following code can be used to disable the trigger: 
 +
 +<code>  message=PLCCMD_TRIGGER1_OFF;
 +  timer=10;do{timer--;}while(timer>0);</code>
 +  
 +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 M03 code | 
 +<code>//Turn on Spindle clockwise
 +#include pins.h
 +#include vars.h
 +main()
 +{
 +  timer=0;
 +  proc=plc_proc_spindle;
 +
 +  val=eparam;
 +  if (val>0xfff) {val=0xfff;};
 +  if (val<0) {val=0;};
 +
 +  dac01=val;
 +
 +  portclr(OUTPUT_CCW_SPINDLE);
 +  portset(OUTPUT_SPINDLE);
 +
 +  gvarset(7370,1); timer=30;do{timer--;}while (timer>0); //Spindle State
 +  gvarset(7371,eparam); timer=30;do{timer--;}while (timer>0); //Spindle Speed Mirror register
 +
 +  //gvarset(7372,0);//Mist State
 +  //timer=30;do{timer--;}while (timer>0); //
 +  //gvarset(7373,0);//Flood State
 +  //timer=30;do{timer--;}while (timer>0); //
 +
 +  //delay after spindle started
 +  timer=spindle_on_delay;
 +  do{timer--;}while (timer>0); //delay for Spindle reach given speed
 +
 +  message=PLCCMD_TRIGGER1_ON;
 +  timer=10;do{timer--;}while(timer>0);
 +
 +  exit(99); //normal exit 
 +};</code>
 +++++
 +
 +++++Click to expand the M05 code |
 +<code>
 +//Spindle Stop
 +//set Spindle speed control via DAC & PWM1 channel
 +
 +#include pins.h
 +#include vars.h
 +
 +
 +main()
 +{
 +  portclr(OUTPUT_SPINDLE);
 +  portclr(OUTPUT_CCW_SPINDLE);
 +  proc=plc_proc_idle;
 +
 +  message=PLCCMD_TRIGGER1_OFF;
 +  timer=10;do{timer--;}while(timer>0);
 +
 +  if (spindle_off_delay!=0)
 +  {
 +    timer=spindle_off_delay;
 +    do { timer--; } while (timer>0);
 +  };
 +
 +  dac01=0x0;
 +
 +  gvarset(7370,0);  timer=30;do{timer--;}while(timer>0); //Spindle State
 +  gvarset(7371,0);  timer=30;do{timer--;}while(timer>0); //Spindle Speed
 +
 +  exit(99);  //normal exit 
 +};</code>
 +
 +++++
 +
 +++++Click to expand the M02 code |
 +<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);
 +};</code>
 +
 +++++
 +
 +//More info on the M02 procedure available here: [[mycnc:stop_end_program|Stop/End program button commands]].//
 +
 +The trigger itself can be set up in Settings > Config > Inputs/Outputs/Sensors > Triggers/Timers to look the following way:
 +
 +{{:plc:hardware-plc-002-spindle-control-trigger.png}}
 +
 +  * **Input Number** can be set to the port which the spindle feedback signal is using (#0 in this case)
 +  * **Trigger** will be set to Falling Edge
 +  * **Output** set to Not Connected
 +  * **Slot** set to Stop Program
  
 === Spindle Speed control for ET10_DAC === === Spindle Speed control for ET10_DAC ===
Line 177: Line 354:
  
 </code> </code>
 +
 +A tutorial on how to use global variable 7184 present in the code above is available on our YouTube channel:
 +
 +{{youtube>iEXeUX0CedM?large}}
  
 === Eliminating tangential knife spin at the start of the program (M212) === === Eliminating tangential knife spin at the start of the program (M212) ===
 +
 +{{youtube>kLuNWFlizhA?large}}
  
 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.  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 macro 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).+{{:plc:five-axes-motion-angle-002.png}}
  
-The macro is provided with the myCNC software, and looks as follows: +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: 
  
 <code>main() <code>main()
Line 213: Line 398:
 };</code> };</code>
  
-This macro 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. +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.  
 + 
 +**//NOTE://** Since M212 changes the current coordinate value, it is necessary to always have a positioning command of the format ''G0C_'' after M212. If, for example, the coordinate is reset to 0 inside the PLC, then the next code after the PLC must be ''G90G0A0''. This  will result in no movement along the axis, but the coordinates will be synchronized.
  
 +When analyzing the program, by default the software does not know that the coordinate inside the PLC has changed, and thus the subsequent G0 command must be used to update it (G1/G2/G3 are NOT suitable for this task). However, the G0 code is only necessary if the M212 is embedded into a G-code program. If the M212 PLC is started independently (for example by clicking a the button which launches the M212 alone), then the system will automatically see that the coordinate has been changed. 
  
  
-==== Gantry Alignment Procedure (with Homing) ====+=== Gantry Alignment Procedure (with Homing) ===
  
 <code c M132> <code c M132>
Line 438: Line 626:
  
  exit(99);  exit(99);
 +};
 +</code>
 +
 +
 +=== Automatic plate rotation and offset adjustment ===
 +
 +{{youtube>THPElzA8Wtk?large}}
 +
 +<code C>#include pins.h
 +#define INPUT_PROBE 7
 +#define ROLLBACK 2000
 +wait_move()
 +{
 +    do { code=gvarget(6060); }while(code!=0x4d);  //wait till motion finished
 +};
 +show_error()
 +{
 +    gvarset(9121,1);
 +    timer=50;do{timer--;}while(timer>0);
 +    message=PLCCMD_MOTION_BREAK; //1033
 +    exit(99);
 +};
 +find_start()
 +{
 +  gvarset(8631,50); //acceleration time 100ms = 0.1s
 +  gvarset(8634,(1<<24)|speed); //Jog speed for X
 +  gvarset(8634,(2<<24)|speed); //Jog speed for Y
 +  gvarset(8635,3); //X+ Y+
 +  timer=0;
 +  do
 +   {
 +      sensor0=portget(INPUT_PROBE);
 +      if ((timer&0xff)==0)       gvarset(8635,3);    };
 +      timer++;
 +    }while(sensor0==0);
 +  timer=2000;
 +  do        if ((timer&0xff)==0)       gvarset(8635,3);    };       timer--;    }while(timer>0);
 +   gvarset(8635,0); wait_move();
 +};
 +do_rollback_y()
 +{
 +  sensor0=portget(INPUT_PROBE);
 +  if (sensor0==0)
 +  {
 +    do{
 +    g0moveA(0,0x02,ROLLBACK); wait_move();
 +    sensor0=portget(INPUT_PROBE);
 +    }while(sensor0==0);
 +  };
 +};
 +do_rollback_x()
 +{
 +  gvarset(8632,speed);
 +  g0moveA(0,0x01,length+(length>>2));
 +  do
 +  {
 +    sensor0=portget(INPUT_PROBE);
 +    if (sensor0==0) { message=stop_code;  };
 +    code=gvarget(6060);
 +  }while(code!=0x4d);//wait till motion finished
 +};
 +find_edge()
 +{
 +  gvarset(8632,speed);
 +  sensor0=portget(INPUT_PROBE);
 +  len=length;
 +  if (sensor0!=0) {len=0-len;};
 +  g0moveA(0,axis,len);
 +  edge=100;
 +  do{
 +   code=gvarget(6060);
 +   if (code==0x4d)
 +    {
 +      edge=0;
 +    }else
 +    {
 +      sensor1=portget(INPUT_PROBE);
 +      if (sensor1!=sensor0)
 +       {
 +        edge=1;
 +        message=stop_code;
 +        do { code=gvarget(6060); }while(code!=0x4d);  //wait till motion finished
 +       };
 +    };
 +  }while (edge==100);
 +};
 +move_x()
 +{
 +  gvarset(8632,speed_fast);
 +  g0moveA(0,0x1,0-length);
 +  do
 +  {
 +    sensor1=portget(INPUT_PROBE);
 +    if (sensor1==0)
 +    {
 +        edge=0;
 +        message=stop_code;
 +        wait_move();
 +    };
 +    code=gvarget(6060);
 +  }while(code!=0x4d);//wait till motion finished
 +};
 +move_y()
 +{
 +  gvarset(8632,speed_fast);
 +  g0moveA(0,0x2,length);
 +  do { code=gvarget(6060); }while(code!=0x4d);//wait till motion finished
 +};
 +move_y0()
 +{
 +  gvarset(8632,speed_fast);
 +  g0moveA(0,0x2,ROLLBACK);
 +  do { code=gvarget(6060); }while(code!=0x4d);//wait till motion finished
 +};
 +save_pos()
 +{
 +    if (edge==0)  {   show_error();    };
 +    //y_pos=gvarget(5042);
 +    //gvarset(400+point, gvarget(5041));  timer=30;do{timer--;}while(timer>0); //
 +    //gvarset(401+point, y_pos);  timer=30;do{timer--;}while(timer>0); //
 +    //point+=2;
 +    gvarset(5730, 1);  timer=30;do{timer--;}while(timer>0); //
 +    gvarset(8632,speed_fast);  g0moveA(0,axis,ROLLBACK); wait_move();
 +};
 +main()
 +{
 +  gvarset(5740, 1);  timer=30;do{timer--;}while(timer>0); //
 +  portset(7);
 +  gvarset(300,300); timer=30;do{timer--;}while(timer>0); //
 +  gvarset(301,1500); timer=30;do{timer--;}while(timer>0); //
 +  point=0;
 +  gvarset(8631,50); //acceleration time 100ms = 0.1s
 +  gvarset(5539,1); //switch to fast g0moveA implementation
 +  edge=0;
 +  stop_code=PLCCMD_LINE_SOFT_STOP;//skip line
 +  length=6000;
 +  speed_probe=gvarget(300);
 +  speed_fast=gvarget(301);
 +  speed=speed_fast;
 +  find_start();
 +  axis=0x1; //X axis
 +  do_rollback_x();
 +  do
 +  {
 +    axis=0x2; //Y axis
 +    speed=speed_fast;
 +    do_rollback_y();
 +    do{  find_edge(); }while((edge==0)&(sensor1!=0));
 +    if (edge!=0)
 +    {
 +      speed=speed_probe;
 +      find_edge();
 +      save_pos();
 +      move_x();
 +    };
 +  }while(edge!=0);
 +    axis=0x1; //X axis
 +    speed=speed_fast;
 +    find_edge();
 +    if (edge==0)  {   show_error();    };
 +    speed=speed_probe;
 +    find_edge();
 +    save_pos();
 +    move_y();
 +    speed=speed_fast;
 +    find_edge();
 +    if (edge==0)  {   show_error();    };
 +    speed=speed_probe;
 +    find_edge();
 +    if (edge==0)  {   show_error();    };
 +    save_pos();
 +    gvarset(5740, 200);  timer=30;do{timer--;}while(timer>0); //
 +    exit(99);
 +}; </code>
 +
 +=== Simultaneous homing for two axes ===
 +
 +The code below allows simultaneous homing for both the X and the Y axes. The example is using a lot of the functionality described in the Jog from PLC section of the PLC manual ([[plc:plc#jog_from_plc|PLC]]. Please refer to the full PLC manual for further explanation on the jog from PLC functionality and its associated [[mycnc:global_variables|global variables]].
 +
 +<code C>#include pins.h
 +
 +wait_move()
 +{
 +    do { code=gvarget(6060); }while(code!=0x4d);  //wait till motion finished
 +};
 +
 +show_error()
 +{
 +    gvarset(9121,1); //bring up popup message 21
 +    timer=50;do{timer--;}while(timer>0);
 +    message=PLCCMD_MOTION_BREAK; //1033
 +    exit(99);
 +};
 +
 +find_home_xy()
 +{
 +
 +  gvarset(5521,1); //disable hardware limits
 +  gvarset(5525,1); //disable software limits
 +
 +  gvarset(8631,50); //acceleration time 100ms = 0.05s
 +
 +  statex=0;
 +  statey=0;
 +  speed=500;
 +  speed_slow=50;
 +
 +  direction=(1<<8)+(2<<8); //set the direction variable to X- Y-
 +
 +  gvarset(8634,(1<<24)|speed); //Jog speed for X
 +  gvarset(8634,(2<<24)|speed); //Jog speed for Y
 +
 +  gvarset(8635,direction); //jog in the set direction (X- Y-)
 +  timer=0;
 +  do
 +   {
 +      changed=0;
 +      if (statex==0) //to home X
 +       {
 +          sens=portget(INPUT_HOME_X); //get state of home x sensor
 +          if (sens!=0)
 +          {
 +            statex=1;
 +            gvarset(8634,(1<<24)|speed_slow); //Jog speed for X
 +            changed=1;
 +          };
 +       };
 +      if (statex==1) //rollback from home X
 +       {
 +          sens=portget(INPUT_HOME_X);
 +          if (sens==0)
 +          {
 +            statex=2;
 +            changed=1;
 +          };
 +       };
 +
 +      if (statey==0) //to home Y
 +       {
 +          sens=portget(INPUT_HOME_Y); //get state of home y sensor
 +          if (sens!=0)
 +          {
 +            statey=1;
 +            gvarset(8634,(2<<24)|speed_slow); //Jog speed for Y
 +            changed=1;
 +          };
 +       };
 +      if (statey==1) //rollback from home X
 +       {
 +          sens=portget(INPUT_HOME_Y); //get state of home y sensor
 +          if (sens==0)
 +          {
 +            statey=2;
 +            changed=1;
 +          };
 +       };
 +
 +  if (changed!=0) //if any of the sensors state is changed
 +  {
 +    direction=0; //set direction to 0 (no movement) before flipping
 +    if (statex==0) { direction=direction | (1<<8);  };  //direction set to X-
 +    if (statex==1) { direction=direction | 1;  }; //direction set to X+
 +    if (statey==0) { direction=direction |  (2<<8);  };  //direction set to Y-
 +    if (statey==1) { direction=direction |  2;  }; //direction set to Y+
 +    gvarset(8635,direction); //jog in new direction for the axes
 +  };
 +
 +
 +
 +      if ((timer&0xff)==0)       gvarset(8635,direction);    };
 +      timer++;
 +      ready=(statex==2)&(statey==2);
 +
 +    }while(ready==0);
 +
 +
 +   gvarset(8635,0); wait_move(); //stop jog
 +
 +};
 +
 +main()
 +{
 +
 +  gvarset(8631,50); //acceleration time 50ms = 0.05s
 +  gvarset(5539,1); //switch to fast g0moveA implementation
 +
 +  find_home_xy();
 +
 +  
 +  exit(99);  //normal exit 
 }; };
 </code> </code>
plc/plc_examples.1562950303.txt.gz · Last modified: 2019/07/12 12:51 by ivan

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki