Compare commits

..

No commits in common. "01113d31e5f25742c69263a3f66846d633007c98" and "1229644aa62b15725d17c394c7a1a5f8d8048e69" have entirely different histories.

20 changed files with 169 additions and 614640 deletions

260
README.md
View file

@ -1,259 +1,3 @@
# sv06-belt-recovery-stress-tests # motion-diagnostics-suite
Belt tension recovery and motion stability test models for bed-slinger 3D printers (e.g., SV06-class machines). Parametric OpenSCAD models and procedures for diagnosing layer shifts, belt tension, and motion instability in FDM 3D printers.
---
![](img/DSC_5098.webp)
## 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.
![](img/20260318_215156_Wed.png)
---
## 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
---

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 235 KiB

View file

@ -147,48 +147,8 @@ module rounded_box_uncentered(x, y, z, r) {
square([x, y], center=false); square([x, y], center=false);
} }
module place_top_label(txt, x, y, z, center_it=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; tx = center_it ? 0 : x/2;
ty = center_it ? 0 : y/2; ty = center_it ? 0 : y/2;
tz = center_it ? z/2 : z; tz = center_it ? z/2 : z;

View file

@ -0,0 +1,166 @@
#!/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"
);
}

Binary file not shown.

View file

@ -1,5 +0,0 @@
sync_info = create
user_id =
setting_id =
base_id = OGFSL19
updated_time = 0

View file

@ -1,16 +0,0 @@
{
"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"
}

View file

@ -1,5 +0,0 @@
sync_info = update
user_id =
setting_id =
base_id = GP004
updated_time = 0

View file

@ -1,24 +0,0 @@
{
"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"
}

View file

@ -1,5 +0,0 @@
sync_info = update
user_id =
setting_id =
base_id = GP004
updated_time = 0

View file

@ -1,26 +0,0 @@
{
"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"
}

View file

@ -1,5 +0,0 @@
sync_info = create
user_id =
setting_id =
base_id = GP004
updated_time = 0

View file

@ -1,23 +0,0 @@
{
"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"
}

Binary file not shown.