Code for driving Galvos with Arduino Uno R3

Together with this code I used Delta Flo’s library for the MCP4822 (link). The gotorate(x, y, r) function calculates the linear distance between the current and desired positions and interpolates the values based of the rate variable. This way it keeps the galvos at a constant rate and eliminates the some of the brighter dots from the galvos starting and stopping instantly.

I defined my coordinates as x1.0, y1.0 being the maximum travel of the galvo mirros. The rate variable is in Units per second(ie a move from x0 y0 to x1 y0 at rate 2.0, would take 0.5 seconds). I generate the below code in inkscape by drawing the desired text as a path, using the nodes to csv plug in to generate a csv, and taking the csv into a custom excel sheet that takes the positions and turns them into compatible code.

#define MCP4X_PORT_WRITE 1

#include <DAC_MCP4X.h>

int x_out=0;
int y_out=0;
float x=0;
float y=0;
int currentblock=0;
int blocknum = 0;
int i = 0;
int h = 0;
float r = 0;

MCP4X dac;

void gotoRate(float x_d, float y_d, float r){
  unsigned long startTime = micros();
  blocknum ++;
  int blocknum_ = blocknum;
  
  float x_prev=x;
  float y_prev=y;

  float x_interval = x_d - x_prev;
  float y_interval = y_d - y_prev;

  float distance = sqrt(pow((x_d-x_prev), 2.0)+pow((y_d-y_prev), 2.0));
  float t = r/(distance*1000000.0);

  for(; !((x == x_d) && (y == y_d)); ){

    float completion = (micros()-startTime)*t;
    x = x_prev + x_interval*completion;
    y = y_prev + y_interval*completion;
    if (x_interval>0){
      x=min(x,x_d);
    }
    if (y_interval>0){
      y=min(y,y_d);
    }

    if (x_interval<0){
      x=max(x,x_d);
    }
    if (y_interval<0){
      y=max(y,y_d);
    }

    x_out = x * 4095;
    y_out = y * 4095;
    dac.output2(x_out, y_out);
  }
}



void goTo(float x_d, float y_d, float t){
  blocknum ++;
  int blocknum_ = blocknum;
  
  float x_prev=x;
  float y_prev=y;


  float x_interval = x_d - x_prev;
  float y_interval = y_d - y_prev;
  


  for(unsigned long startTime = micros(); !((x == x_d) && (y == y_d)); ){
    float completion = (micros()-startTime)/(t*1000000.0);
    x = x_prev + x_interval*completion;
    y = y_prev + y_interval*completion;
    if (x_interval>0){
      x=min(x,x_d);
    }
    if (y_interval>0){
      y=min(y,y_d);
    }
    if (x_interval<0){
      x=max(x,x_d);
    }
    if (y_interval<0){
      y=max(y,y_d);
    }
    x_out = x * 4095;
    y_out = y * 4095;
    dac.output2(x_out, y_out);
  }
}




void setup() {
  dac.init(MCP4X_4822, 5000, 5000, 10, 7, 1);
  dac.setGain2x(MCP4X_CHAN_A, 1);
  dac.setGain2x(MCP4X_CHAN_B, 1);
  dac.begin(1);
  Serial.begin(1000000);
  pinMode(4, INPUT_PULLUP);
}


void loop() {
  if (h==0){
    r = 1;
  }
  if (h==2){
    r = 5;
  }
  if (h==4){
    r = 25;
  }
  if (h==8){
    r = 125;
  }
  if (h==16){
    r = 250;
  }
  if (h==32){
    r = 300;
  }
  h++;
 
  unsigned long startterm = micros();

  gotoRate(0.816031, 0.282731,  r);
  gotoRate(0.816031, 0.702343,  r);
  gotoRate(0.909049, 0.702343,  r);
  gotoRate(0.720947, 0.700276,  r);
  gotoRate(0.814998, 0.702343,  r);
  gotoRate(0.811897, 0.27963,  r);
  gotoRate(0.597956, 0.278596,  r);
  gotoRate(0.620694, 0.2972,  r);
  gotoRate(0.650666, 0.334407,  r);
  gotoRate(0.665136, 0.389184,  r);
  gotoRate(0.664102, 0.441894,  r);
  gotoRate(0.656867, 0.497704,  r);
  gotoRate(0.628961, 0.543179,  r);
  gotoRate(0.596922, 0.561783,  r);
  gotoRate(0.559715, 0.561783,  r);
  gotoRate(0.529743, 0.536978,  r);
  gotoRate(0.509072, 0.487369,  r);
  gotoRate(0.507006, 0.44086,  r);
  gotoRate(0.663069, 0.444994,  r);
  gotoRate(0.664104, 0.393318,  r);
  gotoRate(0.653769, 0.344742,  r);
  gotoRate(0.622763, 0.298233,  r);
  gotoRate(0.596924, 0.27963,  r);
  gotoRate(0.560751, 0.280665,  r);
  gotoRate(0.535946, 0.297201,  r);
  gotoRate(0.508041, 0.340609,  r);
  gotoRate(0.531812, 0.304436,  r);
  gotoRate(0.558684, 0.282732,  r);
  gotoRate(0.370582, 0.281697,  r);
  gotoRate(0.41399, 0.298233,  r);
  gotoRate(0.430526, 0.343709,  r);
  gotoRate(0.410889, 0.299267,  r);
  gotoRate(0.369548, 0.281697,  r);
  gotoRate(0.333375, 0.282732,  r);
  gotoRate(0.295133, 0.302368,  r);
  gotoRate(0.28273, 0.350944,  r);
  gotoRate(0.294099, 0.399519,  r);
  gotoRate(0.31477, 0.421224,  r);
  gotoRate(0.380916, 0.43776,  r);
  gotoRate(0.411921, 0.457397,  r);
  gotoRate(0.426391, 0.499772,  r);
  gotoRate(0.413988, 0.541113,  r);
  gotoRate(0.372647, 0.562817,  r);
  gotoRate(0.333373, 0.560751,  r);
  gotoRate(0.2972, 0.54008,  r);
  gotoRate(0.280663, 0.502873,  r);
  gotoRate(0.294099, 0.541113,  r);
  gotoRate(0.336474, 0.562817,  r);
  gotoRate(0.371614, 0.564884,  r);
  gotoRate(0.416056, 0.54008,  r);
  gotoRate(0.426391, 0.502873,  r);
  gotoRate(0.413989, 0.459464,  r);
  gotoRate(0.387117, 0.441895,  r);
  gotoRate(0.313736, 0.419157,  r);
  gotoRate(0.299267, 0.403654,  r);
  gotoRate(0.277563, 0.355078,  r);
  gotoRate(0.290999, 0.304435,  r);
  gotoRate(0.33234, 0.279631,  r);
  gotoRate(0.133902, 0.281697,  r);
  gotoRate(0.160774, 0.302368,  r);
  gotoRate(0.17731, 0.360245,  r);
  gotoRate(0.174209, 0.702343,  r);
  gotoRate(0.174209, 0.562817,  r);
  gotoRate(0.211416, 0.564883,  r);
  gotoRate(0.125634, 0.563848,  r);
  gotoRate(0.175243, 0.562813,  r);
  gotoRate(0.175243, 0.366442,  r);
  gotoRate(0.162841, 0.30133,  r);
  gotoRate(0.133902, 0.28066,  r);
  gotoRate(0.104963, 0.279625,  r);
  gotoRate(0.816031, 0.282731,  r);
  Serial.println(micros() - startterm);
}

Posted

in

by

Tags: