2 Commits

Author SHA1 Message Date
  Thomas Buck 57aca6a04d use new 3d rendering in docs 3 weeks ago
  Thomas Buck 6d163c2fbf convert to kicad 8 and run drc 3 weeks ago

+ 0
- 3
.gitmodules View File

@@ -1,6 +1,3 @@
1 1
 [submodule "docs/svg-pan-zoom"]
2 2
 	path = docs/svg-pan-zoom
3 3
 	url = https://github.com/WebSVG/svg-pan-zoom
4
-[submodule "docs/modelview"]
5
-	path = docs/modelview
6
-	url = https://github.com/jschobben/modelview

+ 1
- 1
README.md View File

@@ -13,7 +13,7 @@ This project is licensed under the [CERN Open Hardware Licence Version 2 - Stron
13 13
 
14 14
 The docs are built using [mdbook](https://github.com/rust-lang/mdBook), licensed as `MPL-2.0`.
15 15
 The PCB SVG files in the documentation are displayed using [svg-pan-zoom](https://github.com/bumbu/svg-pan-zoom), licensed as `BSD-2-Clause`.
16
-The 3D PCB files in the documentation are displayed using [modelview](https://github.com/jschobben/modelview), licensed as `MIT`.
16
+The 3D PCB files in the documentation are displayed using [three.js](hhttps://github.com/mrdoob/three.js), licensed as `MIT`.
17 17
 
18 18
 Please also take a look at the `README.md` files in the subfolders of this project for more info.
19 19
 

+ 74
- 28
docs/generate_docs.sh View File

@@ -26,41 +26,87 @@
26 26
 # | source.                                                                      |
27 27
 #  ------------------------------------------------------------------------------
28 28
 
29
+INSCH="../hardware/dispensy.kicad_sch"
30
+INPCB="../hardware/dispensy.kicad_pcb"
31
+
29 32
 cd "$(dirname "$0")"
30 33
 
31
-#echo "Generating plots"
34
+if [ "$1" = "build" ] ; then
35
+    echo "Generating plots"
36
+    ../hardware/generate_plot.sh
37
+    echo
38
+
39
+    echo "Generating fab"
40
+    ../hardware/generate_fab.sh
41
+    echo
42
+fi
43
+
32 44
 rm -rf src/plot
33
-#../hardware/generate_plot.sh
34 45
 cp -r ../hardware/plot src
35 46
 
36
-echo "Generating plot includes"
37
-rm -rf src/inc_dispensy_sch.md
38
-echo "<script src=\"js/svg-pan-zoom.js\" charset=\"UTF-8\"></script>" >> src/inc_dispensy_sch.md
39
-for f in `ls src/plot/dispensy.kicad_sch.svg/*.svg | sort -r`; do
40
-    file=`echo $f | sed 's:src/:./:g'`
41
-    name=`echo $f | sed 's:src/plot/dispensy.kicad_sch.svg/::g' | sed 's:.svg::g'`
42
-    echo $name
43
-    echo "<h2>$name</h2>" >> src/inc_dispensy_sch.md
44
-    echo "<div style=\"background-color: white; border: 1px solid black;\">" >> src/inc_dispensy_sch.md
45
-    echo "<embed type=\"image/svg+xml\" src=\"$file\" id=\"pz_$name\" style=\"width:100%;\"/>" >> src/inc_dispensy_sch.md
46
-    echo "<script>" >> src/inc_dispensy_sch.md
47
-    echo "document.getElementById('pz_$name').addEventListener('load', function(){" >> src/inc_dispensy_sch.md
48
-    echo "svgPanZoom(document.getElementById('pz_$name'), {controlIconsEnabled: true, minZoom: 1.0});" >> src/inc_dispensy_sch.md
49
-    echo "})" >> src/inc_dispensy_sch.md
50
-    echo "</script>" >> src/inc_dispensy_sch.md
51
-    echo "</div>" >> src/inc_dispensy_sch.md
52
-    echo >> src/inc_dispensy_sch.md
53
-    echo "[Direct link to \`$name\`]($file)." >> src/inc_dispensy_sch.md
54
-    echo >> src/inc_dispensy_sch.md
47
+for path in $INSCH
48
+do
49
+    IN=`echo $path | sed "s:../hardware/::g"`
50
+    o="src/inc_$IN.md"
51
+    echo "Include for $IN at $o"
52
+
53
+    rm -rf $o
54
+    echo "<script src=\"js/svg-pan-zoom.js\" charset=\"UTF-8\"></script>" >> $o
55
+
56
+    for f in `ls src/plot/$IN.svg/*.svg | sort -r`; do
57
+        file=`echo $f | sed 's:src/:./:g'`
58
+        name=`echo $f | sed "s:src/plot/$IN.svg/::g" | sed 's:.svg::g'`
59
+        echo "Sheet at $name"
60
+
61
+        echo "<h2>$name</h2>" >> $o
62
+        echo "<div style=\"background-color: white; border: 1px solid black;\">" >> $o
63
+        echo "<embed type=\"image/svg+xml\" src=\"$file\" id=\"pz_$name\" style=\"width:100%;\"/>" >> $o
64
+        echo "<script>" >> $o
65
+        echo "document.getElementById('pz_$name').addEventListener('load', function(){" >> $o
66
+        echo "svgPanZoom(document.getElementById('pz_$name'), {controlIconsEnabled: true, minZoom: 1.0});" >> $o
67
+        echo "})" >> $o
68
+        echo "</script>" >> $o
69
+        echo "</div>" >> $o
70
+        echo >> $o
71
+        echo "[Direct link to \`$name\`]($file)." >> $o
72
+        echo >> $o
73
+    done
74
+
75
+    echo
55 76
 done
56 77
 
57
-echo "Preparing modelview dependencies"
58
-cd modelview
59
-sed -i 's/info\.inner/info_elem\.inner/g' modelview.js
60
-./fetch_deps.sh
61
-cd ..
62
-rm -rf src/js/deps
63
-cp -r modelview/deps src/js
78
+plot_3d() {
79
+    echo '<script type="importmap">' >> $1
80
+    echo '    {' >> $1
81
+    echo '        "imports": {' >> $1
82
+    echo '            "three": "https://cdn.jsdelivr.net/npm/three@0.163.0/build/three.module.js",' >> $1
83
+    echo '            "three/addons/": "https://cdn.jsdelivr.net/npm/three@0.163.0/examples/jsm/"' >> $1
84
+    echo '        }' >> $1
85
+    echo '    }' >> $1
86
+    echo '</script>' >> $1
87
+    echo "<p>Status: \"<span id=\"3d_info_$2\">Preparing 3D model...</span>\"</p>" >> $1
88
+    echo "<div id=\"3d_viewer_$2\" style=\"width: 100%; height: 100%; background-color: white; border: 1px solid black; position: relative;\"></div>" >> $1
89
+    echo '<script type="module">' >> $1
90
+    echo "    var info = document.getElementById(\"3d_info_$2\");" >> $1
91
+    echo "    var view = document.getElementById(\"3d_viewer_$2\");" >> $1
92
+    echo '    view.style.height = Math.floor(view.clientWidth * 0.707) + "px";' >> $1
93
+    echo '    import { init_3d } from "./js/3d.js";' >> $1
94
+    echo "    init_3d(\"$3\", view, info, view.clientWidth, view.clientHeight);" >> $1
95
+    echo '</script>' >> $1
96
+}
97
+
98
+for path in $INPCB
99
+do
100
+    IN=`echo $path | sed "s:../hardware/::g"`
101
+    o="src/inc_$IN.md"
102
+    file="plot/$IN.wrl"
103
+    name=`echo $file | sed "s:plot/::g" | sed 's:.wrl::g'`
104
+    echo "Include for $IN at $o, $file, $name"
105
+    rm -rf $o
106
+
107
+    plot_3d $o $name $file
108
+done
109
+echo
64 110
 
65 111
 echo "Generating docs"
66 112
 if [ "$1" = "serve" ] ; then

+ 0
- 1
docs/modelview

@@ -1 +0,0 @@
1
-Subproject commit d3f2ffd2cd04e263b4db3910023b6c028bd0eb64

+ 231
- 0
docs/src/js/3d.js View File

@@ -0,0 +1,231 @@
1
+/*
2
+ * 3d.js
3
+ *
4
+ * Copyright (c) 2024 Thomas Buck (thomas@xythobuz.de)
5
+ *
6
+ * For the fitCameraToObject() function also:
7
+ * Copyright (c) 2024 Michal Jirků
8
+ * https://wejn.org/2020/12/cracking-the-threejs-object-fitting-nut/
9
+ *
10
+ * For everything else:
11
+ *
12
+ * This program is free software: you can redistribute it and/or modify
13
+ * it under the terms of the GNU General Public License as published by
14
+ * the Free Software Foundation, either version 3 of the License, or
15
+ * (at your option) any later version.
16
+ *
17
+ * This program is distributed in the hope that it will be useful,
18
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
+ * GNU General Public License for more details.
21
+ *
22
+ * See <http://www.gnu.org/licenses/>.
23
+ */
24
+
25
+import * as THREE from 'three';
26
+import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
27
+import { STLLoader } from 'three/addons/loaders/STLLoader.js'
28
+import { VRMLLoader } from 'three/addons/loaders/VRMLLoader.js';
29
+
30
+function fitCameraToObject(camera, object, offset, orbitControls, yOffset) {
31
+    const boundingBox = new THREE.Box3();
32
+    boundingBox.setFromObject( object );
33
+
34
+    var middle = new THREE.Vector3();
35
+    boundingBox.getCenter(middle);
36
+
37
+    var size = new THREE.Vector3();
38
+    boundingBox.getSize(size);
39
+
40
+    // figure out how to fit the box in the view:
41
+    // 1. figure out horizontal FOV (on non-1.0 aspects)
42
+    // 2. figure out distance from the object in X and Y planes
43
+    // 3. select the max distance (to fit both sides in)
44
+    //
45
+    // The reason is as follows:
46
+    //
47
+    // Imagine a bounding box (BB) is centered at (0,0,0).
48
+    // Camera has vertical FOV (camera.fov) and horizontal FOV
49
+    // (camera.fov scaled by aspect, see fovh below)
50
+    //
51
+    // Therefore if you want to put the entire object into the field of view,
52
+    // you have to compute the distance as: z/2 (half of Z size of the BB
53
+    // protruding towards us) plus for both X and Y size of BB you have to
54
+    // figure out the distance created by the appropriate FOV.
55
+    //
56
+    // The FOV is always a triangle:
57
+    //
58
+    //  (size/2)
59
+    // +--------+
60
+    // |       /
61
+    // |      /
62
+    // |     /
63
+    // | F° /
64
+    // |   /
65
+    // |  /
66
+    // | /
67
+    // |/
68
+    //
69
+    // F° is half of respective FOV, so to compute the distance (the length
70
+    // of the straight line) one has to: `size/2 / Math.tan(F)`.
71
+    //
72
+    // FTR, from https://threejs.org/docs/#api/en/cameras/PerspectiveCamera
73
+    // the camera.fov is the vertical FOV.
74
+
75
+    const fov = camera.fov * ( Math.PI / 180 );
76
+    const fovh = 2*Math.atan(Math.tan(fov/2) * camera.aspect);
77
+    let dx = size.z / 2 + Math.abs( size.x / 2 / Math.tan( fovh / 2 ) );
78
+    let dy = size.z / 2 + Math.abs( size.y / 2 / Math.tan( fov / 2 ) );
79
+    let cameraZ = Math.max(dx, dy);
80
+
81
+    // offset the camera, if desired (to avoid filling the whole canvas)
82
+    if( offset !== undefined && offset !== 0 ) cameraZ *= offset;
83
+
84
+    camera.target = middle;
85
+    camera.position.set( middle.x, middle.y + yOffset * cameraZ, middle.z + cameraZ );
86
+
87
+    // set the far plane of the camera so that it easily encompasses the whole object
88
+    const minZ = boundingBox.min.z;
89
+    const cameraToFarEdge = ( minZ < 0 ) ? -minZ + cameraZ : cameraZ - minZ;
90
+
91
+    camera.far = cameraToFarEdge * 3;
92
+    camera.updateProjectionMatrix();
93
+
94
+    if ( orbitControls !== undefined ) {
95
+        // set camera to rotate around the center
96
+        orbitControls.target = middle;
97
+
98
+        // prevent camera from zooming out far enough to create far plane cutoff
99
+        orbitControls.maxDistance = cameraToFarEdge * 2;
100
+    }
101
+}
102
+
103
+export function init_3d(path, container, status, div_width, div_height) {
104
+    const width = div_width;
105
+    const height = div_height;
106
+
107
+    const scene = new THREE.Scene();
108
+    //scene.add(new THREE.AxesHelper(1));
109
+
110
+    const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000);
111
+
112
+    const renderer = new THREE.WebGLRenderer({ antialias: true });
113
+    renderer.setSize(width, height);
114
+
115
+    const controls = new OrbitControls(camera, renderer.domElement);
116
+    controls.enableDamping = true;
117
+    controls.autoRotate = true;
118
+
119
+    for (const i of [1, -1]) {
120
+        for (const j of [0, 1, 2]) {
121
+            const light = new THREE.DirectionalLight(0xffffff, 0.5);
122
+            light.position.set(i * (j == 0 ? 1 : 0),
123
+                                i * (j == 1 ? 1 : 0),
124
+                                i * (j == 2 ? 1 : 0));
125
+            scene.add(light);
126
+        }
127
+    }
128
+
129
+    if (path.endsWith(".stl")) {
130
+        const light_amb = new THREE.AmbientLight(0x424242);
131
+        scene.add(light_amb);
132
+
133
+        const material = new THREE.MeshStandardMaterial();
134
+        //material.roughness = 0.75;
135
+
136
+        const loader = new STLLoader();
137
+        loader.load(
138
+            path,
139
+            function (geometry) {
140
+                const mesh = new THREE.Mesh(geometry, material);
141
+                mesh.rotation.setFromVector3(new THREE.Vector3(-Math.PI / 2, 0, 0));
142
+                scene.add(mesh);
143
+                fitCameraToObject(camera, scene, 0, controls, 0);
144
+                controls.update();
145
+                status.textContent = "Loaded STL 100%";
146
+            },
147
+            (xhr) => {
148
+                const s = Math.floor((xhr.loaded / xhr.total) * 100) + '% loaded';
149
+                console.log(s);
150
+                status.textContent = s;
151
+            },
152
+            (error) => {
153
+                console.log(error);
154
+                status.textContent = error;
155
+            }
156
+        );
157
+    } else if (path.endsWith(".wrl")) {
158
+        const light_amb = new THREE.AmbientLight(0xffffff);
159
+        scene.add(light_amb);
160
+
161
+        const loader = new VRMLLoader();
162
+        loader.load(
163
+            path,
164
+            function (object) {
165
+                scene.add(object);
166
+                fitCameraToObject(camera, scene, 0, controls, 0);
167
+                controls.update();
168
+                status.textContent = "Loaded VRML 100%";
169
+            },
170
+            (xhr) => {
171
+                const s = Math.floor((xhr.loaded / xhr.total) * 100) + '% loaded';
172
+                console.log(s);
173
+                status.textContent = s;
174
+            },
175
+            (error) => {
176
+                console.log(error);
177
+                status.textContent = error;
178
+            }
179
+        );
180
+    } else {
181
+        const s = "error: unknown filetype for " + path;
182
+        console.log(s);
183
+        status.textContent = s;
184
+    }
185
+
186
+    camera.position.z = 50;
187
+    controls.update();
188
+
189
+    function animate() {
190
+        requestAnimationFrame(animate);
191
+        controls.update();
192
+        renderer.render(scene, camera);
193
+    }
194
+
195
+    animate();
196
+    status.textContent = "3D model ready!";
197
+
198
+    container.appendChild(renderer.domElement);
199
+
200
+    const div = document.createElement("div");
201
+    div.style.position = "absolute";
202
+    div.style.left = "5px";
203
+    div.style.top = "5px";
204
+    div.style.background = "white";
205
+    div.style.color = "black";
206
+    container.appendChild(div);
207
+
208
+    const chk_ar = document.createElement("input");
209
+    chk_ar.type = "checkbox";
210
+    chk_ar.checked = true;
211
+    chk_ar.addEventListener('change', function() {
212
+        controls.autoRotate = this.checked;
213
+    });
214
+
215
+    const div_ar = document.createElement("div");
216
+    div_ar.appendChild(chk_ar);
217
+    div_ar.appendChild(document.createTextNode("Auto-Rotate"));
218
+    div.appendChild(div_ar);
219
+
220
+    const btn_rst = document.createElement("input");
221
+    btn_rst.type = "button";
222
+    btn_rst.value = "Reset Camera";
223
+    btn_rst.addEventListener('click', function() {
224
+        fitCameraToObject(camera, scene, 0, controls, 0);
225
+        controls.update();
226
+    });
227
+
228
+    const div_rst = document.createElement("div");
229
+    div_rst.appendChild(btn_rst);
230
+    div.appendChild(div_rst);
231
+}

+ 0
- 1
docs/src/js/modelview.js View File

@@ -1 +0,0 @@
1
-../../modelview/modelview.js

+ 1
- 32
docs/src/main_board_pcb.md View File

@@ -50,35 +50,4 @@ You can also view the [Main-Board PCB layout as PDF](./plot/dispensy.kicad_pcb.p
50 50
 
51 51
 ## 3D PCB Model
52 52
 
53
-<p>Status: "<span id="3d_info">Preparing 3D model...</span>"</p>
54
-<div id="3d_viewer" style="width: 100%; height: 100%; background-color: white; border: 1px solid black;"></div>
55
-<script type="module">
56
-    var view = document.getElementById('3d_viewer');
57
-    view.style.height = (view.clientWidth * 0.707) + "px";
58
-    var info = document.getElementById('3d_info');
59
-    import * as View from './js/modelview.js';
60
-    View.init(view, info);
61
-    const file = './plot/dispensy.3mf';
62
-    var xhttp = new XMLHttpRequest();
63
-    xhttp.responseType = 'arraybuffer';
64
-    xhttp.onload = function() {
65
-        if (this.status != 200) {
66
-            info.textContent = "Download of " + file + " failed: " + this.status + " " + this.statusText;
67
-            return;
68
-        }
69
-        info.textContent = "Downloaded: " + file;
70
-        var file_parts = file.split(".");
71
-        var ext = file_parts.pop().toLowerCase();
72
-        if (ext == "zip") {
73
-            ext = file_parts.pop().toLowerCase();
74
-        }
75
-        info.textContent = "Loaded file with extension: " + ext;
76
-        var model_data = this.response;
77
-        View.view(ext, model_data);
78
-    };
79
-    info.textContent = "Fetching: " + file;
80
-    xhttp.open("GET", file);
81
-    xhttp.send();
82
-</script>
83
-
84
-[Direct link to this file](./plot/dispensy.3mf).
53
+{{#include inc_dispensy.kicad_pcb.md}}

+ 1
- 1
docs/src/main_board_sch.md View File

@@ -4,4 +4,4 @@ This page shows the current version of the schematics as SVG graphics.
4 4
 
5 5
 You can also view the [Main-Board schematics as PDF](./plot/dispensy.kicad_sch.pdf).
6 6
 
7
-{{#include inc_dispensy_sch.md}}
7
+{{#include inc_dispensy.kicad_sch.md}}

+ 40093
- 57418
hardware/dispensy.kicad_pcb
File diff suppressed because it is too large
View File


+ 6
- 0
hardware/dispensy.kicad_prl View File

@@ -67,6 +67,12 @@
67 67
     "visible_layers": "fffffff_ffffffff",
68 68
     "zone_display_mode": 0
69 69
   },
70
+  "git": {
71
+    "repo_password": "",
72
+    "repo_type": "",
73
+    "repo_username": "",
74
+    "ssh_key": ""
75
+  },
70 76
   "meta": {
71 77
     "filename": "dispensy.kicad_prl",
72 78
     "version": 3

+ 120
- 13
hardware/dispensy.kicad_pro View File

@@ -3,14 +3,17 @@
3 3
     "3dviewports": [],
4 4
     "design_settings": {
5 5
       "defaults": {
6
-        "board_outline_line_width": 0.09999999999999999,
7
-        "copper_line_width": 0.19999999999999998,
6
+        "apply_defaults_to_fp_fields": false,
7
+        "apply_defaults_to_fp_shapes": false,
8
+        "apply_defaults_to_fp_text": false,
9
+        "board_outline_line_width": 0.1,
10
+        "copper_line_width": 0.2,
8 11
         "copper_text_italic": false,
9 12
         "copper_text_size_h": 1.5,
10 13
         "copper_text_size_v": 1.5,
11 14
         "copper_text_thickness": 0.3,
12 15
         "copper_text_upright": false,
13
-        "courtyard_line_width": 0.049999999999999996,
16
+        "courtyard_line_width": 0.05,
14 17
         "dimension_precision": 4,
15 18
         "dimension_units": 3,
16 19
         "dimensions": {
@@ -21,7 +24,7 @@
21 24
           "text_position": 0,
22 25
           "units_format": 1
23 26
         },
24
-        "fab_line_width": 0.09999999999999999,
27
+        "fab_line_width": 0.1,
25 28
         "fab_text_italic": false,
26 29
         "fab_text_size_h": 1.0,
27 30
         "fab_text_size_v": 1.0,
@@ -72,6 +75,7 @@
72 75
         "duplicate_footprints": "warning",
73 76
         "extra_footprint": "warning",
74 77
         "footprint": "error",
78
+        "footprint_symbol_mismatch": "warning",
75 79
         "footprint_type_mismatch": "ignore",
76 80
         "hole_clearance": "error",
77 81
         "hole_near_hole": "error",
@@ -92,8 +96,8 @@
92 96
         "pth_inside_courtyard": "ignore",
93 97
         "shorting_items": "error",
94 98
         "silk_edge_clearance": "warning",
95
-        "silk_over_copper": "warning",
96
-        "silk_overlap": "warning",
99
+        "silk_over_copper": "ignore",
100
+        "silk_overlap": "ignore",
97 101
         "skew_out_of_range": "error",
98 102
         "solder_mask_bridge": "error",
99 103
         "starved_thermal": "error",
@@ -113,16 +117,16 @@
113 117
         "max_error": 0.005,
114 118
         "min_clearance": 0.127,
115 119
         "min_connection": 0.127,
116
-        "min_copper_edge_clearance": 0.39999999999999997,
120
+        "min_copper_edge_clearance": 0.4,
117 121
         "min_hole_clearance": 0.25,
118 122
         "min_hole_to_hole": 0.5,
119 123
         "min_microvia_diameter": 0.5,
120
-        "min_microvia_drill": 0.19999999999999998,
124
+        "min_microvia_drill": 0.2,
121 125
         "min_resolved_spokes": 2,
122 126
         "min_silk_clearance": 0.15,
123 127
         "min_text_height": 1.0,
124 128
         "min_text_thickness": 0.153,
125
-        "min_through_hole_diameter": 0.19999999999999998,
129
+        "min_through_hole_diameter": 0.2,
126 130
         "min_track_width": 0.127,
127 131
         "min_via_annular_width": 0.13,
128 132
         "min_via_diameter": 0.5,
@@ -133,9 +137,6 @@
133 137
       },
134 138
       "teardrop_options": [
135 139
         {
136
-          "td_allow_use_two_tracks": true,
137
-          "td_curve_segcount": 5,
138
-          "td_on_pad_in_zone": false,
139 140
           "td_onpadsmd": true,
140 141
           "td_onroundshapesonly": false,
141 142
           "td_ontrackend": false,
@@ -144,29 +145,35 @@
144 145
       ],
145 146
       "teardrop_parameters": [
146 147
         {
148
+          "td_allow_use_two_tracks": true,
147 149
           "td_curve_segcount": 0,
148 150
           "td_height_ratio": 1.0,
149 151
           "td_length_ratio": 0.5,
150 152
           "td_maxheight": 2.0,
151 153
           "td_maxlen": 1.0,
154
+          "td_on_pad_in_zone": false,
152 155
           "td_target_name": "td_round_shape",
153 156
           "td_width_to_size_filter_ratio": 0.9
154 157
         },
155 158
         {
159
+          "td_allow_use_two_tracks": true,
156 160
           "td_curve_segcount": 0,
157 161
           "td_height_ratio": 1.0,
158 162
           "td_length_ratio": 0.5,
159 163
           "td_maxheight": 2.0,
160 164
           "td_maxlen": 1.0,
165
+          "td_on_pad_in_zone": false,
161 166
           "td_target_name": "td_rect_shape",
162 167
           "td_width_to_size_filter_ratio": 0.9
163 168
         },
164 169
         {
170
+          "td_allow_use_two_tracks": true,
165 171
           "td_curve_segcount": 0,
166 172
           "td_height_ratio": 1.0,
167 173
           "td_length_ratio": 0.5,
168 174
           "td_maxheight": 2.0,
169 175
           "td_maxlen": 1.0,
176
+          "td_on_pad_in_zone": false,
170 177
           "td_target_name": "td_track_end",
171 178
           "td_width_to_size_filter_ratio": 0.9
172 179
         }
@@ -181,6 +188,32 @@
181 188
         1.5,
182 189
         2.0
183 190
       ],
191
+      "tuning_pattern_settings": {
192
+        "diff_pair_defaults": {
193
+          "corner_radius_percentage": 80,
194
+          "corner_style": 1,
195
+          "max_amplitude": 1.0,
196
+          "min_amplitude": 0.2,
197
+          "single_sided": false,
198
+          "spacing": 1.0
199
+        },
200
+        "diff_pair_skew_defaults": {
201
+          "corner_radius_percentage": 80,
202
+          "corner_style": 1,
203
+          "max_amplitude": 1.0,
204
+          "min_amplitude": 0.2,
205
+          "single_sided": false,
206
+          "spacing": 0.6
207
+        },
208
+        "single_track_defaults": {
209
+          "corner_radius_percentage": 80,
210
+          "corner_style": 1,
211
+          "max_amplitude": 1.0,
212
+          "min_amplitude": 0.2,
213
+          "single_sided": false,
214
+          "spacing": 0.6
215
+        }
216
+      },
184 217
       "via_dimensions": [
185 218
         {
186 219
           "diameter": 0.0,
@@ -197,6 +230,13 @@
197 230
       ],
198 231
       "zones_allow_external_fillets": false
199 232
     },
233
+    "ipc2581": {
234
+      "dist": "",
235
+      "distpn": "",
236
+      "internal_id": "",
237
+      "mfg": "",
238
+      "mpn": ""
239
+    },
200 240
     "layer_presets": [],
201 241
     "viewports": []
202 242
   },
@@ -455,14 +495,75 @@
455 495
       "gencad": "",
456 496
       "idf": "",
457 497
       "netlist": "",
498
+      "plot": "",
499
+      "pos_files": "",
458 500
       "specctra_dsn": "",
459 501
       "step": "",
502
+      "svg": "",
460 503
       "vrml": ""
461 504
     },
462 505
     "page_layout_descr_file": ""
463 506
   },
464 507
   "schematic": {
465 508
     "annotate_start_num": 0,
509
+    "bom_fmt_presets": [],
510
+    "bom_fmt_settings": {
511
+      "field_delimiter": ",",
512
+      "keep_line_breaks": false,
513
+      "keep_tabs": false,
514
+      "name": "CSV",
515
+      "ref_delimiter": ",",
516
+      "ref_range_delimiter": "",
517
+      "string_delimiter": "\""
518
+    },
519
+    "bom_presets": [],
520
+    "bom_settings": {
521
+      "exclude_dnp": false,
522
+      "fields_ordered": [
523
+        {
524
+          "group_by": false,
525
+          "label": "Reference",
526
+          "name": "Reference",
527
+          "show": true
528
+        },
529
+        {
530
+          "group_by": true,
531
+          "label": "Value",
532
+          "name": "Value",
533
+          "show": true
534
+        },
535
+        {
536
+          "group_by": false,
537
+          "label": "Datasheet",
538
+          "name": "Datasheet",
539
+          "show": true
540
+        },
541
+        {
542
+          "group_by": false,
543
+          "label": "Footprint",
544
+          "name": "Footprint",
545
+          "show": true
546
+        },
547
+        {
548
+          "group_by": false,
549
+          "label": "Qty",
550
+          "name": "${QUANTITY}",
551
+          "show": true
552
+        },
553
+        {
554
+          "group_by": true,
555
+          "label": "DNP",
556
+          "name": "${DNP}",
557
+          "show": true
558
+        }
559
+      ],
560
+      "filter_string": "",
561
+      "group_symbols": true,
562
+      "name": "Grouped By Value",
563
+      "sort_asc": true,
564
+      "sort_field": "Reference"
565
+    },
566
+    "connection_grid_size": 50.0,
466 567
     "drawing": {
467 568
       "dashed_lines_dash_length_ratio": 12.0,
468 569
       "dashed_lines_gap_length_ratio": 3.0,
@@ -476,6 +577,11 @@
476 577
       "intersheets_ref_suffix": "",
477 578
       "junction_size_choice": 3,
478 579
       "label_size_ratio": 0.375,
580
+      "operating_point_overlay_i_precision": 3,
581
+      "operating_point_overlay_i_range": "~A",
582
+      "operating_point_overlay_v_precision": 3,
583
+      "operating_point_overlay_v_range": "~V",
584
+      "overbar_offset_ratio": 1.23,
479 585
       "pin_symbol_size": 25.0,
480 586
       "text_offset_ratio": 0.15
481 587
     },
@@ -491,6 +597,7 @@
491 597
     "spice_external_command": "spice \"%I\"",
492 598
     "spice_model_current_sheet_as_root": true,
493 599
     "spice_save_all_currents": false,
600
+    "spice_save_all_dissipations": false,
494 601
     "spice_save_all_voltages": false,
495 602
     "subpart_first_id": 65,
496 603
     "subpart_id_separator": 0
@@ -498,7 +605,7 @@
498 605
   "sheets": [
499 606
     [
500 607
       "a50b51f9-900f-4bbb-8934-4acbc429c37b",
501
-      ""
608
+      "Root"
502 609
     ],
503 610
     [
504 611
       "635c7f01-c861-45f9-bb15-e53673572e1d",

+ 6308
- 2328
hardware/dispensy.kicad_sch
File diff suppressed because it is too large
View File


+ 4
- 12
hardware/generate_plot.sh View File

@@ -72,7 +72,7 @@ do
72 72
         echo "Exporting board $TYPE"
73 73
         kicad-cli pcb export $TYPE \
74 74
             -t "KiCad Classic"  \
75
-            -l $LAYER_F,$LAYER_B \
75
+            -l $LAYER_B,$LAYER_F \
76 76
             -o $OUTDIR/$IN.$TYPE/0_both.$TYPE \
77 77
             $IN
78 78
         echo
@@ -103,16 +103,8 @@ do
103 103
     # | 3D Export |
104 104
     #  -----------
105 105
 
106
-    echo "Exporting board step file"
107
-    rm -rf $OUTDIR/$IN.step
108
-    kicad-cli pcb export step \
109
-        -o $OUTDIR/$IN.step \
106
+    echo "Exporting board 3D"
107
+    kicad-cli pcb export vrml \
108
+        -o $OUTDIR/$IN.wrl \
110 109
         $IN
111
-
112
-    echo "Converting step to 3mf"
113
-    rm -rf $OUTDIR/$IN.3mf
114
-    prusa-slicer --export-3mf $OUTDIR/$IN.step
115
-
116
-    echo "Deleting step file"
117
-    rm -rf $OUTDIR/$IN.step
118 110
 done

+ 22902
- 8331
hardware/pi.kicad_sch
File diff suppressed because it is too large
View File


+ 2271
- 850
hardware/psu_lm2576.kicad_sch
File diff suppressed because it is too large
View File


Loading…
Cancel
Save