code wiki / _hdl_build / nx_fdm_gcode.nx
nx_fdm_gcode.nx source
↩ module page · 66 lines · 3508 B
1// nx_fdm_gcode.nx -- LIB: a standard-FILAMENT (FDM) wall emitter -- the filament arm of the multi-material
2// dispatcher, parallel to nx_paste_gcode (concrete) + nx_metal_gcode (metal), so the SAME wall primitive can
3// be emitted in any material. (Production filament uses the mature nx_slice_*->nx_gcode_emit pipeline for
4// arbitrary geometry; this is the wall primitive for the multi-material demo.) The FDM signature vs concrete/
5// metal: a HOT hotend (M104/M109) + sub-millimetre layers (decimal Z). Reads the material profile (temp +
6// layer height). CARDINAL 26 (never-brick): motion + hotend-temp + extrusion only; no firmware/EEPROM writes.
7// license_tier: ORIGINAL
8import "nx_print_material.nx"
9import "nx_food_science.nx"
10import "nx_seg_store.nx"
11import "nx_syscalls.nx"
12
13// integer microns -> "D.DDD" mm (filament needs sub-mm layer heights, unlike concrete/metal whole-mm)
14func fg_um_to_mm(dst: *u8, off: i64, um: i64) -> i64 {
15 var o: i64 = off
16 o = fd_apnum(dst, o, um / 1000)
17 dst[o] = 46 as u8; o = o + 1
18 let frac: i64 = um % 1000
19 dst[o] = (48 + (frac / 100)) as u8; o = o + 1
20 dst[o] = (48 + ((frac / 10) % 10)) as u8; o = o + 1
21 dst[o] = (48 + (frac % 10)) as u8; o = o + 1
22 return o
23}
24func fg_move(out: *u8, off: i64, x: i64, y: i64, e: i64) -> i64 {
25 var o: i64 = off
26 o = as_append(out, o, "G1 X" as *u8); o = fd_apnum(out, o, x)
27 o = as_append(out, o, " Y" as *u8); o = fd_apnum(out, o, y)
28 o = as_append(out, o, " E" as *u8); o = fd_apnum(out, o, e)
29 o = as_append(out, o, " F1500\n" as *u8)
30 return o
31}
32
33func fg_emit(prefix: *u8, mat_id: *u8, w: i64, d: i64, h: i64, out: *u8) -> i64 {
34 let temp: i64 = pm_field_int(prefix, mat_id, 5)
35 var layer_um: i64 = pm_field_int(prefix, mat_id, 4)
36 if layer_um <= 0 { layer_um = 200 }
37
38 var o: i64 = 0
39 o = as_append(out, o, "; Nishi FDM filament G-code -- " as *u8)
40 let nm: *u8 = sys_mmap(48); pm_field_str(prefix, mat_id, 0, nm); o = as_append(out, o, nm)
41 o = as_append(out, o, " wall\n" as *u8)
42 o = as_append(out, o, "; NEVER-BRICK (Cardinal 26): motion + hotend-temp + extrusion only; no firmware/EEPROM writes\n" as *u8)
43 o = as_append(out, o, "M104 S" as *u8); o = fd_apnum(out, o, temp); out[o] = 10 as u8; o = o + 1 // hotend target
44 o = as_append(out, o, "M140 S60\n" as *u8) // bed target
45 o = as_append(out, o, "M190 S60\n" as *u8) // wait bed
46 o = as_append(out, o, "M109 S" as *u8); o = fd_apnum(out, o, temp); out[o] = 10 as u8; o = o + 1 // wait hotend (HOT)
47 o = as_append(out, o, "G21\nG90\nG28\nG92 E0\n" as *u8)
48
49 let nlayers: i64 = h * 1000 / layer_um
50 var e: i64 = 0
51 var li: i64 = 0
52 while li < nlayers {
53 let zum: i64 = (li + 1) * layer_um
54 o = as_append(out, o, ";LAYER:" as *u8); o = fd_apnum(out, o, li); out[o] = 10 as u8; o = o + 1
55 o = as_append(out, o, "G1 Z" as *u8); o = fg_um_to_mm(out, o, zum); o = as_append(out, o, " F300\n" as *u8)
56 o = as_append(out, o, "G0 X0 Y0\n" as *u8)
57 e = e + w; o = fg_move(out, o, w, 0, e)
58 e = e + d; o = fg_move(out, o, w, d, e)
59 e = e + w; o = fg_move(out, o, 0, d, e)
60 e = e + d; o = fg_move(out, o, 0, 0, e)
61 li = li + 1
62 }
63 o = as_append(out, o, "; end\nM104 S0\nM140 S0\nM84\n" as *u8) // cool down, disable
64 out[o] = 0 as u8
65 return o
66}