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}