link<\/a>). 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.<\/p>\n\n\n\n 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.<\/p>\n\n\n\n
#define MCP4X_PORT_WRITE 1\n\n#include <DAC_MCP4X.h>\n\nint x_out=0;\nint y_out=0;\nfloat x=0;\nfloat y=0;\nint currentblock=0;\nint blocknum = 0;\nint i = 0;\nint h = 0;\nfloat r = 0;\n\nMCP4X dac;\n\nvoid gotoRate(float x_d, float y_d, float r){\n unsigned long startTime = micros();\n blocknum ++;\n int blocknum_ = blocknum;\n \n float x_prev=x;\n float y_prev=y;\n\n float x_interval = x_d - x_prev;\n float y_interval = y_d - y_prev;\n\n float distance = sqrt(pow((x_d-x_prev), 2.0)+pow((y_d-y_prev), 2.0));\n float t = r\/(distance*1000000.0);\n\n for(; !((x == x_d) && (y == y_d)); ){\n\n float completion = (micros()-startTime)*t;\n x = x_prev + x_interval*completion;\n y = y_prev + y_interval*completion;\n if (x_interval>0){\n x=min(x,x_d);\n }\n if (y_interval>0){\n y=min(y,y_d);\n }\n\n if (x_interval<0){\n x=max(x,x_d);\n }\n if (y_interval<0){\n y=max(y,y_d);\n }\n\n x_out = x * 4095;\n y_out = y * 4095;\n dac.output2(x_out, y_out);\n }\n}\n\n\n\nvoid goTo(float x_d, float y_d, float t){\n blocknum ++;\n int blocknum_ = blocknum;\n \n float x_prev=x;\n float y_prev=y;\n\n\n float x_interval = x_d - x_prev;\n float y_interval = y_d - y_prev;\n \n\n\n for(unsigned long startTime = micros(); !((x == x_d) && (y == y_d)); ){\n float completion = (micros()-startTime)\/(t*1000000.0);\n x = x_prev + x_interval*completion;\n y = y_prev + y_interval*completion;\n if (x_interval>0){\n x=min(x,x_d);\n }\n if (y_interval>0){\n y=min(y,y_d);\n }\n if (x_interval<0){\n x=max(x,x_d);\n }\n if (y_interval<0){\n y=max(y,y_d);\n }\n x_out = x * 4095;\n y_out = y * 4095;\n dac.output2(x_out, y_out);\n }\n}\n\n\n\n\nvoid setup() {\n dac.init(MCP4X_4822, 5000, 5000, 10, 7, 1);\n dac.setGain2x(MCP4X_CHAN_A, 1);\n dac.setGain2x(MCP4X_CHAN_B, 1);\n dac.begin(1);\n Serial.begin(1000000);\n pinMode(4, INPUT_PULLUP);\n}\n\n\nvoid loop() {\n if (h==0){\n r = 1;\n }\n if (h==2){\n r = 5;\n }\n if (h==4){\n r = 25;\n }\n if (h==8){\n r = 125;\n }\n if (h==16){\n r = 250;\n }\n if (h==32){\n r = 300;\n }\n h++;\n \n unsigned long startterm = micros();\n\n gotoRate(0.816031, 0.282731, r);\n gotoRate(0.816031, 0.702343, r);\n gotoRate(0.909049, 0.702343, r);\n gotoRate(0.720947, 0.700276, r);\n gotoRate(0.814998, 0.702343, r);\n gotoRate(0.811897, 0.27963, r);\n gotoRate(0.597956, 0.278596, r);\n gotoRate(0.620694, 0.2972, r);\n gotoRate(0.650666, 0.334407, r);\n gotoRate(0.665136, 0.389184, r);\n gotoRate(0.664102, 0.441894, r);\n gotoRate(0.656867, 0.497704, r);\n gotoRate(0.628961, 0.543179, r);\n gotoRate(0.596922, 0.561783, r);\n gotoRate(0.559715, 0.561783, r);\n gotoRate(0.529743, 0.536978, r);\n gotoRate(0.509072, 0.487369, r);\n gotoRate(0.507006, 0.44086, r);\n gotoRate(0.663069, 0.444994, r);\n gotoRate(0.664104, 0.393318, r);\n gotoRate(0.653769, 0.344742, r);\n gotoRate(0.622763, 0.298233, r);\n gotoRate(0.596924, 0.27963, r);\n gotoRate(0.560751, 0.280665, r);\n gotoRate(0.535946, 0.297201, r);\n gotoRate(0.508041, 0.340609, r);\n gotoRate(0.531812, 0.304436, r);\n gotoRate(0.558684, 0.282732, r);\n gotoRate(0.370582, 0.281697, r);\n gotoRate(0.41399, 0.298233, r);\n gotoRate(0.430526, 0.343709, r);\n gotoRate(0.410889, 0.299267, r);\n gotoRate(0.369548, 0.281697, r);\n gotoRate(0.333375, 0.282732, r);\n gotoRate(0.295133, 0.302368, r);\n gotoRate(0.28273, 0.350944, r);\n gotoRate(0.294099, 0.399519, r);\n gotoRate(0.31477, 0.421224, r);\n gotoRate(0.380916, 0.43776, r);\n gotoRate(0.411921, 0.457397, r);\n gotoRate(0.426391, 0.499772, r);\n gotoRate(0.413988, 0.541113, r);\n gotoRate(0.372647, 0.562817, r);\n gotoRate(0.333373, 0.560751, r);\n gotoRate(0.2972, 0.54008, r);\n gotoRate(0.280663, 0.502873, r);\n gotoRate(0.294099, 0.541113, r);\n gotoRate(0.336474, 0.562817, r);\n gotoRate(0.371614, 0.564884, r);\n gotoRate(0.416056, 0.54008, r);\n gotoRate(0.426391, 0.502873, r);\n gotoRate(0.413989, 0.459464, r);\n gotoRate(0.387117, 0.441895, r);\n gotoRate(0.313736, 0.419157, r);\n gotoRate(0.299267, 0.403654, r);\n gotoRate(0.277563, 0.355078, r);\n gotoRate(0.290999, 0.304435, r);\n gotoRate(0.33234, 0.279631, r);\n gotoRate(0.133902, 0.281697, r);\n gotoRate(0.160774, 0.302368, r);\n gotoRate(0.17731, 0.360245, r);\n gotoRate(0.174209, 0.702343, r);\n gotoRate(0.174209, 0.562817, r);\n gotoRate(0.211416, 0.564883, r);\n gotoRate(0.125634, 0.563848, r);\n gotoRate(0.175243, 0.562813, r);\n gotoRate(0.175243, 0.366442, r);\n gotoRate(0.162841, 0.30133, r);\n gotoRate(0.133902, 0.28066, r);\n gotoRate(0.104963, 0.279625, r);\n gotoRate(0.816031, 0.282731, r);\n Serial.println(micros() - startterm);\n}\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"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 […]<\/p>\n","protected":false},"author":1,"featured_media":54,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[6],"tags":[5],"_links":{"self":[{"href":"http:\/\/please.local\/wp-json\/wp\/v2\/posts\/53"}],"collection":[{"href":"http:\/\/please.local\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/please.local\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/please.local\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/please.local\/wp-json\/wp\/v2\/comments?post=53"}],"version-history":[{"count":2,"href":"http:\/\/please.local\/wp-json\/wp\/v2\/posts\/53\/revisions"}],"predecessor-version":[{"id":64,"href":"http:\/\/please.local\/wp-json\/wp\/v2\/posts\/53\/revisions\/64"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/please.local\/wp-json\/wp\/v2\/media\/54"}],"wp:attachment":[{"href":"http:\/\/please.local\/wp-json\/wp\/v2\/media?parent=53"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/please.local\/wp-json\/wp\/v2\/categories?post=53"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/please.local\/wp-json\/wp\/v2\/tags?post=53"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}