Compare commits
4 commits
1229644aa6
...
01113d31e5
| Author | SHA1 | Date | |
|---|---|---|---|
| 01113d31e5 | |||
| 85ee00dc19 | |||
|
|
d9e3b5520f | ||
|
|
da500146f5 |
20 changed files with 614640 additions and 169 deletions
260
README.md
260
README.md
|
|
@ -1,3 +1,259 @@
|
|||
# motion-diagnostics-suite
|
||||
# sv06-belt-recovery-stress-tests
|
||||
|
||||
Parametric OpenSCAD models and procedures for diagnosing layer shifts, belt tension, and motion instability in FDM 3D printers.
|
||||
Belt tension recovery and motion stability test models for bed-slinger 3D printers (e.g., SV06-class machines).
|
||||
|
||||
---
|
||||

|
||||
## Purpose
|
||||
|
||||
These models are designed to help recover from situations where printer motion accuracy has been degraded, typically due to:
|
||||
|
||||
* Adjusting belt tension without a reference baseline
|
||||
* Experiencing layer shifts during prints
|
||||
* Replacing belts or modifying mechanical components
|
||||
|
||||
This project provides:
|
||||
|
||||
* Parametric OpenSCAD models
|
||||
* A structured test procedure
|
||||
* Guidance for interpreting failure modes
|
||||
|
||||
---
|
||||
|
||||
## When To Use This
|
||||
|
||||
Use these tests if you observe:
|
||||
|
||||
* Sudden layer shifts (e.g., 3-5 mm offsets)
|
||||
* Inconsistent dimensional accuracy
|
||||
* Audible belt skipping or motor stutter
|
||||
* After adjusting belt tensioners
|
||||
|
||||
Here's an example of a case for a hand held radio where the top suddendly shift at the 20mm height.
|
||||

|
||||
---
|
||||
|
||||
## Models Included
|
||||
|
||||
### 1. Cube (Baseline Test)
|
||||
|
||||
* Dimensions: 40 × 40 × 40 mm
|
||||
* Purpose:
|
||||
|
||||
* Verify basic printer stability
|
||||
* Detect gross mechanical issues
|
||||
|
||||
---
|
||||
|
||||
### 2. Y-Bar (Axis Stress Test)
|
||||
|
||||
* Dimensions: 20 × 150 × 50 mm
|
||||
* Purpose:
|
||||
|
||||
* Stress the Y-axis (bed movement)
|
||||
* Detect belt slip under momentum and direction reversal
|
||||
|
||||
**Important:**
|
||||
|
||||
* Orient the 150 mm dimension front-to-back on the bed
|
||||
|
||||
---
|
||||
|
||||
### 3. Tower (Long-Duration Test)
|
||||
|
||||
* Dimensions: 18 × 18 × 120 mm
|
||||
* Purpose:
|
||||
|
||||
* Reveal issues that appear only over time
|
||||
* Detect cumulative drift, resonance, or late-stage layer shifts
|
||||
|
||||
---
|
||||
|
||||
## Print Procedure (Recommended Order)
|
||||
|
||||
Run each model as a **separate print job**:
|
||||
|
||||
1. **Cube**
|
||||
|
||||
* Confirms system is not fundamentally broken
|
||||
|
||||
2. **Y-Bar**
|
||||
|
||||
* Directly tests axis tension and inertia behavior
|
||||
|
||||
3. **Tower**
|
||||
|
||||
* Tests stability over time and height
|
||||
|
||||
---
|
||||
|
||||
## Suggested Slicer Settings (Orca Slicer)
|
||||
|
||||
### Cube
|
||||
|
||||
* Layer height: 0.20 mm
|
||||
* Perimeters: 3
|
||||
* Infill: 20-25% (grid or gyroid)
|
||||
|
||||
### Y-Bar
|
||||
|
||||
* Layer height: 0.20 mm
|
||||
* Perimeters: 3
|
||||
* Infill: 15-25% (grid recommended)
|
||||
|
||||
### Tower
|
||||
|
||||
* Layer height: 0.20 mm
|
||||
* Perimeters: 3
|
||||
* Infill: 0-10%
|
||||
* Brim: optional (only if adhesion is an issue)
|
||||
|
||||
See the settings folder for settings used in Orca Slicer.
|
||||
|
||||
---
|
||||
|
||||
## Belt Tension Guidance
|
||||
|
||||
This project assumes GT2 belts (typical for most hobby printers).
|
||||
|
||||
### Frequency Method (Recommended)
|
||||
|
||||
Using a phone-based spectrum analyzer:
|
||||
|
||||
* Target range: **90-110 Hz**
|
||||
* Reference: ~110 Hz ? ~2 lb tension (Voron baseline)
|
||||
|
||||
Procedure:
|
||||
|
||||
1. Move bed so belt span ~ 150 mm
|
||||
2. Pluck belt
|
||||
3. Measure frequency
|
||||
4. Adjust tensioner
|
||||
5. Repeat until stable
|
||||
|
||||
### Notes
|
||||
|
||||
* Too loose:
|
||||
|
||||
* Low frequency (<70 Hz)
|
||||
* Layer shifts likely
|
||||
|
||||
* Too tight:
|
||||
|
||||
* High frequency (>120-130 Hz)
|
||||
* Motor strain, possible missed steps
|
||||
|
||||
---
|
||||
|
||||
## Interpreting Results
|
||||
|
||||
### Good Result
|
||||
|
||||
* Clean vertical alignment
|
||||
* No sudden offsets
|
||||
* Consistent layer stacking
|
||||
|
||||
---
|
||||
|
||||
### Failure Modes
|
||||
|
||||
#### Sudden Layer Shift
|
||||
|
||||
* Cause:
|
||||
|
||||
* Belt too loose
|
||||
* Pulley slipping
|
||||
* Action:
|
||||
|
||||
* Increase tension slightly
|
||||
* Check motor pulley set screws
|
||||
|
||||
---
|
||||
|
||||
#### Repeated Shift at Same Height
|
||||
|
||||
* Cause:
|
||||
|
||||
* Mechanical obstruction
|
||||
* Cable snag
|
||||
* Action:
|
||||
|
||||
* Inspect motion path
|
||||
* Check wiring harness clearance
|
||||
|
||||
---
|
||||
|
||||
#### Gradual Lean / Drift
|
||||
|
||||
* Cause:
|
||||
|
||||
* Frame or axis alignment issue
|
||||
* Action:
|
||||
|
||||
* Inspect rails, wheels, or rods
|
||||
|
||||
---
|
||||
|
||||
#### Ringing / Ghosting (No Shift)
|
||||
|
||||
* Cause:
|
||||
|
||||
* High acceleration
|
||||
* Action:
|
||||
|
||||
* Reduce acceleration (not a belt issue)
|
||||
|
||||
---
|
||||
|
||||
## Notes on Methodology
|
||||
|
||||
These tests intentionally:
|
||||
|
||||
* Emphasize repeated motion in one axis
|
||||
* Increase inertial load with height
|
||||
* Create conditions where marginal tension fails visibly
|
||||
|
||||
This approach isolates motion system issues rather than general print quality.
|
||||
|
||||
---
|
||||
|
||||
## OpenSCAD Usage
|
||||
|
||||
Generate models:
|
||||
|
||||
```bash
|
||||
openscad -D 'model="cube"' -o cube_$(date +%Y%m%d_%H%M).stl stress_test_models.scad
|
||||
openscad -D 'model="ybar"' -o ybar_$(date +%Y%m%d_%H%M).stl stress_test_models.scad
|
||||
openscad -D 'model="tower"' -o tower_$(date +%Y%m%d_%H%M).stl stress_test_models.scad
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Provenance
|
||||
|
||||
Generated with:
|
||||
|
||||
* OpenSCAD
|
||||
* Orca Slicer (recommended)
|
||||
* Frequency-based belt tuning derived from:
|
||||
|
||||
* Voron Design tuning methodology
|
||||
|
||||
This project was developed with ChatGPT.
|
||||
---
|
||||
|
||||
## License
|
||||
|
||||
Recommend: MIT or CC-BY 4.0 for broad reuse.
|
||||
|
||||
---
|
||||
|
||||
## Contributing
|
||||
|
||||
Improvements welcome:
|
||||
|
||||
* Additional test geometries
|
||||
* Axis-specific stress models
|
||||
* Automated calibration workflows
|
||||
|
||||
---
|
||||
BIN
img/20260318_215156_Wed.png
Normal file
BIN
img/20260318_215156_Wed.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.5 MiB |
BIN
img/DSC_5098.webp
Normal file
BIN
img/DSC_5098.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 235 KiB |
|
|
@ -147,8 +147,48 @@ module rounded_box_uncentered(x, y, z, r) {
|
|||
square([x, y], center=false);
|
||||
}
|
||||
|
||||
|
||||
module place_top_label(txt, x, y, z, center_it=false) {
|
||||
|
||||
// --- parameters ---
|
||||
margin = 2; // mm clearance from edges
|
||||
|
||||
// usable space
|
||||
usable_x = x - margin;
|
||||
usable_y = y - margin;
|
||||
|
||||
// choose orientation: run along long axis
|
||||
rotate_text = (y > x);
|
||||
|
||||
// limiting width after orientation
|
||||
limit = rotate_text ? usable_y : usable_x;
|
||||
|
||||
// crude text width estimate factor (~0.6 * size * chars)
|
||||
est_char_width = 1.0;
|
||||
est_len = len(txt) * est_char_width;
|
||||
|
||||
// compute size that fits
|
||||
auto_size = limit / est_len;
|
||||
|
||||
// clamp to your preferred max size
|
||||
final_size = min(label_size, auto_size);
|
||||
|
||||
// placement
|
||||
tx = center_it ? 0 : x/2;
|
||||
ty = center_it ? 0 : y/2;
|
||||
tz = center_it ? z/2 : z;
|
||||
|
||||
translate([tx, ty, tz - label_depth])
|
||||
rotate([0, 0, rotate_text ? 90 : 0])
|
||||
linear_extrude(height=label_depth + 0.02)
|
||||
text(
|
||||
txt,
|
||||
size=final_size,
|
||||
font=label_font,
|
||||
halign="center",
|
||||
valign="center"
|
||||
);
|
||||
}
|
||||
module place_top_labelOLD(txt, x, y, z, center_it=false) {
|
||||
tx = center_it ? 0 : x/2;
|
||||
ty = center_it ? 0 : y/2;
|
||||
tz = center_it ? z/2 : z;
|
||||
|
|
|
|||
|
|
@ -1,166 +0,0 @@
|
|||
#!/usr/bin/openscad -o /tmp/ignore.stl
|
||||
//
|
||||
// stress_test_models.scad
|
||||
// 20260317 ChatGPT
|
||||
// $Id$
|
||||
// $HeadURL$
|
||||
//
|
||||
// Example command lines:
|
||||
//
|
||||
// openscad -D 'model="cube"' -o cube_20260317_1335.stl stress_test_models.scad
|
||||
// openscad -D 'model="ybar"' -o ybar_20260317_1335.stl stress_test_models.scad
|
||||
// openscad -D 'model="tower"' -o tower_20260317_1335.stl stress_test_models.scad
|
||||
// openscad -D 'model="all"' -o all_20260317_1335.stl stress_test_models.scad
|
||||
//
|
||||
// Suggested slicer use:
|
||||
//
|
||||
// 1) Print each model as a SEPARATE run.
|
||||
// 2) For ybar, orient the LONG dimension along the printer's Y axis
|
||||
// so the bed moves the long way front-to-back.
|
||||
// 3) Infill is set in Orca Slicer, not here.
|
||||
//
|
||||
// Suggested slicer settings:
|
||||
//
|
||||
// cube: 0.20 layer, 3 perimeters, 20-25% grid or gyroid
|
||||
// ybar: 0.20 layer, 3 perimeters, 15-25% grid
|
||||
// tower: 0.20 layer, 3 perimeters, 0-10% infill, no brim at first;
|
||||
// add brim only if adhesion becomes the issue rather than motion
|
||||
//
|
||||
|
||||
/* [General] */
|
||||
model = "all"; // [cube,ybar,tower,all]
|
||||
center_models = false; // true / false
|
||||
add_labels = true; // true / false
|
||||
|
||||
/* [Cube Dimensions] */
|
||||
cube_x = 40;
|
||||
cube_y = 40;
|
||||
cube_z = 40;
|
||||
|
||||
/* [Y Bar Dimensions] */
|
||||
ybar_x = 20;
|
||||
ybar_y = 150;
|
||||
ybar_z = 50;
|
||||
|
||||
/* [Tower Dimensions] */
|
||||
tower_x = 18;
|
||||
tower_y = 18;
|
||||
tower_z = 120;
|
||||
|
||||
/* [Edge Treatment] */
|
||||
corner_radius = 1.2; // 0 for sharp corners
|
||||
$fn = 48;
|
||||
|
||||
/* [Labeling] */
|
||||
label_depth = 0.6;
|
||||
label_size = 7;
|
||||
label_font = "Liberation Sans:style=Bold";
|
||||
|
||||
/* [Layout For model="all"] */
|
||||
gap_between_models = 20;
|
||||
|
||||
|
||||
// --------------------------------------------------
|
||||
// Main
|
||||
// --------------------------------------------------
|
||||
|
||||
if (model == "cube") {
|
||||
make_cube();
|
||||
}
|
||||
else if (model == "ybar") {
|
||||
make_ybar();
|
||||
}
|
||||
else if (model == "tower") {
|
||||
make_tower();
|
||||
}
|
||||
else if (model == "all") {
|
||||
make_all();
|
||||
}
|
||||
else {
|
||||
echo("ERROR: model must be one of: cube, ybar, tower, all");
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------
|
||||
// Assemblies
|
||||
// --------------------------------------------------
|
||||
|
||||
module make_all() {
|
||||
x0 = 0;
|
||||
x1 = x0 + cube_x + gap_between_models;
|
||||
x2 = x1 + ybar_x + gap_between_models;
|
||||
|
||||
translate([x0, 0, 0]) make_cube();
|
||||
translate([x1, 0, 0]) make_ybar();
|
||||
translate([x2, 0, 0]) make_tower();
|
||||
}
|
||||
|
||||
|
||||
module make_cube() {
|
||||
difference() {
|
||||
rounded_box(cube_x, cube_y, cube_z, corner_radius, center_models);
|
||||
if (add_labels)
|
||||
place_top_label("CUBE", cube_x, cube_y, cube_z, center_models);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
module make_ybar() {
|
||||
difference() {
|
||||
rounded_box(ybar_x, ybar_y, ybar_z, corner_radius, center_models);
|
||||
if (add_labels)
|
||||
place_top_label("YBAR", ybar_x, ybar_y, ybar_z, center_models);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
module make_tower() {
|
||||
difference() {
|
||||
rounded_box(tower_x, tower_y, tower_z, corner_radius, center_models);
|
||||
if (add_labels)
|
||||
place_top_label("TOWER", tower_x, tower_y, tower_z, center_models);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------
|
||||
// Geometry helpers
|
||||
// --------------------------------------------------
|
||||
|
||||
module rounded_box(x, y, z, r=0, center_it=false) {
|
||||
if (r <= 0) {
|
||||
cube([x, y, z], center=center_it);
|
||||
} else {
|
||||
if (center_it) {
|
||||
translate([-x/2, -y/2, -z/2])
|
||||
rounded_box_uncentered(x, y, z, r);
|
||||
} else {
|
||||
rounded_box_uncentered(x, y, z, r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
module rounded_box_uncentered(x, y, z, r) {
|
||||
linear_extrude(height=z)
|
||||
offset(r=r)
|
||||
offset(delta=-r)
|
||||
square([x, y], center=false);
|
||||
}
|
||||
|
||||
|
||||
module place_top_label(txt, x, y, z, center_it=false) {
|
||||
tx = center_it ? 0 : x/2;
|
||||
ty = center_it ? 0 : y/2;
|
||||
tz = center_it ? z/2 : z;
|
||||
|
||||
translate([tx, ty, tz - label_depth])
|
||||
linear_extrude(height=label_depth + 0.02)
|
||||
text(
|
||||
txt,
|
||||
size=label_size,
|
||||
font=label_font,
|
||||
halign="center",
|
||||
valign="center"
|
||||
);
|
||||
}
|
||||
BIN
orca-slicer/cube_20260317_141440.3mf
Normal file
BIN
orca-slicer/cube_20260317_141440.3mf
Normal file
Binary file not shown.
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
489140
orca-slicer/gcode/Sovol SV06 ACE_ybar_20260317_141440_PLA_0.2_2h49m.gcode
Normal file
489140
orca-slicer/gcode/Sovol SV06 ACE_ybar_20260317_141440_PLA_0.2_2h49m.gcode
Normal file
File diff suppressed because it is too large
Load diff
BIN
orca-slicer/objects_20260317_141440.3mf
Normal file
BIN
orca-slicer/objects_20260317_141440.3mf
Normal file
Binary file not shown.
5
orca-slicer/settings/PolyLite PLA @System - Z-Tower.info
Normal file
5
orca-slicer/settings/PolyLite PLA @System - Z-Tower.info
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
sync_info = create
|
||||
user_id =
|
||||
setting_id =
|
||||
base_id = OGFSL19
|
||||
updated_time = 0
|
||||
16
orca-slicer/settings/PolyLite PLA @System - Z-Tower.json
Normal file
16
orca-slicer/settings/PolyLite PLA @System - Z-Tower.json
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"compatible_printers": [
|
||||
"Sovol SV06 ACE 0.4 nozzle"
|
||||
],
|
||||
"fan_cooling_layer_time": [
|
||||
"20"
|
||||
],
|
||||
"filament_settings_id": [
|
||||
"PolyLite PLA @System - Z-Tower"
|
||||
],
|
||||
"from": "User",
|
||||
"inherits": "PolyLite PLA @System",
|
||||
"is_custom_defined": "0",
|
||||
"name": "PolyLite PLA @System - Z-Tower",
|
||||
"version": "2.3.0.3"
|
||||
}
|
||||
5
orca-slicer/settings/Y-bar_20260317_final.info
Normal file
5
orca-slicer/settings/Y-bar_20260317_final.info
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
sync_info = update
|
||||
user_id =
|
||||
setting_id =
|
||||
base_id = GP004
|
||||
updated_time = 0
|
||||
24
orca-slicer/settings/Y-bar_20260317_final.json
Normal file
24
orca-slicer/settings/Y-bar_20260317_final.json
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"bottom_shell_layers": "5",
|
||||
"brim_type": "outer_only",
|
||||
"from": "User",
|
||||
"inherits": "0.20mm Standard @Sovol SV06 ACE",
|
||||
"initial_layer_line_width": "0.42",
|
||||
"initial_layer_print_height": "0.2",
|
||||
"inner_wall_speed": "80",
|
||||
"is_custom_defined": "0",
|
||||
"line_width": "0.42",
|
||||
"name": "Y-bar_20260317_final",
|
||||
"only_one_wall_top": "0",
|
||||
"outer_wall_acceleration": "1500",
|
||||
"outer_wall_line_width": "0.42",
|
||||
"outer_wall_speed": "60",
|
||||
"print_settings_id": "Y-bar_20260317_final",
|
||||
"skirt_loops": "2",
|
||||
"sparse_infill_density": "20%",
|
||||
"sparse_infill_pattern": "gyroid",
|
||||
"top_shell_layers": "5",
|
||||
"top_solid_infill_flow_ratio": "1",
|
||||
"version": "2.3.0.3",
|
||||
"wall_loops": "3"
|
||||
}
|
||||
5
orca-slicer/settings/Z-tower_20260317_final.info
Normal file
5
orca-slicer/settings/Z-tower_20260317_final.info
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
sync_info = update
|
||||
user_id =
|
||||
setting_id =
|
||||
base_id = GP004
|
||||
updated_time = 0
|
||||
26
orca-slicer/settings/Z-tower_20260317_final.json
Normal file
26
orca-slicer/settings/Z-tower_20260317_final.json
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"bottom_shell_layers": "5",
|
||||
"brim_type": "outer_only",
|
||||
"from": "User",
|
||||
"inherits": "0.20mm Standard @Sovol SV06 ACE",
|
||||
"initial_layer_line_width": "0.42",
|
||||
"initial_layer_print_height": "0.2",
|
||||
"inner_wall_speed": "80",
|
||||
"is_custom_defined": "0",
|
||||
"line_width": "0.42",
|
||||
"name": "Z-tower_20260317_final",
|
||||
"notes": "Orca serialization note\n\nIn Orca Slicer 2.3.0.3, some live profile values may not appear in the saved process JSON even when they are active in the UI. For the Z-tower profile, Sparse infill density was verified in the live UI as 10% before slicing, even though the saved JSON did not include a sparse_infill_density key.\n\nScreenshot was taken showing the 10% value, 20260318_184351_Wed.png",
|
||||
"only_one_wall_top": "0",
|
||||
"outer_wall_acceleration": "1500",
|
||||
"outer_wall_line_width": "0.42",
|
||||
"outer_wall_speed": "40",
|
||||
"print_settings_id": "Z-tower_20260317_final",
|
||||
"seam_gap": "0",
|
||||
"seam_position": "back",
|
||||
"skirt_loops": "2",
|
||||
"sparse_infill_pattern": "line",
|
||||
"top_shell_layers": "5",
|
||||
"top_solid_infill_flow_ratio": "1",
|
||||
"version": "2.3.0.3",
|
||||
"wall_loops": "3"
|
||||
}
|
||||
5
orca-slicer/settings/cube_20260317_final.info
Normal file
5
orca-slicer/settings/cube_20260317_final.info
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
sync_info = create
|
||||
user_id =
|
||||
setting_id =
|
||||
base_id = GP004
|
||||
updated_time = 0
|
||||
23
orca-slicer/settings/cube_20260317_final.json
Normal file
23
orca-slicer/settings/cube_20260317_final.json
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"bottom_shell_layers": "5",
|
||||
"brim_type": "no_brim",
|
||||
"from": "User",
|
||||
"inherits": "0.20mm Standard @Sovol SV06 ACE",
|
||||
"initial_layer_line_width": "0.42",
|
||||
"initial_layer_print_height": "0.2",
|
||||
"inner_wall_speed": "80",
|
||||
"is_custom_defined": "0",
|
||||
"line_width": "0.42",
|
||||
"name": "cube_20260317_final",
|
||||
"only_one_wall_top": "0",
|
||||
"outer_wall_acceleration": "1500",
|
||||
"outer_wall_line_width": "0.42",
|
||||
"outer_wall_speed": "60",
|
||||
"print_settings_id": "cube_20260317_final",
|
||||
"seam_position": "back",
|
||||
"skirt_loops": "2",
|
||||
"sparse_infill_pattern": "grid",
|
||||
"top_shell_layers": "5",
|
||||
"top_solid_infill_flow_ratio": "1",
|
||||
"version": "2.3.0.3"
|
||||
}
|
||||
BIN
orca-slicer/tower_20260317_141440.3mf
Normal file
BIN
orca-slicer/tower_20260317_141440.3mf
Normal file
Binary file not shown.
BIN
orca-slicer/ybar_20260317_141440.3mf
Normal file
BIN
orca-slicer/ybar_20260317_141440.3mf
Normal file
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue