Galvo's movement using the G-Code

Can anyone help me?
This is the code that controls Galvo's movement using the G-Code.
The base code works, but only in a simple form. Galvo jump between positions. It is not possible to control the speed.
I want Galvo to move smoothly. (Code part deactivated) It works in another code, but not in this one. Galvo doesn't move at all.
I don't know what I'm doing wrong.

#include <gcode.h>
#include <MCP48xx.h>

MCP4822 dac(53);       // CS Pin 53

#define LDAC    48     // LDAC Pin
#define Laser   47     // Laser Pin

unsigned int x_i = 0;
unsigned int y_i = 0;
#define F_mSec  10

#define STEPS_MM 10   

float stepsx;
float stepsy;

double X;
double Y;

void moviment_0();
void moviment_1();
void gotoLocation();

#define NUMCOMMANDS 2

commandscallback commands[NUMCOMMANDS] = { { "G1",moviment_1} , {"G0", moviment_0} }; 
gcode Commands(NUMCOMMANDS,commands);

void setup()
{
    Commands.begin();

    pinMode      ( Laser ,  OUTPUT ) ;
    pinMode      ( LDAC  ,  OUTPUT ) ;
    digitalWrite ( LDAC  ,     LOW ) ;      
   
    dac.init();
    dac.turnOnChannelA();
    dac.turnOnChannelB();

    digitalWrite( Laser , HIGH );  
    delay(500);  
    digitalWrite( Laser , LOW );
}

void loop() { Commands.available(); }


void gotoLocation(double x,double y)
{ 
    stepsx = x*STEPS_MM;  // In value X mm to DAC Output  0 = 4000mV
    stepsy = y*STEPS_MM;  // In value Y mm to DAC Output  0 = 4000mV

/*
  //#### X
  if (stepsx  >= x_i ){x_i ++ ; if (x_i >= stepsx) x_i = stepsx; delayMicroseconds(F_mSec); } // Move X ++
 else  
  if (stepsx  <= x_i ){x_i -- ; if (x_i <= stepsx) x_i = stepsx; delayMicroseconds(F_mSec); } // Move X --

//#### Y
  if (stepsy  >= y_i ){y_i ++ ; if (y_i >= stepsy) y_i = stepsy; delayMicroseconds(F_mSec); } // Move Y ++
 else  
  if (stepsy  <= y_i ){y_i -- ; if (y_i <= stepsy) y_i = stepsy; delayMicroseconds(F_mSec); } // Move Y --

    dac.setVoltageA(x_i);       
    dac.setVoltageB(y_i);
    dac.updateDAC();
*/
    delay(10);
    
    dac.setVoltageA(stepsx);       
    dac.setVoltageB(stepsy);      
    dac.updateDAC();

}

//### G00
void moviment_0()
{ 
    double new_0_XValue = X;
    double new_0_YValue = Y;
    if(Commands.availableValue('X'))          // ADDED parameter X in G0
      new_0_XValue = Commands.GetValue('X');
    if(Commands.availableValue('Y'))          // ADDED parameter Y in G0
      new_0_YValue = Commands.GetValue('Y');

      digitalWrite( Laser , LOW );
      gotoLocation(new_0_XValue,new_0_YValue);
}

//### G01
void moviment_1()
{ 
    double new_1_XValue = X;
    double new_1_YValue = Y;
    if(Commands.availableValue('X'))          // ADDED parameter X in G1
      new_1_XValue = Commands.GetValue('X');
    if(Commands.availableValue('Y'))          // ADDED parameter Y in G1
      new_1_YValue = Commands.GetValue('Y');

      digitalWrite( Laser , HIGH );
      gotoLocation(new_1_XValue,new_1_YValue);
}

who is Galvo?

Nice image but does not help...

Where do we find the gcode.h file?

Post a data sheet for your particular galvo setup.

It doesn't matter what Galvo is. It is clear from the code that the voltage is controlled by the DAC. 0 - 4000 mV (1mm = 10mV)

In your movement functions, what do you get if you print the values of new_0_XValue, new_0_YValue, new_1_XValue, new_1_YValue?

Galvo will move the plunge, allow it to control the speed of movement. When there is a large gap between the coordinates (X10 to X200) Galvo jump over very fast. This will be a big problem when engraving.

new_0_XValue movement Laser is turned off. G0
new_1_XValue movement Laser is turned on. G1

When someone offers a solution to my problem. I will be able to set a new line reading delay with a buffer algorithm that adjusts the delay at each coordinate change. Of course, the val = tan (a / b) correction must also be implemented. a = distance x or y, b height (distance of mirrors from the work surface). But this is completely irrelevant at the present stage. It's just a slow and smooth movement. mV ++ up to the given value (coordinates)

179 / 5 000

For a better understanding, currently it works like that (X0 to X200) (old value 0mV jump directly it's new value 2000mV). I want (old value 0mV ++ to new value 2000mV)

The function only moves one step on each axis. You should probably continue moving until you reach the destination. That part seems to be missing from this code.

Note: This code does not move in a straight line. It moves diagonally until the shortest axis has reached its destination, then moves along the longer axis. If you want straight lines you need to step the short axis slower (less often) than the long axis.

Yes, inserting the smooth motion code into a new function causes one more problem. The drawn object floats across the matrix and is small. ignores multiplication * 10. the square is a diamond

Sounds like one or more programming errors.

Have you fixed the problem that you never update X and Y?

What GCode are you using?

G01 X0 Y200 // move laser on
G00 X0 Y200 // move laser off

Now I've changed the code.
To stop reading a new line until the value of x_i and y_i is the same as stepsx and stepsy.
according to my gcode I draw a square.

G0 X10 Y10
G1 X200 Y10
G1 X200 Y200
G1 X10 Y200
G1 X10 Y10

But draw this.


It looks like he started drawing the first line but doesn't finish drawing and then immediately jump to the second

void loop()
{ 
  mov();
  
  if ( read_new_line == true )  Commands.available(); 

  dac.setVoltageA(x_i);
  dac.setVoltageB(y_i);
  dac.updateDAC();  
  
}


void mov()
{
//#### X
   if ( stepsx  >= x_i ) { x_i ++ ; delayMicroseconds(F_mSec); if (x_i >= stepsx) x_i = stepsx;  } // Move X ++
                       else  
                         { x_i -- ; delayMicroseconds(F_mSec); if (x_i <= stepsx) x_i = stepsx;  } // Move X --

//#### Y
  if ( stepsy  >= y_i )  { y_i ++ ; delayMicroseconds(F_mSec); if (y_i >= stepsy) y_i = stepsy;  } // Move Y ++
                       else  
                         { y_i -- ; delayMicroseconds(F_mSec); if (y_i <= stepsy) y_i = stepsy;  } // Move Y --


  if ( ( x_i == stepsx ) && ( y_i == stepsy ))  read_new_line = true  ;  
  if ( ( x_i != stepsx ) && ( y_i != stepsy ))  read_new_line = false ; 

}


void gotoLocation(double x,double y)
{ 
    stepsx = x*STEPS_MM;  // In value X mm to DAC Output  0 = 4000mV
    stepsy = y*STEPS_MM;  // In value Y mm to DAC Output  0 = 4000mV

}

It works now.

void loop()
{ 
  mov();

  if ( ( x_i == stepsx ) && ( y_i == stepsy ))  Commands.available();   //  !!!!!  pause read next line
 
  dac.setVoltageA(x_i);
  dac.setVoltageB(y_i);
  dac.updateDAC();  
  
}


void mov()
{
//#### X
   if ( stepsx  >= x_i ) { x_i ++ ; delayMicroseconds(F_mSec); if (x_i >= stepsx) x_i = stepsx;  } // Move X ++
                       else  
                         { x_i -- ; delayMicroseconds(F_mSec); if (x_i <= stepsx) x_i = stepsx;  } // Move X --

//#### Y
  if ( stepsy  >= y_i )  { y_i ++ ; delayMicroseconds(F_mSec); if (y_i >= stepsy) y_i = stepsy;  } // Move Y ++
                       else  
                         { y_i -- ; delayMicroseconds(F_mSec); if (y_i <= stepsy) y_i = stepsy;  } // Move Y --

}
1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.