Skip to content

Instantly share code, notes, and snippets.

@pingbird
Created September 14, 2024 20:40
Show Gist options
  • Save pingbird/01593ad3cf89f99616cbdef929df9237 to your computer and use it in GitHub Desktop.
Save pingbird/01593ad3cf89f99616cbdef929df9237 to your computer and use it in GitHub Desktop.
import 'dart:io';
import 'dart:math';
const prologue = '''
M201 X2500 Y2500 Z400 E5000 ; sets maximum accelerations, mm/sec^2
M203 X180 Y180 Z12 E80 ; sets maximum feedrates, mm / sec
M204 P2000 R1250 T2500 ; sets acceleration (P, T) and retract acceleration (R), mm/sec^2
M205 X8.00 Y8.00 Z2.00 E10.00 ; sets the jerk limits, mm/sec
M205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec
;TYPE:Custom
M862.3 P "MINI" ; printer model check
G90 ; use absolute coordinates
M83 ; extruder relative mode
M104 S170 ; set extruder temp for bed leveling
M140 S60 ; set bed temp
M109 R170 ; wait for bed leveling temp
M190 S60 ; wait for bed temp
M204 T1250 ; set travel acceleration
G28 ; home all without mesh bed level
G29 ; mesh bed leveling
M204 T2500 ; restore travel acceleration
M104 S215 ; set extruder temp
G92 E0
G1 Y-2 X179 F2400
G1 Z3 F720
M109 S215 ; wait for extruder temp
; intro line
G1 X170 F1000
G1 Z0.2 F720
G1 X110 E8 F900
G1 X40 E10 F700
G92 E0
M221 S95 ; set flow
G21 ; set units to millimeters
G90 ; use absolute coordinates
M83 ; use relative distances for extrusion
M900 K0.2 ; Filament gcode LA 1.5
; ; Filament gcode LA 1.0
''';
const epilogue = '''
G1 E-2 F2100 ; retract
G1 Z10 F720 ; Move print head up
G1 X178 Y178 F4200 ; park print head
G1 Z30.2 F720 ; Move print head further up
G4 ; wait
M104 S0 ; turn off temperature
M140 S0 ; turn off heatbed
M107 ; turn off fan
M221 S100 ; reset flow
M900 K0 ; reset LA
M84 ; disable motors
''';
void main() {
var originX = 16.0;
var originY = 16.0;
var scale = 4.0;
late double perimeterWidth;
late double layerHeight;
late double filamentWidth;
late double filamentCrossArea;
late double perimeterCrossArea;
late double solidOverlap;
late double extrusion;
late double liftHeight;
var retractLength = 2;
var retractExtraExtrusion = 0.0;
filamentWidth = 1.75;
void recalculateFilament() {
filamentCrossArea = pi * pow(filamentWidth / 2, 2);
perimeterCrossArea = (perimeterWidth - layerHeight) * layerHeight +
pi * pow(layerHeight / 2, 2);
extrusion = perimeterCrossArea / filamentCrossArea;
liftHeight = layerHeight * 2;
solidOverlap = perimeterCrossArea / (layerHeight * perimeterWidth);
}
// Feed rates are in mm/min
var feed = 10.0 * 60;
var liftFeed = 12.0 * 60;
var transitionFeed = 150.0 * 60;
String fmt(num x) {
var t = x.toStringAsFixed(5);
if (t.contains('.')) {
t = t.replaceAll(RegExp(r'0*$'), '').replaceAll(RegExp(r'\.$'), '');
}
return t;
}
String fmtInline(num x) {
var t = fmt(x);
if (t.startsWith('0.')) {
t = t.substring(1);
}
return t;
}
var out = StringBuffer();
out.write(prologue);
out.writeln('M106 S255 ; turn on fan');
String transformX(double x) => fmtInline(x * scale + originX);
String transformY(double y) => fmtInline(y * scale + originY);
var currentZ = 0.0;
var retracted = false;
void retract() {
if (retracted) return;
out.writeln('G1 E${fmtInline(-retractLength)} F2100');
out.writeln('G1 F${fmtInline(feed)}');
retracted = true;
}
void unretract() {
if (!retracted) return;
out.writeln(
'G1 E${fmtInline(retractLength + retractExtraExtrusion)} F2100');
out.writeln('G1 F${fmtInline(feed)}');
retracted = false;
}
void nextLayer() {
recalculateFilament();
currentZ += layerHeight;
out.writeln('; next layer');
out.writeln(';LAYER_CHANGE');
out.writeln(';Z:${fmt(currentZ)}');
out.writeln(';HEIGHT:${fmt(layerHeight)}');
out.writeln('G1 Z${fmtInline(currentZ)} F${fmtInline(liftFeed)}');
out.writeln('G1 F${fmtInline(feed)}');
out.writeln('G92 E0.0');
out.writeln();
}
void g0(double x, double y) {
out.writeln('G0 X${transformX(x)} Y${transformY(y)}');
}
void g1(double x, double y, double dist) {
unretract();
out.writeln(
'G1 X${transformX(x)} Y${transformY(y)} E${fmtInline(dist * scale * extrusion)}');
}
// Lift nozzle and move it to the next position
void transition(double x, double y) {
out.writeln('; transition');
retract();
out.writeln('G1 Z${fmtInline(currentZ + liftHeight)} F$liftFeed');
out.writeln('G1 X${transformX(x)} Y${transformY(y)} F$transitionFeed');
out.writeln('G1 Z${fmtInline(currentZ)} F$liftFeed');
out.writeln('G1 F${fmtInline(feed)}');
out.writeln();
}
void line(double x0, double y0, double x1, double y1, bool trans) {
if (trans) {
transition(x0, y0);
}
final distance = sqrt(pow(x1 - x0, 2) + pow(y1 - y0, 2));
g1(x0, y0, 0);
g1(x1, y1, distance);
}
const w = 32;
const h = 32;
final wD = w.toDouble();
final hD = h.toDouble();
var depth = 2.5;
const bottomPerimeterWidth = 0.8;
const topPerimeterWidth = 0.25;
const chamferDepth = 0.4;
void mkSquare(double x, double y, double w, double h) {
out.writeln('; square');
line(x, y, x + w, y, true);
line(x + w, y, x + w, y + h, false);
line(x + w, y + h, x, y + h, false);
line(x, y + h, x, y, false);
out.writeln();
}
void sheet() {
final inset = (perimeterWidth / 2) - (0.25 / 2);
scale = 1.0;
mkSquare(inset, inset, wD * 4.0 - (inset * 2), hD * 4.0 - (inset * 2));
final overlap = (perimeterCrossArea / (layerHeight * perimeterWidth));
print('overlap: $overlap');
final fillX = (perimeterWidth / 2) * overlap;
final fillY = (perimeterWidth / 2) * overlap;
final fillW = wD * 4.0 - (fillX * 2);
final fillH = hD * 4.0 - (fillY * 2);
final fillLines = (fillW / perimeterWidth).round();
final lineWidth = fillW / fillLines;
perimeterWidth = lineWidth / (overlap * 1.1);
for (var i = 0; i < fillLines; i++) {
if (i % 2 == 0) {
line(fillX + (i + 0.5) * lineWidth, fillY,
fillX + (i + 0.5) * lineWidth, fillY + fillH, false);
} else {
line(fillX + (i + 0.5) * lineWidth, fillY + fillH,
fillX + (i + 0.5) * lineWidth, fillY, false);
}
}
}
void grid() {
// Thicc first layer
currentZ = 0.0;
feed = 30 * 60;
perimeterWidth = 0.6;
retractExtraExtrusion = 0.1;
layerHeight = 0.2;
retract();
nextLayer();
g0(0, 0);
// Skirt
mkSquare(-1, -1, wD + 2, hD + 2);
sheet();
scale = 4.0;
const gridLayerHeight = 0.15;
final numLayers = depth ~/ gridLayerHeight;
final topZ = (numLayers - 1) * gridLayerHeight;
for (var layer = 0; layer < numLayers; layer++) {
var z = layer * gridLayerHeight;
final gridPerimeterWidth = topPerimeterWidth +
(bottomPerimeterWidth - topPerimeterWidth) *
(z / chamferDepth).clamp(0, 1);
layerHeight = gridLayerHeight;
final p1 = topPerimeterWidth;
final p2 = gridPerimeterWidth;
final p3 = (p1 + p2) / 2;
final inset = ((p2 - p1) / 4) / scale;
final gridInset = ((p2 / 2) - (p1 / 2)) / scale;
perimeterWidth = p3;
retractExtraExtrusion = 0.05;
feed = 50 * 60;
retract();
nextLayer();
g0(0, 0);
mkSquare(inset, inset, wD - (inset * 2), hD - (inset * 2));
perimeterWidth = gridPerimeterWidth;
retractExtraExtrusion = 0.1;
recalculateFilament();
retract();
if (layer % 2 == 1) {
g1(0, hD, 0);
}
out.writeln('; vertical lines');
var dir = layer % 2 == 0;
for (var i = 1; i < w; i++) {
if (dir) {
line(i.toDouble(), gridInset, i.toDouble(), hD - gridInset, i == 1);
} else {
line(i.toDouble(), hD - gridInset, i.toDouble(), gridInset, i == 1);
}
dir = !dir;
retract();
}
// Avoid crossing the perimeter
dir = layer % 2 == 0;
if (dir) {
g1(wD - gridInset, hD - gridInset, 0);
} else {
g1(gridInset, gridInset, 0);
}
out.writeln('; horizontal lines');
for (var i = 1; i < w; i++) {
if (dir) {
line(wD - gridInset, hD - i, gridInset, hD - i, i == 1);
} else {
line(gridInset, hD - i, wD - gridInset, hD - i, i == 1);
}
dir = !dir;
retract();
}
// if (layer == 0) {
// retract();
// retractExtraExtrusion = 0;
// final insetStep = ((perimeterWidth / solidOverlap) / 2) / scale;
// for (var i = 0; i < w; i++) {
// for (var j = 0; j < h; j++) {
// for (var r = 0; r < 2; r++) {
// final inset = insetStep * (r + 1);
// mkSquare(
// i + inset,
// j + inset,
// 1 - inset * 2,
// 1 - inset * 2,
// );
// retract();
// }
// }
// }
// }
}
}
// calibration stuff
// void row(double gridPerimeterWidth) {
// originX = 16 + 40 * 3;
// grid(
// gridPerimeterWidth,
// 0,
// );
//
// originX = 16 + 40 * 2;
// grid(
// gridPerimeterWidth,
// 0.05,
// );
//
// originX = 16 + 40;
// grid(
// gridPerimeterWidth,
// 0.1,
// );
//
// originX = 16;
// grid(
// gridPerimeterWidth,
// 0.15,
// );
// }
//
// originY = 16;
// row(0.15);
//
// originY = 16 + 40;
// row(0.20);
//
// originY = 16 + 40 * 2;
// row(0.2);
//
// originY = 16 + 40 * 3;
// row(0.25);
originX = 8;
originY = 8;
grid();
out.write(epilogue);
File('grid.gcode').writeAsStringSync(out.toString());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment