Compare commits
678 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e4dac1039d | ||
|
|
269305fa23 | ||
|
|
e820ea3141 | ||
|
|
531575651c | ||
|
|
d0f09727a9 | ||
|
|
ccc25a03d5 | ||
|
|
ce064e6e2d | ||
|
|
79d65d8ead | ||
|
|
cc4227aec8 | ||
|
|
f100d75c19 | ||
|
|
ef4f84e3ae | ||
|
|
76b57ba05a | ||
|
|
44aa5def73 | ||
|
|
e0b2d7c51d | ||
|
|
aac92ffb91 | ||
|
|
6df7356baa | ||
|
|
e505ab0df1 | ||
|
|
f2179da8ad | ||
|
|
0fd2dd7c11 | ||
|
|
d6f3f6b664 | ||
|
|
58d61c7887 | ||
|
|
6d90ebe6f8 | ||
|
|
0af0bc946e | ||
|
|
afa58de014 | ||
|
|
3a47d972db | ||
|
|
db4f0c24cd | ||
|
|
6b108aa885 | ||
|
|
581b1439f3 | ||
|
|
cf6a56cebf | ||
|
|
35f41b7402 | ||
|
|
824e55d75a | ||
|
|
f01ced8ed4 | ||
|
|
7699304f9b | ||
|
|
b8f92c73ed | ||
|
|
a726c58671 | ||
|
|
147d805231 | ||
|
|
729a2e8306 | ||
|
|
e5150fe187 | ||
|
|
043170265b | ||
|
|
d2aa78c16a | ||
|
|
065a8eb826 | ||
|
|
a79d87ca8e | ||
|
|
e231ac7422 | ||
|
|
a00d7b418f | ||
|
|
cbbc6801a0 | ||
|
|
4bbd631086 | ||
|
|
9ba94ded9e | ||
|
|
1c71ea27e0 | ||
|
|
5bb0bd755d | ||
|
|
ab6a8ec76e | ||
|
|
be58c7f8ec | ||
|
|
7cadd8d3f4 | ||
|
|
58890e32a2 | ||
|
|
7bb9ce8436 | ||
|
|
7c65e76ad0 | ||
|
|
bf92ffb5bf | ||
|
|
2cc0313b72 | ||
|
|
31687bc009 | ||
|
|
76f07979bb | ||
|
|
150cae1d1f | ||
|
|
9db0bec792 | ||
|
|
b3e8429b54 | ||
|
|
95e4c2d617 | ||
|
|
9f420f71a5 | ||
|
|
67a5cd0409 | ||
|
|
334507306b | ||
|
|
9cb98a00fc | ||
|
|
bb41765714 | ||
|
|
cd1e669306 | ||
|
|
64a1837fec | ||
|
|
c349863988 | ||
|
|
52fa91fb9a | ||
|
|
b161a69e98 | ||
|
|
ac72f8ec78 | ||
|
|
f3c4deb1ab | ||
|
|
f973886dac | ||
|
|
e541466591 | ||
|
|
31730fa031 | ||
|
|
c55842b428 | ||
|
|
8d4f7db66e | ||
|
|
097e6c524b | ||
|
|
077280bb62 | ||
|
|
5f9ce32fae | ||
|
|
ccb660a0ea | ||
|
|
22f7be8b74 | ||
|
|
b45ccfea97 | ||
|
|
f6c2e8b4eb | ||
|
|
3da7697c66 | ||
|
|
b98e12c19a | ||
|
|
3328ade194 | ||
|
|
8432f6f40c | ||
|
|
90bc3be6a0 | ||
|
|
4372d1812c | ||
|
|
d25e02144c | ||
|
|
a5e55c2acc | ||
|
|
37b9a2442f | ||
|
|
c4058f71fb | ||
|
|
057acb07b7 | ||
|
|
47e45ab391 | ||
|
|
4f89251f03 | ||
|
|
c3f916c60e | ||
|
|
936a4acd0d | ||
|
|
a33792f07e | ||
|
|
f57c29442c | ||
|
|
99989a668f | ||
|
|
5a919c892a | ||
|
|
24bbc43fd0 | ||
|
|
97590b8e0b | ||
|
|
ed13c5733d | ||
|
|
a7c8476e98 | ||
|
|
3d7e8fa5ec | ||
|
|
ca7dd8bfd4 | ||
|
|
363bcfb233 | ||
|
|
b6bf455155 | ||
|
|
1a437c1fd1 | ||
|
|
04a12ec9bd | ||
|
|
e4bb90a1ca | ||
|
|
f382762962 | ||
|
|
925562cfb1 | ||
|
|
ca04caa42c | ||
|
|
2b81b2935c | ||
|
|
34c3cb5c01 | ||
|
|
7fac0de1f8 | ||
|
|
b903f84c80 | ||
|
|
7efbc021a5 | ||
|
|
e30053f2a9 | ||
|
|
c7f0d039ac | ||
|
|
29e0996858 | ||
|
|
2549ccd722 | ||
|
|
530a37196c | ||
|
|
8fca908445 | ||
|
|
0079311b0b | ||
|
|
1e71909d02 | ||
|
|
def524bdf4 | ||
|
|
a2df01b88e | ||
|
|
216905ceca | ||
|
|
fedf90680e | ||
|
|
e7498fa241 | ||
|
|
dd5695405f | ||
|
|
08d03ae0eb | ||
|
|
368703fd78 | ||
|
|
46355f903e | ||
|
|
21597f9b07 | ||
|
|
55eed2e9be | ||
|
|
f5c99c1dec | ||
|
|
67278a6d8a | ||
|
|
fb798e3cba | ||
|
|
7a265f159a | ||
|
|
0225d17343 | ||
|
|
aa693fbdc1 | ||
|
|
7cbc44b8d3 | ||
|
|
102ec4938d | ||
|
|
75fa74313c | ||
|
|
215b4c5a1e | ||
|
|
b8745bc973 | ||
|
|
bc5e961d73 | ||
|
|
1302514ea8 | ||
|
|
d32506bd2e | ||
|
|
770b92863f | ||
|
|
459e521991 | ||
|
|
bd1ba86839 | ||
|
|
d4bf51231a | ||
|
|
3db483e270 | ||
|
|
1146d228fa | ||
|
|
1e07be4db4 | ||
|
|
e85f9473fc | ||
|
|
f7a7223b30 | ||
|
|
36ae433b57 | ||
|
|
8eb1110aa8 | ||
|
|
909eef3978 | ||
|
|
c5d94a74a5 | ||
|
|
852d1666bb | ||
|
|
b0d859f220 | ||
|
|
97927172f1 | ||
|
|
630989c0fe | ||
|
|
d29eb731a9 | ||
|
|
822616ae7f | ||
|
|
978b321f80 | ||
|
|
7c7573f69f | ||
|
|
efd9e7a6df | ||
|
|
fe98dd3585 | ||
|
|
b261d31ec5 | ||
|
|
144868c600 | ||
|
|
5c267e4f69 | ||
|
|
50d1ad9019 | ||
|
|
b2691d4730 | ||
|
|
d348f0da87 | ||
|
|
0820394e13 | ||
|
|
357b2f477c | ||
|
|
820dd0b5e3 | ||
|
|
f49f298003 | ||
|
|
9f755750d3 | ||
|
|
1940ba7062 | ||
|
|
a698aef29b | ||
|
|
c5d4e14298 | ||
|
|
a9a0bb87fa | ||
|
|
31ec098577 | ||
|
|
43f2eac239 | ||
|
|
c3550158bb | ||
|
|
19d18c2bc1 | ||
|
|
348a41c325 | ||
|
|
33887b8c39 | ||
|
|
0e9b8abde2 | ||
|
|
e5ef15ad0f | ||
|
|
cb3fede19a | ||
|
|
8e7eac9b08 | ||
|
|
ae4eb35a70 | ||
|
|
c68c0c6526 | ||
|
|
b3a6fbed74 | ||
|
|
9ec2ad0992 | ||
|
|
d05aa81927 | ||
|
|
c0311bee33 | ||
|
|
93e4897044 | ||
|
|
731236cf20 | ||
|
|
92aea93500 | ||
|
|
be1effebc3 | ||
|
|
6ab16d2407 | ||
|
|
50a8efe0a5 | ||
|
|
de7c1f76db | ||
|
|
b112cac47a | ||
|
|
68dc28580f | ||
|
|
d9e35481be | ||
|
|
8c2991ceac | ||
|
|
864918b1f9 | ||
|
|
47b6144ff6 | ||
|
|
cf79b3c342 | ||
|
|
439f6684be | ||
|
|
d22b30342a | ||
|
|
51d64ad7f8 | ||
|
|
170b9678fb | ||
|
|
364faf497b | ||
|
|
18b56c3cda | ||
|
|
95392595f6 | ||
|
|
4b5db04f78 | ||
|
|
1165c0c9c5 | ||
|
|
0b2c89ecaf | ||
|
|
929733f0a7 | ||
|
|
ed0882dc10 | ||
|
|
d48e8ea162 | ||
|
|
5a1b2d61ae | ||
|
|
531134f092 | ||
|
|
f80456a698 | ||
|
|
5144c5f01e | ||
|
|
1379a59085 | ||
|
|
7cca8d970a | ||
|
|
742d6481a9 | ||
|
|
05ba62600c | ||
|
|
a4e2540f14 | ||
|
|
30a49d3186 | ||
|
|
c8d9d575a1 | ||
|
|
2a5778be3a | ||
|
|
2857255ef1 | ||
|
|
3d4ee9e962 | ||
|
|
174754299a | ||
|
|
7b6a44e8f9 | ||
|
|
f7f78433a2 | ||
|
|
48ddfba415 | ||
|
|
67c6234907 | ||
|
|
a9f2a1375a | ||
|
|
390d549c0c | ||
|
|
094b9de69e | ||
|
|
91691afdcf | ||
|
|
d1da6100a6 | ||
|
|
32b763efb1 | ||
|
|
d459ae648d | ||
|
|
e3a49dc692 | ||
|
|
0c0087ce42 | ||
|
|
5791a4d8c4 | ||
|
|
4573932f89 | ||
|
|
947a7b2b0f | ||
|
|
f15cd62587 | ||
|
|
ea7de3bcad | ||
|
|
b595c3e423 | ||
|
|
d6f72eefa1 | ||
|
|
ea129d869e | ||
|
|
aac2fee9de | ||
|
|
c8dc47b162 | ||
|
|
ac3aa097fb | ||
|
|
ef6068dc42 | ||
|
|
5801e6f4d0 | ||
|
|
30013a1fb8 | ||
|
|
a8d4a7ef46 | ||
|
|
8fe8a6deb3 | ||
|
|
18b04ffe68 | ||
|
|
50196c7141 | ||
|
|
ab4060e145 | ||
|
|
165317e33f | ||
|
|
5632cf6d77 | ||
|
|
ce79b6ca00 | ||
|
|
b656792616 | ||
|
|
cf4f23ebf2 | ||
|
|
f3edea2943 | ||
|
|
40b7ba5111 | ||
|
|
1588426229 | ||
|
|
4acda88e8d | ||
|
|
6b4e44011c | ||
|
|
ca7a80a946 | ||
|
|
afd5d55c00 | ||
|
|
e5d95fdd00 | ||
|
|
983c84b12f | ||
|
|
75de9cb4c0 | ||
|
|
fa3d2b97bd | ||
|
|
eec58b99fe | ||
|
|
109eff0191 | ||
|
|
5a993b743e | ||
|
|
1ae67441c3 | ||
|
|
34fe4cce14 | ||
|
|
480415d2e8 | ||
|
|
a5189f7c25 | ||
|
|
0bce44e1bb | ||
|
|
a20d9d3bd5 | ||
|
|
82a542faed | ||
|
|
ee67715e2b | ||
|
|
28fe6a5df0 | ||
|
|
9b56c4f780 | ||
|
|
daf4d237c0 | ||
|
|
051e8724a0 | ||
|
|
22f0db06a1 | ||
|
|
2b9124f3c0 | ||
|
|
79632878ac | ||
|
|
22132a5516 | ||
|
|
ad480bd470 | ||
|
|
96acfdc6d2 | ||
|
|
e6208c6f02 | ||
|
|
a27e82aef3 | ||
|
|
11e9bb286e | ||
|
|
b065f51454 | ||
|
|
a8a912fbb5 | ||
|
|
e94f3b7827 | ||
|
|
65f0fd6238 | ||
|
|
3387cccdcf | ||
|
|
52df40dfbb | ||
|
|
08aacec0b2 | ||
|
|
1b07be070b | ||
|
|
e88eab18d0 | ||
|
|
868a1f951b | ||
|
|
f337fb1802 | ||
|
|
e0bd221c57 | ||
|
|
be3131de3e | ||
|
|
3f59c3dd48 | ||
|
|
5fb1c76c0e | ||
|
|
71063fe500 | ||
|
|
cbf019a468 | ||
|
|
fbec3ebb63 | ||
|
|
64e6d85898 | ||
|
|
d15c106288 | ||
|
|
f067d0cc78 | ||
|
|
2eaf3510ab | ||
|
|
a5d27c55e1 | ||
|
|
0daf19c003 | ||
|
|
cf2393efc8 | ||
|
|
74cf4dc9e0 | ||
|
|
71db5fbe31 | ||
|
|
5633e6c249 | ||
|
|
50142cc1b3 | ||
|
|
635a199a47 | ||
|
|
f4910e119a | ||
|
|
742048a08d | ||
|
|
e1146c04fd | ||
|
|
8572cae9a0 | ||
|
|
dd240f6471 | ||
|
|
454a873cb8 | ||
|
|
ed011b5f25 | ||
|
|
7783767c35 | ||
|
|
cd24d61515 | ||
|
|
1fefd695de | ||
|
|
43179d7b6c | ||
|
|
82738955d2 | ||
|
|
f2d232ef77 | ||
|
|
c5ecb37b4e | ||
|
|
ac5e207241 | ||
|
|
7c7de85f01 | ||
|
|
09a64d24f1 | ||
|
|
c0c892d524 | ||
|
|
a434341aa9 | ||
|
|
2c5eba44ee | ||
|
|
13ccb1a46f | ||
|
|
98580ac1c2 | ||
|
|
334a839123 | ||
|
|
273a98d39a | ||
|
|
7a9553b38a | ||
|
|
7d0f3649f3 | ||
|
|
63dffd9307 | ||
|
|
5b124d59f2 | ||
|
|
70f765f62f | ||
|
|
a084c38b41 | ||
|
|
c52c398ae8 | ||
|
|
f168032901 | ||
|
|
f20dd0c9be | ||
|
|
7510efe827 | ||
|
|
270080cd4c | ||
|
|
c0bf4327fd | ||
|
|
756514adef | ||
|
|
eba252d3fd | ||
|
|
940db6bd70 | ||
|
|
6a60fe998d | ||
|
|
fce993478c | ||
|
|
cb29143939 | ||
|
|
e2b4b1616f | ||
|
|
acefe26e0f | ||
|
|
0025fbf10d | ||
|
|
ca505bf4ac | ||
|
|
89835940f7 | ||
|
|
28fa954487 | ||
|
|
94dc8167c9 | ||
|
|
260d12af6d | ||
|
|
ce0f4fe038 | ||
|
|
244d0aa65b | ||
|
|
2af73d1006 | ||
|
|
a31c31aed4 | ||
|
|
b988596519 | ||
|
|
8faab46ed2 | ||
|
|
7d897d84d7 | ||
|
|
5cdba1fda8 | ||
|
|
211e34e62b | ||
|
|
21563c5965 | ||
|
|
32a85edb16 | ||
|
|
733506dfb2 | ||
|
|
d9f960fb0c | ||
|
|
f60b0093b7 | ||
|
|
5294b3cd2d | ||
|
|
00ea4428a3 | ||
|
|
70b5e1eb69 | ||
|
|
68d78f0791 | ||
|
|
e1833e020a | ||
|
|
4125e176b7 | ||
|
|
fa9b321991 | ||
|
|
f7c2d918b6 | ||
|
|
f3ac1a2306 | ||
|
|
b4f03e8363 | ||
|
|
649d7c54f0 | ||
|
|
2991c7a831 | ||
|
|
ebd9035325 | ||
|
|
5c7c8c984b | ||
|
|
b0ee323e2e | ||
|
|
32175bc66a | ||
|
|
bbd3f18178 | ||
|
|
85797a1f76 | ||
|
|
295a6f48fc | ||
|
|
1eb416002b | ||
|
|
7e9ee6aef7 | ||
|
|
80bcafda77 | ||
|
|
b91b0f24db | ||
|
|
0dbfa915de | ||
|
|
5b3444c060 | ||
|
|
bae094eac3 | ||
|
|
58b77e783f | ||
|
|
997719af13 | ||
|
|
f767bee8ff | ||
|
|
e08bb4f196 | ||
|
|
3a1d9e779c | ||
|
|
b41770caa6 | ||
|
|
38d7b9ada0 | ||
|
|
4061026c25 | ||
|
|
ecf53e6194 | ||
|
|
4ad44e3e83 | ||
|
|
53b718a621 | ||
|
|
0cbfcfd3d1 | ||
|
|
d725160706 | ||
|
|
cc6b416660 | ||
|
|
5922a1ea1b | ||
|
|
fe676fa099 | ||
|
|
cda08a844a | ||
|
|
6aba3c552b | ||
|
|
52ab93be6d | ||
|
|
640169310f | ||
|
|
154397b92c | ||
|
|
efb27f095c | ||
|
|
e11851276d | ||
|
|
f529d7476d | ||
|
|
696ee69f2c | ||
|
|
593b4d2656 | ||
|
|
19d6205492 | ||
|
|
6078145dcd | ||
|
|
eb02043943 | ||
|
|
4889e8241d | ||
|
|
7e497af184 | ||
|
|
483c51e864 | ||
|
|
e907253dba | ||
|
|
f85b43a789 | ||
|
|
373c7ff301 | ||
|
|
2622b439fc | ||
|
|
af1cd3c4ce | ||
|
|
d350e2c617 | ||
|
|
8a0c9a457a | ||
|
|
06ef60011e | ||
|
|
7aec52dfb3 | ||
|
|
d651851567 | ||
|
|
41058d22a6 | ||
|
|
f08a0c5e93 | ||
|
|
74de181e59 | ||
|
|
d9a32f75fa | ||
|
|
3e88ffabf1 | ||
|
|
77a2c95b5e | ||
|
|
4e01ab4ef0 | ||
|
|
13acdf7832 | ||
|
|
890298d34d | ||
|
|
0216201cb6 | ||
|
|
20b404ecf5 | ||
|
|
0791c69499 | ||
|
|
93d0526a77 | ||
|
|
968ed58b61 | ||
|
|
b96542f0e5 | ||
|
|
9a97a348ae | ||
|
|
28b7a28651 | ||
|
|
544f8c1e85 | ||
|
|
d0590ccb0e | ||
|
|
76e2b041b4 | ||
|
|
d94c856118 | ||
|
|
3ac9fc6e63 | ||
|
|
926829e737 | ||
|
|
8f747e2720 | ||
|
|
eb73b5d0b0 | ||
|
|
bbe53cf8e5 | ||
|
|
7148ebd565 | ||
|
|
fc4a9e7564 | ||
|
|
ca0d0135dc | ||
|
|
2511471b0d | ||
|
|
ba3428822d | ||
|
|
9a2eb4bedd | ||
|
|
8a830ff0ce | ||
|
|
189ebb4c7d | ||
|
|
bedbfceafc | ||
|
|
c60c9ee302 | ||
|
|
995367bd52 | ||
|
|
9519e05394 | ||
|
|
7a606633fa | ||
|
|
d887a403ff | ||
|
|
4fbecfa1fc | ||
|
|
711a69396f | ||
|
|
c89983fd96 | ||
|
|
d94dc44e98 | ||
|
|
ea18034258 | ||
|
|
6841f0b5a8 | ||
|
|
9972db5a2a | ||
|
|
eb801631b9 | ||
|
|
780e3c3022 | ||
|
|
efe63d5efe | ||
|
|
4ec1244c31 | ||
|
|
268e39fe52 | ||
|
|
064212a191 | ||
|
|
3819ad2986 | ||
|
|
e110e1fecc | ||
|
|
5f640699b7 | ||
|
|
4367a985e2 | ||
|
|
e90edc0447 | ||
|
|
1ace688ea3 | ||
|
|
183e0decf8 | ||
|
|
a748cf39eb | ||
|
|
f020ed179e | ||
|
|
2c4ca88887 | ||
|
|
404cd376b5 | ||
|
|
26378c2564 | ||
|
|
ff9543eee2 | ||
|
|
1b1d2adb31 | ||
|
|
b93fd5b1b5 | ||
|
|
879c45db19 | ||
|
|
d798fae20b | ||
|
|
0728c1a8be | ||
|
|
75f8709947 | ||
|
|
528f9f7604 | ||
|
|
c8af3feee6 | ||
|
|
cb4e165071 | ||
|
|
2a55741ea8 | ||
|
|
c9dfdf21e5 | ||
|
|
20ddd842b7 | ||
|
|
c38a63d4db | ||
|
|
2994638380 | ||
|
|
ef7d4dd3cb | ||
|
|
4344f7fc10 | ||
|
|
c381d03aad | ||
|
|
c812a40a37 | ||
|
|
65613aeddf | ||
|
|
83d3c17280 | ||
|
|
141bd0ce9b | ||
|
|
c78b90767f | ||
|
|
970831ee0d | ||
|
|
5ae22a5e51 | ||
|
|
1e6fa5722a | ||
|
|
26246b1f28 | ||
|
|
3799f40f29 | ||
|
|
739d37feac | ||
|
|
c4fe43ffce | ||
|
|
ee4f37fe0c | ||
|
|
e50c2aa38d | ||
|
|
237c242d65 | ||
|
|
d7b29eca47 | ||
|
|
bf301a977e | ||
|
|
3e1febce78 | ||
|
|
3025638b9b | ||
|
|
4bf1b042b1 | ||
|
|
c2d48aba87 | ||
|
|
e3e3aa63d7 | ||
|
|
42ca985bef | ||
|
|
2db5415d09 | ||
|
|
680c92de40 | ||
|
|
61fbd193f9 | ||
|
|
33c2c8f1bd | ||
|
|
2ab47cd20c | ||
|
|
75a1e9ea21 | ||
|
|
5a88a14afc | ||
|
|
abe79056c9 | ||
|
|
6869e7d1ec | ||
|
|
c5bff88943 | ||
|
|
11816295e7 | ||
|
|
2740838b2e | ||
|
|
5712283e91 | ||
|
|
6d376017bc | ||
|
|
a11add60e2 | ||
|
|
c331406774 | ||
|
|
3505a0727d | ||
|
|
70068985a7 | ||
|
|
907cfb9105 | ||
|
|
6c3db80d89 | ||
|
|
bf3c41cd06 | ||
|
|
6ad344c8a6 | ||
|
|
2e3fa8da13 | ||
|
|
f70fefa06f | ||
|
|
31ae74c56c | ||
|
|
22487d95e9 | ||
|
|
838da992e8 | ||
|
|
9c52ad4310 | ||
|
|
018c5daa94 | ||
|
|
99b233df3f | ||
|
|
640ff1ad56 | ||
|
|
cd9e21e3aa | ||
|
|
7fd14848ca | ||
|
|
1f11c171c7 | ||
|
|
461390ac87 | ||
|
|
15248706ae | ||
|
|
8e1b516eb6 | ||
|
|
4a8f9407b8 | ||
|
|
46cf3ef145 | ||
|
|
cf475a9a39 | ||
|
|
22c49a7c3f | ||
|
|
76bafadb71 | ||
|
|
3ef7c00b73 | ||
|
|
bdd26e421b | ||
|
|
d5dc6b785d | ||
|
|
8f4f5da11c | ||
|
|
6d03dee104 | ||
|
|
93262919ed | ||
|
|
68864333f3 | ||
|
|
eff1c8604d | ||
|
|
85e6cd865c | ||
|
|
48e9fa04e7 | ||
|
|
832c0bc017 | ||
|
|
6793970198 | ||
|
|
606222da5b | ||
|
|
add370230f | ||
|
|
2bf9e27b9e | ||
|
|
06a4753f73 | ||
|
|
bf4e851e21 | ||
|
|
35f3f6506b | ||
|
|
c539fed8bb | ||
|
|
b5b365289c | ||
|
|
75d5737211 | ||
|
|
e097b08520 | ||
|
|
6466af6313 | ||
|
|
c463893a5e | ||
|
|
b2caa486c5 | ||
|
|
75b89f5261 | ||
|
|
8c8261ba80 | ||
|
|
f8a28401c0 | ||
|
|
97f30765a1 | ||
|
|
f616a88b15 | ||
|
|
7c5f9ee458 | ||
|
|
460cc88f3d | ||
|
|
06d73207e7 | ||
|
|
0fc4f0946e | ||
|
|
7e78b2665e | ||
|
|
aed958eb5c | ||
|
|
4eeb43b191 | ||
|
|
a4439b93b7 | ||
|
|
5e060c3c65 | ||
|
|
0f1a142779 | ||
|
|
bb8926d67a | ||
|
|
a301713361 |
1
.gitignore
vendored
@@ -3,3 +3,4 @@ out
|
||||
*.pyc
|
||||
.config
|
||||
.config.old
|
||||
klippy/.version
|
||||
|
||||
23
.travis.yml
@@ -2,11 +2,24 @@
|
||||
language: c
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- gcc-avr
|
||||
- avr-libc
|
||||
- wget
|
||||
apt:
|
||||
packages:
|
||||
# AVR GCC packages
|
||||
- gcc-avr
|
||||
- avr-libc
|
||||
# PRU GCC build packages
|
||||
- pv
|
||||
- libmpfr-dev
|
||||
- libgmp-dev
|
||||
- libmpc-dev
|
||||
- texinfo
|
||||
- libncurses5-dev
|
||||
- bison
|
||||
- flex
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- travis_cache
|
||||
|
||||
install: ./scripts/travis-install.sh
|
||||
|
||||
|
||||
2
Makefile
@@ -32,7 +32,7 @@ dirs-y = src
|
||||
cc-option=$(shell if test -z "`$(1) $(2) -S -o /dev/null -xc /dev/null 2>&1`" \
|
||||
; then echo "$(2)"; else echo "$(3)"; fi ;)
|
||||
|
||||
CFLAGS := -I$(OUT) -Isrc -I$(OUT)board-generic/ -O2 -MD -g \
|
||||
CFLAGS := -I$(OUT) -Isrc -I$(OUT)board-generic/ -std=gnu11 -O2 -MD -g \
|
||||
-Wall -Wold-style-definition $(call cc-option,$(CC),-Wtype-limits,) \
|
||||
-ffunction-sections -fdata-sections
|
||||
CFLAGS += -flto -fwhole-program -fno-use-linker-plugin
|
||||
|
||||
@@ -113,19 +113,19 @@ delta_radius: 174.75
|
||||
# angles.
|
||||
[delta_calibrate]
|
||||
radius: 50
|
||||
# Radius (in mm) of the area that may be probed. This is typically
|
||||
# the size of the printer bed. This parameter must be provided.
|
||||
# Radius (in mm) of the area that may be probed. This is the radius
|
||||
# of nozzle coordinates to be probed; if using an automatic probe
|
||||
# with an XY offset then choose a radius small enough so that the
|
||||
# probe always fits over the bed. This parameter must be provided.
|
||||
#speed: 50
|
||||
# The speed (in mm/s) of non-probing moves during the
|
||||
# calibration. The default is 50.
|
||||
# The speed (in mm/s) of non-probing moves during the calibration.
|
||||
# The default is 50.
|
||||
#horizontal_move_z: 5
|
||||
# The height (in mm) that the head should be commanded to move to
|
||||
# just prior to starting a probe operation. The default is 5.
|
||||
#manual_probe:
|
||||
# If true, then DELTA_CALIBRATE will perform manual probing. If
|
||||
# false, then a PROBE command will be run at each probe
|
||||
# point. Manual probing is accomplished by manually jogging the Z
|
||||
# position of the print head at each probe point and then issuing a
|
||||
# NEXT extended g-code command to record the position at that
|
||||
# point. The default is false if a [probe] config section is present
|
||||
# and true otherwise.
|
||||
#samples: 1
|
||||
# The number of times to probe each point. The probed z-values will
|
||||
# be averaged. The default is to probe 1 time.
|
||||
#sample_retract_dist: 2.0
|
||||
# The distance (in mm) to retract between each sample if sampling
|
||||
# more than once. The default is 2mm.
|
||||
|
||||
@@ -11,26 +11,58 @@
|
||||
# Z height probe. One may define this section to enable Z height
|
||||
# probing hardware. When this section is enabled, PROBE and
|
||||
# QUERY_PROBE extended g-code commands become available. The probe
|
||||
# section also creates a virtual probe:z_virtual_endstop pin. One may
|
||||
# set the stepper_z endstop_pin to this virtual pin on cartesian style
|
||||
# printers that use the probe in place of a z endstop.
|
||||
# section also creates a virtual "probe:z_virtual_endstop" pin. One
|
||||
# may set the stepper_z endstop_pin to this virtual pin on cartesian
|
||||
# style printers that use the probe in place of a z endstop. If using
|
||||
# "probe:z_virtual_endstop" then do not define a position_endstop in
|
||||
# the stepper_z config section.
|
||||
#[probe]
|
||||
#pin: ar15
|
||||
# Probe detection pin. This parameter must be provided.
|
||||
#x_offset: 0.0
|
||||
# The distance (in mm) between the probe and the nozzle along the
|
||||
# x-axis. The default is 0.
|
||||
#y_offset: 0.0
|
||||
# The distance (in mm) between the probe and the nozzle along the
|
||||
# y-axis. The default is 0.
|
||||
#z_offset:
|
||||
# The distance (in mm) between the bed and the nozzle when the probe
|
||||
# triggers. This parameter must be provided.
|
||||
#speed: 5.0
|
||||
# Speed (in mm/s) of the Z axis when probing. The default is 5mm/s.
|
||||
#activate_gcode:
|
||||
# A list of G-Code commands (one per line) to execute prior to each
|
||||
# probe attempt. This may be useful if the probe needs to be
|
||||
# activated in some way. The default is to not run any special
|
||||
# G-Code commands on activation.
|
||||
# A list of G-Code commands (one per line; subsequent lines
|
||||
# indented) to execute prior to each probe attempt. This may be
|
||||
# useful if the probe needs to be activated in some way. Do not
|
||||
# issue any commands here that move the toolhead (eg, G1). The
|
||||
# default is to not run any special G-Code commands on activation.
|
||||
#deactivate_gcode:
|
||||
# A list of G-Code commands (one per line) to execute after each
|
||||
# probe attempt completes. The default is to not run any special
|
||||
# G-Code commands on deactivation.
|
||||
# A list of G-Code commands (one per line; subsequent lines
|
||||
# indented) to execute after each probe attempt completes. Do not
|
||||
# issue any commands here that move the toolhead. The default is to
|
||||
# not run any special G-Code commands on deactivation.
|
||||
|
||||
|
||||
# BLTouch probe. One may define this section (instead of a probe
|
||||
# section) to enable a BLTouch probe. (Note! This bltouch module may
|
||||
# not work correctly with some BLTouch "clones"!) A virtual
|
||||
# "probe:z_virtual_endstop" pin is also created (see the "probe"
|
||||
# section above for the details).
|
||||
#[bltouch]
|
||||
#sensor_pin:
|
||||
# Pin connected to the BLTouch sensor pin. This parameter must be
|
||||
# provided.
|
||||
#control_pin:
|
||||
# Pin connected to the BLTouch control pin. This parameter must be
|
||||
# provided.
|
||||
#pin_move_time: 0.200
|
||||
# The amount of time (in seconds) that it takes the BLTouch pin to
|
||||
# move up or down. The default is 0.200 seconds.
|
||||
#x_offset:
|
||||
#y_offset:
|
||||
#z_offset:
|
||||
#speed:
|
||||
# See the "probe" section for information on these parameters.
|
||||
|
||||
|
||||
# Bed tilt compensation. One may define a [bed_tilt] config section to
|
||||
@@ -42,27 +74,174 @@
|
||||
#y_adjust: 0
|
||||
# The amount to add to each move's Z height for each mm on the Y
|
||||
# axis. The default is 0.
|
||||
#z_adjust: 0
|
||||
# The amount to add to the Z height when the nozzle is nominally at
|
||||
# 0,0. The default is 0.
|
||||
# The remaining parameters control a BED_TILT_CALIBRATE extended
|
||||
# g-code command that may be used to calibrate appropriate x and y
|
||||
# adjustment parameters.
|
||||
#points:
|
||||
# A newline separated list of X,Y points that should be probed
|
||||
# during a BED_TILT_CALIBRATE command. The default is to not enable
|
||||
# the command.
|
||||
# A list of X,Y coordinates (one per line; subsequent lines
|
||||
# indented) that should be probed during a BED_TILT_CALIBRATE
|
||||
# command. Specify coordinates of the nozzle and be sure the probe
|
||||
# is above the bed at the given nozzle coordinates. The default is
|
||||
# to not enable the command.
|
||||
#speed: 50
|
||||
# The speed (in mm/s) of non-probing moves during the
|
||||
# calibration. The default is 50.
|
||||
#horizontal_move_z: 5
|
||||
# The height (in mm) that the head should be commanded to move to
|
||||
# just prior to starting a probe operation. The default is 5.
|
||||
#manual_probe:
|
||||
# If true, then BED_TILT_CALIBRATE will perform manual probing. If
|
||||
# false, then a PROBE command will be run at each probe
|
||||
# point. Manual probing is accomplished by manually jogging the Z
|
||||
# position of the print head at each probe point and then issuing a
|
||||
# NEXT extended g-code command to record the position at that
|
||||
# point. The default is false if a [probe] config section is present
|
||||
# and true otherwise.
|
||||
#samples: 1
|
||||
# The number of times to probe each point. The probed z-values
|
||||
# will be averaged. The default is to probe 1 time.
|
||||
#sample_retract_dist: 2.0
|
||||
# The distance (in mm) to retract between each sample if
|
||||
# sampling more than once. Default is 2mm.
|
||||
|
||||
|
||||
# Mesh Bed Leveling. One may define a [bed_mesh] config section
|
||||
# to enable move transformations that offset the z axis based
|
||||
# on a mesh generated from probed points. Note that bed_mesh
|
||||
# and bed_tilt are incompatible, both cannot be defined. When
|
||||
# using a probe to home the z-axis, it is recommended to define
|
||||
# a [homing_override] section in printer.cfg to home toward the
|
||||
# center of the print area.
|
||||
#[bed_mesh]
|
||||
#speed: 50
|
||||
# The speed (in mm/s) of non-probing moves during the
|
||||
# calibration. The default is 50.
|
||||
#horizontal_move_z: 5
|
||||
# The height (in mm) that the head should be commanded to move to
|
||||
# just prior to starting a probe operation. The default is 5.
|
||||
#samples: 1
|
||||
# The number of times to probe each point. The probed z-values
|
||||
# will be averaged. The default is to probe 1 time.
|
||||
#sample_retract_dist: 2.0
|
||||
# The distance (in mm) to retract between each sample if
|
||||
# sampling more than once. Default is 2mm.
|
||||
#min_point:
|
||||
# An X,Y point defining the minimum coordinate to probe on
|
||||
# the bed. Note that this refers to the nozzle position,
|
||||
# and take care that you do not define a point that will move
|
||||
# the probe off of the bed. This parameter must be provided.
|
||||
#max_point:
|
||||
# An X,Y point defining the maximum coordinate to probe on
|
||||
# the bed. Follow the same precautions as listed in min_point.
|
||||
# Also note that this does not necessarily define the last point
|
||||
# probed, only the maximum coordinate. This parameter must be provided.
|
||||
#probe_count: 3,3
|
||||
# A comma separated pair of integer values (X,Y) defining the number
|
||||
# of points to probe along each axis. A single value is also valid,
|
||||
# in which case that value will be for both axes. Default is 3,3
|
||||
# which probes a 3x3 grid.
|
||||
#fade_start: 1.0
|
||||
# The gcode z position in which to start phasing out z-adjustment
|
||||
# when fade is enabled. Default is 1.0.
|
||||
#fade_end: 0.0
|
||||
# The gcode z position in which phasing out completes. When set
|
||||
# to a value below fade_start, fade is disabled. It should be
|
||||
# noted that fade may add unwanted scaling along the z-axis of a
|
||||
# print. If a user wishes to enable fade, a value of 10.0 is
|
||||
# recommended. Default is 0.0, which disables fade.
|
||||
#fade_target:
|
||||
# The z position in which fade should converge. When this value is set
|
||||
# to a non-zero value it must be within the range of z-values in the mesh.
|
||||
# Users that wish to converge to the z homing position should set this to 0.
|
||||
# Default is the average z value of the mesh.
|
||||
#split_delta_z: .025
|
||||
# The amount of Z difference (in mm) along a move that will
|
||||
# trigger a split. Default is .025.
|
||||
#move_check_distance: 5.0
|
||||
# The distance (in mm) along a move to check for split_delta_z.
|
||||
# This is also the minimum length that a move can be split. Default
|
||||
# is 5.0.
|
||||
#mesh_pps: 2,2
|
||||
# A comma separated pair of integers (X,Y) defining the number of
|
||||
# points per segment to interpolate in the mesh along each axis. A
|
||||
# "segment" can be defined as the space between each probed
|
||||
# point. The user may enter a single value which will be applied
|
||||
# to both axes. Default is 2,2.
|
||||
#algorithm: lagrange
|
||||
# The interpolation algorithm to use. May be either "lagrange"
|
||||
# or "bicubic". This option will not affect 3x3 grids, which
|
||||
# are forced to use lagrange sampling. Default is lagrange.
|
||||
#bicubic_tension: .2
|
||||
# When using the bicubic algorithm the tension parameter above
|
||||
# may be applied to change the amount of slope interpolated.
|
||||
# Larger numbers will increase the amount of slope, which
|
||||
# results in more curvature in the mesh. Default is .2.
|
||||
|
||||
|
||||
# Multiple Z stepper tilt adjustment. This feature enables independent
|
||||
# adjustment of multiple z steppers (see stepper_z1 section below) to
|
||||
# adjust for tilt. If this section is present then a Z_TILT_ADJUST
|
||||
# extended G-Code command becomes available.
|
||||
#[z_tilt]
|
||||
#z_positions:
|
||||
# A list of X,Y coordinates (one per line; subsequent lines
|
||||
# indented) describing the location of each Z stepper. The first
|
||||
# entry corresponds to stepper_z, the second to stepper_z1, the
|
||||
# third to stepper_z2, etc. This parameter must be provided.
|
||||
#points:
|
||||
# A list of X,Y coordinates (one per line; subsequent lines
|
||||
# indented) that should be probed during a Z_TILT_ADJUST command.
|
||||
# Specify coordinates of the nozzle and be sure the probe is above
|
||||
# the bed at the given nozzle coordinates. This parameter must be
|
||||
# provided.
|
||||
#speed: 50
|
||||
# The speed (in mm/s) of non-probing moves during the calibration.
|
||||
# The default is 50.
|
||||
#horizontal_move_z: 5
|
||||
# The height (in mm) that the head should be commanded to move to
|
||||
# just prior to starting a probe operation. The default is 5.
|
||||
#samples: 1
|
||||
# The number of times to probe each point. The probed z-values
|
||||
# will be averaged. The default is to probe 1 time.
|
||||
#sample_retract_dist: 2.0
|
||||
# The distance (in mm) to retract between each sample if
|
||||
# sampling more than once. Default is 2mm.
|
||||
|
||||
|
||||
# Moving gantry leveling using 4 independently controlled Z motors.
|
||||
# Corrects hyperbolic parabola effects (potato chip) on moving gantry
|
||||
# which is more flexible.
|
||||
# WARNING: Using this on a moving bed may lead to undesirable results.
|
||||
# If this section is present then a QUAD_GANTRY_LEVEL extended G-Code
|
||||
# command becomes available. This routine assumes the following Z motor
|
||||
# configuration:
|
||||
# ----------------
|
||||
# |Z1 Z2|
|
||||
# | --------- |
|
||||
# | | | |
|
||||
# | | | |
|
||||
# | x-------- |
|
||||
# |Z Z3|
|
||||
# ----------------
|
||||
# Where x is the (0,0) point on the bed
|
||||
#[quad_gantry_level]
|
||||
#gantry_corners:
|
||||
# A newline separated list of X,Y coordinates describing the
|
||||
# two opposing corners of the gantry. The first entry corresponds to
|
||||
# Z, the second to Z2.
|
||||
# This parameter must be provided.
|
||||
#points:
|
||||
# A newline separated list of four X,Y points that should be probed
|
||||
# during a QUAD_GANTRY_LEVEL command.
|
||||
# Order of the locations is important, and should correspond to Z,Z1
|
||||
# Z2, and Z3 location in order.
|
||||
# This parameter must be provided.
|
||||
# For maximum accuracy, ensure your probe offsets are configured.
|
||||
#speed: 50
|
||||
# The speed (in mm/s) of non-probing moves during the calibration.
|
||||
# The default is 50.
|
||||
#horizontal_move_z: 5
|
||||
# The height (in mm) that the head should be commanded to move to
|
||||
# just prior to starting a probe operation. The default is 5
|
||||
#samples: 1
|
||||
# Number of probe samples per point. The defaut is 1
|
||||
#sample_retract_dist: 2.0
|
||||
# Distance in mm to retract the probe between samples. Default is 2.
|
||||
|
||||
|
||||
# In a multi-extruder printer add an additional extruder section for
|
||||
@@ -82,17 +261,18 @@
|
||||
# should specify "shared_heater: extruder3". The default is to not
|
||||
# reuse an existing heater.
|
||||
#deactivate_gcode:
|
||||
# A list of G-Code commands (one per line) to execute on a G-Code
|
||||
# tool change command (eg, "T1") that deactivates this extruder and
|
||||
# activates some other extruder. It only makes sense to define this
|
||||
# section on multi-extruder printers. The default is to not run any
|
||||
# special G-Code commands on deactivation.
|
||||
# A list of G-Code commands (one per line; subsequent lines
|
||||
# indented) to execute on a G-Code tool change command (eg, "T1")
|
||||
# that deactivates this extruder and activates some other
|
||||
# extruder. It only makes sense to define this section on
|
||||
# multi-extruder printers. The default is to not run any special
|
||||
# G-Code commands on deactivation.
|
||||
#activate_gcode:
|
||||
# A list of G-Code commands (one per line) to execute on a G-Code
|
||||
# tool change command (eg, "T0") that activates this extruder. It
|
||||
# only makes sense to define this section on multi-extruder
|
||||
# printers. The default is to not run any special G-Code commands on
|
||||
# activation.
|
||||
# A list of G-Code commands (one per line; subsequent lines
|
||||
# indented) to execute on a G-Code tool change command (eg, "T0")
|
||||
# that activates this extruder. It only makes sense to define this
|
||||
# section on multi-extruder printers. The default is to not run any
|
||||
# special G-Code commands on activation.
|
||||
|
||||
|
||||
# Support for cartesian printers with dual carriages on a single
|
||||
@@ -144,6 +324,18 @@
|
||||
# default is 120.
|
||||
|
||||
|
||||
# Idle timeout. An idle timeout is automatically enabled - add an
|
||||
# explicit idle_timeout config section to change the default settings.
|
||||
#[idle_timeout]
|
||||
#gcode:
|
||||
# A list of G-Code commands (one per line; subsequent lines
|
||||
# indented) to execute on an idle timeout. The default is to run
|
||||
# "TURN_OFF_HEATERS" and "M84".
|
||||
#timeout: 600
|
||||
# Idle time (in seconds) to wait before running the above G-Code
|
||||
# commands. The default is 600 seconds.
|
||||
|
||||
|
||||
# Multi-stepper axes. On a cartesian style printer, the stepper
|
||||
# controlling a given axis may have additional config blocks defining
|
||||
# steppers that should be stepped in concert with the primary
|
||||
@@ -158,57 +350,127 @@
|
||||
#endstop_pin: ^ar19
|
||||
# If an endstop_pin is defined for the additional stepper then the
|
||||
# stepper will home until the endstop is triggered. Otherwise, the
|
||||
# endstop will home until the endstop on the primary stepper for the
|
||||
# stepper will home until the endstop on the primary stepper for the
|
||||
# axis is triggered.
|
||||
|
||||
|
||||
# Stepper phase adjusted endstops. The following additional parameters
|
||||
# may be added to a stepper axis definition to improve the accuracy of
|
||||
# endstop switches.
|
||||
#[stepper_z]
|
||||
#homing_stepper_phases:
|
||||
# One may set this to the number of phases of the stepper motor
|
||||
# driver (which is the number of micro-steps multiplied by
|
||||
# four). This parameter must be provided if using stepper phase
|
||||
# adjustments.
|
||||
#homing_endstop_accuracy: 0.200
|
||||
# Stepper phase adjusted endstops. To use this feature, define a
|
||||
# config section with an "endstop_phase" prefix followed by the name
|
||||
# of the corresponding stepper config section (for example,
|
||||
# "[endstop_phase stepper_z]"). This feature can improve the accuracy
|
||||
# of endstop switches. Add a bare "[endstop_phase]" declaration to
|
||||
# enable the ENDSTOP_PHASE_CALIBRATE command.
|
||||
#[endstop_phase stepper_z]
|
||||
#phases:
|
||||
# This specifies the number of phases of the given stepper motor
|
||||
# driver (which is the number of micro-steps multiplied by four).
|
||||
# This setting is automatically determined if one uses TMC2130,
|
||||
# TMC2208, TMC2224 or TMC2660 drivers with run-time configuration.
|
||||
# Otherwise, this parameter must be provided.
|
||||
#endstop_accuracy: 0.200
|
||||
# Sets the expected accuracy (in mm) of the endstop. This represents
|
||||
# the maximum error distance the endstop may trigger (eg, if an
|
||||
# endstop may occasionally trigger 100um early or up to 100um late
|
||||
# then set this to 0.200 for 200um). The default is
|
||||
# homing_stepper_phases*step_distance.
|
||||
#homing_endstop_phase:
|
||||
# phases*step_distance.
|
||||
#endstop_phase:
|
||||
# This specifies the phase of the stepper motor driver to expect
|
||||
# when hitting the endstop. Only set this value if one is sure the
|
||||
# stepper motor driver is reset every time the mcu is reset. If this
|
||||
# is not set, then the stepper phase will be detected on the first
|
||||
# home and that phase will be used on all subsequent homes.
|
||||
#homing_endstop_align_zero: False
|
||||
# If true then the code will arrange for the zero position on the
|
||||
# axis to occur at a full step on the stepper motor. (If used on the
|
||||
# Z axis and the print layer height is a multiple of a full step
|
||||
# distance then every layer will occur on a full step.) The default
|
||||
# is False.
|
||||
#endstop_align_zero: False
|
||||
# If true then the position_endstop of the axis will effectively be
|
||||
# modified so that the zero position for the axis occurs at a full
|
||||
# step on the stepper motor. (If used on the Z axis and the print
|
||||
# layer height is a multiple of a full step distance then every
|
||||
# layer will occur on a full step.) The default is False.
|
||||
|
||||
|
||||
# Heater cooling fans (one may define any number of sections with a
|
||||
# "heater_fan" prefix). A "heater fan" is a fan that will be enabled
|
||||
# whenever its associated heater is active. In the event of an MCU
|
||||
# software error the heater_fan will be set to its max_power.
|
||||
# whenever its associated heater is active. By default, a heater_fan
|
||||
# has a shutdown_speed equal to max_power.
|
||||
#[heater_fan my_nozzle_fan]
|
||||
# See the "fan" section for fan configuration parameters.
|
||||
#pin: ar4
|
||||
# The remaining variables are specific to heater_fan.
|
||||
#pin:
|
||||
#max_power:
|
||||
#shutdown_speed:
|
||||
#cycle_time:
|
||||
#hardware_pwm:
|
||||
#kick_start_time:
|
||||
# See the "fan" section in example.cfg for a description of the
|
||||
# above parameters.
|
||||
#heater: extruder
|
||||
# Name of the config section defining the heater that this fan is
|
||||
# associated with. The default is "extruder".
|
||||
# associated with. If a comma separated list of heater names is
|
||||
# provided here, then the fan will be enabled when any of the given
|
||||
# heaters are enabled. The default is "extruder".
|
||||
#heater_temp: 50.0
|
||||
# A temperature (in Celsius) that the heater must drop below before
|
||||
# the fan is disabled. The default is 50 Celsius.
|
||||
#fan_speed:
|
||||
#fan_speed: 1.0
|
||||
# The fan speed (expressed as a value from 0.0 to 1.0) that the fan
|
||||
# will be set to when its associated heater is enabled. The default
|
||||
# is max_power.
|
||||
# is 1.0
|
||||
|
||||
|
||||
# Temperature-triggered cooling fans (one may define any number of
|
||||
# sections with a "temperature_fan" prefix). A "temperature fan" is a
|
||||
# fan that will be enabled whenever its associated sensor is above a
|
||||
# set temperature. By default, a temperature_fan has a shutdown_speed
|
||||
# equal to max_power.
|
||||
#[temperature_fan my_temp_fan]
|
||||
#pin:
|
||||
#max_power:
|
||||
#shutdown_speed:
|
||||
#cycle_time:
|
||||
#hardware_pwm:
|
||||
#kick_start_time:
|
||||
# See the "fan" section in example.cfg for a description of the
|
||||
# above parameters.
|
||||
#sensor_type: EPCOS 100K B57560G104F
|
||||
#sensor_pin: analog13
|
||||
# See the "heater" section for details about the sensor_type and
|
||||
# sensor_pin parameters.
|
||||
#min_temp: 0
|
||||
#max_temp: 100
|
||||
# The maximum range of valid temperatures (in Celsius) that the
|
||||
# sensor must remain within. This controls a safety feature
|
||||
# implemented in the micro-controller code - should the measured
|
||||
# temperature ever fall outside this range then the micro-controller
|
||||
# will go into a shutdown state. Set this range just wide enough so
|
||||
# that reasonable temperatures do not result in an error. These
|
||||
# parameters must be provided.
|
||||
#target_temp: 40.0
|
||||
# A temperature (in Celsius) that will be the target temperature.
|
||||
# The default is 40 degrees.
|
||||
#max_speed: 1.0
|
||||
# The fan speed (expressed as a value from 0.0 to 1.0) that the fan
|
||||
# will be set to when the sensor temperature exceeds the set value.
|
||||
# The default is 1.0.
|
||||
#min_speed: 0.3
|
||||
# The minimum fan speed (expressed as a value from 0.0 to 1.0) that
|
||||
# the fan will be set to when the sensor temperature is the set
|
||||
# value. The default is 0.3.
|
||||
#control: watermark
|
||||
# Control algorithm (either watermark or pid). This parameter must
|
||||
# be provided.
|
||||
#pid_Kp: 40
|
||||
# Kp is the "proportional" constant for the pid. This parameter must
|
||||
# be provided for PID heaters.
|
||||
#pid_Ki: 0.2
|
||||
# Ki is the "integral" constant for the pid. This parameter must be
|
||||
# provided for PID heaters.
|
||||
#pid_Kd: 0.1
|
||||
# Kd is the "derivative" constant for the pid. This parameter must
|
||||
# be provided for PID heaters.
|
||||
#pid_deriv_time: 2.0
|
||||
# A time value (in seconds) over which the derivative in the pid
|
||||
# will be smoothed to reduce the impact of measurement noise. The
|
||||
# default is 2 seconds.
|
||||
#pid_integral_max:
|
||||
# The maximum "windup" the integral term may accumulate. The default
|
||||
# is to use the same value as max_power.
|
||||
|
||||
|
||||
# Additional micro-controllers (one may define any number of sections
|
||||
@@ -239,7 +501,18 @@
|
||||
# The maximum pulse width time (in seconds). This should correspond
|
||||
# with an angle of maximum_servo_angle. The default is 0.002
|
||||
# seconds.
|
||||
|
||||
#initial_angle: 70
|
||||
# Initial angle to set the servo to when the mcu resets. Must be between
|
||||
# 0 and maximum_servo_angle This parameter is optional. If both
|
||||
# initial_angle and initial_pulse_width are set initial_angle will be used.
|
||||
#initial_pulse_width: 0.0015
|
||||
# Initial pulse width time (in seconds) to set the servo to when
|
||||
# the mcu resets. Must be between minimum_pulse_width and maximum_pulse_width.
|
||||
# This parameter is optional. If both initial_angle and initial_pulse_width
|
||||
# are set initial_angle will be used
|
||||
#enable: True
|
||||
# Enable or disable servo. It can be enabled or disabled later using
|
||||
# SET_SERVO SERVO=my_servo ENABLE=<0|1> g-command. The default is True (=enabled)
|
||||
|
||||
# Statically configured digital output pins (one may define any number
|
||||
# of sections with a "static_digital_output" prefix). Pins configured
|
||||
@@ -254,25 +527,25 @@
|
||||
|
||||
# Run-time configurable output pins (one may define any number of
|
||||
# sections with an "output_pin" prefix). Pins configured here will be
|
||||
# setup as output pins and one may modify them at run-time using the
|
||||
# "SET_PIN PIN=my_pin VALUE=.1" extended g-code command.
|
||||
# setup as output pins and one may modify them at run-time using
|
||||
# "SET_PIN PIN=my_pin VALUE=.1" type extended g-code commands.
|
||||
#[output_pin my_pin]
|
||||
#pin:
|
||||
# The pin to configure as an output. This parameter must be
|
||||
# provided.
|
||||
#pwm: False
|
||||
# Set if the output pin should be capable of
|
||||
# pulse-width-modulation. If this is true, the value fields should
|
||||
# be between 0 and 1; if it is false the value fields should be
|
||||
# either 0 or 1. The default is False.
|
||||
# Set if the output pin should be capable of pulse-width-modulation.
|
||||
# If this is true, the value fields should be between 0 and 1; if it
|
||||
# is false the value fields should be either 0 or 1. The default is
|
||||
# False.
|
||||
#static_value:
|
||||
# If this is set, then the pin is assigned to this value at startup
|
||||
# and the pin can not be changed during runtime. A static pin uses
|
||||
# slightly less ram in the micro-controller. The default is to use
|
||||
# runtime configuration of pins.
|
||||
#value:
|
||||
# The value to initially set the pin to during MCU
|
||||
# configuration. The default is 0 (for low voltage).
|
||||
# The value to initially set the pin to during MCU configuration.
|
||||
# The default is 0 (for low voltage).
|
||||
#shutdown_value:
|
||||
# The value to set the pin to on an MCU shutdown event. The default
|
||||
# is 0 (for low voltage).
|
||||
@@ -324,9 +597,8 @@
|
||||
# The value to statically set the given AD5206 channel to. This is
|
||||
# typically set to a number between 0.0 and 1.0 with 1.0 being the
|
||||
# highest resistance and 0.0 being the lowest resistance. However,
|
||||
# the range may be changed with the 'scale' parameter (see
|
||||
# below). If a channel is not specified then it is left
|
||||
# unconfigured.
|
||||
# the range may be changed with the 'scale' parameter (see below).
|
||||
# If a channel is not specified then it is left unconfigured.
|
||||
#scale:
|
||||
# This parameter can be used to alter how the 'channel_x' parameters
|
||||
# are interpreted. If provided, then the 'channel_x' parameters
|
||||
@@ -338,17 +610,256 @@
|
||||
# default is to not scale the 'channel_x' parameters.
|
||||
|
||||
|
||||
# Statically configured MCP4451 digipot connected via I2C bus (one may
|
||||
# define any number of sections with an "mcp4451" prefix).
|
||||
#[mcp4451 my_digipot]
|
||||
#i2c_mcu: mcu
|
||||
# The name of the micro-controller that the MCP4451 chip is
|
||||
# connected to. The default is "mcu".
|
||||
#i2c_address:
|
||||
# The i2c address that the chip is using on the i2c bus. This
|
||||
# parameter must be provided.
|
||||
#wiper_0:
|
||||
#wiper_1:
|
||||
#wiper_2:
|
||||
#wiper_3:
|
||||
# The value to statically set the given MCP4451 "wiper" to. This is
|
||||
# typically set to a number between 0.0 and 1.0 with 1.0 being the
|
||||
# highest resistance and 0.0 being the lowest resistance. However,
|
||||
# the range may be changed with the 'scale' parameter (see
|
||||
# below). If a wiper is not specified then it is left unconfigured.
|
||||
#scale:
|
||||
# This parameter can be used to alter how the 'wiper_x' parameters
|
||||
# are interpreted. If provided, then the 'wiper_x' parameters should
|
||||
# be between 0.0 and 'scale'. This may be useful when the MCP4451 is
|
||||
# used to set stepper voltage references. The 'scale' can be set to
|
||||
# the equivalent stepper amperage if the MCP4451 were at its highest
|
||||
# resistance, and then the 'wiper_x' parameters can be specified
|
||||
# using the desired amperage value for the stepper. The default is
|
||||
# to not scale the 'wiper_x' parameters.
|
||||
|
||||
|
||||
# Configure an SX1509 I2C to GPIO expander. Due to the delay incurred
|
||||
# by I2C communication you should NOT use SX1509 pins as stepper enable,
|
||||
# step or dir pins or any other pin that requires fast bit-banging. They
|
||||
# are best used as static or gcode controlled digital outputs or hardware-pwm
|
||||
# pins for e.g. fans. One may define any number of sections with an "sx1509"
|
||||
# prefix. Each expander provides a set of 16 pins (sx1509_my_sx1509:PIN_0 to
|
||||
# sx1509_my_sx1509:PIN_15) which can be used in the printer configuration.
|
||||
#[sx1509 my_sx1509]
|
||||
#address:
|
||||
# I2C address used by this expander. Depending on the hardware jumpers
|
||||
# this is one out of the following addresses: 0x3E 0x3F 0x70 0x71. This
|
||||
# parameter must be provided
|
||||
#bus: 0
|
||||
# If the I2C implementation of your microcontroller supports multiple I2C
|
||||
# busses, you may specify the bus number here. The default is 0.
|
||||
|
||||
|
||||
# Configure a TMC2130 stepper motor driver via SPI bus. To use this
|
||||
# feature, define a config section with a "tmc2130" prefix followed by
|
||||
# the name of the corresponding stepper config section (for example,
|
||||
# "[tmc2130 stepper_x]").
|
||||
#[tmc2130 stepper_x]
|
||||
#cs_pin:
|
||||
# The pin corresponding to the TMC2130 chip select line. This pin
|
||||
# will be set to low at the start of SPI messages and raised to high
|
||||
# after the message completes. This parameter must be provided.
|
||||
#microsteps:
|
||||
# The number of microsteps to configure the driver to use. Valid
|
||||
# values are 1, 2, 4, 8, 16, 32, 64, 128, 256. This parameter must
|
||||
# be provided.
|
||||
#interpolate: True
|
||||
# If true, enable step interpolation (the driver will internally
|
||||
# step at a rate of 256 micro-steps). The default is True.
|
||||
#run_current:
|
||||
# The amount of current (in amps) to configure the driver to use
|
||||
# during stepper movement. This parameter must be provided.
|
||||
#hold_current:
|
||||
# The amount of current (in amps) to configure the driver to use
|
||||
# when the stepper is not moving. The default is to use the same
|
||||
# value as run_current.
|
||||
#sense_resistor: 0.110
|
||||
# The resistance (in ohms) of the motor sense resistor. The default
|
||||
# is 0.110 ohms.
|
||||
#stealthchop_threshold: 0
|
||||
# The velocity (in mm/s) to set the "stealthChop" threshold to. When
|
||||
# set, "stealthChop" mode will be enabled if the stepper motor
|
||||
# velocity is below this value. The default is 0, which disables
|
||||
# "stealthChop" mode.
|
||||
#driver_IHOLDDELAY: 8
|
||||
#driver_TPOWERDOWN: 0
|
||||
#driver_BLANK_TIME_SELECT: 1
|
||||
#driver_TOFF: 4
|
||||
#driver_HEND: 7
|
||||
#driver_HSTRT: 0
|
||||
#driver_PWM_AUTOSCALE: True
|
||||
#driver_PWM_FREQ: 1
|
||||
#driver_PWM_GRAD: 4
|
||||
#driver_PWM_AMPL: 128
|
||||
#driver_SGT: 0
|
||||
# Set the given register during the configuration of the TMC2130
|
||||
# chip. This may be used to set custom motor parameters. The
|
||||
# defaults for each parameter are next to the parameter name in the
|
||||
# above list.
|
||||
#diag1_pin:
|
||||
# The micro-controller pin attached to the DIAG1 line of the TMC2130
|
||||
# chip. Setting this creates a "tmc2130_stepper_x:virtual_endstop"
|
||||
# virtual pin which may be used as the stepper's endstop_pin. Doing
|
||||
# this enables "sensorless homing". (Be sure to also set driver_SGT
|
||||
# to an appropriate sensitivity value.) The default is to not enable
|
||||
# sensorless homing.
|
||||
|
||||
|
||||
# Configure a TMC2208 (or TMC2224) stepper motor driver via single
|
||||
# wire UART. To use this feature, define a config section with a
|
||||
# "tmc2208" prefix followed by the name of the corresponding stepper
|
||||
# config section (for example, "[tmc2208 stepper_x]").
|
||||
#[tmc2208 stepper_x]
|
||||
#uart_pin:
|
||||
# The pin connected to the TMC2208 PDN_UART line. This parameter
|
||||
# must be provided.
|
||||
#tx_pin:
|
||||
# If using separate receive and transmit lines to communicate with
|
||||
# the driver then set uart_pin to the receive pin and tx_pin to the
|
||||
# transmit pin. The default is to use uart_pin for both reading and
|
||||
# writing.
|
||||
#microsteps:
|
||||
# The number of microsteps to configure the driver to use. Valid
|
||||
# values are 1, 2, 4, 8, 16, 32, 64, 128, 256. This parameter must
|
||||
# be provided.
|
||||
#interpolate: True
|
||||
# If true, enable step interpolation (the driver will internally
|
||||
# step at a rate of 256 micro-steps). The default is True.
|
||||
#run_current:
|
||||
# The amount of current (in amps) to configure the driver to use
|
||||
# during stepper movement. This parameter must be provided.
|
||||
#hold_current:
|
||||
# The amount of current (in amps) to configure the driver to use
|
||||
# when the stepper is not moving. The default is to use the same
|
||||
# value as run_current.
|
||||
#sense_resistor: 0.110
|
||||
# The resistance (in ohms) of the motor sense resistor. The default
|
||||
# is 0.110 ohms.
|
||||
#stealthchop_threshold: 0
|
||||
# The velocity (in mm/s) to set the "stealthChop" threshold to. When
|
||||
# set, "stealthChop" mode will be enabled if the stepper motor
|
||||
# velocity is below this value. The default is 0, which disables
|
||||
# "stealthChop" mode.
|
||||
#driver_IHOLDDELAY: 8
|
||||
#driver_TPOWERDOWN: 20
|
||||
#driver_BLANK_TIME_SELECT: 2
|
||||
#driver_TOFF: 3
|
||||
#driver_HEND: 0
|
||||
#driver_HSTRT: 5
|
||||
#driver_PWM_AUTOGRAD: True
|
||||
#driver_PWM_AUTOSCALE: True
|
||||
#driver_PWM_LIM: 12
|
||||
#driver_PWM_REG: 8
|
||||
#driver_PWM_FREQ: 1
|
||||
#driver_PWM_GRAD: 14
|
||||
#driver_PWM_OFS: 36
|
||||
# Set the given register during the configuration of the TMC2208
|
||||
# chip. This may be used to set custom motor parameters. The
|
||||
# defaults for each parameter are next to the parameter name in the
|
||||
# above list.
|
||||
|
||||
|
||||
# Configure a TMC2660 stepper motor driver via SPI bus. To use this
|
||||
# feature, define a config section with a tmc2660 prefix followed by
|
||||
# the name of the corresponding stepper config section (for example,
|
||||
# "[tmc2660 stepper_x]"). The current of the TMC2660 stepper driver
|
||||
# is adjustable at run-time using
|
||||
# "SET_TMC_CURRENT STEPPER=stepper_x CURRENT=.1" type extended g-code
|
||||
# commands.
|
||||
#[tmc2660 stepper_x]
|
||||
#cs_pin:
|
||||
# The pin corresponding to the TMC2660 chip select line. This pin
|
||||
# will be set to low at the start of SPI messages and set to high
|
||||
# after the message transfer completes. This parameter must be provided.
|
||||
#spi_bus:
|
||||
# Select the SPI bus the TMC2660 stepper driver is connected to.
|
||||
# This depends on the physical connections on your board, as well as
|
||||
# the SPI implementation of your particular micro-controller. The
|
||||
# default is bus 0.
|
||||
#spi_speed: 2000000
|
||||
# SPI bus frequency used to communicate with the TMC2660 stepper
|
||||
# driver. The default is 2000000.
|
||||
#microsteps:
|
||||
# The number of microsteps to configure the driver to use. Valid
|
||||
# values are 1, 2, 4, 8, 16, 32, 64, 128, 256. This parameter must
|
||||
# be provided.
|
||||
#interpolate: True
|
||||
# If true, enable step interpolation (the driver will internally
|
||||
# step at a rate of 256 micro-steps). This only works if microsteps
|
||||
# is set to 16. The default is True.
|
||||
#run_current:
|
||||
# The amount of current (in ampere) used by the driver during stepper
|
||||
# movement. This parameter must be provided.
|
||||
#idle_current_percent: 100
|
||||
# The percentage of the run_current the stepper driver will be
|
||||
# lowered to when the idle timeout expires (you need to set up the
|
||||
# timeout using a [idle_timeout] config section). The current will
|
||||
# be raised again once the stepper has to move again. Make sure to
|
||||
# set this to a high enough value such that the steppers do not lose
|
||||
# their position. There is also small delay until the current is
|
||||
# raised again, so take this into account when commanding fast moves
|
||||
# while the stepper is idling. The default is 100 (no reduction).
|
||||
#driver_DEDGE: False
|
||||
#driver_TBL: 36
|
||||
# Valid values are 16, 24, 36, 54.
|
||||
#driver_CHM: spreadcycle
|
||||
# Valid values are 'spreadcycle' and 'constant_toff'
|
||||
#driver_RNDTF: False
|
||||
#driver_HDEC: False
|
||||
#driver_HEND: 7 if spreadcycle is used, 3 otherwise
|
||||
#driver_HSTRT: 5 if spreadcycle is used, 4 otherwise
|
||||
#driver_TOFF: 7 if spreadcycle is used, 4 otherwise
|
||||
#driver_SEIMIN: half
|
||||
# Valid values are 'quarter' and 'half'.
|
||||
#driver_SEDN: 32
|
||||
# Valid values are 1, 2, 8, 32.
|
||||
#driver_SEMAX: 0
|
||||
#driver_SEUP: 1
|
||||
# Valid values are 1, 2, 4, 8.
|
||||
#driver_SEMIN: 0
|
||||
#driver_SFILT: True
|
||||
#driver_SGT: -64
|
||||
#driver_SLPH: min
|
||||
# Valid values are 'min', 'min_tc', 'med_tc', 'max'
|
||||
#driver_SLPL: min
|
||||
# Valid values are 'min', 'med', 'max'
|
||||
#driver_DISS2G: False
|
||||
#driver_TS2G: 0.8
|
||||
# Valid values are 0.8, 1.2, 1.6, 3.2.
|
||||
#driver_VSENSE: high
|
||||
# Valid values are 'high' and 'low'
|
||||
#
|
||||
# Set the given parameter during the configuration of the TMC2660
|
||||
# chip. This may be used to set custom driver parameters. The
|
||||
# defaults for each parameter are next to the parameter name in the
|
||||
# list above. See the TMC2660 datasheet about what each parameter
|
||||
# does and what the restrictions on parameter combinations are.
|
||||
|
||||
|
||||
# Homing override. One may use this mechanism to run a series of
|
||||
# g-code commands in place of a G28 found in the normal g-code input.
|
||||
# This may be useful on printers that require a specific procedure to
|
||||
# home the machine.
|
||||
#[homing_override]
|
||||
#gcode:
|
||||
# A list of G-Code commands (one per line) to execute in place of
|
||||
# all G28 commands found in the normal g-code input. If a G28 is
|
||||
# contained in this list of commands then it will invoke the normal
|
||||
# homing procedure for the printer. The commands listed here must
|
||||
# home all axes. This parameter must be provided.
|
||||
# A list of G-Code commands (one per line; subsequent lines
|
||||
# indented) to execute in place of G28 commands found in the normal
|
||||
# g-code input. If a G28 is contained in this list of commands then
|
||||
# it will invoke the normal homing procedure for the printer. The
|
||||
# commands listed here must home all axes. This parameter must be
|
||||
# provided.
|
||||
#axes: xyz
|
||||
# The axes to override. For example, if this is set to "z" then the
|
||||
# override script will only be run when the z axis is homed (eg, via
|
||||
# a "G28" or "G28 Z0" command). Note, the override script should
|
||||
# still home all axes. The default is "xyz" which causes the
|
||||
# override script to be run in place of all G28 commands.
|
||||
#set_position_x:
|
||||
#set_position_y:
|
||||
#set_position_z:
|
||||
@@ -359,6 +870,15 @@
|
||||
# axis. The default is to not force a position for an axis.
|
||||
|
||||
|
||||
# Support manually moving stepper motors for diagnostic purposes.
|
||||
# Note, using this feature may place the printer in an invalid state -
|
||||
# see docs/G-Codes.md for important details.
|
||||
#[force_move]
|
||||
#enable_force_move: False
|
||||
# Set to true to enable FORCE_MOVE and SET_KINEMATIC_POSITION
|
||||
# extended G-Code commands. The default is false.
|
||||
|
||||
|
||||
# A virtual sdcard may be useful if the host machine is not fast
|
||||
# enough to run OctoPrint well. It allows the Klipper host software to
|
||||
# directly print gcode files stored in a directory on the host using
|
||||
@@ -375,24 +895,157 @@
|
||||
# Support for a display attached to the micro-controller.
|
||||
#[display]
|
||||
#lcd_type:
|
||||
# The type of LCD chip in use. This may be either "hd44780" (which
|
||||
# is used in "RepRapDiscount 2004 Smart Controller" type displays)
|
||||
# or "st7920" (which is used in "RepRapDiscount 12864 Full Graphic
|
||||
# Smart Controller" type displays). This parameter must be
|
||||
# provided.
|
||||
# The type of LCD chip in use. This may be "hd44780" (which is used
|
||||
# in "RepRapDiscount 2004 Smart Controller" type displays), "st7920"
|
||||
# (which is used in "RepRapDiscount 12864 Full Graphic Smart
|
||||
# Controller" type displays), "uc1701" (which is used in "MKS Mini
|
||||
# 12864" type displays), or "ssd1306". This parameter must be
|
||||
# provided.
|
||||
#rs_pin:
|
||||
#e_pin:
|
||||
#d4_pin:
|
||||
#d5_pin:
|
||||
#d6_pin:
|
||||
#d7_pin:
|
||||
# The pins connected to an hd44780 type lcd. These parameters must
|
||||
# be provided when using an hd44780 display.
|
||||
# The pins connected to an hd44780 type lcd. These parameters must
|
||||
# be provided when using an hd44780 display.
|
||||
#cs_pin:
|
||||
#sclk_pin:
|
||||
#sid_pin:
|
||||
# The pins connected to an st7920 type lcd. These parameters must
|
||||
# be provided when using an st7920 display.
|
||||
# The pins connected to an st7920 type lcd. These parameters must be
|
||||
# provided when using an st7920 display.
|
||||
#cs_pin:
|
||||
#a0_pin:
|
||||
# The pins connected to an uc1701 type lcd. These parameters must be
|
||||
# provided when using an uc1701 display.
|
||||
#cs_pin:
|
||||
#dc_pin:
|
||||
# The pins connected to an ssd1306 type lcd when in "4-wire" spi
|
||||
# mode. The default is to use i2c mode for ssd1306 displays.
|
||||
#menu_root:
|
||||
# Entry point for menu, root menu container name. If this parameter
|
||||
# is not provided then default menu root is used. When provided
|
||||
# menu entry is 'deck' type then it'll be initiated immediately at startup.
|
||||
# Description of menu items is located in example-menu.cfg file.
|
||||
#menu_timeout:
|
||||
# Timeout for menu. Being inactive this amount of seconds will trigger
|
||||
# menu exit or return to root menu when having autorun enabled.
|
||||
# The default is 0 seconds (disabled)
|
||||
#encoder_pins:
|
||||
# The pins connected to encoder. 2 pins must be provided when
|
||||
# using encoder. This parameter must be provided when using menu.
|
||||
#click_pin:
|
||||
# The pin connected to 'enter' button or encoder 'click'. This parameter
|
||||
# must be provided when using menu.
|
||||
#back_pin:
|
||||
# The pin connected to 'back' button. This parameter is optional, menu
|
||||
# can be used without it.
|
||||
#up_pin:
|
||||
# The pin connected to 'up' button. This parameter must be provided
|
||||
# when using menu without encoder.
|
||||
#down_pin:
|
||||
# The pin connected to 'down' button. This parameter must be provided
|
||||
# when using menu without encoder.
|
||||
#kill_pin:
|
||||
# The pin connected to 'kill' button. This button will call
|
||||
# emergency stop.
|
||||
|
||||
|
||||
# Custom thermistors (one may define any number of sections with a
|
||||
# "thermistor" prefix). A custom thermistor may be used in the
|
||||
# sensor_type field of a heater config section. (For example, if one
|
||||
# defines a "[thermistor my_thermistor]" section then one may use a
|
||||
# "sensor_type: my_thermistor" when defining a heater.) Be sure to
|
||||
# place the thermistor section in the config file above its first use
|
||||
# in a heater section.
|
||||
#[thermistor my_thermistor]
|
||||
#temperature1:
|
||||
#resistance1:
|
||||
#temperature2:
|
||||
#resistance2:
|
||||
#temperature3:
|
||||
#resistance3:
|
||||
# Three resistance measurements (in Ohms) at the given temperatures
|
||||
# (in Celsius). The three measurements will be used to calculate the
|
||||
# Steinhart-Hart coefficients for the thermistor. These parameters
|
||||
# must be provided when using Steinhart-Hart to define the
|
||||
# thermistor.
|
||||
#beta:
|
||||
# Alternatively, one may define temperature1, resistance1, and beta
|
||||
# to define the thermistor parameters. This parameter must be
|
||||
# provided when using "beta" to define the thermistor.
|
||||
|
||||
|
||||
# Custom ADC temperature sensors (one may define any number of
|
||||
# sections with an "adc_temperature" prefix). This allows one to
|
||||
# define a custom temperature sensor that measures a voltage on an
|
||||
# Analog to Digital Converter (ADC) pin and uses linear interpolation
|
||||
# between a set of configured temperature/voltage measurements to
|
||||
# determine the temperature. The resulting sensor can be used as a
|
||||
# sensor_type in a heater section. (For example, if one defines a
|
||||
# "[adc_temperature my_sensor]" section then one may use a
|
||||
# "sensor_type: my_sensor" when defining a heater.) Be sure to place
|
||||
# the sensor section in the config file above its first use in a
|
||||
# heater section.
|
||||
#[adc_temperature my_sensor]
|
||||
#temperature1:
|
||||
#voltage1:
|
||||
#temperature2:
|
||||
#voltage2:
|
||||
#...
|
||||
# A set of temperatures (in Celsius) and voltages (in Volts) to use
|
||||
# as reference when converting a temperature. At least two
|
||||
# measurements must be provided.
|
||||
|
||||
|
||||
# MAXxxxxx serial peripheral interface (SPI) temperature based
|
||||
# sensors. The following parameters are available in heater sections
|
||||
# that use one of these sensor types.
|
||||
#[extruder]
|
||||
# See the "extruder" section in example.cfg for a description of
|
||||
# heater parameters. The parameters below describe sensor parameters.
|
||||
#sensor_type:
|
||||
# One of "MAX6675", "MAX31855", "MAX31856", or "MAX31865".
|
||||
#spi_speed: 4000000
|
||||
# The SPI speed (in hz) to use when communicating with the chip.
|
||||
# The default is 4000000.
|
||||
#sensor_pin:
|
||||
# The chip select line for the sensor chip. This parameter must be
|
||||
# provided.
|
||||
#tc_type: K
|
||||
#tc_use_50Hz_filter: False
|
||||
#tc_averaging_count: 1
|
||||
# The above parameters control the sensor parameters of MAX31856
|
||||
# chips. The defaults for each parameter are next to the parameter
|
||||
# name in the above list.
|
||||
#rtd_nominal_r: 100
|
||||
#rtd_reference_r: 430
|
||||
#rtd_num_of_wires: 2
|
||||
#rtd_use_50Hz_filter: False
|
||||
# The above parameters control the sensor parameters of MAX31865
|
||||
# chips. The defaults for each parameter are next to the parameter
|
||||
# name in the above list.
|
||||
|
||||
|
||||
# G-Code macros (one may define any number of sections with a
|
||||
# "gcode_macro" prefix).
|
||||
#[gcode_macro my_cmd]
|
||||
#gcode:
|
||||
# A list of G-Code commands (one per line; subsequent lines
|
||||
# indented) to execute in place of "my_cmd". This parameter is
|
||||
# evaluated using Python "string format syntax" with the command
|
||||
# parameters as named arguments. For example, if one were to define
|
||||
# a macro MY_DELAY with gcode "G4 P{DELAY}" then the command
|
||||
# "MY_DELAY DELAY=100" would evaluate to "G4 P100". This parameter
|
||||
# must be provided.
|
||||
#default_parameter_<parameter>:
|
||||
# One may define any number of options with a "default_parameter_"
|
||||
# prefix. Use this to define default values for g-code parameters.
|
||||
# For example, if one were to define the macro MY_DELAY with gcode
|
||||
# "G4 P{DELAY}" along with "default_parameter_DELAY = 50" then the
|
||||
# command "MY_DELAY" would evaluate to "G4 P50". The default is to
|
||||
# require that all parameters used in the gcode script be present in
|
||||
# the command invoking the macro.
|
||||
|
||||
|
||||
# Replicape support - see the generic-replicape.cfg file for further
|
||||
|
||||
186
config/example-menu.cfg
Normal file
@@ -0,0 +1,186 @@
|
||||
# This file serves as documentation for config parameters. One may
|
||||
# copy and edit this file to configure a new menu layout.
|
||||
# The snippets in this file may be copied into the main printer.cfg file.
|
||||
# See the "example.cfg" file for description of common config parameters.
|
||||
|
||||
# Available menu elements:
|
||||
# item - purely visual element
|
||||
# command - same like 'item' but with gcode trigger
|
||||
# input - same like 'command' but has value changing capabilities
|
||||
# list - menu element container, with entry and exit gcode triggers
|
||||
# vsdcard - same as 'list' but will append files from virtual sdcard
|
||||
# deck - special container for custom screens (cards) has entry and exit gcode triggers.
|
||||
# card - special content card for custom screens. Can only be used in 'deck'!
|
||||
|
||||
#[menu item1]
|
||||
#type: item
|
||||
# Type will determine menu item properties and behaviours:
|
||||
#name:
|
||||
# This is mandatory attribute for every menu element.
|
||||
# You can use Python output formatting for parameter and transform values.
|
||||
# Quotes can be used in the beginning and end of name.
|
||||
#cursor:
|
||||
# It allows to change cursor character for selected menu element.
|
||||
# The default is >
|
||||
# This parameter is optional.
|
||||
#width:
|
||||
# This attribute accepts integer value. Element name is cut to this width.
|
||||
# This parameter is optional.
|
||||
#scroll:
|
||||
# This attribute accepts static boolean value. You can use it together with 'width'.
|
||||
# When this is enabled then names longer than width are scrolled back and forth.
|
||||
# The default is disabled. This parameter is optional.
|
||||
#enable:
|
||||
# This attribute accepts static boolean values and parameters (converted to boolean).
|
||||
# It accepts multiple logical expressions. Values separated by comma will return True if all elements are true.
|
||||
# Values on different lines will return True if any element is true.
|
||||
# You can use logical negation by using character ! as parameter prefix.
|
||||
#parameter:
|
||||
# This attribute accepts float values or special variables. Multiple values are delimited by comma.
|
||||
# All available parameter variables can be listed by 'MENU DO=dump' gcode, menu itself must be running.
|
||||
# This value is available for output formatting as {0}..{n} Where n is count of parameters.
|
||||
#transform:
|
||||
# This attribute allows to transform parameters value to something else.
|
||||
# More than one transformation can be added. Each transformation must be on separate line.
|
||||
# These transformed values are available for output formatting as {n+1}..{x}
|
||||
# Where n is count of parameters and x is count of transformations.
|
||||
# In order to transform the value of a particular parameter, you must add
|
||||
# an parameter index as prefix. Like this "transform: 1.choose('OFF','ON')"
|
||||
# If the index is not set then the default index 0 is used.
|
||||
#
|
||||
# map(fromLow,fromHigh,toLow,toHigh) - interpolate re-maps a parameter value from one range to another.
|
||||
# Output value type is taken from toHigh. It can be int or float.
|
||||
#
|
||||
# choose(e1,e2) - boolean chooser, converts the value of the parameter to the boolean type (0 and 1),
|
||||
# and selects the corresponding value by the index from the list.
|
||||
#
|
||||
# choose(e1,e2,...) - int chooser, converts the value of the parameter to the int type
|
||||
# and selects the corresponding value by the index from the list.
|
||||
#
|
||||
# choose({key:value,..}) - special dictionary chooser, parameter value cast type by first key type.
|
||||
# Selects the corresponding value by the key from the dictionary.
|
||||
#
|
||||
# int(), float(), bool(), str(), abs(), bin(), hex(), oct(), days(), hours(), minutes(), seconds()
|
||||
# These will convert parameter value to the special form.
|
||||
# int,float,bool,str,abs,bin,hex and oct are python functions.
|
||||
# days,hours,minutes,seconds will convert parameter value (it's taken as seconds) to time specific value
|
||||
#
|
||||
# scale(xx) - Multiplies parameter value by this xx. Pure interger or float value is excpected.
|
||||
|
||||
|
||||
#[menu command1]
|
||||
#type:command
|
||||
#name:
|
||||
#cursor:
|
||||
#width:
|
||||
#scroll:
|
||||
#enable:
|
||||
#parameter:
|
||||
#transform:
|
||||
#gcode:
|
||||
# When menu element is clicked then gcodes on this attribute will be executed.
|
||||
# Can have multiline gcode script and supports output formatting for parameter and transform values.
|
||||
#action:
|
||||
# Special action can be executed. Supports [back, exit] menu commands
|
||||
# and [respond response_info] command. Respond command will send '// response_info' to host.
|
||||
|
||||
#[menu input1]
|
||||
#name:
|
||||
#cursor:
|
||||
#width:
|
||||
#enable:
|
||||
#transform:
|
||||
#parameter:
|
||||
# Value from parameter (always index 0) is taken as input value when in edit mode.
|
||||
#gcode:
|
||||
# This will be triggered in realtime or on exit from edit mode.
|
||||
#reverse:
|
||||
# This attribute accepts static boolean value.
|
||||
# When enabled it will reverse increment and decrement directions for input.
|
||||
# The default is False. This parameter is optional.
|
||||
#readonly:
|
||||
# This attribute accepts same logical expression as 'enable'.
|
||||
# When true then input element is readonly like 'item' and cannot enter to edit mode.
|
||||
# The default is False. This parameter is optional.
|
||||
#realtime:
|
||||
# This attribute accepts static boolean value.
|
||||
# When enabled it will execute gcode after each value change.
|
||||
# The default is False. This parameter is optional.
|
||||
#input_min:
|
||||
# It accepts integer or float value. Will set minimal bound for edit value.
|
||||
# The default is 2.2250738585072014e-308. This parameter is optional.
|
||||
#input_max:
|
||||
# It accepts integer or float value. Will set maximal bound for edit value.
|
||||
# The default is 1.7976931348623157e+308. This parameter is optional.
|
||||
#input_step:
|
||||
# This is mandatory attribute for input.
|
||||
# It accepts positive integer or float value. Will determine increment
|
||||
# and decrement steps for edit value.
|
||||
#input_step2:
|
||||
# This is optional attribute for input.
|
||||
# It accepts positive integer or float value. Will determine fast rate
|
||||
# increment and decrement steps for edit value.
|
||||
# The default is 0 (input_step will be used instead)
|
||||
|
||||
#[menu list1]
|
||||
#type:list or vsdcard
|
||||
#name:
|
||||
#cursor:
|
||||
#width:
|
||||
#scroll:
|
||||
#enable:
|
||||
#enter_gcode:
|
||||
# Will trigger gcode script when entering to this menu container.
|
||||
# This parameter is optional.
|
||||
#leave_gcode:
|
||||
# Will trigger gcode script when leaving from this menu container.
|
||||
# This parameter is optional.
|
||||
#show_back:
|
||||
# This attribute accepts static boolean value.
|
||||
# Show back [..] as first element.
|
||||
# The default is True. This parameter is optional.
|
||||
#show_title:
|
||||
# This attribute accepts static boolean value.
|
||||
# Show container name next to back [..] element.
|
||||
# The default is True. This parameter is optional.
|
||||
#items:
|
||||
# Menu elements listed in this container.
|
||||
# Each element must be on separate line.
|
||||
# Elements can be grouped on same line by separating them with comma
|
||||
#
|
||||
# When element name stars with . then menu system will add parent
|
||||
# container config name as prefix to element name (delimited by space)
|
||||
|
||||
#[menu infodeck]
|
||||
#type: deck
|
||||
#name:
|
||||
#cursor:
|
||||
#width:
|
||||
#scroll:
|
||||
#enable:
|
||||
#enter_gcode
|
||||
#leave_gcode
|
||||
#longpress_menu:
|
||||
# Entry point to menu container. When this attribute is set then
|
||||
# long press > 1s will initiate this menu container if not in edit mode.
|
||||
# The default is disabled. This parameter is optional.
|
||||
#items:
|
||||
# It accepts only 'card' elements. You are able to switch between different card screens
|
||||
# by using encoder or up/down buttons.
|
||||
|
||||
#[menu card1]
|
||||
#type: card
|
||||
#name:
|
||||
#content:
|
||||
# Card screen content. Each line represents display line.
|
||||
# Quotes can be used in the beginning and end of line.
|
||||
# Rendered elements are available for output formatting as {0}..{x}. It's always string type.
|
||||
#items:
|
||||
# List of elements in card. Each line represents a single index for content formatting.
|
||||
# It's possible to show multiple elements in one place by separating them with comma on single line.
|
||||
# If first element is integer then timed cycle is used (integer value is cycle time in seconds)
|
||||
# If no integer element then first enabled element is shown.
|
||||
# In cycler multiple elements can be grouped into one postition by separating them with |
|
||||
# This way only simple menu items can be grouped.
|
||||
# Example: 5,prt_time, prt_progress - elements prt_time and prt_progress are switched after 5s
|
||||
# Example: msg,xpos|ypos - elements xpos and ypos are grouped and showed together when msg is disabled.
|
||||
@@ -9,17 +9,17 @@
|
||||
# micro-controllers on the printer. Typically, both the X and Y axes
|
||||
# are connected to the main micro-controller.
|
||||
[mcu]
|
||||
serial: /dev/ttyACM0
|
||||
serial: /dev/serial/by-path/platform-3f980000.usb-usb-0:1.2:1.0-port0
|
||||
pin_map: arduino
|
||||
|
||||
# The "zboard" micro-controller will be used to control the Z axis.
|
||||
[mcu zboard]
|
||||
serial: /dev/ttyACM1
|
||||
serial: /dev/serial/by-path/platform-3f980000.usb-usb-0:1.3:1.0-port0
|
||||
pin_map: arduino
|
||||
|
||||
# The "auxboard" micro-controller will be used to control the heaters.
|
||||
[mcu auxboard]
|
||||
serial: /dev/ttyACM2
|
||||
serial: /dev/serial/by-path/platform-3f980000.usb-usb-0:1.4:1.0-port0
|
||||
pin_map: arduino
|
||||
|
||||
[stepper_x]
|
||||
|
||||
@@ -51,7 +51,11 @@ position_max: 200
|
||||
# is 5mm/s.
|
||||
#homing_retract_dist: 5.0
|
||||
# Distance to backoff (in mm) before homing a second time during
|
||||
# homing. The default is 5mm.
|
||||
# homing. Set this to zero to disable the second home. The default
|
||||
# is 5mm.
|
||||
#second_homing_speed:
|
||||
# Velocity (in mm/s) of the stepper when performing the second home.
|
||||
# The default is homing_speed/2.
|
||||
#homing_positive_dir:
|
||||
# If true, homing will cause the stepper to move in a positive
|
||||
# direction (away from zero); if false, home towards zero. The
|
||||
@@ -96,29 +100,28 @@ nozzle_diameter: 0.500
|
||||
# Diameter of the nozzle orifice (in mm). This parameter must be
|
||||
# provided.
|
||||
filament_diameter: 3.500
|
||||
# Diameter of the raw filament (in mm) as it enters the
|
||||
# The nominal diameter of the raw filament (in mm) as it enters the
|
||||
# extruder. This parameter must be provided.
|
||||
#max_extrude_cross_section:
|
||||
# Maximum area of the cross section of an extrusion line (in
|
||||
# mm^2). This setting prevents excessive amounts of extrusion during
|
||||
# relatively small XY moves. If a move requests an extrusion rate
|
||||
# that would exceed this value it will cause an error to be
|
||||
# returned. The default is: 4.0 * nozzle_diameter^2
|
||||
# Maximum area (in mm^2) of an extrusion cross section (eg,
|
||||
# extrusion width multiplied by layer height). This setting prevents
|
||||
# excessive amounts of extrusion during relatively small XY moves.
|
||||
# If a move requests an extrusion rate that would exceed this value
|
||||
# it will cause an error to be returned. The default is: 4.0 *
|
||||
# nozzle_diameter^2
|
||||
#max_extrude_only_distance: 50.0
|
||||
# Maximum length (in mm of raw filament) that an extrude only move
|
||||
# may be. If an extrude only move requests a distance greater than
|
||||
# this value it will cause an error to be returned. The default is
|
||||
# 50mm.
|
||||
# Maximum length (in mm of raw filament) that a retraction or
|
||||
# extrude-only move may have. If a retraction or extrude-only move
|
||||
# requests a distance greater than this value it will cause an error
|
||||
# to be returned. The default is 50mm.
|
||||
#max_extrude_only_velocity:
|
||||
# Maximum velocity (in mm/s) of the extruder motor for extrude only
|
||||
# moves. If this is not specified then it is calculated to match the
|
||||
# limit an XY printing move with a max_extrude_cross_section
|
||||
# extrusion would have.
|
||||
#max_extrude_only_accel:
|
||||
# Maximum acceleration (in mm/s^2) of the extruder motor for extrude
|
||||
# only moves. If this is not specified then it is calculated to
|
||||
# match the limit an XY printing move with a
|
||||
# max_extrude_cross_section extrusion would have.
|
||||
# Maximum velocity (in mm/s) and acceleration (in mm/s^2) of the
|
||||
# extruder motor for retractions and extrude-only moves. These
|
||||
# settings do not place any limit on normal printing moves. If not
|
||||
# specified then they are calculated to match the limit an XY
|
||||
# printing move with a cross section of 4.0*nozzle_diameter^2 would
|
||||
# have.
|
||||
#pressure_advance: 0.0
|
||||
# The amount of raw filament to push into the extruder during
|
||||
# extruder acceleration. An equal amount of filament is retracted
|
||||
@@ -146,8 +149,12 @@ heater_pin: ar10
|
||||
# periods) to the heater. The default is 1.0.
|
||||
sensor_type: EPCOS 100K B57560G104F
|
||||
# Type of sensor - this may be "EPCOS 100K B57560G104F", "ATC
|
||||
# Semitec 104GT-2", "NTC 100K beta 3950", or "AD595". This parameter
|
||||
# must be provided.
|
||||
# Semitec 104GT-2", "NTC 100K beta 3950", "Honeywell 100K
|
||||
# 135-104LAG-J01", "NTC 100K MGB18-104F39050L32", "AD595", "PT100
|
||||
# INA826", "MAX6675", "MAX31855", "MAX31856", or "MAX31865".
|
||||
# Additional sensor types may be available - see the
|
||||
# example-extras.cfg file for details. This parameter must be
|
||||
# provided.
|
||||
sensor_pin: analog13
|
||||
# Analog input pin connected to the sensor. This parameter must be
|
||||
# provided.
|
||||
@@ -157,7 +164,11 @@ sensor_pin: analog13
|
||||
# thermistor. The default is 4700 ohms.
|
||||
#adc_voltage: 5.0
|
||||
# The ADC comparison voltage. This parameter is only valid when the
|
||||
# sensor is an AD595. The default is 5 volts.
|
||||
# sensor is an AD595 or "PT100 INA826". The default is 5 volts.
|
||||
#smooth_time: 2.0
|
||||
# A time value (in seconds) over which temperature measurements will
|
||||
# be smoothed to reduce the impact of measurement noise. The default
|
||||
# is 2 seconds.
|
||||
control: pid
|
||||
# Control algorithm (either pid or watermark). This parameter must
|
||||
# be provided.
|
||||
@@ -170,10 +181,6 @@ pid_Ki: 1.08
|
||||
pid_Kd: 114
|
||||
# Kd is the "derivative" constant for the pid. This parameter must
|
||||
# be provided for PID heaters.
|
||||
#pid_deriv_time: 2.0
|
||||
# A time value (in seconds) over which the derivative in the pid
|
||||
# will be smoothed to reduce the impact of measurement noise. The
|
||||
# default is 2 seconds.
|
||||
#pid_integral_max:
|
||||
# The maximum "windup" the integral term may accumulate. The default
|
||||
# is to use the same value as max_power.
|
||||
@@ -222,7 +229,14 @@ pin: ar9
|
||||
# enabled for extended periods, while a value of 0.5 would allow the
|
||||
# pin to be enabled for no more than half the time. This setting may
|
||||
# be used to limit the total power output (over extended periods) to
|
||||
# the fan. The default is 1.0.
|
||||
# the fan. If this value is less than 1.0 then fan speed requests
|
||||
# will be scaled between zero and max_power (for example, if
|
||||
# max_power is .9 and a fan speed of 80% is requested then the fan
|
||||
# power will be set to 72%). The default is 1.0.
|
||||
#shutdown_speed: 0
|
||||
# The desired fan speed (expressed as a value from 0.0 to 1.0) if
|
||||
# the micro-controller software enters an error state. The default
|
||||
# is 0.
|
||||
#cycle_time: 0.010
|
||||
# The amount of time (in seconds) for each PWM power cycle to the
|
||||
# fan. It is recommended this be 10 milliseconds or greater when
|
||||
@@ -237,7 +251,9 @@ pin: ar9
|
||||
# Micro-controller information.
|
||||
[mcu]
|
||||
serial: /dev/ttyACM0
|
||||
# The serial port to connect to the MCU. The default is /dev/ttyS0
|
||||
# The serial port to connect to the MCU. If unsure (or if it
|
||||
# changes) see the "Where's my serial port?" section of the FAQ. The
|
||||
# default is /dev/ttyS0
|
||||
#baud: 250000
|
||||
# The baud rate to use. The default is 250000.
|
||||
pin_map: arduino
|
||||
@@ -281,14 +297,16 @@ max_z_accel: 30
|
||||
# mm/s^2) of movement along the z axis. It limits the acceleration
|
||||
# of the z stepper motor on cartesian printers. The default is to
|
||||
# use max_accel for max_z_accel.
|
||||
#motor_off_time: 600
|
||||
# Time (in seconds) of idle time before the printer will try to
|
||||
# disable active motors. The default is 600 seconds.
|
||||
#junction_deviation: 0.02
|
||||
# Distance (in mm) used to control the internal approximated
|
||||
# centripetal velocity cornering algorithm. A larger number will
|
||||
# permit higher "cornering speeds" at the junction of two moves. The
|
||||
# default is 0.02mm.
|
||||
#square_corner_velocity: 5.0
|
||||
# The maximum velocity (in mm/s) that the toolhead may travel a 90
|
||||
# degree corner at. A non-zero value can reduce changes in extruder
|
||||
# flow rates by enabling instantaneous velocity changes of the
|
||||
# toolhead during cornering. This value configures the internal
|
||||
# centripetal velocity cornering algorithm; corners with angles
|
||||
# larger than 90 degrees will have a higher cornering velocity while
|
||||
# corners with angles less than 90 degrees will have a lower
|
||||
# cornering velocity. If this is set to zero then the toolhead will
|
||||
# decelerate to zero at each corner. The default is 5mm/s.
|
||||
|
||||
|
||||
# Looking for more options? Check the example-extras.cfg file.
|
||||
|
||||
@@ -49,7 +49,7 @@ filament_diameter: 1.750
|
||||
heater_pin: P9_15
|
||||
sensor_type: EPCOS 100K B57560G104F
|
||||
pullup_resistor: 2000
|
||||
sensor_pin: P9_36
|
||||
sensor_pin: host:analog5
|
||||
control: pid
|
||||
pid_Kp: 22.2
|
||||
pid_Ki: 1.08
|
||||
@@ -61,7 +61,7 @@ max_temp: 250
|
||||
heater_pin: P8_11
|
||||
sensor_type: EPCOS 100K B57560G104F
|
||||
pullup_resistor: 2000
|
||||
sensor_pin: P9_33
|
||||
sensor_pin: host:analog4
|
||||
control: watermark
|
||||
min_temp: 0
|
||||
max_temp: 130
|
||||
@@ -73,6 +73,9 @@ pin: P9_41
|
||||
serial: /dev/rpmsg_pru30
|
||||
pin_map: beaglebone
|
||||
|
||||
[mcu host]
|
||||
serial: /tmp/klipper_host_mcu
|
||||
|
||||
[printer]
|
||||
kinematics: cartesian
|
||||
max_velocity: 300
|
||||
|
||||
362
config/generic-duet2.cfg
Normal file
@@ -0,0 +1,362 @@
|
||||
# This file contains common pin mappings for Duet2 boards. To use
|
||||
# this config, the firmware should be compiled for the SAM4E8E.
|
||||
|
||||
# See the example.cfg file for a description of available parameters.
|
||||
|
||||
## Drivers
|
||||
# Here are the pins for the 10 stepper drivers supported by a Duet2 board
|
||||
# | Drive | DIR pin | STEP pin | ENDSTOP pin | SPI EN pin |
|
||||
# |-------|----------|-----------|--------------|-------------|
|
||||
# | X | PD11 | PD6 | PC14 | PD14 |
|
||||
# | Y | PD12 | PD7 | PA2 | PC9 |
|
||||
# | Z | PD13 | PD8 | PD29 | PC10 |
|
||||
# | E0 | PA1 | PD5 | PD10 | PC17 |
|
||||
# | E1 | PD9 | PD4 | PC16 | PC25 |
|
||||
# | E2 | PD28 | PD2 | PE0* | PD23 |
|
||||
# | E3 | PD22 | PD1 | PE1* | PD24 |
|
||||
# | E4 | PD16 | PD0 | PE2* | PD25 |
|
||||
# | E5 | PD17 | PD3 | PE3* | PD26 |
|
||||
# | E6 | PA25 | PD21 | PA17* | PC28 |
|
||||
# Pins marked with asterisks (*) are only assigned to these functions
|
||||
# if no duex is connected. If a duex is connected, these endstops are
|
||||
# remapped to the SX1509 on the Duex (unfortunately they can't be used
|
||||
# as endstops in klipper, however one may use them as digital outs or
|
||||
# PWM outs). The SPI EN pins are required for the TMC2660 drivers (use
|
||||
# the SPI EN pin as 'cs_pin' in the respective config block). The
|
||||
# **enable pin for all steppers** is TMC_EN = !PC6.
|
||||
#
|
||||
## Fans
|
||||
# | FAN | PIN |
|
||||
# |------|-----------------------|
|
||||
# | FAN0 | PC23 |
|
||||
# | FAN1 | PC26 |
|
||||
# | FAN2 | PA0 |
|
||||
# | FAN3 | sx1509_duex:PIN_12* |
|
||||
# | FAN4 | sx1509_duex:PIN_7* |
|
||||
# | FAN5 | sx1509_duex:PIN_6* |
|
||||
# | FAN6 | sx1509_duex:PIN_5* |
|
||||
# | FAN7 | sx1509_duex:PIN_4* |
|
||||
# | FAN8 | sx1509_duex:PIN_15* |
|
||||
# Pins marked with (*) assume the following sx1509 config section:
|
||||
#[sx1509 duex]
|
||||
#address: 0x3E
|
||||
#
|
||||
## Heaters and Thermistors
|
||||
# | Extruder Drive | HEAT pin | TEMP pin |
|
||||
# |----------------|-----------|-----------|
|
||||
# | BED | PA19 | PC13 |
|
||||
# | E0 | PA20 | PC15 |
|
||||
# | E1 | PA16 | PC12 |
|
||||
# | E2 | PC3 | PC29 |
|
||||
# | E3 | PC5 | PC30 |
|
||||
# | E4 | PC8 | PC31 |
|
||||
# | E5 | PC11 | PC27 |
|
||||
# | E6 | PA15 | PA18 |
|
||||
#
|
||||
## Misc pins
|
||||
# | Name | Pin |
|
||||
# |-------------|---------|
|
||||
# | ZProbe_IN | PC1 |
|
||||
# | PS_ON | PD15 |
|
||||
# | LED_ONBOARD | PC2 |
|
||||
# | SPI0_CS0 | PC24 |
|
||||
# | SPI0_CS1 | PB2 |
|
||||
# | SPI0_CS2 | PC18 |
|
||||
# | SPI0_CS3 | PC19 |
|
||||
# | SPI0_CS4 | PC20 |
|
||||
# | SPI0_CS5 | PA24 |
|
||||
# | SPI0_CS6 | PE1* |
|
||||
# | SPI0_CS7 | PE2* |
|
||||
# | SPI0_CS8 | PE3* |
|
||||
# | SX1509_IRQ | PA17* |
|
||||
# | SG_TST | PE0* |
|
||||
# | ENC_SW | PA7 |
|
||||
# | ENC_A | PA8 |
|
||||
# | ENC_B | PC7 |
|
||||
# | LCD_DB7 | PD18 |
|
||||
# | LCD_DB6 | PD19 |
|
||||
# | LCD_DB5 | PD20 |
|
||||
# | LCD_DB4 | PD21** |
|
||||
# | LCD_RS | PC28** |
|
||||
# | LCD_E | PA25** |
|
||||
# Pins marked with one asterisk (*) replace E2_STOP-E6_STOP if a duex is present
|
||||
# Pins marked with two asterisks (**) share pins with drive E6.
|
||||
# For the remaining pins check the schematics provided here: https://github.com/T3P3/Duet
|
||||
|
||||
[stepper_x]
|
||||
step_pin: PD6
|
||||
dir_pin: PD11
|
||||
enable_pin: !PC6 # shared between all steppers
|
||||
step_distance: .0125
|
||||
endstop_pin: ^PC14
|
||||
position_endstop: 0
|
||||
position_max: 250
|
||||
|
||||
[tmc2660 stepper_x]
|
||||
cs_pin: PD14 # X_SPI_EN Required for communication
|
||||
spi_bus: 1 # All TMC2660 drivers are connected to USART1, which is bus 1 on the sam4e port
|
||||
microsteps: 16
|
||||
interpolate: True # 1/16 micro-steps interpolated to 1/256
|
||||
run_current: 1.000
|
||||
idle_current_percent: 20
|
||||
|
||||
[stepper_y]
|
||||
step_pin: PD7
|
||||
dir_pin: !PD12
|
||||
enable_pin: !PC6
|
||||
step_distance: .0125
|
||||
endstop_pin: ^PA2
|
||||
position_endstop: 0
|
||||
position_max: 210
|
||||
|
||||
[tmc2660 stepper_y]
|
||||
cs_pin: PC9
|
||||
spi_bus: 1
|
||||
microsteps: 16
|
||||
interpolate: True
|
||||
run_current: 1.000
|
||||
idle_current_percent: 20
|
||||
|
||||
[stepper_z]
|
||||
step_pin: PD8
|
||||
dir_pin: PD13
|
||||
enable_pin: !PC6
|
||||
step_distance: .0025
|
||||
endstop_pin: ^PD29
|
||||
position_endstop: 0.5
|
||||
position_max: 200
|
||||
|
||||
[tmc2660 stepper_z]
|
||||
cs_pin: PC10
|
||||
spi_bus: 1
|
||||
microsteps: 16
|
||||
interpolate: True
|
||||
run_current: 1.000
|
||||
|
||||
#On drive E4
|
||||
[stepper_z1]
|
||||
step_pin: PD0
|
||||
dir_pin: PD16
|
||||
enable_pin: !PC6
|
||||
step_distance: .0025
|
||||
|
||||
[tmc2660 stepper_z1]
|
||||
cs_pin: PD25
|
||||
spi_bus: 1
|
||||
microsteps: 16
|
||||
interpolate: True
|
||||
run_current: 1.000
|
||||
|
||||
#On drive E5
|
||||
[stepper_z2]
|
||||
step_pin: PD3
|
||||
dir_pin: !PD17
|
||||
enable_pin: !PC6
|
||||
step_distance: .0025
|
||||
|
||||
[tmc2660 stepper_z2]
|
||||
cs_pin: PD26
|
||||
spi_bus: 1
|
||||
microsteps: 16
|
||||
interpolate: True
|
||||
run_current: 1.000
|
||||
|
||||
#On drive E6
|
||||
[stepper_z3]
|
||||
step_pin: PD21
|
||||
dir_pin: !PA25
|
||||
enable_pin: !PC6
|
||||
step_distance: .0025
|
||||
|
||||
[tmc2660 stepper_z3]
|
||||
cs_pin: PC28
|
||||
spi_bus: 1
|
||||
microsteps: 16
|
||||
interpolate: True
|
||||
run_current: 1.000
|
||||
|
||||
#On drive E0
|
||||
[extruder0]
|
||||
step_pin: PD5
|
||||
dir_pin: PA1
|
||||
enable_pin: !PC6
|
||||
step_distance: .002
|
||||
nozzle_diameter: 0.400
|
||||
filament_diameter: 1.750
|
||||
heater_pin: PA20
|
||||
sensor_type: EPCOS 100K B57560G104F
|
||||
sensor_pin: PC15
|
||||
control: pid
|
||||
pid_Kp: 22.2
|
||||
pid_Ki: 1.08
|
||||
pid_Kd: 114
|
||||
min_temp: 0
|
||||
max_temp: 250
|
||||
|
||||
[tmc2660 extruder0]
|
||||
cs_pin: PC17
|
||||
spi_bus: 1
|
||||
microsteps: 16
|
||||
interpolate: True
|
||||
run_current: 1.000
|
||||
|
||||
#On drive E1
|
||||
[extruder1]
|
||||
step_pin: PD4
|
||||
dir_pin: PD9
|
||||
enable_pin: !PC6
|
||||
step_distance: .002
|
||||
nozzle_diameter: 0.400
|
||||
filament_diameter: 1.750
|
||||
heater_pin: PA16
|
||||
sensor_type: EPCOS 100K B57560G104F
|
||||
sensor_pin: PC12
|
||||
control: pid
|
||||
pid_Kp: 22.2
|
||||
pid_Ki: 1.08
|
||||
pid_Kd: 114
|
||||
min_temp: 0
|
||||
max_temp: 250
|
||||
|
||||
[tmc2660 extruder1]
|
||||
cs_pin: PC25
|
||||
spi_bus: 1
|
||||
microsteps: 16
|
||||
interpolate: True
|
||||
run_current: 1.000
|
||||
|
||||
# On drive E2
|
||||
[extruder2]
|
||||
step_pin: PD2
|
||||
dir_pin: !PD28
|
||||
enable_pin: !PC6
|
||||
step_distance: .002
|
||||
nozzle_diameter: 0.400
|
||||
filament_diameter: 1.750
|
||||
heater_pin: PC3
|
||||
sensor_type: EPCOS 100K B57560G104F
|
||||
sensor_pin: PC29
|
||||
control: pid
|
||||
pid_Kp: 22.2
|
||||
pid_Ki: 1.08
|
||||
pid_Kd: 114
|
||||
min_temp: 0
|
||||
max_temp: 250
|
||||
|
||||
[tmc2660 extruder2]
|
||||
cs_pin: PD23
|
||||
spi_bus: 1
|
||||
microsteps: 16
|
||||
interpolate: True
|
||||
run_current: 1.000
|
||||
|
||||
# On drive E3
|
||||
[extruder3]
|
||||
step_pin: PD1
|
||||
dir_pin: !PD22
|
||||
enable_pin: !PC6
|
||||
step_distance: .002
|
||||
nozzle_diameter: 0.400
|
||||
filament_diameter: 1.750
|
||||
heater_pin: PC5
|
||||
sensor_type: EPCOS 100K B57560G104F
|
||||
sensor_pin: PC30
|
||||
control: pid
|
||||
pid_Kp: 22.2
|
||||
pid_Ki: 1.08
|
||||
pid_Kd: 114
|
||||
min_temp: 0
|
||||
max_temp: 250
|
||||
|
||||
[tmc2660 extruder3]
|
||||
cs_pin: PD24
|
||||
spi_bus: 1
|
||||
microsteps: 16
|
||||
interpolate: True
|
||||
run_current: 1.000
|
||||
|
||||
[heater_bed]
|
||||
heater_pin: PA19
|
||||
sensor_type: EPCOS 100K B57560G104F
|
||||
sensor_pin: PC13
|
||||
control: watermark
|
||||
min_temp: 0
|
||||
max_temp: 130
|
||||
|
||||
# Fan0
|
||||
[fan]
|
||||
pin: PC23
|
||||
|
||||
# Fan1 controlled by extruder0
|
||||
[heater_fan nozzle_cooling_fan]
|
||||
pin: PC26
|
||||
heater: extruder0
|
||||
heater_temp: 45
|
||||
fan_speed: 1.0
|
||||
|
||||
# Fan2, controlled by E5_TEMP
|
||||
[temperature_fan chamber_fan]
|
||||
pin: PA0
|
||||
max_power: 1
|
||||
shutdown_speed: 1
|
||||
cycle_time: 0.01
|
||||
min_temp: 40
|
||||
max_temp: 120
|
||||
sensor_type: EPCOS 100K B57560G104F
|
||||
sensor_pin: PC27
|
||||
control: pid
|
||||
pid_Kp: 22.2
|
||||
pid_Ki: 1.08
|
||||
pid_Kd: 114
|
||||
|
||||
[mcu]
|
||||
serial: /dev/ttyACM0
|
||||
restart_method: command
|
||||
|
||||
[sx1509 duex]
|
||||
address: 0x3E # Address is fixed on duex boards
|
||||
|
||||
[printer]
|
||||
kinematics: cartesian
|
||||
max_velocity: 300
|
||||
max_accel: 3000
|
||||
max_z_velocity: 5
|
||||
max_z_accel: 100
|
||||
|
||||
[static_digital_output onboard_led]
|
||||
pins: !PC2
|
||||
|
||||
[output_pin FAN3]
|
||||
pin: !sx1509_duex:PIN_12
|
||||
pwm: True
|
||||
hardware_pwm: True # Only hardware PWM fans are supported
|
||||
|
||||
[output_pin FAN4]
|
||||
pin: !sx1509_duex:PIN_7
|
||||
pwm: True
|
||||
hardware_pwm: True
|
||||
|
||||
[output_pin FAN5]
|
||||
pin: !sx1509_duex:PIN_6
|
||||
pwm: True
|
||||
hardware_pwm: True
|
||||
|
||||
[output_pin FAN6]
|
||||
pin: !sx1509_duex:PIN_5
|
||||
pwm: True
|
||||
hardware_pwm: True
|
||||
|
||||
[output_pin FAN7]
|
||||
pin: !sx1509_duex:PIN_4
|
||||
pwm: True
|
||||
hardware_pwm: True
|
||||
|
||||
[output_pin FAN8]
|
||||
pin: !sx1509_duex:PIN_15
|
||||
pwm: True
|
||||
hardware_pwm: True
|
||||
|
||||
[output_pin GPIO1] # General purpose pin broken out on the duex
|
||||
pin: sx1509_duex:PIN_11
|
||||
pwm: False
|
||||
value: 1
|
||||
106
config/generic-einsy-rambo.cfg
Normal file
@@ -0,0 +1,106 @@
|
||||
# This file contains common pin mappings for Einsy Rambo boards. To use
|
||||
# this config, the firmware should be compiled for the AVR atmega2560.
|
||||
|
||||
# See the example.cfg file for a description of available parameters.
|
||||
|
||||
[stepper_x]
|
||||
step_pin: PC0
|
||||
dir_pin: PL0
|
||||
enable_pin: !PA7
|
||||
step_distance: .005
|
||||
endstop_pin: ^PB6
|
||||
#endstop_pin: tmc2130_stepper_x:virtual_endstop
|
||||
position_endstop: 0
|
||||
position_max: 250
|
||||
|
||||
[tmc2130 stepper_x]
|
||||
cs_pin: PG0
|
||||
microsteps: 16
|
||||
run_current: .5
|
||||
sense_resistor: 0.220
|
||||
diag1_pin: !PK2
|
||||
|
||||
[stepper_y]
|
||||
step_pin: PC1
|
||||
dir_pin: !PL1
|
||||
enable_pin: !PA6
|
||||
step_distance: .005
|
||||
endstop_pin: ^PB5
|
||||
#endstop_pin: tmc2130_stepper_y:virtual_endstop
|
||||
position_endstop: 0
|
||||
position_max: 210
|
||||
|
||||
[tmc2130 stepper_y]
|
||||
cs_pin: PG2
|
||||
microsteps: 16
|
||||
run_current: .5
|
||||
sense_resistor: 0.220
|
||||
diag1_pin: !PK7
|
||||
|
||||
[stepper_z]
|
||||
step_pin: PC2
|
||||
dir_pin: PL2
|
||||
enable_pin: !PA5
|
||||
step_distance: .0025
|
||||
endstop_pin: ^PB4
|
||||
#endstop_pin: tmc2130_stepper_z:virtual_endstop
|
||||
position_endstop: 0.5
|
||||
position_max: 200
|
||||
|
||||
[tmc2130 stepper_z]
|
||||
cs_pin: PK5
|
||||
microsteps: 16
|
||||
run_current: .5
|
||||
sense_resistor: 0.220
|
||||
diag1_pin: !PK6
|
||||
|
||||
[extruder]
|
||||
step_pin: PC3
|
||||
dir_pin: PL6
|
||||
enable_pin: !PA4
|
||||
step_distance: .002
|
||||
nozzle_diameter: 0.400
|
||||
filament_diameter: 1.750
|
||||
heater_pin: PE5
|
||||
sensor_type: EPCOS 100K B57560G104F
|
||||
sensor_pin: PF0
|
||||
control: pid
|
||||
pid_Kp: 22.2
|
||||
pid_Ki: 1.08
|
||||
pid_Kd: 114
|
||||
min_temp: 0
|
||||
max_temp: 250
|
||||
|
||||
[tmc2130 extruder]
|
||||
cs_pin: PK4
|
||||
microsteps: 16
|
||||
run_current: .5
|
||||
sense_resistor: 0.220
|
||||
diag1_pin: !PK3
|
||||
|
||||
[heater_bed]
|
||||
heater_pin: PG5
|
||||
sensor_type: EPCOS 100K B57560G104F
|
||||
sensor_pin: PF2
|
||||
control: watermark
|
||||
min_temp: 0
|
||||
max_temp: 130
|
||||
|
||||
[fan]
|
||||
pin: PH5
|
||||
|
||||
#[heater_fan nozzle_cooling_fan]
|
||||
#pin: PH3
|
||||
|
||||
[mcu]
|
||||
serial: /dev/ttyACM0
|
||||
|
||||
[printer]
|
||||
kinematics: cartesian
|
||||
max_velocity: 300
|
||||
max_accel: 3000
|
||||
max_z_velocity: 5
|
||||
max_z_accel: 100
|
||||
|
||||
[static_digital_output yellow_led]
|
||||
pins: !PB7
|
||||
@@ -2,12 +2,12 @@
|
||||
# this config, the firmware should be compiled for the AVR
|
||||
# atmega1284p.
|
||||
|
||||
# Note, a number of Melzi boards are shipped without a bootloader. In
|
||||
# that case, an external programmer will be needed to flash a
|
||||
# bootloader to the board (for example, see
|
||||
# http://www.instructables.com/id/Flashing-a-Bootloader-to-the-CR-10/
|
||||
# ). Once that is done, one should be able to use the standard "make
|
||||
# flash" command to flash Klipper.
|
||||
# Note, a number of Melzi boards are shipped with a bootloader that
|
||||
# requires the following command to flash the board:
|
||||
# avrdude -p atmega1284p -c arduino -b 57600 -P /dev/ttyUSB0 -U out/klipper.elf.hex
|
||||
# If the above command does not work and "make flash" does not work
|
||||
# then one may need to flash a bootloader to the board - see the
|
||||
# Klipper docs/Bootloaders.md file for more information.
|
||||
|
||||
# See the example.cfg file for a description of available parameters.
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ max_z_accel: 100
|
||||
pin: PL3
|
||||
pwm: True
|
||||
scale: 2.0
|
||||
cycle_time: .002
|
||||
cycle_time: .000030
|
||||
hardware_pwm: True
|
||||
static_value: 1.3
|
||||
|
||||
@@ -86,7 +86,7 @@ static_value: 1.3
|
||||
pin: PL4
|
||||
pwm: True
|
||||
scale: 2.0
|
||||
cycle_time: .002
|
||||
cycle_time: .000030
|
||||
hardware_pwm: True
|
||||
static_value: 1.3
|
||||
|
||||
@@ -94,7 +94,7 @@ static_value: 1.3
|
||||
pin: PL5
|
||||
pwm: True
|
||||
scale: 2.0
|
||||
cycle_time: .002
|
||||
cycle_time: .000030
|
||||
hardware_pwm: True
|
||||
static_value: 1.25
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ max_temp: 130
|
||||
pin: PC6
|
||||
|
||||
[mcu]
|
||||
serial: /dev/ttyACM0
|
||||
serial: /dev/serial/by-id/usb-Klipper_Klipper_firmware_12345-if00
|
||||
|
||||
[printer]
|
||||
kinematics: cartesian
|
||||
|
||||
109
config/generic-radds.cfg
Normal file
@@ -0,0 +1,109 @@
|
||||
# This file contains common pin mappings for RADDS (v1.5) boards. To
|
||||
# use this config, the firmware should be compiled for the Arduino
|
||||
# Due.
|
||||
|
||||
# See the example.cfg file for a description of available parameters.
|
||||
|
||||
# Temp sensor pins: analog0..analog4
|
||||
# Mosfet Pins: ar7 (Heatbed), ar8, ar9, ar11, ar12, ar13
|
||||
|
||||
[stepper_x]
|
||||
step_pin: ar24
|
||||
dir_pin: ar23
|
||||
enable_pin: ar26
|
||||
step_distance: .0125
|
||||
endstop_pin: ^ar28
|
||||
#endstop_pin: ^ar34
|
||||
position_endstop: 0
|
||||
position_max: 200
|
||||
homing_speed: 50
|
||||
|
||||
[stepper_y]
|
||||
step_pin: ar17
|
||||
dir_pin: !ar16
|
||||
enable_pin: ar22
|
||||
step_distance: .0125
|
||||
endstop_pin: ^ar30
|
||||
#endstop_pin: ^ar36
|
||||
position_endstop: 0
|
||||
position_max: 200
|
||||
homing_speed: 50
|
||||
|
||||
[stepper_z]
|
||||
step_pin: ar2
|
||||
dir_pin: ar3
|
||||
enable_pin: ar15
|
||||
step_distance: .0025
|
||||
endstop_pin: ^ar32
|
||||
#endstop_pin: ^ar38
|
||||
position_endstop: 0.5
|
||||
position_max: 200
|
||||
|
||||
[extruder]
|
||||
step_pin: analog7
|
||||
dir_pin: analog6
|
||||
enable_pin: analog8
|
||||
step_distance: .002
|
||||
nozzle_diameter: 0.400
|
||||
filament_diameter: 1.750
|
||||
heater_pin: ar13
|
||||
sensor_type: EPCOS 100K B57560G104F
|
||||
sensor_pin: analog0
|
||||
control: pid
|
||||
pid_Kp: 22.2
|
||||
pid_Ki: 1.08
|
||||
pid_Kd: 114
|
||||
min_temp: 0
|
||||
max_temp: 250
|
||||
|
||||
#[extruder1]
|
||||
#step_pin: analog10
|
||||
#dir_pin: analog9
|
||||
#enable_pin: analog11
|
||||
|
||||
#[extruder2]
|
||||
#step_pin: ar51
|
||||
#dir_pin: ar53
|
||||
#enable_pin: ar49
|
||||
|
||||
[heater_bed]
|
||||
heater_pin: ar7
|
||||
sensor_type: EPCOS 100K B57560G104F
|
||||
sensor_pin: analog1
|
||||
control: watermark
|
||||
min_temp: 0
|
||||
max_temp: 130
|
||||
|
||||
[fan]
|
||||
pin: ar9
|
||||
|
||||
#[heater_fan nozzle_cooling_fan]
|
||||
#pin: ar8
|
||||
|
||||
[mcu]
|
||||
serial: /dev/ttyACM0
|
||||
pin_map: arduino
|
||||
|
||||
[printer]
|
||||
kinematics: cartesian
|
||||
max_velocity: 300
|
||||
max_accel: 3000
|
||||
max_z_velocity: 5
|
||||
max_z_accel: 100
|
||||
|
||||
# "RepRapDiscount 2004 Smart Controller" type displays
|
||||
#[display]
|
||||
#lcd_type: hd44780
|
||||
#rs_pin: ar42
|
||||
#e_pin: ar43
|
||||
#d4_pin: ar44
|
||||
#d5_pin: ar45
|
||||
#d6_pin: ar46
|
||||
#d7_pin: ar47
|
||||
|
||||
# "RepRapDiscount 128x64 Full Graphic Smart Controller" type displays
|
||||
#[display]
|
||||
#lcd_type: st7920
|
||||
#cs_pin: ar42
|
||||
#sclk_pin: ar44
|
||||
#sid_pin: ar43
|
||||
@@ -92,6 +92,8 @@ max_z_accel: 100
|
||||
#d5_pin: ar25
|
||||
#d6_pin: ar27
|
||||
#d7_pin: ar29
|
||||
#encoder_pins: ^ar31, ^ar33
|
||||
#click_pin: ^!ar35
|
||||
|
||||
# "RepRapDiscount 128x64 Full Graphic Smart Controller" type displays
|
||||
#[display]
|
||||
@@ -99,3 +101,5 @@ max_z_accel: 100
|
||||
#cs_pin: ar16
|
||||
#sclk_pin: ar23
|
||||
#sid_pin: ar17
|
||||
#encoder_pins: ^ar31, ^ar33
|
||||
#click_pin: ^!ar35
|
||||
|
||||
106
config/generic-re-arm.cfg
Normal file
@@ -0,0 +1,106 @@
|
||||
# This file contains common pin mappings for Re-Arm. To use this
|
||||
# config, the firmware should be compiled for the LPC176x.
|
||||
|
||||
# The "make flash" command does not work on the Re-Arm. Instead,
|
||||
# after running "make", copy the generated "out/klipper.bin" file to a
|
||||
# file named "firmware.bin" on an SD card and then restart the Re-Arm
|
||||
# with that SD card.
|
||||
|
||||
# See the example.cfg file for a description of available parameters.
|
||||
|
||||
[stepper_x]
|
||||
step_pin: P2.1
|
||||
dir_pin: P0.11
|
||||
enable_pin: !P0.10
|
||||
step_distance: .0125
|
||||
endstop_pin: ^P1.24
|
||||
#endstop_pin: ^P1.25
|
||||
position_endstop: 0.5
|
||||
position_min: 0
|
||||
position_max: 200
|
||||
homing_speed: 50
|
||||
|
||||
# The stepper_y section is used to describe the Y axis as well as the
|
||||
# stepper controlling the X-Y movement.
|
||||
[stepper_y]
|
||||
step_pin: P2.2
|
||||
dir_pin: P0.20
|
||||
enable_pin: !P0.19
|
||||
step_distance: .0125
|
||||
endstop_pin: ^P1.26
|
||||
#endstop_pin: ^P1.27
|
||||
position_endstop: 0
|
||||
position_max: 200
|
||||
homing_speed: 50
|
||||
|
||||
[stepper_z]
|
||||
step_pin: P2.3
|
||||
dir_pin: P0.22
|
||||
enable_pin: !P0.21
|
||||
step_distance: .0025
|
||||
endstop_pin: ^P1.29
|
||||
#endstop_pin: ^P1.28
|
||||
position_endstop: 0.5
|
||||
position_min: 0
|
||||
position_max: 200
|
||||
|
||||
[extruder]
|
||||
step_pin: P2.0
|
||||
dir_pin: P0.5
|
||||
enable_pin: !P0.4
|
||||
step_distance: .0011365
|
||||
nozzle_diameter: 0.400
|
||||
filament_diameter: 1.750
|
||||
heater_pin: P2.5
|
||||
sensor_type: EPCOS 100K B57560G104F
|
||||
sensor_pin: P0.23
|
||||
control: pid
|
||||
pid_Kp: 22.2
|
||||
pid_Ki: 1.08
|
||||
pid_Kd: 114
|
||||
min_temp: 0
|
||||
max_temp: 250
|
||||
|
||||
#[extruder1]
|
||||
#step_pin: P2.8
|
||||
#dir_pin: P2.13
|
||||
#enable_pin: !P4.29
|
||||
#heater_pin: P2.4
|
||||
#sensor_pin: P0.25
|
||||
#...
|
||||
|
||||
[heater_bed]
|
||||
heater_pin: P2.7
|
||||
sensor_type: EPCOS 100K B57560G104F
|
||||
sensor_pin: P0.24
|
||||
control: watermark
|
||||
min_temp: 0
|
||||
max_temp: 130
|
||||
|
||||
[fan]
|
||||
pin: P2.4
|
||||
|
||||
[mcu]
|
||||
serial: /dev/serial/by-id/usb-Klipper_Klipper_firmware_12345-if00
|
||||
|
||||
[printer]
|
||||
kinematics: cartesian
|
||||
max_velocity: 300
|
||||
max_accel: 3000
|
||||
max_z_velocity: 5
|
||||
max_z_accel: 100
|
||||
|
||||
|
||||
# "RepRapDiscount 128x64 Full Graphic Smart Controller" type displays
|
||||
# Re-Arm will only work with this type of display
|
||||
#[display]
|
||||
#lcd_type: st7920
|
||||
#cs_pin: P0.16
|
||||
#sclk_pin: P0.15
|
||||
#sid_pin: P0.18
|
||||
#encoder_pins: ^P3.25, ^P3.26
|
||||
#click_pin: ^!P2.11
|
||||
#kill_pin: ^!P1.22
|
||||
# Ground the buzzer pin to prevent stray voltages causing an audible "whine"
|
||||
#[static_digital_output buzzer]
|
||||
#pins: !P1.30
|
||||
115
config/generic-rumba.cfg
Normal file
@@ -0,0 +1,115 @@
|
||||
# This file contains common pin mappings for RUMBA boards. To use
|
||||
# this config, the firmware should be compiled for the AVR atmega2560.
|
||||
|
||||
# See the example.cfg file for a description of available parameters.
|
||||
|
||||
[stepper_x]
|
||||
step_pin: ar17
|
||||
dir_pin: ar16
|
||||
enable_pin: !ar48
|
||||
step_distance: .0125
|
||||
endstop_pin: ^ar37
|
||||
#endstop_pin: ^ar36
|
||||
position_endstop: 0
|
||||
position_max: 200
|
||||
homing_speed: 50
|
||||
|
||||
[stepper_y]
|
||||
step_pin: ar54
|
||||
dir_pin: !ar47
|
||||
enable_pin: !ar55
|
||||
step_distance: .0125
|
||||
endstop_pin: ^ar35
|
||||
#endstop_pin: ^ar34
|
||||
position_endstop: 0
|
||||
position_max: 200
|
||||
homing_speed: 50
|
||||
|
||||
[stepper_z]
|
||||
step_pin: ar57
|
||||
dir_pin: ar56
|
||||
enable_pin: !ar62
|
||||
step_distance: .0125
|
||||
endstop_pin: ^ar33
|
||||
#endstop_pin: ^ar32
|
||||
position_endstop: 0.5
|
||||
position_max: 200
|
||||
|
||||
[extruder]
|
||||
step_pin: ar23
|
||||
dir_pin: ar22
|
||||
enable_pin: !ar24
|
||||
step_distance: .002
|
||||
nozzle_diameter: 0.400
|
||||
filament_diameter: 1.750
|
||||
heater_pin: ar2
|
||||
sensor_type: EPCOS 100K B57560G104F
|
||||
sensor_pin: analog15
|
||||
control: pid
|
||||
pid_Kp: 22.2
|
||||
pid_Ki: 1.08
|
||||
pid_Kd: 114
|
||||
min_temp: 0
|
||||
max_temp: 250
|
||||
|
||||
#[extruder1]
|
||||
#step_pin: ar26
|
||||
#dir_pin: ar3
|
||||
#enable_pin: !ar27
|
||||
#heater_pin: ar9
|
||||
#sensor_pin: analog14
|
||||
#...
|
||||
|
||||
#[extruder2]
|
||||
#step_pin: ar29
|
||||
#dir_pin: ar6
|
||||
#enable_pin: !ar39
|
||||
#heater_pin: ar9
|
||||
#sensor_pin: analog13
|
||||
#...
|
||||
|
||||
[heater_bed]
|
||||
heater_pin: ar9
|
||||
sensor_type: NTC 100K beta 3950
|
||||
sensor_pin: analog11
|
||||
control: watermark
|
||||
min_temp: 0
|
||||
max_temp: 130
|
||||
|
||||
[fan]
|
||||
pin: ar7
|
||||
|
||||
#[heater_fan fan1]
|
||||
#pin: ar8
|
||||
|
||||
[mcu]
|
||||
serial: /dev/ttyACM0
|
||||
pin_map: arduino
|
||||
|
||||
[printer]
|
||||
kinematics: cartesian
|
||||
max_velocity: 300
|
||||
max_accel: 3000
|
||||
max_z_velocity: 5
|
||||
max_z_accel: 100
|
||||
|
||||
# "RepRapDiscount 2004 Smart Controller" type displays
|
||||
#[display]
|
||||
#lcd_type: hd44780
|
||||
#rs_pin: ar19
|
||||
#e_pin: ar42
|
||||
#d4_pin: ar18
|
||||
#d5_pin: ar38
|
||||
#d6_pin: ar41
|
||||
#d7_pin: ar40
|
||||
#encoder_pins: ^ar11, ^ar12
|
||||
#click_pin: ^!ar43
|
||||
|
||||
# "RepRapDiscount 128x64 Full Graphic Smart Controller" type displays
|
||||
#[display]
|
||||
#lcd_type: st7920
|
||||
#cs_pin: ar19
|
||||
#sclk_pin: ar18
|
||||
#sid_pin: ar42
|
||||
#encoder_pins: ^ar11, ^ar12
|
||||
#click_pin: ^!ar43
|
||||
115
config/generic-smoothieboard.cfg
Normal file
@@ -0,0 +1,115 @@
|
||||
# This file contains common pin mappings for Smoothieboard. To use
|
||||
# this config, the firmware should be compiled for the LPC176x.
|
||||
|
||||
# The "make flash" command does not work on the Smoothieboard.
|
||||
# Instead, after running "make", copy the generated "out/klipper.bin"
|
||||
# file to a file named "firmware.bin" on an SD card and then restart
|
||||
# the Smoothieboard with that SD card.
|
||||
|
||||
# See the example.cfg file for a description of available parameters.
|
||||
|
||||
[stepper_x]
|
||||
step_pin: P2.0
|
||||
dir_pin: P0.5
|
||||
enable_pin: !P0.4
|
||||
step_distance: .0125
|
||||
endstop_pin: ^P1.24
|
||||
#endstop_pin: ^P1.25
|
||||
position_endstop: 0
|
||||
position_max: 200
|
||||
homing_speed: 50
|
||||
|
||||
[stepper_y]
|
||||
step_pin: P2.1
|
||||
dir_pin: !P0.11
|
||||
enable_pin: !P0.10
|
||||
step_distance: .0125
|
||||
endstop_pin: ^P1.26
|
||||
#endstop_pin: ^P1.27
|
||||
position_endstop: 0
|
||||
position_max: 200
|
||||
homing_speed: 50
|
||||
|
||||
[stepper_z]
|
||||
step_pin: P2.2
|
||||
dir_pin: P0.20
|
||||
enable_pin: !P0.19
|
||||
step_distance: .0025
|
||||
endstop_pin: ^P1.28
|
||||
#endstop_pin: ^P1.29
|
||||
position_endstop: 0.5
|
||||
position_max: 200
|
||||
|
||||
[extruder]
|
||||
step_pin: P2.3
|
||||
dir_pin: P0.22
|
||||
enable_pin: !P0.21
|
||||
step_distance: .002
|
||||
nozzle_diameter: 0.400
|
||||
filament_diameter: 1.750
|
||||
heater_pin: P2.7
|
||||
sensor_type: EPCOS 100K B57560G104F
|
||||
sensor_pin: P0.24
|
||||
control: pid
|
||||
pid_Kp: 22.2
|
||||
pid_Ki: 1.08
|
||||
pid_Kd: 114
|
||||
min_temp: 0
|
||||
max_temp: 250
|
||||
|
||||
#[extruder1]
|
||||
#step_pin: P2.8
|
||||
#dir_pin: P2.13
|
||||
#enable_pin: !P4.29
|
||||
#heater_pin: P2.6
|
||||
#sensor_pin: P0.25
|
||||
#...
|
||||
|
||||
[heater_bed]
|
||||
heater_pin: P2.5
|
||||
sensor_type: EPCOS 100K B57560G104F
|
||||
sensor_pin: P0.23
|
||||
control: watermark
|
||||
min_temp: 0
|
||||
max_temp: 130
|
||||
|
||||
[fan]
|
||||
pin: P2.4
|
||||
|
||||
[mcu]
|
||||
serial: /dev/serial/by-id/usb-Klipper_Klipper_firmware_12345-if00
|
||||
|
||||
[printer]
|
||||
kinematics: cartesian
|
||||
max_velocity: 300
|
||||
max_accel: 3000
|
||||
max_z_velocity: 5
|
||||
max_z_accel: 100
|
||||
|
||||
[static_digital_output leds]
|
||||
pins: P1.18, P1.19, P1.20, P1.21, P4.28
|
||||
|
||||
[mcp4451 stepper_digipot1]
|
||||
i2c_address: 88
|
||||
# Scale the config so that wiper values can be specified in amps.
|
||||
scale: 2.25
|
||||
# wiper 0 is X (aka alpha), 1 is Y, 2 is Z, 3 is E0
|
||||
wiper_0: 1.0
|
||||
wiper_1: 1.0
|
||||
wiper_2: 1.0
|
||||
wiper_3: 1.0
|
||||
|
||||
[mcp4451 stepper_digipot2]
|
||||
i2c_address: 90
|
||||
scale: 2.25
|
||||
# wiper 0 is E1
|
||||
wiper_0: 1.0
|
||||
|
||||
# "RepRapDiscount 128x64 Full Graphic Smart Controller" type displays
|
||||
#[display]
|
||||
#lcd_type: st7920
|
||||
#cs_pin: P0.16
|
||||
#sclk_pin: P0.15
|
||||
#sid_pin: P0.18
|
||||
#encoder_pins: ^P3.25, ^P3.26
|
||||
#click_pin: ^!P1.30
|
||||
222
config/kit-voron2-2018.cfg
Normal file
@@ -0,0 +1,222 @@
|
||||
# This file is an example configuration for the Voron 2 CoreXY printer
|
||||
# running on two RAMPS boards. This file was created by "Maglin".
|
||||
# X/Y/E steppers/endstops/thermisters/heaters are on one MCU/RAMPS
|
||||
# board while Z steppers/mechanical switch/endstop_pin are on the
|
||||
# second MCU/RAMPS labeled z.
|
||||
|
||||
# This file is only an example - be sure to review and update it
|
||||
# according to the specifics of your printer. See the example.cfg and
|
||||
# example-extras.cfg files for a description of available parameters.
|
||||
|
||||
[mcu]
|
||||
# mcu for X/Y/E steppers main MCU
|
||||
serial: /dev/serial/by-path/platform-3f980000.usb-usb-0:1.3:1.0-port0
|
||||
pin_map: arduino
|
||||
|
||||
[mcu z]
|
||||
# mcu for the Z steppers
|
||||
serial: /dev/serial/by-path/platform-3f980000.usb-usb-0:1.2:1.0-port0
|
||||
pin_map: arduino
|
||||
|
||||
[stepper_x]
|
||||
# use preceding ! to invert logic and ^ to activate internal 5V pullup
|
||||
# this is for all pin definitions. Not all pins have interal pullups
|
||||
step_pin: ar54
|
||||
dir_pin: ar55
|
||||
enable_pin: !ar38
|
||||
step_distance: 0.0125
|
||||
endstop_pin: ^ar2
|
||||
position_min: 0
|
||||
position_endstop: 248
|
||||
position_max: 248
|
||||
homing_speed: 50
|
||||
|
||||
[stepper_y]
|
||||
step_pin: ar60
|
||||
dir_pin: ar61
|
||||
enable_pin: !ar56
|
||||
step_distance: 0.0125
|
||||
endstop_pin: ^ar15
|
||||
position_min: -5
|
||||
position_endstop: 245
|
||||
position_max: 245
|
||||
homing_speed: 50
|
||||
|
||||
[stepper_z]
|
||||
# X stepper pins on MCU Z
|
||||
step_pin: z:ar54
|
||||
dir_pin: z:ar55
|
||||
enable_pin: !z:ar38
|
||||
step_distance: 0.00625
|
||||
# probe:z_virtual_endstop is a virtual pin definition only available if
|
||||
# a probe section is defined
|
||||
#endstop_pin: probe:z_virtual_endstop
|
||||
# mechanical switch on mcu Z X min endstop pin
|
||||
endstop_pin: ^z:ar3
|
||||
position_endstop: -0.376
|
||||
position_min: -5
|
||||
position_max: 245
|
||||
homing_speed: 12
|
||||
|
||||
[stepper_z1]
|
||||
# Y stepper pins on MCU Z
|
||||
step_pin: z:ar60
|
||||
dir_pin: !z:ar61
|
||||
enable_pin: !z:ar56
|
||||
step_distance: 0.00625
|
||||
|
||||
[stepper_z2]
|
||||
# Z stepper pins on MCU Z
|
||||
step_pin: z:ar46
|
||||
dir_pin: z:ar48
|
||||
enable_pin: !z:ar62
|
||||
step_distance: 0.00625
|
||||
|
||||
[stepper_z3]
|
||||
# E0 stepper pins on MCU Z
|
||||
step_pin: z:ar26
|
||||
dir_pin: !z:ar28
|
||||
enable_pin: !z:ar24
|
||||
step_distance: 0.00625
|
||||
|
||||
# extended G-Code command Z_TILT_ADJUST can be used to level gantry
|
||||
[z_tilt]
|
||||
# belt locations from origin 0,0
|
||||
z_positions:
|
||||
-56,-17
|
||||
-56,322
|
||||
311,322
|
||||
311,-17
|
||||
# probing locations for gantry leveling
|
||||
points:
|
||||
50,50
|
||||
50,195
|
||||
195,195
|
||||
195,50
|
||||
# travel speed between probe points
|
||||
speed: 150
|
||||
# Move Z to this position for safe probing
|
||||
horizontal_move_z: 15
|
||||
|
||||
# this is required for gantry leveling and replaces your G28 command
|
||||
# with the gcode used here. Used to home X/Y/Z with mechanical switches
|
||||
[homing_override]
|
||||
set_position_z: 0
|
||||
gcode:
|
||||
G90
|
||||
G0 Z15 F600
|
||||
G28 X0 Y0
|
||||
G0 X248 Y225 F3000
|
||||
G28 Z
|
||||
G0 Z15 F6000
|
||||
|
||||
# macro to level the gantry. use G32 in the terminal to call
|
||||
[gcode_macro g32]
|
||||
gcode:
|
||||
Z_TILT_ADJUST
|
||||
Z_TILT_ADJUST
|
||||
Z_TILT_ADJUST
|
||||
G28
|
||||
G0 X125 Y125 Z125 F3600
|
||||
|
||||
# Use print_start for you slicer starting script
|
||||
[gcode_macro print_start]
|
||||
gcode:
|
||||
G1 X0 Y15 Z0.3 F7000
|
||||
G92 E0
|
||||
G1 E14 F600
|
||||
G92 E0
|
||||
G1 X60.0 E9.0 F1000.0
|
||||
G1 X100.0 E12.5 F1000.0
|
||||
G1 E12 F1000.0
|
||||
G92 E-0.5
|
||||
|
||||
# Use print_end for you slicer ending script
|
||||
[gcode_macro print_end]
|
||||
gcode:
|
||||
M104 S0
|
||||
M140 S0
|
||||
M107
|
||||
G92 E0
|
||||
G91
|
||||
G1 Z10 E-10 F3000
|
||||
G90
|
||||
G0 X125 Y245 F1000
|
||||
|
||||
[extruder]
|
||||
# on E0 stepper pins of main MCU
|
||||
step_pin: ar26
|
||||
dir_pin: ar28
|
||||
enable_pin: !ar24
|
||||
step_distance: 0.003339
|
||||
nozzle_diameter: 0.400
|
||||
filament_diameter: 1.750
|
||||
max_extrude_only_distance: 100.0
|
||||
heater_pin: ar10
|
||||
max_power: 1.0
|
||||
sensor_type: ATC Semitec 104GT-2
|
||||
sensor_pin: analog13
|
||||
control: pid
|
||||
pid_Kp: 21.759
|
||||
pid_Ki: 1.107
|
||||
pid_Kd: 106.889
|
||||
min_temp: 0
|
||||
max_temp: 300
|
||||
|
||||
# thermally controlled hotend fan
|
||||
[heater_fan my_nozzle_fan]
|
||||
# Located on Z MCU on fan D9
|
||||
pin: z:ar9
|
||||
|
||||
[probe]
|
||||
# Z_Min pins on MCU Z (must be on same MCU as steppers)
|
||||
pin: ^!z:ar18
|
||||
z_offset: 1.15
|
||||
speed: 2.0
|
||||
|
||||
[heater_bed]
|
||||
heater_pin: ar8
|
||||
# NTC 100K MGB18-104F39050L32 is for Kenovo thermistors
|
||||
sensor_type: NTC 100K MGB18-104F39050L32
|
||||
sensor_pin: analog14
|
||||
# pid gives you better control over bed heat
|
||||
control: pid
|
||||
pid_Kp: 63.832
|
||||
pid_Ki: 3.404
|
||||
pid_Kd: 299.213
|
||||
min_temp: 0
|
||||
max_temp: 130
|
||||
|
||||
# print cooling fan
|
||||
[fan]
|
||||
# On z MCU on extruder heater pin D10
|
||||
pin: z:ar10
|
||||
|
||||
# "RepRapDiscount 2004 Smart Controller" type displays
|
||||
#[display]
|
||||
#lcd_type: hd44780
|
||||
#rs_pin: ar16
|
||||
#e_pin: ar17
|
||||
#d4_pin: ar23
|
||||
#d5_pin: ar25
|
||||
#d6_pin: ar27
|
||||
#d7_pin: ar29
|
||||
|
||||
# "RepRapDiscount 128x64 Full Graphic Smart Controller" type displays
|
||||
[display]
|
||||
lcd_type: st7920
|
||||
cs_pin: ar16
|
||||
sclk_pin: ar23
|
||||
sid_pin: ar17
|
||||
|
||||
[printer]
|
||||
# settings below are the max and can't be commanded over in gcode
|
||||
kinematics: corexy
|
||||
max_velocity: 500
|
||||
max_accel: 3000
|
||||
max_z_velocity: 100
|
||||
max_z_accel: 50
|
||||
|
||||
[idle_timeout]
|
||||
# high motor off time so I don't have to relevel gantry often
|
||||
timeout: 6000
|
||||
120
config/printer-adimlab-2018.cfg
Normal file
@@ -0,0 +1,120 @@
|
||||
# This file contains pin mappings for the ADIMLab 3d printer 2018.
|
||||
# To use this config, the firmware should be compiled for the AVR atmega2560.
|
||||
|
||||
# See the example.cfg file for a description of available parameters.
|
||||
|
||||
[stepper_x]
|
||||
step_pin: ar25
|
||||
dir_pin: !ar23
|
||||
enable_pin: !ar27
|
||||
step_distance: .0125
|
||||
endstop_pin: ^!ar22
|
||||
position_min: -5
|
||||
position_endstop: -5
|
||||
position_max: 310
|
||||
homing_speed: 30.0
|
||||
|
||||
[stepper_y]
|
||||
step_pin: ar32
|
||||
dir_pin: !ar33
|
||||
enable_pin: !ar31
|
||||
step_distance: .0125
|
||||
endstop_pin: ^!ar26
|
||||
position_endstop: 0
|
||||
position_max: 310
|
||||
homing_speed: 30.0
|
||||
|
||||
[stepper_z]
|
||||
step_pin: ar35
|
||||
dir_pin: ar36
|
||||
enable_pin: !ar34
|
||||
step_distance: .0025
|
||||
endstop_pin: ^!ar29
|
||||
position_endstop: 0.0
|
||||
position_max: 400
|
||||
homing_speed: 5.0
|
||||
|
||||
[extruder]
|
||||
step_pin: ar42
|
||||
dir_pin: ar43
|
||||
enable_pin: !ar37
|
||||
step_distance: .010799
|
||||
nozzle_diameter: 0.400
|
||||
filament_diameter: 1.750
|
||||
heater_pin: ar2
|
||||
sensor_type: ATC Semitec 104GT-2
|
||||
sensor_pin: analog8
|
||||
control: pid
|
||||
pid_Kp: 15.717
|
||||
pid_Ki: 0.569
|
||||
pid_Kd: 108.451
|
||||
min_temp: 0
|
||||
max_temp: 245
|
||||
|
||||
[heater_bed]
|
||||
heater_pin: ar4
|
||||
sensor_type: EPCOS 100K B57560G104F
|
||||
sensor_pin: analog10
|
||||
control: pid
|
||||
pid_Kp: 74.883
|
||||
pid_Ki: 1.809
|
||||
pid_Kd: 775.038
|
||||
min_temp: 0
|
||||
max_temp: 110
|
||||
|
||||
[verify_heater heater_bed]
|
||||
# adjust for personal bed setup, this prevents stock heated bed from issuing
|
||||
# false positive heating errors due to slow temperature increase
|
||||
# 1 deg per 2 minutes.
|
||||
heating_gain: 1
|
||||
check_gain_time: 120
|
||||
|
||||
[mcu]
|
||||
serial: /dev/ttyUSB0
|
||||
pin_map: arduino
|
||||
|
||||
[printer]
|
||||
kinematics: cartesian
|
||||
max_velocity: 300
|
||||
max_accel: 3000
|
||||
max_z_velocity: 10
|
||||
max_z_accel: 60
|
||||
|
||||
[output_pin stepper_xy_current]
|
||||
pin: ar44
|
||||
pwm: True
|
||||
scale: 2.0
|
||||
cycle_time: .000030
|
||||
hardware_pwm: True
|
||||
static_value: 1.3
|
||||
|
||||
[output_pin stepper_z_current]
|
||||
pin: ar45
|
||||
pwm: True
|
||||
scale: 2.0
|
||||
cycle_time: .000030
|
||||
hardware_pwm: True
|
||||
static_value: 1.3
|
||||
|
||||
[output_pin stepper_e_current]
|
||||
pin: ar46
|
||||
pwm: True
|
||||
scale: 2.0
|
||||
cycle_time: .000030
|
||||
hardware_pwm: True
|
||||
static_value: 1.25
|
||||
|
||||
[display]
|
||||
lcd_type: st7920
|
||||
cs_pin: ar20
|
||||
sclk_pin: ar14
|
||||
sid_pin: ar15
|
||||
encoder_pins: ^ar41, ^ar40
|
||||
click_pin: ^!ar19
|
||||
|
||||
# The filament runout sensor (on pin ar24) is not currently supported
|
||||
# in Klipper.
|
||||
|
||||
[output_pin case_light]
|
||||
pin: ar7
|
||||
value: 1
|
||||
@@ -77,3 +77,12 @@ max_velocity: 300
|
||||
max_accel: 1000
|
||||
max_z_velocity: 20
|
||||
max_z_accel: 100
|
||||
|
||||
[display]
|
||||
lcd_type: hd44780
|
||||
rs_pin: PA3
|
||||
e_pin: PA2
|
||||
d4_pin: PD2
|
||||
d5_pin: PD3
|
||||
d6_pin: PC0
|
||||
d7_pin: PC1
|
||||
|
||||
88
config/printer-anet-e10-2018.cfg
Normal file
@@ -0,0 +1,88 @@
|
||||
# This file contains common pin mappings for Anet E10 printer from
|
||||
# 2018. To use this config, the firmware should be compiled for the
|
||||
# AVR atmega1284p.
|
||||
|
||||
# Note that the "make flash" command does not work with Anet boards -
|
||||
# the boards are typically flashed with this command:
|
||||
# avrdude -p atmega1284p -c arduino -b 57600 -P /dev/ttyUSB0 -U out/klipper.elf.hex
|
||||
|
||||
# See the example.cfg file for a description of available parameters.
|
||||
|
||||
[stepper_x]
|
||||
step_pin: PD7
|
||||
dir_pin: PC5
|
||||
enable_pin: !PD6
|
||||
step_distance: .0125
|
||||
endstop_pin: ^!PC2
|
||||
position_endstop: -3
|
||||
position_max: 220
|
||||
position_min: -3
|
||||
homing_speed: 50
|
||||
|
||||
[stepper_y]
|
||||
step_pin: PC6
|
||||
dir_pin: !PC7
|
||||
enable_pin: !PD6
|
||||
step_distance: .0125
|
||||
endstop_pin: ^!PC3
|
||||
position_endstop: -22
|
||||
position_min: -22
|
||||
position_max: 270
|
||||
homing_speed: 50
|
||||
|
||||
[stepper_z]
|
||||
step_pin: PB3
|
||||
dir_pin: !PB2
|
||||
enable_pin: !PA5
|
||||
step_distance: .0025
|
||||
endstop_pin: ^!PC4
|
||||
position_endstop: 0.5
|
||||
position_max: 300
|
||||
homing_speed: 20
|
||||
|
||||
[extruder]
|
||||
step_pin: PB1
|
||||
dir_pin: !PB0
|
||||
enable_pin: !PD6
|
||||
step_distance: 0.01
|
||||
nozzle_diameter: 0.400
|
||||
filament_diameter: 1.750
|
||||
heater_pin: PD5
|
||||
sensor_type: ATC Semitec 104GT-2
|
||||
sensor_pin: PA7
|
||||
control: pid
|
||||
pid_Kp: 27.0
|
||||
pid_Ki: 1.3
|
||||
pid_Kd: 136.09
|
||||
min_temp: 10
|
||||
max_temp: 250
|
||||
|
||||
[heater_bed]
|
||||
heater_pin: PD4
|
||||
sensor_type: ATC Semitec 104GT-2
|
||||
sensor_pin: PA6
|
||||
control: pid
|
||||
pid_Kp: 72.8
|
||||
pid_Ki: 1.2
|
||||
pid_Kd: 1100
|
||||
min_temp: 10
|
||||
max_temp: 130
|
||||
|
||||
[fan]
|
||||
pin: PB4
|
||||
|
||||
[mcu]
|
||||
serial: /dev/ttyUSB0
|
||||
|
||||
[printer]
|
||||
kinematics: cartesian
|
||||
max_velocity: 300
|
||||
max_accel: 1000
|
||||
max_z_velocity: 20
|
||||
max_z_accel: 1000
|
||||
|
||||
[display]
|
||||
lcd_type: st7920
|
||||
cs_pin: PA4
|
||||
sclk_pin: PA1
|
||||
sid_pin:PA3
|
||||
109
config/printer-anycubic-kossel-2016.cfg
Normal file
@@ -0,0 +1,109 @@
|
||||
# This file contains a configuration for the Anycubic Kossel delta
|
||||
# printer from 2016.
|
||||
|
||||
# The Anycubic delta printers use the TriGorilla board which is an
|
||||
# AVR ATmega2560 Arduino + RAMPS compatible board.
|
||||
# To use this config, the firmware should be compiled for the AVR atmega2560.
|
||||
|
||||
# See the example.cfg file for a description of available parameters.
|
||||
|
||||
[stepper_a]
|
||||
step_pin: ar54
|
||||
dir_pin: !ar55
|
||||
enable_pin: !ar38
|
||||
step_distance: .0125
|
||||
endstop_pin: ^ar2
|
||||
homing_speed: 60
|
||||
# The next parameter needs to be adjusted for
|
||||
# your printer. You may want to start with 280
|
||||
# and meassure the distance from nozzle to bed.
|
||||
# This value then needs to be added.
|
||||
position_endstop: 273.0
|
||||
arm_length: 229.4
|
||||
|
||||
[stepper_b]
|
||||
step_pin: ar60
|
||||
dir_pin: !ar61
|
||||
enable_pin: !ar56
|
||||
step_distance: .0125
|
||||
endstop_pin: ^ar15
|
||||
|
||||
[stepper_c]
|
||||
step_pin: ar46
|
||||
dir_pin: !ar48
|
||||
enable_pin: !ar62
|
||||
step_distance: .0125
|
||||
endstop_pin: ^ar19
|
||||
|
||||
[extruder]
|
||||
step_pin: ar26
|
||||
dir_pin: !ar28
|
||||
enable_pin: !ar24
|
||||
step_distance: 0.010989
|
||||
nozzle_diameter: 0.400
|
||||
filament_diameter: 1.750
|
||||
heater_pin: ar10
|
||||
sensor_type: EPCOS 100K B57560G104F
|
||||
sensor_pin: analog13
|
||||
control: pid
|
||||
pid_Kp: 25.349
|
||||
pid_Ki: 1.216
|
||||
pid_Kd: 132.130
|
||||
min_extrude_temp: 150
|
||||
min_temp: 0
|
||||
max_temp: 275
|
||||
|
||||
#[heater_bed]
|
||||
#heater_pin: ar8
|
||||
#sensor_type: EPCOS 100K B57560G104F
|
||||
#sensor_pin: analog14
|
||||
#control: watermark
|
||||
#min_temp: 0
|
||||
#max_temp: 130
|
||||
|
||||
[fan]
|
||||
pin: ar9
|
||||
kick_start_time: 0.200
|
||||
|
||||
[heater_fan extruder_cooler_fan]
|
||||
pin: ar44
|
||||
|
||||
[mcu]
|
||||
serial: /dev/serial/by-id/usb-Silicon_Labs_CP2102_USB_to_UART_Bridge_Controller_0001-if00-port0
|
||||
pin_map: arduino
|
||||
|
||||
[printer]
|
||||
kinematics: delta
|
||||
max_velocity: 500
|
||||
max_accel: 3000
|
||||
max_z_velocity: 200
|
||||
delta_radius: 99.8
|
||||
# if you want to DELTA_CALIBRATE you may need that
|
||||
#minimum_z_position: -5
|
||||
|
||||
[idle_timeout]
|
||||
timeout: 360
|
||||
|
||||
#[delta_calibrate]
|
||||
#radius: 80
|
||||
#manual_probe:
|
||||
# If true, then DELTA_CALIBRATE will perform manual probing. If
|
||||
# false, then a PROBE command will be run at each probe
|
||||
# point. Manual probing is accomplished by manually jogging the Z
|
||||
# position of the print head at each probe point and then issuing a
|
||||
# NEXT extended g-code command to record the position at that
|
||||
# point. The default is false if a [probe] config section is present
|
||||
# and true otherwise.
|
||||
|
||||
# "RepRapDiscount 2004 Smart Controller" type displays
|
||||
[display]
|
||||
lcd_type: hd44780
|
||||
rs_pin: ar16
|
||||
e_pin: ar17
|
||||
d4_pin: ar23
|
||||
d5_pin: ar25
|
||||
d6_pin: ar27
|
||||
d7_pin: ar29
|
||||
encoder_pins: ^ar31, ^ar33
|
||||
click_pin: ^!ar35
|
||||
kill_pin: ^!ar41
|
||||
109
config/printer-anycubic-kossel-plus-2017.cfg
Normal file
@@ -0,0 +1,109 @@
|
||||
# This file contains a configuration for the "Anycubic Kossel Linear
|
||||
# Plus Large Printing Size", "Anycubic Kossel Pulley Plus Large
|
||||
# Printing Size" and similar delta printer from 2017.
|
||||
# The Anycubic delta printers use the TriGorilla board which is an
|
||||
# AVR ATmega2560 Arduino + RAMPS compatible board.
|
||||
# To use this config, the firmware should be compiled for the AVR atmega2560.
|
||||
|
||||
# See the example.cfg file for a description of available parameters.
|
||||
|
||||
[stepper_a]
|
||||
step_pin: ar54
|
||||
dir_pin: !ar55
|
||||
enable_pin: !ar38
|
||||
step_distance: .0125
|
||||
endstop_pin: ^ar2
|
||||
homing_speed: 60
|
||||
# The next parameter needs to be adjusted for
|
||||
# your printer. You may want to start with 280
|
||||
# and meassure the distance from nozzle to bed.
|
||||
# This value then needs to be added.
|
||||
position_endstop: 295.6
|
||||
arm_length: 271.50
|
||||
|
||||
[stepper_b]
|
||||
step_pin: ar60
|
||||
dir_pin: !ar61
|
||||
enable_pin: !ar56
|
||||
step_distance: .0125
|
||||
endstop_pin: ^ar15
|
||||
|
||||
[stepper_c]
|
||||
step_pin: ar46
|
||||
dir_pin: !ar48
|
||||
enable_pin: !ar62
|
||||
step_distance: .0125
|
||||
endstop_pin: ^ar19
|
||||
|
||||
[extruder]
|
||||
step_pin: ar26
|
||||
dir_pin: !ar28
|
||||
enable_pin: !ar24
|
||||
step_distance: 0.010989
|
||||
nozzle_diameter: 0.400
|
||||
filament_diameter: 1.750
|
||||
heater_pin: ar10
|
||||
sensor_type: EPCOS 100K B57560G104F
|
||||
sensor_pin: analog13
|
||||
control: pid
|
||||
pid_Kp: 25.349
|
||||
pid_Ki: 1.216
|
||||
pid_Kd: 132.130
|
||||
min_extrude_temp: 150
|
||||
min_temp: 0
|
||||
max_temp: 275
|
||||
|
||||
#[heater_bed]
|
||||
#heater_pin: ar8
|
||||
#sensor_type: EPCOS 100K B57560G104F
|
||||
#sensor_pin: analog14
|
||||
#control: watermark
|
||||
#min_temp: 0
|
||||
#max_temp: 130
|
||||
|
||||
[fan]
|
||||
pin: ar9
|
||||
kick_start_time: 0.200
|
||||
|
||||
[heater_fan extruder_cooler_fan]
|
||||
pin: ar44
|
||||
|
||||
[mcu]
|
||||
serial: /dev/ttyUSB0
|
||||
pin_map: arduino
|
||||
|
||||
[printer]
|
||||
kinematics: delta
|
||||
max_velocity: 500
|
||||
max_accel: 3000
|
||||
max_z_velocity: 200
|
||||
delta_radius: 115
|
||||
# if you want to DELTA_CALIBRATE you may need that
|
||||
#minimum_z_position: -5
|
||||
|
||||
[idle_timeout]
|
||||
timeout: 360
|
||||
|
||||
#[delta_calibrate]
|
||||
#radius: 115
|
||||
#manual_probe:
|
||||
# If true, then DELTA_CALIBRATE will perform manual probing. If
|
||||
# false, then a PROBE command will be run at each probe
|
||||
# point. Manual probing is accomplished by manually jogging the Z
|
||||
# position of the print head at each probe point and then issuing a
|
||||
# NEXT extended g-code command to record the position at that
|
||||
# point. The default is false if a [probe] config section is present
|
||||
# and true otherwise.
|
||||
|
||||
# "RepRapDiscount 2004 Smart Controller" type displays
|
||||
[display]
|
||||
lcd_type: hd44780
|
||||
rs_pin: ar16
|
||||
e_pin: ar17
|
||||
d4_pin: ar23
|
||||
d5_pin: ar25
|
||||
d6_pin: ar27
|
||||
d7_pin: ar29
|
||||
encoder_pins: ^ar31, ^ar33
|
||||
click_pin: ^!ar35
|
||||
kill_pin: ^!ar41
|
||||
@@ -2,12 +2,12 @@
|
||||
# CR-10. To use this config, the firmware should be compiled for the
|
||||
# AVR atmega1284p.
|
||||
|
||||
# Note, a number of Melzi boards are shipped without a bootloader. In
|
||||
# that case, an external programmer will be needed to flash a
|
||||
# bootloader to the board (for example, see
|
||||
# http://www.instructables.com/id/Flashing-a-Bootloader-to-the-CR-10/
|
||||
# ). Once that is done, one should be able to use the standard "make
|
||||
# flash" command to flash Klipper.
|
||||
# Note, a number of Melzi boards are shipped with a bootloader that
|
||||
# requires the following command to flash the board:
|
||||
# avrdude -p atmega1284p -c arduino -b 57600 -P /dev/ttyUSB0 -U out/klipper.elf.hex
|
||||
# If the above command does not work and "make flash" does not work
|
||||
# then one may need to flash a bootloader to the board - see the
|
||||
# Klipper docs/Bootloaders.md file for more information.
|
||||
|
||||
# See the example.cfg file for a description of available parameters.
|
||||
|
||||
@@ -86,3 +86,5 @@ lcd_type: st7920
|
||||
cs_pin: PA3
|
||||
sclk_pin: PA1
|
||||
sid_pin: PC1
|
||||
encoder_pins: ^PD2, ^PD3
|
||||
click_pin: ^!PC0
|
||||
|
||||
90
config/printer-creality-cr10mini-2017.cfg
Normal file
@@ -0,0 +1,90 @@
|
||||
# This file contains common pin mappings for the 2017 Creality CR-10
|
||||
# mini. To use this config, the firmware should be compiled for the
|
||||
# AVR atmega1284p.
|
||||
|
||||
# Note, a number of Melzi boards are shipped with a bootloader that
|
||||
# requires the following command to flash the board:
|
||||
# avrdude -p atmega1284p -c arduino -b 57600 -P /dev/ttyUSB0 -U out/klipper.elf.hex
|
||||
# If the above command does not work and "make flash" does not work
|
||||
# then one may need to flash a bootloader to the board - see the
|
||||
# Klipper docs/Bootloaders.md file for more information.
|
||||
|
||||
# See the example.cfg file for a description of available parameters.
|
||||
|
||||
[stepper_x]
|
||||
step_pin: PD7
|
||||
dir_pin: !PC5
|
||||
enable_pin: !PD6
|
||||
step_distance: .0125
|
||||
endstop_pin: ^PC2
|
||||
position_endstop: 0
|
||||
position_max: 300
|
||||
homing_speed: 50
|
||||
|
||||
[stepper_y]
|
||||
step_pin: PC6
|
||||
dir_pin: !PC7
|
||||
enable_pin: !PD6
|
||||
step_distance: .0125
|
||||
endstop_pin: ^PC3
|
||||
position_endstop: 0
|
||||
position_max: 220
|
||||
homing_speed: 50
|
||||
|
||||
[stepper_z]
|
||||
step_pin: PB3
|
||||
dir_pin: PB2
|
||||
enable_pin: !PA5
|
||||
step_distance: .0025
|
||||
endstop_pin: ^PC4
|
||||
position_endstop: 0.0
|
||||
position_max: 300
|
||||
|
||||
[extruder]
|
||||
step_pin: PB1
|
||||
dir_pin: !PB0
|
||||
enable_pin: !PD6
|
||||
step_distance: 0.010526
|
||||
nozzle_diameter: 0.400
|
||||
filament_diameter: 1.750
|
||||
heater_pin: PD5
|
||||
sensor_type: EPCOS 100K B57560G104F
|
||||
sensor_pin: PA7
|
||||
control: pid
|
||||
pid_Kp: 22.57
|
||||
pid_Ki: 1.72
|
||||
pid_Kd: 73.96
|
||||
min_temp: 0
|
||||
max_temp: 250
|
||||
|
||||
[heater_bed]
|
||||
heater_pin: PD4
|
||||
sensor_type: EPCOS 100K B57560G104F
|
||||
sensor_pin: PA6
|
||||
control: pid
|
||||
pid_Kp: 426.68
|
||||
pid_Ki: 78.92
|
||||
pid_Kd: 576.71
|
||||
min_temp: 0
|
||||
max_temp: 130
|
||||
|
||||
[fan]
|
||||
pin: PB4
|
||||
|
||||
[mcu]
|
||||
serial: /dev/ttyUSB0
|
||||
|
||||
[printer]
|
||||
kinematics: cartesian
|
||||
max_velocity: 300
|
||||
max_accel: 3000
|
||||
max_z_velocity: 5
|
||||
max_z_accel: 100
|
||||
|
||||
[display]
|
||||
lcd_type: st7920
|
||||
cs_pin: PA3
|
||||
sclk_pin: PA1
|
||||
sid_pin: PC1
|
||||
encoder_pins: ^PD2, ^PD3
|
||||
click_pin: ^!PC0
|
||||
@@ -30,7 +30,7 @@ enable_pin: !ar62
|
||||
step_distance: .0025
|
||||
endstop_pin: ^ar18
|
||||
position_endstop: 0.5
|
||||
position_max: 200
|
||||
position_max: 400
|
||||
|
||||
[extruder]
|
||||
step_pin: ar26
|
||||
@@ -73,3 +73,11 @@ max_velocity: 300
|
||||
max_accel: 3000
|
||||
max_z_velocity: 5
|
||||
max_z_accel: 100
|
||||
|
||||
[display]
|
||||
lcd_type: st7920
|
||||
cs_pin: ar16
|
||||
sclk_pin: ar23
|
||||
sid_pin: ar17
|
||||
encoder_pins: ^ar33, ^ar31
|
||||
click_pin: ^!ar35
|
||||
|
||||
81
config/printer-creality-cr20-2018.cfg
Normal file
@@ -0,0 +1,81 @@
|
||||
# This file contains pin mappings for the Creality CR-20. To use
|
||||
# this config, the firmware should be compiled for the AVR atmega2560.
|
||||
|
||||
# See the example.cfg file for a description of available parameters.
|
||||
|
||||
[stepper_x]
|
||||
step_pin: PF0
|
||||
dir_pin: PF1
|
||||
enable_pin: !PD7
|
||||
step_distance: .0125
|
||||
endstop_pin: ^PE5
|
||||
position_endstop: 0
|
||||
position_max: 235
|
||||
homing_speed: 50
|
||||
|
||||
[stepper_y]
|
||||
step_pin: PF6
|
||||
dir_pin: PF7
|
||||
enable_pin: !PF2
|
||||
step_distance: .0125
|
||||
endstop_pin: ^PJ1
|
||||
position_endstop: 0
|
||||
position_max: 235
|
||||
homing_speed: 50
|
||||
|
||||
[stepper_z]
|
||||
step_pin: PL3
|
||||
dir_pin: !PL1
|
||||
enable_pin: !PK0
|
||||
step_distance: .0025
|
||||
endstop_pin: ^PD3
|
||||
position_endstop: 0.5
|
||||
position_max: 250
|
||||
|
||||
[extruder]
|
||||
step_pin: PA4
|
||||
dir_pin: PA6
|
||||
enable_pin: !PA2
|
||||
step_distance: .010526
|
||||
nozzle_diameter: 0.400
|
||||
filament_diameter: 1.750
|
||||
heater_pin: PB4
|
||||
sensor_type: EPCOS 100K B57560G104F
|
||||
sensor_pin: PK5
|
||||
control: pid
|
||||
pid_Kp: 22.2
|
||||
pid_Ki: 1.08
|
||||
pid_Kd: 114
|
||||
min_temp: 0
|
||||
max_temp: 250
|
||||
|
||||
[heater_bed]
|
||||
heater_pin: PH5
|
||||
sensor_type: EPCOS 100K B57560G104F
|
||||
sensor_pin: PK6
|
||||
control: pid
|
||||
pid_Kp: 690.34
|
||||
pid_Ki: 111.47
|
||||
pid_Kd: 1068.83
|
||||
min_temp: 0
|
||||
max_temp: 130
|
||||
|
||||
[fan]
|
||||
pin: PH6
|
||||
|
||||
[mcu]
|
||||
serial: /dev/ttyUSB0
|
||||
|
||||
[printer]
|
||||
kinematics: cartesian
|
||||
max_velocity: 300
|
||||
max_accel: 3000
|
||||
max_z_velocity: 5
|
||||
max_z_accel: 100
|
||||
|
||||
[display]
|
||||
lcd_type: uc1701
|
||||
cs_pin: PA3
|
||||
a0_pin: PA5
|
||||
encoder_pins: ^PC4, ^PC6
|
||||
click_pin: ^!PC2
|
||||
93
config/printer-creality-ender2-2017.cfg
Normal file
@@ -0,0 +1,93 @@
|
||||
# This file contains common pin mappings for the 2017 Creality
|
||||
# Ender 2. To use this config, the firmware should be compiled for the
|
||||
# AVR atmega1284p.
|
||||
|
||||
# Note, a number of Melzi boards are shipped with a bootloader that
|
||||
# requires the following command to flash the board:
|
||||
# avrdude -p atmega1284p -c arduino -b 57600 -P /dev/ttyUSB0 -U out/klipper.elf.hex
|
||||
# If the above command does not work and "make flash" does not work
|
||||
# then one may need to flash a bootloader to the board - see the
|
||||
# Klipper docs/Bootloaders.md file for more information.
|
||||
|
||||
# See the example.cfg file for a description of available parameters.
|
||||
|
||||
[stepper_x]
|
||||
step_pin: PD7
|
||||
dir_pin: !PC5
|
||||
enable_pin: !PD6
|
||||
step_distance: .0125
|
||||
endstop_pin: ^PC2
|
||||
position_endstop: 0
|
||||
position_max: 165
|
||||
homing_speed: 50
|
||||
|
||||
[stepper_y]
|
||||
step_pin: PC6
|
||||
dir_pin: !PC7
|
||||
enable_pin: !PD6
|
||||
step_distance: .0125
|
||||
endstop_pin: ^PC3
|
||||
position_endstop: 0
|
||||
position_max: 165
|
||||
homing_speed: 50
|
||||
|
||||
[stepper_z]
|
||||
step_pin: PB3
|
||||
dir_pin: PB2
|
||||
enable_pin: !PA5
|
||||
step_distance: .0025
|
||||
endstop_pin: ^PC4
|
||||
position_endstop: 0.0
|
||||
position_max: 205
|
||||
|
||||
[extruder]
|
||||
step_pin: PB1
|
||||
dir_pin: !PB0
|
||||
enable_pin: !PD6
|
||||
step_distance: 0.010753
|
||||
nozzle_diameter: 0.400
|
||||
filament_diameter: 1.750
|
||||
max_extrude_only_distance: 500.0
|
||||
max_extrude_only_velocity: 200.0
|
||||
max_extrude_only_accel: 500.0
|
||||
heater_pin: PD5
|
||||
sensor_type: EPCOS 100K B57560G104F
|
||||
sensor_pin: PA7
|
||||
control: pid
|
||||
pid_Kp: 21.73
|
||||
pid_Ki: 1.54
|
||||
pid_Kd: 76.55
|
||||
min_temp: 0
|
||||
max_temp: 250
|
||||
|
||||
[heater_bed]
|
||||
heater_pin: PD4
|
||||
sensor_type: EPCOS 100K B57560G104F
|
||||
sensor_pin: PA6
|
||||
control: pid
|
||||
# PID Tuned for 60C
|
||||
pid_Kp: 72.487
|
||||
pid_Ki: 2.279
|
||||
pid_Kd: 576.275
|
||||
min_temp: 0
|
||||
max_temp: 100
|
||||
|
||||
[fan]
|
||||
pin: PB4
|
||||
|
||||
[mcu]
|
||||
serial: /dev/ttyUSB0
|
||||
|
||||
[printer]
|
||||
kinematics: cartesian
|
||||
max_velocity: 300
|
||||
max_accel: 1500
|
||||
max_z_velocity: 5
|
||||
max_z_accel: 100
|
||||
|
||||
[display]
|
||||
lcd_type: uc1701
|
||||
cs_pin: PA3
|
||||
a0_pin: PA1
|
||||
encoder_pins: ^PD2, ^PD3
|
||||
click_pin: ^!PC0
|
||||
93
config/printer-creality-ender3-2018.cfg
Normal file
@@ -0,0 +1,93 @@
|
||||
# This file contains common pin mappings for the 2018 Creality
|
||||
# Ender 3. To use this config, the firmware should be compiled for the
|
||||
# AVR atmega1284p.
|
||||
|
||||
# Note, a number of Melzi boards are shipped with a bootloader that
|
||||
# requires the following command to flash the board:
|
||||
# avrdude -p atmega1284p -c arduino -b 57600 -P /dev/ttyUSB0 -U out/klipper.elf.hex
|
||||
# If the above command does not work and "make flash" does not work
|
||||
# then one may need to flash a bootloader to the board - see the
|
||||
# Klipper docs/Bootloaders.md file for more information.
|
||||
|
||||
# See the example.cfg file for a description of available parameters.
|
||||
|
||||
[stepper_x]
|
||||
step_pin: PD7
|
||||
dir_pin: !PC5
|
||||
enable_pin: !PD6
|
||||
step_distance: .0125
|
||||
endstop_pin: ^PC2
|
||||
position_endstop: 0
|
||||
position_max: 235
|
||||
homing_speed: 50
|
||||
|
||||
[stepper_y]
|
||||
step_pin: PC6
|
||||
dir_pin: !PC7
|
||||
enable_pin: !PD6
|
||||
step_distance: .0125
|
||||
endstop_pin: ^PC3
|
||||
position_endstop: 0
|
||||
position_max: 235
|
||||
homing_speed: 50
|
||||
|
||||
[stepper_z]
|
||||
step_pin: PB3
|
||||
dir_pin: PB2
|
||||
enable_pin: !PA5
|
||||
step_distance: .0025
|
||||
endstop_pin: ^PC4
|
||||
position_endstop: 0.0
|
||||
position_max: 250
|
||||
|
||||
[extruder]
|
||||
max_extrude_only_distance: 100.0
|
||||
step_pin: PB1
|
||||
dir_pin: !PB0
|
||||
enable_pin: !PD6
|
||||
step_distance: 0.010526
|
||||
nozzle_diameter: 0.400
|
||||
filament_diameter: 1.750
|
||||
heater_pin: PD5
|
||||
sensor_type: EPCOS 100K B57560G104F
|
||||
sensor_pin: PA7
|
||||
control: pid
|
||||
# tuned for stock hardware with 200 degree Celsius target
|
||||
pid_Kp: 21.527
|
||||
pid_Ki: 1.063
|
||||
pid_Kd: 108.982
|
||||
min_temp: 0
|
||||
max_temp: 250
|
||||
|
||||
[heater_bed]
|
||||
heater_pin: PD4
|
||||
sensor_type: EPCOS 100K B57560G104F
|
||||
sensor_pin: PA6
|
||||
control: pid
|
||||
# tuned for stock hardware with 50 degree Celsius target
|
||||
pid_Kp: 54.027
|
||||
pid_Ki: 0.770
|
||||
pid_Kd: 948.182
|
||||
min_temp: 0
|
||||
max_temp: 130
|
||||
|
||||
[fan]
|
||||
pin: PB4
|
||||
|
||||
[mcu]
|
||||
serial: /dev/ttyUSB0
|
||||
|
||||
[printer]
|
||||
kinematics: cartesian
|
||||
max_velocity: 300
|
||||
max_accel: 3000
|
||||
max_z_velocity: 5
|
||||
max_z_accel: 100
|
||||
|
||||
[display]
|
||||
lcd_type: st7920
|
||||
cs_pin: PA3
|
||||
sclk_pin: PA1
|
||||
sid_pin: PC1
|
||||
encoder_pins: ^PD2, ^PD3
|
||||
click_pin: ^!PC0
|
||||
@@ -12,8 +12,10 @@ endstop_pin: ^!PB6
|
||||
position_endstop: 0.0
|
||||
position_max: 200
|
||||
homing_speed: 50
|
||||
homing_stepper_phases: 32
|
||||
homing_endstop_accuracy: .200
|
||||
|
||||
[endstop_phase stepper_x]
|
||||
phases: 32
|
||||
endstop_accuracy: .200
|
||||
|
||||
[stepper_y]
|
||||
step_pin: PC1
|
||||
@@ -24,8 +26,10 @@ endstop_pin: ^!PB5
|
||||
position_endstop: 0.0
|
||||
position_max: 250
|
||||
homing_speed: 50
|
||||
homing_stepper_phases: 32
|
||||
homing_endstop_accuracy: .200
|
||||
|
||||
[endstop_phase stepper_y]
|
||||
phases: 32
|
||||
endstop_accuracy: .200
|
||||
|
||||
[stepper_z]
|
||||
step_pin: PC2
|
||||
@@ -37,8 +41,10 @@ position_min: 0.1
|
||||
position_endstop: 0.7
|
||||
position_max: 200
|
||||
homing_retract_dist: 2.0
|
||||
homing_stepper_phases: 32
|
||||
homing_endstop_accuracy: .070
|
||||
|
||||
[endstop_phase stepper_z]
|
||||
phases: 32
|
||||
endstop_accuracy: .070
|
||||
|
||||
[extruder]
|
||||
step_pin: PC3
|
||||
|
||||
79
config/printer-micromake-d1-2016.cfg
Normal file
@@ -0,0 +1,79 @@
|
||||
# This file contains a configuration for the "Micromake D1" delta
|
||||
# printer (using the Makeboard 1.3 electronics). To use this config,
|
||||
# the firmware should be compiled for the AVR atmega2560.
|
||||
|
||||
# See the example.cfg file for a description of available parameters.
|
||||
|
||||
[stepper_a]
|
||||
step_pin: ar54
|
||||
dir_pin: !ar55
|
||||
enable_pin: !ar38
|
||||
step_distance: .01
|
||||
endstop_pin: ^ar2
|
||||
homing_speed: 100
|
||||
position_endstop: 319.5
|
||||
arm_length: 217.0
|
||||
|
||||
[stepper_b]
|
||||
step_pin: ar60
|
||||
dir_pin: !ar61
|
||||
enable_pin: !ar56
|
||||
step_distance: .01
|
||||
endstop_pin: ^ar15
|
||||
|
||||
[stepper_c]
|
||||
step_pin: ar46
|
||||
dir_pin: !ar48
|
||||
enable_pin: !ar62
|
||||
step_distance: .01
|
||||
endstop_pin: ^ar19
|
||||
|
||||
[extruder]
|
||||
step_pin: ar26
|
||||
dir_pin: ar28
|
||||
enable_pin: !ar24
|
||||
step_distance: 0.006271
|
||||
nozzle_diameter: 0.400
|
||||
filament_diameter: 1.750
|
||||
heater_pin: ar10
|
||||
sensor_type: EPCOS 100K B57560G104F
|
||||
sensor_pin: analog13
|
||||
control: pid
|
||||
pid_Kp: 22.2
|
||||
pid_Ki: 1.08
|
||||
pid_Kd: 114
|
||||
min_temp: 0
|
||||
max_temp: 250
|
||||
max_extrude_only_distance: 100.0
|
||||
|
||||
[fan]
|
||||
pin: ar9
|
||||
|
||||
[mcu]
|
||||
serial: /dev/ttyACM0
|
||||
pin_map: arduino
|
||||
|
||||
[printer]
|
||||
kinematics: delta
|
||||
max_velocity: 300
|
||||
max_accel: 3000
|
||||
max_z_velocity: 150
|
||||
delta_radius: 95
|
||||
|
||||
[delta_calibrate]
|
||||
radius: 80
|
||||
|
||||
#[probe]
|
||||
#pin: ^!ar18
|
||||
|
||||
[display]
|
||||
lcd_type: hd44780
|
||||
rs_pin: ar16
|
||||
e_pin: ar17
|
||||
d4_pin: ar23
|
||||
d5_pin: ar25
|
||||
d6_pin: ar27
|
||||
d7_pin: ar29
|
||||
encoder_pins: ^ar31, ^ar33
|
||||
click_pin: ^!ar35
|
||||
kill_pin: ^!ar41
|
||||
@@ -2,12 +2,12 @@
|
||||
# use this config, the firmware should be compiled for the AVR
|
||||
# atmega1284p.
|
||||
|
||||
# Note, a number of Melzi boards are shipped without a bootloader. In
|
||||
# that case, an external programmer will be needed to flash a
|
||||
# bootloader to the board (for example, see
|
||||
# http://www.instructables.com/id/Flashing-a-Bootloader-to-the-CR-10/
|
||||
# ). Once that is done, one should be able to use the standard "make
|
||||
# flash" command to flash Klipper.
|
||||
# Note, a number of Melzi boards are shipped with a bootloader that
|
||||
# requires the following command to flash the board:
|
||||
# avrdude -p atmega1284p -c arduino -b 57600 -P /dev/ttyUSB0 -U out/klipper.elf.hex
|
||||
# If the above command does not work and "make flash" does not work
|
||||
# then one may need to flash a bootloader to the board - see the
|
||||
# Klipper docs/Bootloaders.md file for more information.
|
||||
|
||||
# See the example.cfg file for a description of available parameters.
|
||||
|
||||
@@ -65,6 +65,11 @@ control: watermark
|
||||
min_temp: 0
|
||||
max_temp: 150
|
||||
|
||||
[verify_heater heater_bed]
|
||||
# adjust for personal bed setup, this prevents stock heated bed from issuing
|
||||
# false positive heating errors due to slow temperature increase
|
||||
check_gain_time: 600
|
||||
|
||||
[fan]
|
||||
pin: PB4
|
||||
|
||||
91
config/printer-tronxy-x8-2018.cfg
Normal file
@@ -0,0 +1,91 @@
|
||||
# This file contains the configurations and pin mappings for the
|
||||
# Tronxy X8 using the CXY-V2-0508 board. To use this config file, the
|
||||
# firmware should be compiled for the AVR ATmega1284p, 16MHz.
|
||||
|
||||
# Some Tronxy printers come without a bootloader present on the
|
||||
# board. In that case, use MCUDude MightyCore ATmega1284p bootloader
|
||||
# with TQFP44 Sanguino pinout. The package can be found at
|
||||
# (https://github.com/MCUdude/MightyCore). Follow Klipper install
|
||||
# instructions but instead of "make flash FLASH_DEVICE=/dev/ttyACM0",
|
||||
# use the following command:
|
||||
# avrdude -p atmega1284p -c arduino -b 115200 -P /dev/ttyUSB0 -U out/klipper.elf.hex
|
||||
|
||||
# See the example.cfg and example-extras.cfg files for a description
|
||||
# of available parameters.
|
||||
|
||||
[mcu]
|
||||
serial: /dev/ttyUSB0
|
||||
|
||||
[stepper_x]
|
||||
step_pin: PD7
|
||||
dir_pin: PC5
|
||||
enable_pin: !PD6
|
||||
step_distance: 0.010
|
||||
endstop_pin: ^!PC2
|
||||
position_endstop: -47
|
||||
position_max: 220
|
||||
position_min: -47
|
||||
homing_speed: 50
|
||||
|
||||
[stepper_y]
|
||||
step_pin: PC6
|
||||
dir_pin: PC7
|
||||
enable_pin: !PD6
|
||||
step_distance: 0.010
|
||||
endstop_pin: ^!PC3
|
||||
position_endstop: 0
|
||||
position_max: 220
|
||||
position_min: 0
|
||||
homing_speed: 50
|
||||
|
||||
[stepper_z]
|
||||
step_pin: PB3
|
||||
dir_pin: !PB2
|
||||
enable_pin: !PD6
|
||||
step_distance: 0.0025
|
||||
endstop_pin: ^!PC4
|
||||
position_endstop: 0
|
||||
position_max: 210
|
||||
homing_speed: 10
|
||||
|
||||
[extruder]
|
||||
step_pin: PB1
|
||||
dir_pin: PB0
|
||||
enable_pin: !PD6
|
||||
step_distance: 0.009931
|
||||
nozzle_diameter: 0.400
|
||||
filament_diameter: 1.750
|
||||
heater_pin: PD5
|
||||
sensor_type: EPCOS 100K B57560G104F
|
||||
sensor_pin: PA7
|
||||
control: pid
|
||||
pid_Kp: 22.2
|
||||
pid_Ki: 1.08
|
||||
pid_Kd: 114
|
||||
min_temp: 0
|
||||
max_temp: 275
|
||||
|
||||
[heater_bed]
|
||||
heater_pin: PD4
|
||||
sensor_type: EPCOS 100K B57560G104F
|
||||
sensor_pin: PA6
|
||||
control: watermark
|
||||
max_delta: 2.0
|
||||
min_temp: 0
|
||||
max_temp: 150
|
||||
|
||||
[fan]
|
||||
pin: PB4
|
||||
|
||||
[printer]
|
||||
kinematics: cartesian
|
||||
max_velocity: 300
|
||||
max_accel: 1000
|
||||
max_z_velocity: 20
|
||||
max_z_accel: 100
|
||||
|
||||
[display]
|
||||
lcd_type: st7920
|
||||
cs_pin: PA1
|
||||
sclk_pin: PC0
|
||||
sid_pin: PA3
|
||||
95
config/printer-velleman-k8200-2013.cfg
Normal file
@@ -0,0 +1,95 @@
|
||||
# This file contains common pin mappings for the Velleman K8200 and
|
||||
# 3Drag 3D printers (circa 2013). To use this config, the firmware
|
||||
# should be compiled for the AVR atmega2560.
|
||||
|
||||
# Based on config from Martin Malmqvist and Per Hjort.
|
||||
|
||||
# See the example.cfg file for a description of available parameters.
|
||||
|
||||
[stepper_x]
|
||||
step_pin: ar54
|
||||
dir_pin: !ar55
|
||||
enable_pin: !ar38
|
||||
step_distance: .0125
|
||||
endstop_pin: ^ar3
|
||||
position_endstop: 0
|
||||
position_max: 200
|
||||
homing_speed: 50
|
||||
|
||||
[stepper_y]
|
||||
step_pin: ar60
|
||||
dir_pin: !ar61
|
||||
enable_pin: !ar56
|
||||
step_distance: .0125
|
||||
endstop_pin: ^ar14
|
||||
position_endstop: 0
|
||||
position_max: 200
|
||||
homing_speed: 50
|
||||
|
||||
[stepper_z]
|
||||
step_pin: ar46
|
||||
dir_pin: !ar48
|
||||
enable_pin: !ar63
|
||||
step_distance: .0025
|
||||
endstop_pin: ^ar18
|
||||
position_endstop: 0.5
|
||||
# Set position_max to 200 if you have the original Z-axis setup.
|
||||
position_max: 250
|
||||
|
||||
[extruder]
|
||||
step_pin: ar26
|
||||
# Remove the "!" from dir_pin if you have an original extruder
|
||||
dir_pin: !ar28
|
||||
enable_pin: !ar24
|
||||
# You will have to calculate your own step_distance.
|
||||
# This is for the belted extruder https://www.thingiverse.com/thing:339928
|
||||
step_distance: .001333
|
||||
nozzle_diameter: 0.400
|
||||
filament_diameter: 2.85
|
||||
heater_pin: ar10
|
||||
sensor_type: ATC Semitec 104GT-2
|
||||
sensor_pin: analog13
|
||||
control: pid
|
||||
pid_Kp: 21.503
|
||||
pid_Ki: 1.103
|
||||
pid_Kd: 104.825
|
||||
min_temp: 0
|
||||
max_temp: 250
|
||||
|
||||
[heater_bed]
|
||||
heater_pin: ar9
|
||||
sensor_type: ATC Semitec 104GT-2
|
||||
sensor_pin: analog14
|
||||
control: pid
|
||||
pid_Kp: 75.283
|
||||
pid_Ki: 0.588
|
||||
pid_Kd: 2408.103
|
||||
min_temp: 0
|
||||
max_temp: 130
|
||||
|
||||
[fan]
|
||||
pin: ar8
|
||||
kick_start_time: 0.500
|
||||
|
||||
[mcu]
|
||||
serial: /dev/ttyUSB0
|
||||
pin_map: arduino
|
||||
|
||||
[printer]
|
||||
kinematics: cartesian
|
||||
max_velocity: 300
|
||||
max_accel: 1000
|
||||
max_z_velocity: 10
|
||||
max_z_accel: 100
|
||||
|
||||
# The LCD is untested - "RepRapDiscount 2004 Smart Controller" displays
|
||||
#[display]
|
||||
#lcd_type: hd44780
|
||||
#rs_pin: ar27
|
||||
#e_pin: ar29
|
||||
#d4_pin: ar37
|
||||
#d5_pin: ar35
|
||||
#d6_pin: ar33
|
||||
#d7_pin: ar31
|
||||
#encoder_pins: ^ar16, ^ar17
|
||||
#click_pin: ^!ar23
|
||||
104
config/printer-wanhao-duplicator-6-2016.cfg
Normal file
@@ -0,0 +1,104 @@
|
||||
# Support for the Wanhao Duplicator 6 and its clones (eg, Monoprice
|
||||
# Ultimate). To use this config, the firmware should be compiled for
|
||||
# the AVR atmega2560.
|
||||
|
||||
# See the example.cfg file for a description of available parameters.
|
||||
|
||||
[stepper_x]
|
||||
step_pin: PA3
|
||||
dir_pin: !PA1
|
||||
enable_pin: !PA5
|
||||
step_distance: 0.0125
|
||||
endstop_pin: ^!PA0
|
||||
position_endstop: 0
|
||||
position_max: 200
|
||||
homing_speed: 50
|
||||
|
||||
[stepper_y]
|
||||
step_pin: PC5
|
||||
dir_pin: PC4
|
||||
enable_pin: !PC6
|
||||
step_distance: 0.0125
|
||||
endstop_pin: ^!PA4
|
||||
position_endstop: 0
|
||||
position_max: 200
|
||||
homing_speed: 50
|
||||
|
||||
[stepper_z]
|
||||
step_pin: PC2
|
||||
dir_pin: !PC1
|
||||
enable_pin: !PC3
|
||||
step_distance: 0.0025
|
||||
endstop_pin: ^!PA7
|
||||
position_endstop: 0.5
|
||||
position_max: 175
|
||||
homing_speed: 25
|
||||
|
||||
[extruder]
|
||||
step_pin: PL7
|
||||
dir_pin: !PL6
|
||||
enable_pin: !PC0
|
||||
step_distance: 0.010091
|
||||
nozzle_diameter: 0.400
|
||||
filament_diameter: 1.7500
|
||||
heater_pin: PE4
|
||||
sensor_type: PT100 INA826
|
||||
sensor_pin: PK0
|
||||
control: pid
|
||||
pid_Kp: 26.571
|
||||
pid_Ki: 0.927
|
||||
pid_Kd: 190.318
|
||||
min_temp: 0
|
||||
max_temp: 250
|
||||
|
||||
[heater_bed]
|
||||
heater_pin: PG5
|
||||
sensor_type: EPCOS 100K B57560G104F
|
||||
sensor_pin: PK2
|
||||
control: pid
|
||||
pid_Kp: 59.593
|
||||
pid_Ki: 3.01
|
||||
pid_Kd: 294.985
|
||||
min_temp: 0
|
||||
max_temp: 110
|
||||
|
||||
[fan]
|
||||
pin: PH4
|
||||
|
||||
[mcu]
|
||||
serial: /dev/ttyACM0
|
||||
|
||||
[printer]
|
||||
kinematics: cartesian
|
||||
max_velocity: 300
|
||||
max_accel: 3000
|
||||
max_z_velocity: 5
|
||||
max_z_accel: 100
|
||||
|
||||
# Software control for Stepper current
|
||||
[output_pin stepper_xy_current]
|
||||
pin: PL5
|
||||
pwm: True
|
||||
scale: 2.782
|
||||
cycle_time: .000030
|
||||
hardware_pwm: True
|
||||
static_value: 1.2
|
||||
|
||||
[output_pin stepper_z_current]
|
||||
pin: PL4
|
||||
pwm: True
|
||||
scale: 2.782
|
||||
cycle_time: .000030
|
||||
hardware_pwm: True
|
||||
static_value: 1.2
|
||||
|
||||
[output_pin stepper_e_current]
|
||||
pin: PL3
|
||||
pwm: True
|
||||
scale: 2.782
|
||||
cycle_time: .000030
|
||||
hardware_pwm: True
|
||||
static_value: 1.0
|
||||
|
||||
# N.B. No support for the Display as yet. SSD1309 OLED graphical
|
||||
# display connected with i2C.
|
||||
@@ -1,20 +1,22 @@
|
||||
# This file contains pin mappings and other appropriate default parameters
|
||||
# for a Wanhao Duplicator i3 v2.1 and its clones
|
||||
# (Monoprice Maker Select, Cocoon Create, etc.)
|
||||
# See the files example.cfg and example-extras.cfg for a description of available parameters.
|
||||
# This file contains pin mappings and other appropriate default
|
||||
# parameters for a Wanhao Duplicator i3 v2.1 and its clones (Monoprice
|
||||
# Maker Select, Cocoon Create, etc.).
|
||||
#
|
||||
# This will probably work on older revisions (v1.0, v2.0) of the printer
|
||||
# but is untested on those versions.
|
||||
#
|
||||
|
||||
# Note, a number of Melzi boards are shipped with a bootloader that
|
||||
# requires the following command to flash the board:
|
||||
# avrdude -p atmega1284p -c arduino -b 57600 -P /dev/ttyUSB0 -U out/klipper.elf.hex
|
||||
# If the above command does not work and "make flash" does not work
|
||||
# then one may need to flash a bootloader to the board - see the
|
||||
# Klipper docs/Bootloaders.md file for more information.
|
||||
|
||||
# See the example.cfg file for a description of available parameters.
|
||||
|
||||
# For best results with klipper and the Wanhao Duplicator i3, follow these
|
||||
# guidelines:
|
||||
#
|
||||
# - Flash a bootloader to the Melzi board in the printer
|
||||
# See http://www.instructables.com/id/Using-an-Arduino-to-Flash-the-Melzi-Board-Wanhao-I/
|
||||
#
|
||||
# - Make sure the auto-reset jumper is *enabled* on the Melzi board
|
||||
# (See step 1 in the bootloader tutorial above)
|
||||
#
|
||||
# - Locate the USB serial port for your printer in /dev/serial/by-id/ format.
|
||||
# See https://github.com/KevinOConnor/klipper/blob/master/docs/FAQ.md#wheres-my-serial-port
|
||||
# It will be something like:
|
||||
@@ -65,6 +67,12 @@
|
||||
# (like an upgraded hot end or a separate MOSFET for your heated bed), you may
|
||||
# want to increase these values.
|
||||
#
|
||||
# Note: Some Melzi boards were shipped with 10K pullup resistors
|
||||
# instead of 4.7K. If the temperatures on your printer seem way
|
||||
# off before running the PID tune, you may need to add
|
||||
# "pullup_resistor: 10000" to both the extruder and the heater_bed
|
||||
# config sections.
|
||||
#
|
||||
# * [mcu] > serial
|
||||
#
|
||||
# Enter the USB serial port of the printer in /dev/serial/by-id/ format
|
||||
@@ -157,3 +165,5 @@ lcd_type: st7920
|
||||
cs_pin: PC1
|
||||
sclk_pin: PD3
|
||||
sid_pin: PC0
|
||||
encoder_pins: ^PA2, ^PA1
|
||||
click_pin: ^!PA3
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
# This file provides example config file settings for the BLTouch
|
||||
# automatic bed leveling sensor. This file is just a "snippet" of
|
||||
# sections specific to the BLTouch - it must be added to a config file
|
||||
# containing the configuration of the rest of the printer.
|
||||
|
||||
# Be sure to review and update this config with the appropriate pins
|
||||
# and coordinates for your printer.
|
||||
|
||||
# See the "example.cfg" and "example-extras.cfg" files for a
|
||||
# description of config parameters.
|
||||
|
||||
# Define the BLTouch servo
|
||||
[servo bltouch]
|
||||
pin: ar32
|
||||
maximum_servo_angle: 180
|
||||
minimum_pulse_width: 0.0006
|
||||
maximum_pulse_width: 0.0024
|
||||
|
||||
# Define a probe using the BLTouch
|
||||
[probe]
|
||||
pin: ar30
|
||||
activate_gcode:
|
||||
SET_SERVO SERVO=bltouch ANGLE=10
|
||||
SET_SERVO SERVO=bltouch ANGLE=60
|
||||
G4 P200
|
||||
deactivate_gcode:
|
||||
SET_SERVO SERVO=bltouch ANGLE=90
|
||||
|
||||
# Example bed_tilt config section
|
||||
[bed_tilt]
|
||||
#x_adjust:
|
||||
#y_adjust:
|
||||
points:
|
||||
100,100
|
||||
10,10
|
||||
10,100
|
||||
10,190
|
||||
100,10
|
||||
100,190
|
||||
190,10
|
||||
190,100
|
||||
190,190
|
||||
probe_z_offset: 2.345
|
||||
|
||||
# If the BLTouch is used to home the Z axis, then define a
|
||||
# homing_override section, use probe:z_virtual_endstop as the
|
||||
# endstop_pin in the stepper_z section, and set the endstop_position
|
||||
# in the stepper_z section to match the probe's probe_z_offset.
|
||||
#[homing_override]
|
||||
#set_position_z: 5
|
||||
#gcode:
|
||||
# ; G90 ; Uncomment these 2 lines to blindly lift the Z 2mm at start
|
||||
# ; G1 Z7 F600
|
||||
# G28 X0 Y0
|
||||
# G1 X100 Y100 F3600
|
||||
# G28 Z0
|
||||
36
config/sample-macros.cfg
Normal file
@@ -0,0 +1,36 @@
|
||||
# This file provides examples of Klipper G-Code macros. The snippets
|
||||
# in this file may be copied into the main printer.cfg file.
|
||||
#
|
||||
# See the "example.cfg" file for description of common config parameters.
|
||||
|
||||
|
||||
# M300 : Play tone, Beeper support, as commonly found on usual LCD displays
|
||||
# i.e. RepRapDiscount 2004 Smart Controller, RepRapDiscount 12864 Full Graphic
|
||||
# This defines a custom I/O pin and a custom GCODE macro
|
||||
# Usage: M300 [P<ms>] [S<Hz>] P is the tone duration, S the tone frequency.
|
||||
# as it is based on a PWM duty cycle, the frequency won't be pitch perfect.
|
||||
#
|
||||
#[output_pin BEEPER_pin]
|
||||
#pin: ar37
|
||||
# Beeper pin. This parameter must be provided.
|
||||
# ar37 is the default RAMPS/MKS pin.
|
||||
#pwm: True
|
||||
# A piezo beeper needs a PWM signal, a DC buzzer doesn't.
|
||||
#value: 0
|
||||
# Silent at power on, set to 1 if active low.
|
||||
#shutdown_value: 0
|
||||
# Disable at emergency shutdown (no PWM would be available anyway).
|
||||
#cycle_time: 0.001
|
||||
# PWM frequency : 0.001 = 1ms will give a base tone of 1kHz
|
||||
#scale: 1000
|
||||
# PWM parameter will be in the range of (0-1000 Hz).
|
||||
# Although not pitch perfect.
|
||||
#
|
||||
#[gcode_macro M300]
|
||||
#default_parameter_S=1000
|
||||
# Allows for a default 1kHz tone if S is omitted
|
||||
#default_parameter_P=100
|
||||
# Allows for a default 10ms duration is P is omitted
|
||||
#gcode: SET_PIN PIN=BEEPER_pin VALUE={S}
|
||||
# G4 P{P}
|
||||
# SET_PIN PIN=BEEPER_pin VALUE=0
|
||||
51
config/sample-probe-as-z-endstop.cfg
Normal file
@@ -0,0 +1,51 @@
|
||||
# This file provides example config file settings for use on a printer
|
||||
# that uses a Z probe instead of a traditional Z endstop switch. This
|
||||
# file is just a "snippet" of config sections - it must be added to a
|
||||
# config file containing the configuration of the rest of the printer.
|
||||
|
||||
# Be sure to review and update this config with the appropriate pins
|
||||
# and coordinates for your printer.
|
||||
|
||||
# See the "example.cfg" and "example-extras.cfg" files for a
|
||||
# description of config parameters.
|
||||
|
||||
# Define a probe
|
||||
[probe]
|
||||
pin: ar30
|
||||
z_offset: 2.345
|
||||
|
||||
# Example settings to add to stepper_z section
|
||||
[stepper_z]
|
||||
endstop_pin: probe:z_virtual_endstop
|
||||
position_min: -2 # The Z carriage may need to travel below the Z=0
|
||||
# homing point if the bed has a significant tilt.
|
||||
|
||||
# The homing_override section modifies the default G28 behavior
|
||||
[homing_override]
|
||||
set_position_z: 5
|
||||
axes: z
|
||||
gcode:
|
||||
; G90 ; Uncomment these 2 lines to blindly lift the Z 2mm at start
|
||||
; G1 Z7 F600
|
||||
G28 X0 Y0
|
||||
G1 X100 Y100 F3600
|
||||
G28 Z0
|
||||
|
||||
# Example bed_tilt config section
|
||||
[bed_tilt]
|
||||
points:
|
||||
100,100
|
||||
10,10
|
||||
10,100
|
||||
10,190
|
||||
100,10
|
||||
100,190
|
||||
190,10
|
||||
190,100
|
||||
190,190
|
||||
|
||||
# Example bed_mesh config section
|
||||
[bed_mesh]
|
||||
min_point: 20,20
|
||||
max_point: 200,200
|
||||
probe_count: 4,4
|
||||
272
docs/Bootloaders.md
Executable file
@@ -0,0 +1,272 @@
|
||||
This document provides information on common bootloaders found on
|
||||
micro-controllers that Klipper supports.
|
||||
|
||||
The bootloader is 3rd-party software that runs on the micro-controller
|
||||
when it is first powered on. It is typically used to flash a new
|
||||
application (eg, Klipper) to the micro-controller without requiring
|
||||
specialized hardware. Unfortunately, there is no industry wide
|
||||
standard for flashing a micro-controller, nor is there a standard
|
||||
bootloader that works across all micro-controllers. Worse, it is
|
||||
common for each bootloader to require a different set of steps to
|
||||
flash an application.
|
||||
|
||||
If one can flash a bootloader to a micro-controller then one can
|
||||
generally also use that mechanism to flash an application, but care
|
||||
should be taken when doing this as one may inadvertently remove the
|
||||
bootloader. In contrast, a bootloader will generally only permit a
|
||||
user to flash an application. It is therefore recommended to use a
|
||||
bootloader to flash an application where possible.
|
||||
|
||||
This document attempts to describe common bootloaders, the steps
|
||||
needed to flash a bootloader, and the steps needed to flash an
|
||||
application. This document is not an authoritative reference; it is
|
||||
intended as a collection of useful information that the Klipper
|
||||
developers have accumulated.
|
||||
|
||||
AVR micro-controllers
|
||||
=====================
|
||||
|
||||
In general, the Arduino project is a good reference for bootloaders
|
||||
and flashing procedures on the 8-bit Atmel Atmega micro-controllers.
|
||||
In particular, the "boards.txt" file:
|
||||
https://github.com/arduino/Arduino/blob/1.8.5/hardware/arduino/avr/boards.txt
|
||||
is a useful reference.
|
||||
|
||||
To flash a bootloader itself, the AVR chips require an external
|
||||
hardware flashing tool (which communicates with the chip using
|
||||
SPI). This tool can be purchased (for example, do a web search for
|
||||
"avr isp", "arduino isp", or "usb tiny isp"). It is also possible to
|
||||
use another Arduino or Raspberry Pi to flash an AVR bootloader (for
|
||||
example, do a web search for "program an avr using raspberry pi"). The
|
||||
examples below are written assuming an "AVR ISP Mk2" type device is in
|
||||
use.
|
||||
|
||||
The "avrdude" program is the most common tool used to flash atmega
|
||||
chips (both bootloader flashing and application flashing).
|
||||
|
||||
## Atmega2560 ##
|
||||
|
||||
This chip is typically found in the "Arduino Mega" and is very common
|
||||
in 3d printer boards.
|
||||
|
||||
To flash the bootloader itself use something like:
|
||||
```
|
||||
wget 'https://github.com/arduino/Arduino/raw/1.8.5/hardware/arduino/avr/bootloaders/stk500v2/stk500boot_v2_mega2560.hex'
|
||||
|
||||
avrdude -cavrispv2 -patmega2560 -P/dev/ttyACM0 -b115200 -e -u -U lock:w:0x3F:m -U efuse:w:0xFD:m -U hfuse:w:0xD8:m -U lfuse:w:0xFF:m
|
||||
avrdude -cavrispv2 -patmega2560 -P/dev/ttyACM0 -b115200 -U flash:w:stk500boot_v2_mega2560.hex
|
||||
avrdude -cavrispv2 -patmega2560 -P/dev/ttyACM0 -b115200 -U lock:w:0x0F:m
|
||||
```
|
||||
|
||||
To flash an application use something like:
|
||||
```
|
||||
avrdude -cwiring -patmega2560 -P/dev/ttyACM0 -b115200 -D -Uflash:w:out/klipper.elf.hex:i
|
||||
```
|
||||
|
||||
## Atmega1280 ##
|
||||
|
||||
This chip is typically found in earlier versions of the "Arduino
|
||||
Mega".
|
||||
|
||||
To flash the bootloader itself use something like:
|
||||
```
|
||||
wget 'https://github.com/arduino/Arduino/raw/1.8.5/hardware/arduino/avr/bootloaders/atmega/ATmegaBOOT_168_atmega1280.hex'
|
||||
|
||||
avrdude -cavrispv2 -patmega1280 -P/dev/ttyACM0 -b115200 -e -u -U lock:w:0x3F:m -U efuse:w:0xF5:m -U hfuse:w:0xDA:m -U lfuse:w:0xFF:m
|
||||
avrdude -cavrispv2 -patmega1280 -P/dev/ttyACM0 -b115200 -U flash:w:ATmegaBOOT_168_atmega1280.hex
|
||||
avrdude -cavrispv2 -patmega1280 -P/dev/ttyACM0 -b115200 -U lock:w:0x0F:m
|
||||
```
|
||||
|
||||
To flash an application use something like:
|
||||
```
|
||||
avrdude -carduino -patmega1280 -P/dev/ttyACM0 -b57600 -D -Uflash:w:out/klipper.elf.hex:i
|
||||
```
|
||||
|
||||
## Atmega1284p ##
|
||||
|
||||
This chip is commonly found in "Melzi" style 3d printer boards.
|
||||
|
||||
To flash the bootloader itself use something like:
|
||||
```
|
||||
wget 'https://github.com/Lauszus/Sanguino/raw/1.0.2/bootloaders/optiboot/optiboot_atmega1284p.hex'
|
||||
|
||||
avrdude -cavrispv2 -patmega1284p -P/dev/ttyACM0 -b115200 -e -u -U lock:w:0x3F:m -U efuse:w:0xFD:m -U hfuse:w:0xDE:m -U lfuse:w:0xFF:m
|
||||
avrdude -cavrispv2 -patmega1284p -P/dev/ttyACM0 -b115200 -U flash:w:optiboot_atmega1284p.hex
|
||||
avrdude -cavrispv2 -patmega1284p -P/dev/ttyACM0 -b115200 -U lock:w:0x0F:m
|
||||
```
|
||||
|
||||
To flash an application use something like:
|
||||
```
|
||||
avrdude -carduino -patmega1284p -P/dev/ttyACM0 -b115200 -D -Uflash:w:out/klipper.elf.hex:i
|
||||
```
|
||||
|
||||
Note that a number of "Melzi" style boards come preloaded with a
|
||||
bootloader that uses a baud rate of 57600. In this case, to flash an
|
||||
application use something like this instead:
|
||||
```
|
||||
avrdude -carduino -patmega1284p -P/dev/ttyACM0 -b57600 -D -Uflash:w:out/klipper.elf.hex:i
|
||||
```
|
||||
|
||||
## At90usb1286 ##
|
||||
|
||||
This document does not cover the method to flash a bootloader to the
|
||||
At90usb1286 nor does it cover general application flashing to this
|
||||
device.
|
||||
|
||||
The Teensy++ device from pjrc.com comes with a proprietary bootloader.
|
||||
It requires a custom flashing tool from
|
||||
https://github.com/PaulStoffregen/teensy_loader_cli . One can flash an
|
||||
application with it using something like:
|
||||
```
|
||||
teensy_loader_cli --mcu=at90usb1286 out/klipper.elf.hex -v
|
||||
```
|
||||
|
||||
## Atmega168 ##
|
||||
|
||||
The atmega168 has limited flash space. If using a bootloader, it is
|
||||
recommended to use the Optiboot bootloader. To flash that bootloader
|
||||
use something like:
|
||||
```
|
||||
wget 'https://github.com/arduino/Arduino/raw/1.8.5/hardware/arduino/avr/bootloaders/optiboot/optiboot_atmega168.hex'
|
||||
|
||||
avrdude -cavrispv2 -patmega168 -P/dev/ttyACM0 -b115200 -e -u -U lock:w:0x3F:m -U efuse:w:0x04:m -U hfuse:w:0xDD:m -U lfuse:w:0xFF:m
|
||||
avrdude -cavrispv2 -patmega168 -P/dev/ttyACM0 -b115200 -U flash:w:optiboot_atmega168.hex
|
||||
avrdude -cavrispv2 -patmega168 -P/dev/ttyACM0 -b115200 -U lock:w:0x0F:m
|
||||
```
|
||||
|
||||
To flash an application via the Optiboot bootloader use something
|
||||
like:
|
||||
```
|
||||
avrdude -carduino -patmega168 -P/dev/ttyACM0 -b115200 -D -Uflash:w:out/klipper.elf.hex:i
|
||||
```
|
||||
|
||||
SAM3 micro-controllers (Arduino Due)
|
||||
====================================
|
||||
|
||||
It is not common to use a bootloader with the SAM3 mcu. The chip
|
||||
itself has a ROM that allows the flash to be programmed from 3.3V
|
||||
serial port or from USB.
|
||||
|
||||
To enable the ROM, the "erase" pin is held high during a reset, which
|
||||
erases the flash contents, and causes the ROM to run. On an Arduino
|
||||
Due, this sequence can be accomplished by setting a baud rate of 1200
|
||||
on the "programming usb port" (the USB port closest to the power
|
||||
supply).
|
||||
|
||||
The code at https://github.com/shumatech/BOSSA can be used to program
|
||||
the SAM3. It is recommended to use version 1.9 or later.
|
||||
|
||||
To flash an application use something like:
|
||||
```
|
||||
bossac -U -p /dev/ttyACM0 -a -e -w out/klipper.bin -v -b
|
||||
bossac -U -p /dev/ttyACM0 -R
|
||||
```
|
||||
|
||||
SAM4 micro-controllers (Duet Wifi)
|
||||
====================================
|
||||
|
||||
It is not common to use a bootloader with the SAM4 mcu. The chip
|
||||
itself has a ROM that allows the flash to be programmed from 3.3V
|
||||
serial port or from USB.
|
||||
|
||||
To enable the ROM, the "erase" pin is held high during a reset, which
|
||||
erases the flash contents, and causes the ROM to run.
|
||||
|
||||
The code at https://github.com/shumatech/BOSSA can be used to program
|
||||
the SAM4. It is necessary to use version `1.8.0` or higher.
|
||||
|
||||
To flash an application use something like:
|
||||
```
|
||||
bossac --port=/dev/ttyACM0 -b -U -e -w -v -R out/klipper.bin
|
||||
```
|
||||
|
||||
SAMD21 micro-controllers (Arduino Zero)
|
||||
=======================================
|
||||
|
||||
The SAMD21 bootloader is flashed via the ARM Serial Wire Debug (SWD)
|
||||
interface. This is commonly done with a dedicated SWD hardware dongle.
|
||||
Alternatively, it appears one can use a Raspberry Pi with OpenOCD as a
|
||||
programmer (see:
|
||||
https://learn.adafruit.com/programming-microcontrollers-using-openocd-on-raspberry-pi
|
||||
).
|
||||
|
||||
Unfortunately, there are two common bootloaders deployed on the
|
||||
SAMD21. One comes standard with the "Arduino Zero" and the other comes
|
||||
standard with the "Arduino M0".
|
||||
|
||||
The Arduino Zero uses an 8KiB bootloader (the application must be
|
||||
compiled with a start address of 8KiB). One can enter the bootloader
|
||||
by double clicking the reset button. To flash an application use
|
||||
something like:
|
||||
```
|
||||
bossac -U -p "$(FLASH_DEVICE)" --offset=0x2000 -w out/klipper.bin -v -b -R
|
||||
```
|
||||
|
||||
The Arduino M0 uses a 16KiB bootloader (the application must be
|
||||
compiled with a start address of 16KiB). To flash an application,
|
||||
reset the micro-controller and run the flash command within the first
|
||||
few seconds of boot - something like:
|
||||
```
|
||||
avrdude -c stk500v2 -p atmega2560 -P /dev/ttyACM0 -u -Uflash:w:out/klipper.elf.hex:i
|
||||
```
|
||||
|
||||
STM32F103 micro-controllers (Blue Pill devices)
|
||||
===============================================
|
||||
|
||||
The STM32F103 devices have a ROM that can flash a bootloader or
|
||||
application via 3.3V serial. To access this ROM, one should connect
|
||||
the "boot 0" pin to high and "boot 1" pin to low, and then reset the
|
||||
device. The "stm32flash" package can then be used to flash the device
|
||||
using something like:
|
||||
```
|
||||
stm32flash -w out/klipper.bin -v -g 0 /dev/ttyAMA0
|
||||
```
|
||||
|
||||
Note that if one is using a Raspberry Pi for the 3.3V serial, the
|
||||
stm32flash protocol uses a serial parity mode which the Raspberry Pi's
|
||||
"miniuart" does not support. See
|
||||
https://www.raspberrypi.org/documentation/configuration/uart.md for
|
||||
details on enabling the full uart on the Raspberry Pi GPIO pins.
|
||||
|
||||
After flashing, set both "boot 0" and "boot 1" back to low so that
|
||||
future resets boot from flash.
|
||||
|
||||
## STM32F103 with stm32duino bootloader ##
|
||||
|
||||
The "stm32duino" project has a USB capable bootloader - see:
|
||||
https://github.com/rogerclarkmelbourne/STM32duino-bootloader
|
||||
|
||||
This bootloader can be flashed via 3.3V serial with something like:
|
||||
```
|
||||
wget 'https://github.com/rogerclarkmelbourne/STM32duino-bootloader/raw/master/binaries/generic_boot20_pc13.bin'
|
||||
|
||||
stm32flash -w generic_boot20_pc13.bin -v -g 0 /dev/ttyAMA0
|
||||
```
|
||||
|
||||
This bootloader uses 8KiB of flash space (the application must be
|
||||
compiled with a start address of 8KiB). Flash an application with
|
||||
something like:
|
||||
```
|
||||
dfu-util -d 1eaf:0003 -a 2 -R -D out/klipper.bin
|
||||
```
|
||||
|
||||
The bootloader typically runs for only a short period after boot. It
|
||||
may be necessary to time the above command so that it runs while the
|
||||
bootloader is still active (the bootloader will flash a board led
|
||||
while it is running). Alternatively, set the "boot 0" pin to low and
|
||||
"boot 1" pin to high to stay in the bootloader after a reset.
|
||||
|
||||
LPC176x micro-controllers (Smoothieboards)
|
||||
==========================================
|
||||
|
||||
This document does not describe the method to flash a bootloader
|
||||
itself - see: http://smoothieware.org/flashing-the-bootloader for
|
||||
further information on that topic.
|
||||
|
||||
It is common for Smoothieboards to come with a bootloader from:
|
||||
https://github.com/triffid/LPC17xx-DFU-Bootloader . When using this
|
||||
bootloader the application must be compiled with a start address of
|
||||
16KiB. The easiest way to flash an application with this bootloader is
|
||||
to copy the application file (eg, `out/klipper.bin`) to a file named
|
||||
`firmware.bin` on an SD card, and then to reboot the micro-controller
|
||||
with that SD card.
|
||||
@@ -17,8 +17,11 @@ arranges for includes of "board/somefile.h" to first look in the
|
||||
current architecture directory (eg, src/avr/somefile.h) and then in
|
||||
the generic directory (eg, src/generic/somefile.h).
|
||||
|
||||
The **klippy/** directory contains the C and Python source for the
|
||||
host part of the software.
|
||||
The **klippy/** directory contains the host software. Most of the host
|
||||
software is written in Python, however the **klippy/chelper/**
|
||||
directory contains some C code helpers. The **klippy/kinematics/**
|
||||
directory contains the robot kinematics code. The **klippy/extras/**
|
||||
directory contains the host code extensible "modules".
|
||||
|
||||
The **lib/** directory contains external 3rd-party library code that
|
||||
is necessary to build some targets.
|
||||
@@ -105,9 +108,9 @@ DECL_COMMAND macro in the micro-controller code).
|
||||
|
||||
There are four threads in the Klippy host code. The main thread
|
||||
handles incoming gcode commands. A second thread (which resides
|
||||
entirely in the **klippy/serialqueue.c** C code) handles low-level IO
|
||||
with the serial port. The third thread is used to process response
|
||||
messages from the micro-controller in the Python code (see
|
||||
entirely in the **klippy/chelper/serialqueue.c** C code) handles
|
||||
low-level IO with the serial port. The third thread is used to process
|
||||
response messages from the micro-controller in the Python code (see
|
||||
**klippy/serialhdl.py**). The fourth thread writes debug messages to
|
||||
the log (see **klippy/queuelogger.py**) so that the other threads
|
||||
never block on log writes.
|
||||
@@ -147,7 +150,7 @@ provides further information on the mechanics of moves.
|
||||
zero duration.
|
||||
* When Move.move() is called, everything about the move is known -
|
||||
its start location, its end location, its acceleration, its
|
||||
start/crusing/end velocity, and distance traveled during
|
||||
start/cruising/end velocity, and distance traveled during
|
||||
acceleration/cruising/deceleration. All the information is stored in
|
||||
the Move() class and is in cartesian space in units of millimeters
|
||||
and seconds.
|
||||
@@ -157,56 +160,65 @@ provides further information on the mechanics of moves.
|
||||
|
||||
* The goal of the kinematics classes is to translate the movement in
|
||||
cartesian space to movement on each stepper. The kinematics classes
|
||||
are in cartesian.py, corexy.py, delta.py, and extruder.py. The
|
||||
kinematic class is given a chance to audit the move
|
||||
(`ToolHead.move() -> kin.check_move()`) before it goes on the
|
||||
look-ahead queue, but once the move arrives in *kin*.move() the
|
||||
kinematic class is required to handle the move as specified. The
|
||||
kinematic classes translate the three parts of each move
|
||||
(acceleration, constant "cruising" velocity, and deceleration) to
|
||||
the associated movement on each stepper. Note that the extruder is
|
||||
handled in its own kinematic class. Since the Move() class specifies
|
||||
the exact movement time and since step pulses are sent to the
|
||||
micro-controller with specific timing, stepper movements produced by
|
||||
the extruder class will be in sync with head movement even though
|
||||
the code is kept separate.
|
||||
are located in the klippy/kinematics/ directory. The kinematic class
|
||||
is given a chance to audit the move (`ToolHead.move() ->
|
||||
kin.check_move()`) before it goes on the look-ahead queue, but once
|
||||
the move arrives in *kin*.move() the kinematic class is required to
|
||||
handle the move as specified. Note that the extruder is handled in
|
||||
its own kinematic class. Since the Move() class specifies the exact
|
||||
movement time and since step pulses are sent to the micro-controller
|
||||
with specific timing, stepper movements produced by the extruder
|
||||
class will be in sync with head movement even though the code is
|
||||
kept separate.
|
||||
|
||||
* For efficiency reasons, the stepper pulse times are generated in C
|
||||
code. The code flow is: `kin.move() -> MCU_Stepper.step_const() ->
|
||||
stepcompress_push_const()`, or for delta kinematics:
|
||||
`DeltaKinematics.move() -> MCU_Stepper.step_delta() ->
|
||||
stepcompress_push_delta()`. The MCU_Stepper code just performs unit
|
||||
and axis transformation (millimeters to step distances), and calls
|
||||
the C code. The C code calculates the stepper step times for each
|
||||
movement and fills an array (struct stepcompress.queue) with the
|
||||
corresponding micro-controller clock counter times for every
|
||||
step. Here the "micro-controller clock counter" value directly
|
||||
corresponds to the micro-controller's hardware counter - it is
|
||||
relative to when the micro-controller was last powered up.
|
||||
* Klipper uses an
|
||||
[iterative solver](https://en.wikipedia.org/wiki/Root-finding_algorithm)
|
||||
to generate the step times for each stepper. For efficiency reasons,
|
||||
the stepper pulse times are generated in C code. The code flow is:
|
||||
`kin.move() -> MCU_Stepper.step_itersolve() ->
|
||||
itersolve_gen_steps()` (in klippy/chelper/itersolve.c). The goal of
|
||||
the iterative solver is to find step times given a function that
|
||||
calculates a stepper position from a time. This is done by
|
||||
repeatedly "guessing" various times until the stepper position
|
||||
formula returns the desired position of the next step on the
|
||||
stepper. The feedback produced from each guess is used to improve
|
||||
future guesses so that the process rapidly converges to the desired
|
||||
time. The kinematic stepper position formulas are located in the
|
||||
klippy/chelper/ directory (eg, kin_cart.c, kin_corexy.c,
|
||||
kin_delta.c, kin_extruder.c).
|
||||
|
||||
* After the iterative solver calculates the step times they are added
|
||||
to an array: `itersolve_gen_steps() -> queue_append()` (in
|
||||
klippy/chelper/stepcompress.c). The array (struct
|
||||
stepcompress.queue) stores the corresponding micro-controller clock
|
||||
counter times for every step. Here the "micro-controller clock
|
||||
counter" value directly corresponds to the micro-controller's
|
||||
hardware counter - it is relative to when the micro-controller was
|
||||
last powered up.
|
||||
|
||||
* The next major step is to compress the steps: `stepcompress_flush()
|
||||
-> compress_bisect_add()` (in stepcompress.c). This code generates
|
||||
and encodes a series of micro-controller "queue_step" commands that
|
||||
correspond to the list of stepper step times built in the previous
|
||||
stage. These "queue_step" commands are then queued, prioritized, and
|
||||
sent to the micro-controller (via stepcompress.c:steppersync and
|
||||
serialqueue.c:serialqueue).
|
||||
-> compress_bisect_add()` (in klippy/chelper/stepcompress.c). This
|
||||
code generates and encodes a series of micro-controller "queue_step"
|
||||
commands that correspond to the list of stepper step times built in
|
||||
the previous stage. These "queue_step" commands are then queued,
|
||||
prioritized, and sent to the micro-controller (via
|
||||
stepcompress.c:steppersync and serialqueue.c:serialqueue).
|
||||
|
||||
* Processing of the queue_step commands on the micro-controller starts
|
||||
in command.c which parses the command and calls
|
||||
`command_queue_step()`. The command_queue_step() code (in stepper.c)
|
||||
just appends the parameters of each queue_step command to a per
|
||||
stepper queue. Under normal operation the queue_step command is
|
||||
parsed and queued at least 100ms before the time of its first
|
||||
step. Finally, the generation of stepper events is done in
|
||||
`stepper_event()`. It's called from the hardware timer interrupt at
|
||||
the scheduled time of the first step. The stepper_event() code
|
||||
generates a step pulse and then reschedules itself to run at the
|
||||
time of the next step pulse for the given queue_step parameters. The
|
||||
parameters for each queue_step command are "interval", "count", and
|
||||
"add". At a high-level, stepper_event() runs the following, 'count'
|
||||
times: `do_step(); next_wake_time = last_wake_time + interval;
|
||||
interval += add;`
|
||||
in src/command.c which parses the command and calls
|
||||
`command_queue_step()`. The command_queue_step() code (in
|
||||
src/stepper.c) just appends the parameters of each queue_step
|
||||
command to a per stepper queue. Under normal operation the
|
||||
queue_step command is parsed and queued at least 100ms before the
|
||||
time of its first step. Finally, the generation of stepper events is
|
||||
done in `stepper_event()`. It's called from the hardware timer
|
||||
interrupt at the scheduled time of the first step. The
|
||||
stepper_event() code generates a step pulse and then reschedules
|
||||
itself to run at the time of the next step pulse for the given
|
||||
queue_step parameters. The parameters for each queue_step command
|
||||
are "interval", "count", and "add". At a high-level, stepper_event()
|
||||
runs the following, 'count' times: `do_step(); next_wake_time =
|
||||
last_wake_time + interval; interval += add;`
|
||||
|
||||
The above may seem like a lot of complexity to execute a
|
||||
movement. However, the only really interesting parts are in the
|
||||
@@ -291,84 +303,91 @@ This section provides some tips on adding support to Klipper for
|
||||
additional types of printer kinematics. This type of activity requires
|
||||
excellent understanding of the math formulas for the target
|
||||
kinematics. It also requires software development skills - though one
|
||||
should only need to update the host software (which is written in
|
||||
Python).
|
||||
should only need to update the host software.
|
||||
|
||||
Useful steps:
|
||||
1. Start by studying the [above section](#code-flow-of-a-move-command)
|
||||
and the [Kinematics document](Kinematics.md).
|
||||
2. Review the existing kinematic classes in cartesian.py, corexy.py,
|
||||
and delta.py. The kinematic classes are tasked with converting a
|
||||
move in cartesian coordinates to the movement on each stepper. One
|
||||
1. Start by studying the
|
||||
"[code flow of a move](#code-flow-of-a-move-command)" section and
|
||||
the [Kinematics document](Kinematics.md).
|
||||
2. Review the existing kinematic classes in the klippy/kinematics/
|
||||
directory. The kinematic classes are tasked with converting a move
|
||||
in cartesian coordinates to the movement on each stepper. One
|
||||
should be able to copy one of these files as a starting point.
|
||||
3. Implement the `get_postion()` method in the new kinematics
|
||||
class. This method converts the current stepper position of each
|
||||
stepper axis (stored in millimeters) to a position in cartesian
|
||||
space (also in millimeters).
|
||||
4. Implement the `set_postion()` method. This is the inverse of
|
||||
get_position() - it sets each axis position (in millimeters) given
|
||||
a position in cartesian coordinates.
|
||||
5. Implement the `move()` method. The goal of the move() method is to
|
||||
convert a move defined in cartesian space to a series of stepper
|
||||
step times that implement the requested movement.
|
||||
* The `move()` method is passed a "print_time" parameter (which
|
||||
stores a time in seconds) and a "move" class instance that fully
|
||||
defines the movement. The goal is to repeatedly invoke the
|
||||
`stepper.step()` method with the time (relative to print_time)
|
||||
that each stepper should step at to obtain the desired motion.
|
||||
* One "trick" to help with the movement calculations is to imagine
|
||||
there is a physical rail between `move.start_pos` and
|
||||
`move.end_pos` that confines the print head so that it can only
|
||||
move along this straight line of motion. Then, if the head is
|
||||
confined to that imaginary rail, the head is at `move.start_pos`,
|
||||
only one stepper is enabled (all other steppers can move freely),
|
||||
and the given stepper is stepped a single step, then one can
|
||||
imagine that the head will move along the line of movement some
|
||||
distance. Determine the formula converting this step distance to
|
||||
distance along the line of movement. Once one has the distance
|
||||
along the line of movement, one can figure out the time that the
|
||||
head should be at that position (using the standard formulas for
|
||||
velocity and acceleration). This time is the ideal step time for
|
||||
the given stepper and it can be passed to the `stepper.step()`
|
||||
method.
|
||||
* The `stepper.step()` method must always be called with an
|
||||
increasing time for a given stepper (steps must be scheduled in
|
||||
the order they are to be executed). A common error during
|
||||
kinematic development is to receive an "Internal error in
|
||||
stepcompress" failure - this is generally due to the step()
|
||||
method being invoked with a time earlier than the last scheduled
|
||||
step. For example, if the last step in move1 is scheduled at a
|
||||
time greater than the first step in move2 it will generally
|
||||
result in the above error.
|
||||
* Fractional steps. Be aware that a move request is given in
|
||||
cartesian space and it is not confined to discreet
|
||||
locations. Thus a move's start and end locations may translate to
|
||||
a location on a stepper axis that is between two steps (a
|
||||
fractional step). The code must handle this. The preferred
|
||||
approach is to schedule the next step at the time a move would
|
||||
position the stepper axis at least half way towards the next
|
||||
possible step location. Incorrect handling of fractional steps is
|
||||
a common cause of "Internal error in stepcompress" failures.
|
||||
6. Other methods. The `home()`, `check_move()`, and other methods
|
||||
should also be implemented. However, at the start of development
|
||||
one can use empty code here.
|
||||
7. Implement test cases. Create a g-code file with a series of moves
|
||||
3. Implement the C stepper kinematic position functions for each
|
||||
stepper if they are not already available (see kin_cart.c,
|
||||
kin_corexy.c, and kin_delta.c in klippy/chelper/). The function
|
||||
should call `move_get_coord()` to convert a given move time (in
|
||||
seconds) to a cartesian coordinate (in millimeters), and then
|
||||
calculate the desired stepper position (in millimeters) from that
|
||||
cartesian coordinate.
|
||||
4. Implement the `calc_position()` method in the new kinematics class.
|
||||
This method calculates the position of the toolhead in cartesian
|
||||
coordinates from the current position of each stepper. It does not
|
||||
need to be efficient as it is typically only called during homing
|
||||
and probing operations.
|
||||
5. Other methods. Implement the `move()`, `check_move()`, `home()`,
|
||||
`motor_off()`, `set_position()`, and `get_steppers()` methods.
|
||||
These functions are typically used to provide kinematic specific
|
||||
checks. However, at the start of development one can use
|
||||
boiler-plate code here.
|
||||
6. Implement test cases. Create a g-code file with a series of moves
|
||||
that can test important cases for the given kinematics. Follow the
|
||||
[debugging documentation](Debugging.md) to convert this g-code file
|
||||
to micro-controller commands. This is useful to exercise corner
|
||||
cases and to check for regressions.
|
||||
8. Optimize if needed. One may notice that the existing kinematic
|
||||
classes do not call `stepper.step()`. This is purely an
|
||||
optimization - the inner loop of the kinematic calculations were
|
||||
moved to C to reduce load on the host cpu. All of the existing
|
||||
kinematic classes started development using `stepper.step()` and
|
||||
then were later optimized. The g-code to mcu command translation
|
||||
(described in the previous step) is a useful tool during
|
||||
optimization - if a code change is purely an optimization then it
|
||||
should not impact the resulting text representation of the mcu
|
||||
commands (though minor changes in output due to floating point
|
||||
rounding are possible). So, one can use this system to detect
|
||||
regressions.
|
||||
|
||||
Porting to a new micro-controller
|
||||
=================================
|
||||
|
||||
This section provides some tips on porting Klipper's micro-controller
|
||||
code to a new architecture. This type of activity requires good
|
||||
knowledge of embedded development and hands-on access to the target
|
||||
micro-controller.
|
||||
|
||||
Useful steps:
|
||||
1. Start by identifying any 3rd party libraries that will be used
|
||||
during the port. Common examples include "CMSIS" wrappers and
|
||||
manufacturer "HAL" libraries. All 3rd party code needs to be GNU
|
||||
GPLv3 compatible. The 3rd party code should be committed to the
|
||||
Klipper lib/ directory. Update the lib/README file with information
|
||||
on where and when the library was obtained. It is preferable to
|
||||
copy the code into the Klipper repository unchanged, but if any
|
||||
changes are required then those changes should be listed explicitly
|
||||
in the lib/README file.
|
||||
2. Create a new architecture sub-directory in the src/ directory and
|
||||
add initial Kconfig and Makefile support. Use the existing
|
||||
architectures as a guide. The src/simulator provides a basic
|
||||
example of a minimum starting point.
|
||||
3. The first main coding task is to bring up communication support to
|
||||
the target board. This is the most difficult step in a new port.
|
||||
Once basic communication is working, the remaining steps tend to be
|
||||
much easier. It is typical to use an RS-232 style serial port
|
||||
during initial development as these types of hardware devices are
|
||||
generally easier to enable and control. During this phase, make
|
||||
liberal use of helper code from the src/generic/ directory (check
|
||||
how src/simulator/Makefile includes the generic C code into the
|
||||
build). It is also necessary to define timer_read_time() (which
|
||||
returns the current system clock) in this phase, but it is not
|
||||
necessary to fully support timer irq handling.
|
||||
4. Get familiar with the the console.py tool (as described in the
|
||||
[debugging document](Debugging.md)) and verify connectivity to the
|
||||
micro-controller with it. This tool translates the low-level
|
||||
micro-controller communication protocol to a human readable form.
|
||||
5. Add support for timer dispatch from hardware interrupts. See
|
||||
Klipper
|
||||
[commit 970831ee](https://github.com/KevinOConnor/klipper/commit/970831ee0d3b91897196e92270d98b2a3067427f)
|
||||
as an example of steps 1-5 done for the LPC176x architecture.
|
||||
6. Bring up basic GPIO input and output support. See Klipper
|
||||
[commit c78b9076](https://github.com/KevinOConnor/klipper/commit/c78b90767f19c9e8510c3155b89fb7ad64ca3c54)
|
||||
as an example of this.
|
||||
7. Bring up additional peripherals - for example see Klipper commit
|
||||
[65613aed](https://github.com/KevinOConnor/klipper/commit/65613aeddfb9ef86905cb1dade9e773a02ef3c27),
|
||||
[c812a40a](https://github.com/KevinOConnor/klipper/commit/c812a40a3782415e454b04bf7bd2158a6f0ec8b5),
|
||||
and
|
||||
[c381d03a](https://github.com/KevinOConnor/klipper/commit/c381d03aad5c3ee761169b7c7bced519cc14da29).
|
||||
8. Create a sample Klipper config file in the config/ directory. Test
|
||||
the micro-controller with the main klippy.py program.
|
||||
9. Consider adding build test cases in the test/ directory.
|
||||
|
||||
Time
|
||||
====
|
||||
@@ -424,8 +443,8 @@ Some things to be aware of when reviewing the code:
|
||||
conversion is never ambiguous. The host converts from 64bit clocks
|
||||
to 32bit clocks by simply truncating the high-order bits. To ensure
|
||||
there is no ambiguity in this conversion, the
|
||||
**klippy/serialqueue.c** code will buffer messages until they are
|
||||
within 2^31 clock ticks of their target time.
|
||||
**klippy/chelper/serialqueue.c** code will buffer messages until
|
||||
they are within 2^31 clock ticks of their target time.
|
||||
* Multiple micro-controllers: The host software supports using
|
||||
multiple micro-controllers on a single printer. In this case, the
|
||||
"MCU clock" of each micro-controller is tracked separately. The
|
||||
|
||||
@@ -81,27 +81,38 @@ require a change to the pullup setting of the pin (the '^' at the
|
||||
start of the endstop_pin name - most printers will use a pullup
|
||||
resistor and the '^' should be present).
|
||||
|
||||
### Verify stepper motor direction
|
||||
### Verify stepper motors
|
||||
|
||||
Make sure the printer.cfg file does not have "homing_speed" set for
|
||||
any axis (or set it to a value of 5 or less).
|
||||
Use the STEPPER_BUZZ command to verify the connectivity of each
|
||||
stepper motor. Start by manually positioning the given axis to a
|
||||
midway point and then run `STEPPER_BUZZ STEPPER=stepper_x` . The
|
||||
STEPPER_BUZZ command will cause the given stepper to move one
|
||||
millimeter in a positive direction and then it will return to its
|
||||
starting position. (If the endstop is defined at position_endstop=0
|
||||
then at the start of each movement the stepper will move away from the
|
||||
endstop.) It will perform this oscillation ten times.
|
||||
|
||||
On cartesian style printers, manually move the X axis to a midway
|
||||
point, issue a G28X0 command, and verify that the X motor moves slowly
|
||||
towards the endstop defined for that axis. If the motor moves in the
|
||||
wrong direction issue an M112 command to abort the move. A wrong
|
||||
direction generally indicates that the "dir_pin" for the axis needs to
|
||||
If the stepper does not move at all, then verify the "enable_pin" and
|
||||
"step_pin" settings for the stepper. If the stepper motor moves but
|
||||
does not return to its original position then verify the "dir_pin"
|
||||
setting. If the stepper motor oscillates in an incorrect direction,
|
||||
then it generally indicates that the "dir_pin" for the axis needs to
|
||||
be inverted. This is done by adding a '!' to the "dir_pin" in the
|
||||
printer config file (or removing it if one is already there). For
|
||||
example, change "dir_pin: xyz" to "dir_pin: !xyz". Then RESTART and
|
||||
retest the axis. If the axis does not move at all, then verify the
|
||||
"enable_pin" and "step_pin" settings for the axis. For cartesian style
|
||||
printers, repeat the test for the Y and Z axis with G28Y0 and G28Z0.
|
||||
printer config file (or removing it if one is already there). If the
|
||||
motor moves significantly more or significantly less than one
|
||||
millimeter then verify the "step_distance" setting.
|
||||
|
||||
For delta style printers, manually move all three carriages to a
|
||||
midway point and then issue a G28 command. Verify all three motors
|
||||
move simultaneously upwards. If not, issue an M112 command and follow
|
||||
the troubleshooting steps in the preceding paragraph.
|
||||
Run the above test for each stepper motor defined in the config
|
||||
file. (Set the STEPPER parameter of the STEPPER_BUZZ command to the
|
||||
name of the config section that is to be tested.) If there is no
|
||||
filament in the extruder then one can use STEPPER_BUZZ to verify the
|
||||
extruder motor connectivity (use STEPPER=extruder). Otherwise, it's
|
||||
best to test the extruder motor separately (see the next section).
|
||||
|
||||
After verifying all endstops and verifying all stepper motors the
|
||||
homing mechanism should be tested. Issue a G28 command to home all
|
||||
axes. Remove power from the printer if it does not home properly.
|
||||
Rerun the endstop and stepper motor verification steps if necessary.
|
||||
|
||||
### Verify extruder motor
|
||||
|
||||
@@ -128,8 +139,8 @@ To calibrate the extruder, navigate to the OctoPrint terminal tab and
|
||||
run the PID_CALIBRATE command. For example: `PID_CALIBRATE
|
||||
HEATER=extruder TARGET=170`
|
||||
|
||||
At the completion of the tuning test, update the printer.cfg file with
|
||||
the recommended pid_Kp, pid_Ki, and pid_Kd values.
|
||||
At the completion of the tuning test run `SAVE_CONFIG` to update the
|
||||
printer.cfg file the new PID settings.
|
||||
|
||||
If the printer has a heated bed and it supports being driven by PWM
|
||||
(Pulse Width Modulation) then it is recommended to use PID control for
|
||||
@@ -145,3 +156,12 @@ in the Klipper configuration file. It may be necessary to perform
|
||||
detailed printer calibration - a number of guides are available online
|
||||
to help with this (for example, do a web search for "3d printer
|
||||
calibration").
|
||||
|
||||
See the [Slicers](Slicers.md) document for information on configuring
|
||||
a slicer with Klipper. If one is using traditional endstop switches
|
||||
with Trinamic stepper motor drivers then see the
|
||||
[Endstop Phase](Endstop_Phase.md) document. If using a delta printer,
|
||||
see the [Delta Calibrate](Delta_Calibrate.md) document.
|
||||
|
||||
After one has verified that basic printing works, it is a good idea to
|
||||
consider calibrating [pressure advance](Pressure_Advance.md).
|
||||
|
||||
@@ -4,26 +4,32 @@ developers.
|
||||
Issue reporting
|
||||
===============
|
||||
|
||||
In order to report a problem or request a change in behavior, it is
|
||||
necessary to collect the Klipper log file. The first step is to
|
||||
**issue an M112 command** in the OctoPrint terminal window immediately
|
||||
after the undesirable event occurs. This causes Klipper to go into a
|
||||
"shutdown state" and it will cause additional debugging information to
|
||||
be written to the log file.
|
||||
It is very important to attach the Klipper log file to all
|
||||
reports. The log file has been engineered to answer common questions
|
||||
the Klipper developers have about the software and its environment
|
||||
(software version, hardware type, configuration, event timing, and
|
||||
hundreds of other questions). **The developers need the Klipper log
|
||||
file to provide any meaningful assistance**; only this log file
|
||||
provides the necessary information.
|
||||
|
||||
Issue requests are submitted through Github. **All issues must
|
||||
On a problem report the first step is to **issue an M112 command** in
|
||||
the OctoPrint terminal window immediately after the undesirable event
|
||||
occurs. This causes Klipper to go into a "shutdown state" and it will
|
||||
cause additional debugging information to be written to the log file.
|
||||
|
||||
Issue requests are submitted through Github. **All Github issues must
|
||||
include the full /tmp/klippy.log log file from the session that
|
||||
produced the error.** An "scp" and/or "sftp" utility is needed to
|
||||
acquire this log file. The "scp" utility comes standard with Linux and
|
||||
MacOS desktops. There are freely available scp utilities for other
|
||||
desktops (eg, WinSCP).
|
||||
produced the event being reported.** An "scp" and/or "sftp" utility is
|
||||
needed to acquire this log file. The "scp" utility comes standard with
|
||||
Linux and MacOS desktops. There are freely available scp utilities for
|
||||
other desktops (eg, WinSCP).
|
||||
|
||||
Use the scp utility to copy the `/tmp/klippy.log` file from the host
|
||||
machine to your desktop. It is a good idea to compress the klippy.log
|
||||
file before posting it (eg, using zip or gzip). Open a new issue at
|
||||
https://github.com/KevinOConnor/klipper/issues , provide a description
|
||||
of the problem, and **attach the `klippy.log` file to the issue**:
|
||||

|
||||
Use the scp utility to copy the `/tmp/klippy.log` file from the
|
||||
Raspberry Pi to your desktop. It is a good idea to compress the
|
||||
klippy.log file before posting it (eg, using zip or gzip). Open a new
|
||||
issue at https://github.com/KevinOConnor/klipper/issues , provide a
|
||||
description of the problem, and **attach the `klippy.log` file to the
|
||||
issue**: 
|
||||
|
||||
Mailing list
|
||||
============
|
||||
|
||||
241
docs/Debugging.md
Normal file → Executable file
@@ -171,3 +171,244 @@ The script will extract the printer config file and will extract MCU
|
||||
shutdown information. The information dumps from an MCU shutdown (if
|
||||
present) will be reordered by timestamp to assist in diagnosing cause
|
||||
and effect scenarios.
|
||||
|
||||
Micro-controller Benchmarks
|
||||
===========================
|
||||
|
||||
This section describes the mechanism used to generate the Klipper
|
||||
micro-controller step rate benchmarks.
|
||||
|
||||
The primary goal of the benchmarks is to provide a consistent
|
||||
mechanism for measuring the impact of coding changes within the
|
||||
software. A secondary goal is to provide high-level metrics for
|
||||
comparing the performance between chips and between software
|
||||
platforms.
|
||||
|
||||
The step rate benchmark is designed to find the maximum stepping rate
|
||||
that the hardware and software can reach. This benchmark stepping rate
|
||||
is not achievable in day-to-day use as Klipper needs to perform other
|
||||
tasks (eg, mcu/host communication, temperature reading, endstop
|
||||
checking) in any real-world usage.
|
||||
|
||||
In general, the pins for the benchmark tests are chosen to flash LEDs
|
||||
or other innocuous pins. **Always verify that it is safe to drive the
|
||||
configured pins prior to running a benchmark.** It is not recommended
|
||||
to drive an actual stepper during a benchmark.
|
||||
|
||||
## Step rate benchmark test ##
|
||||
|
||||
The test is performed using the console.py tool (described above). The
|
||||
micro-controller is configured for the particular hardware platform
|
||||
(see below) and then the following is cut-and-paste into the
|
||||
console.py terminal window:
|
||||
```
|
||||
SET start_clock {clock+freq}
|
||||
SET ticks 1000
|
||||
|
||||
reset_step_clock oid=0 clock={start_clock}
|
||||
set_next_step_dir oid=0 dir=0
|
||||
queue_step oid=0 interval={ticks} count=60000 add=0
|
||||
set_next_step_dir oid=0 dir=1
|
||||
queue_step oid=0 interval=3000 count=1 add=0
|
||||
|
||||
reset_step_clock oid=1 clock={start_clock}
|
||||
set_next_step_dir oid=1 dir=0
|
||||
queue_step oid=1 interval={ticks} count=60000 add=0
|
||||
set_next_step_dir oid=1 dir=1
|
||||
queue_step oid=1 interval=3000 count=1 add=0
|
||||
|
||||
reset_step_clock oid=2 clock={start_clock}
|
||||
set_next_step_dir oid=2 dir=0
|
||||
queue_step oid=2 interval={ticks} count=60000 add=0
|
||||
set_next_step_dir oid=2 dir=1
|
||||
queue_step oid=2 interval=3000 count=1 add=0
|
||||
```
|
||||
|
||||
The above tests three steppers simultaneously stepping. If running the
|
||||
above results in a "Rescheduled timer in the past" or "Stepper too far
|
||||
in past" error then it indicates the `ticks` parameter is too low (it
|
||||
results in a stepping rate that is too fast). The goal is to find the
|
||||
lowest setting of the ticks parameter that reliably results in a
|
||||
successful completion of the test. It should be possible to bisect the
|
||||
ticks parameter until a stable value is found.
|
||||
|
||||
On a failure, one can copy-and-paste the following to clear the error
|
||||
in preparation for the next test:
|
||||
```
|
||||
clear_shutdown
|
||||
```
|
||||
|
||||
To obtain the single stepper and dual stepper benchmarks, the same
|
||||
configuration sequence is used, but only the first block (for the
|
||||
single stepper case) or first two blocks (for the dual stepper case)
|
||||
of the above test is cut-and-paste into the console.py window.
|
||||
|
||||
To produce the benchmarks found in the Features.md document, the total
|
||||
number of steps per second is calculated by multiplying the number of
|
||||
active steppers with the nominal mcu frequency and dividing by the
|
||||
final ticks parameter. The results are rounded to the nearest K. For
|
||||
example, with three active steppers:
|
||||
```
|
||||
ECHO Test result is: {"%.0fK" % (3. * freq / ticks / 1000.)}
|
||||
```
|
||||
|
||||
### AVR step rate benchmark ###
|
||||
|
||||
The following configuration sequence is used on AVR chips:
|
||||
```
|
||||
PINS arduino
|
||||
allocate_oids count=3
|
||||
config_stepper oid=0 step_pin=ar29 dir_pin=ar28 min_stop_interval=0 invert_step=0
|
||||
config_stepper oid=1 step_pin=ar27 dir_pin=ar26 min_stop_interval=0 invert_step=0
|
||||
config_stepper oid=2 step_pin=ar23 dir_pin=ar22 min_stop_interval=0 invert_step=0
|
||||
finalize_config crc=0
|
||||
```
|
||||
|
||||
The test was last run on commit `b161a69e` with gcc version `avr-gcc
|
||||
(GCC) 4.8.1`. Both the 16Mhz and 20Mhz tests were run using simulavr
|
||||
configured for an atmega644p (previous tests have confirmed simulavr
|
||||
results match tests on both a 16Mhz at90usb and a 16Mhz atmega2560).
|
||||
On both 16Mhz and 20Mhz the best single stepper result is `SET ticks
|
||||
106`, the best dual stepper result is `SET ticks 276`, and the best
|
||||
three stepper result is `SET ticks 481`.
|
||||
|
||||
### Arduino Due step rate benchmark ###
|
||||
|
||||
The following configuration sequence is used on the Due:
|
||||
```
|
||||
allocate_oids count=3
|
||||
config_stepper oid=0 step_pin=PB27 dir_pin=PA21 min_stop_interval=0 invert_step=0
|
||||
config_stepper oid=1 step_pin=PB26 dir_pin=PC30 min_stop_interval=0 invert_step=0
|
||||
config_stepper oid=2 step_pin=PA21 dir_pin=PC30 min_stop_interval=0 invert_step=0
|
||||
finalize_config crc=0
|
||||
```
|
||||
|
||||
The test was last run on commit `b161a69e` with gcc version
|
||||
`arm-none-eabi-gcc (Fedora 7.1.0-5.fc27) 7.1.0`. The best single
|
||||
stepper result is `SET ticks 207`, the best dual stepper result is
|
||||
`SET ticks 205`, and the best three stepper result is `SET ticks 317`.
|
||||
|
||||
### Duet Wifi step rate benchmark ###
|
||||
|
||||
The following configuration sequence is used on the Duet Wifi:
|
||||
```
|
||||
allocate_oids count=3
|
||||
config_stepper oid=0 step_pin=PD6 dir_pin=PD11 min_stop_interval=0 invert_step=0
|
||||
config_stepper oid=1 step_pin=PD7 dir_pin=PD12 min_stop_interval=0 invert_step=0
|
||||
config_stepper oid=2 step_pin=PD8 dir_pin=PD13 min_stop_interval=0 invert_step=0
|
||||
finalize_config crc=0
|
||||
```
|
||||
|
||||
The test was last run on commit `34c3cb5c` with gcc version
|
||||
`arm-none-eabi-gcc (15:5.4.1+svn241155-1) 5.4.1 20160919`. The best
|
||||
single stepper result is `SET ticks 295`, the best dual stepper result
|
||||
is `SET ticks 264`, and the best three stepper result is `SET ticks
|
||||
282`.
|
||||
|
||||
### Beaglebone PRU step rate benchmark ###
|
||||
|
||||
The following configuration sequence is used on the PRU:
|
||||
```
|
||||
PINS beaglebone
|
||||
allocate_oids count=3
|
||||
config_stepper oid=0 step_pin=P8_13 dir_pin=P8_12 min_stop_interval=0 invert_step=0
|
||||
config_stepper oid=1 step_pin=P8_15 dir_pin=P8_14 min_stop_interval=0 invert_step=0
|
||||
config_stepper oid=2 step_pin=P8_19 dir_pin=P8_18 min_stop_interval=0 invert_step=0
|
||||
finalize_config crc=0
|
||||
```
|
||||
|
||||
The test was last run on commit `b161a69e` with gcc version `pru-gcc
|
||||
(GCC) 8.0.0 20170530 (experimental)`. The best single stepper result
|
||||
is `SET ticks 861`, the best dual stepper result is `SET ticks 853`,
|
||||
and the best three stepper result is `SET ticks 883`.
|
||||
|
||||
### STM32F103 step rate benchmark ###
|
||||
|
||||
The following configuration sequence is used on the STM32F103:
|
||||
```
|
||||
allocate_oids count=3
|
||||
config_stepper oid=0 step_pin=PC13 dir_pin=PB5 min_stop_interval=0 invert_step=0
|
||||
config_stepper oid=1 step_pin=PB3 dir_pin=PB6 min_stop_interval=0 invert_step=0
|
||||
config_stepper oid=2 step_pin=PA4 dir_pin=PB7 min_stop_interval=0 invert_step=0
|
||||
finalize_config crc=0
|
||||
```
|
||||
|
||||
The test was last run on commit `b161a69e` with gcc version
|
||||
`arm-none-eabi-gcc (Fedora 7.1.0-5.fc27) 7.1.0`. The best single
|
||||
stepper result is `SET ticks 41`, the best dual stepper result is `SET
|
||||
ticks 48`, and the best three stepper result is `SET ticks 80`.
|
||||
|
||||
### LPC176x step rate benchmark ###
|
||||
|
||||
The following configuration sequence is used on the LPC176x:
|
||||
```
|
||||
allocate_oids count=3
|
||||
config_stepper oid=0 step_pin=P1.20 dir_pin=P1.18 min_stop_interval=0 invert_step=0
|
||||
config_stepper oid=1 step_pin=P1.21 dir_pin=P1.18 min_stop_interval=0 invert_step=0
|
||||
config_stepper oid=2 step_pin=P1.23 dir_pin=P1.18 min_stop_interval=0 invert_step=0
|
||||
finalize_config crc=0
|
||||
```
|
||||
|
||||
The test was last run on commit `b161a69e` with gcc version
|
||||
`arm-none-eabi-gcc (Fedora 7.1.0-5.fc27) 7.1.0`. For the 100Mhz
|
||||
LPC1768, the best single stepper result is `SET ticks 119`, the best
|
||||
dual stepper result is `SET ticks 118`, and the best three stepper
|
||||
result is `SET ticks 154`. The 120Mhz LPC1769 results were obtained by
|
||||
overclocking an LPC1768 to 120Mhz - the best single stepper result is
|
||||
`SET ticks 140`, the best dual stepper result is `SET ticks 137`, and
|
||||
the best three stepper result is `SET ticks 154`.
|
||||
|
||||
### SAMD21 step rate benchmark ###
|
||||
|
||||
The following configuration sequence is used on the SAMD21:
|
||||
```
|
||||
allocate_oids count=3
|
||||
config_stepper oid=0 step_pin=PA27 dir_pin=PA20 min_stop_interval=0 invert_step=0
|
||||
config_stepper oid=1 step_pin=PB3 dir_pin=PA21 min_stop_interval=0 invert_step=0
|
||||
config_stepper oid=2 step_pin=PA17 dir_pin=PA21 min_stop_interval=0 invert_step=0
|
||||
finalize_config crc=0
|
||||
```
|
||||
|
||||
The test was last run on commit `b161a69e` with gcc version
|
||||
`arm-none-eabi-gcc (Fedora 7.1.0-5.fc27) 7.1.0`. The best single
|
||||
stepper result is `SET ticks 277`, the best dual stepper result is
|
||||
`SET ticks 410`, and the best three stepper result is `SET ticks 664`.
|
||||
|
||||
## Command dispatch benchmark ##
|
||||
|
||||
The command dispatch benchmark tests how many "dummy" commands the
|
||||
micro-controller can process. It is primarily a test of the hardware
|
||||
communication mechanism. The test is run using the console.py tool
|
||||
(described above). The following is cut-and-paste into the console.py
|
||||
terminal window:
|
||||
```
|
||||
DELAY {clock+freq} get_uptime
|
||||
FLOOD 100000 0.0 end_group
|
||||
get_uptime
|
||||
```
|
||||
|
||||
When the test completes, determine the difference between the clocks
|
||||
reported in the two "uptime" response messages. The total number of
|
||||
commands per second is then `100000 * mcu_frequency / clock_diff`.
|
||||
|
||||
| MCU | Rate | Build | Build compiler |
|
||||
| ------------------- | ---- | -------- | ------------------- |
|
||||
| atmega2560 (serial) | 23K | b161a69e | avr-gcc (GCC) 4.8.1 |
|
||||
| at90usb1286 (USB) | 75K | b161a69e | avr-gcc (GCC) 4.8.1 |
|
||||
| sam3x8e (serial) | 23K | b161a69e | arm-none-eabi-gcc (Fedora 7.1.0-5.fc27) 7.1.0 |
|
||||
| pru (shared memory) | 5K | b161a69e | pru-gcc (GCC) 8.0.0 20170530 (experimental) |
|
||||
| stm32f103 (USB) | 335K | b161a69e | arm-none-eabi-gcc (Fedora 7.1.0-5.fc27) 7.1.0 |
|
||||
| lpc1768 (USB) | 546K | b161a69e | arm-none-eabi-gcc (Fedora 7.1.0-5.fc27) 7.1.0 |
|
||||
| lpc1769 (USB) | 619K | b161a69e | arm-none-eabi-gcc (Fedora 7.1.0-5.fc27) 7.1.0 |
|
||||
| samd21 (USB) | 238K | b161a69e | arm-none-eabi-gcc (Fedora 7.1.0-5.fc27) 7.1.0 |
|
||||
|
||||
Host Benchmarks
|
||||
===============
|
||||
|
||||
It is possible to run timing tests on the host software using the
|
||||
"batch mode" processing mechanism described above. This is typically
|
||||
done by choosing a large and complex G-Code file and timing how long
|
||||
it takes for the host software to process it. For example:
|
||||
```
|
||||
time ~/klippy-env/bin/python ./klippy/klippy.py config/example.cfg -i something_complex.gcode -o /dev/null -d out/klipper.dict
|
||||
```
|
||||
|
||||
213
docs/Delta_Calibrate.md
Normal file
@@ -0,0 +1,213 @@
|
||||
This document describes Klipper's automatic calibration system for
|
||||
"delta" style printers.
|
||||
|
||||
Delta calibration involves finding the tower endstop positions, tower
|
||||
angles, delta radius, and delta arm lengths. These settings control
|
||||
printer motion on a delta printer. Each one of these parameters has a
|
||||
non-obvious and non-linear impact and it is difficult to calibrate
|
||||
them manually. In contrast, the software calibration code can provide
|
||||
excellent results with just a few minutes of time. No special probing
|
||||
hardware is necessary to get good results.
|
||||
|
||||
Basic delta calibration
|
||||
=======================
|
||||
|
||||
Klipper has a DELTA_CALIBRATE command that can perform basic delta
|
||||
calibration. This command probes seven different points on the bed and
|
||||
calculates new values for the tower angles, tower endstops, and delta
|
||||
radius.
|
||||
|
||||
In order to perform this calibration the initial delta parameters (arm
|
||||
lengths, radius, and endstop positions) must be provided and they
|
||||
should have an accuracy to within a few millimeters. Most delta
|
||||
printer kits will provide these parameters - configure the printer
|
||||
with these initial defaults and then go on to run the DELTA_CALIBRATE
|
||||
command as described below. If no defaults are available then search
|
||||
online for a delta calibration guide that can provide a basic starting
|
||||
point.
|
||||
|
||||
During the delta calibration process it may be necessary for the
|
||||
printer to probe below what would otherwise be considered the plane of
|
||||
the bed. It is typical to permit this during calibration by updating
|
||||
the config so that the printer's `minimum_z_position=-5`. (Once
|
||||
calibration completes, one can remove this setting from the config.)
|
||||
|
||||
There are two ways to perform the probing - manual probing and
|
||||
automatic probing. Automatic probing utilizes a hardware device
|
||||
capable of triggering when the toolhead is at a set distance from the
|
||||
bed. Manual probing involves using the "paper test" to determine the
|
||||
height at each probe point. It is recommended to use manual probing
|
||||
for delta calibration. A number of common printer kits come with
|
||||
probes that are not sufficiently accurate (specifically, small
|
||||
differences in arm length can cause effector tilt which can skew an
|
||||
automatic probe). Manual probing only takes a few minutes and it
|
||||
eliminates error introduced by the probe.
|
||||
|
||||
To perform the basic probe, make sure the config has a
|
||||
[delta_calibrate] section defined and run:
|
||||
```
|
||||
G28
|
||||
DELTA_CALIBRATE METHOD=manual
|
||||
```
|
||||
After probing the seven points new delta parameters will be
|
||||
calculated. Save and apply these parameters by running:
|
||||
```
|
||||
SAVE_CONFIG
|
||||
```
|
||||
|
||||
The basic calibration should provide delta parameters that are
|
||||
accurate enough for basic printing. If this is a new printer, this is
|
||||
a good time to print some basic objects and verify general
|
||||
functionality.
|
||||
|
||||
Enhanced delta calibration
|
||||
==========================
|
||||
|
||||
The basic delta calibration generally does a good job of calculating
|
||||
delta parameters such that the nozzle is the correct distance from the
|
||||
bed. However, it does not attempt to calibrate X and Y dimensional
|
||||
accuracy. It's a good idea to perform an enhanced delta calibration to
|
||||
verify dimensional accuracy.
|
||||
|
||||
This calibration procedure requires printing a test object and
|
||||
measuring parts of that test object with digital calipers.
|
||||
|
||||
Prior to running an enhanced delta calibration one must run the basic
|
||||
delta calibration (via the DELTA_CALIBRATE command) and save the
|
||||
results (via the SAVE_CONFIG command).
|
||||
|
||||
Use a slicer to generate G-Code from the
|
||||
[docs/prints/calibrate_size.stl](prints/calibrate_size.stl) file.
|
||||
Slice the object using a slow speed (eg, 40mm/s). If possible, use a
|
||||
stiff plastic (such as PLA) for the object. The object has a diameter
|
||||
of 140mm. If this is too large for the printer then one can scale it
|
||||
down (but be sure to uniformly scale both the X and Y axes). If the
|
||||
printer supports significantly larger prints then this object can also
|
||||
be increased in size. A larger size can improve the measurement
|
||||
accuracy, but good print adhesion is more important than a larger
|
||||
print size.
|
||||
|
||||
Print the test object and wait for it to fully cool. The commands
|
||||
described below must be run with the same printer settings used to
|
||||
print the calibration object (don't run DELTA_CALIBRATE between
|
||||
printing and measuring, or do something that would otherwise change
|
||||
the printer configuration).
|
||||
|
||||
If possible, perform the measurements described below while the object
|
||||
is still attached to the print bed, but don't worry if the part
|
||||
detaches from the bed - just try to avoid bending the object when
|
||||
performing the measurements.
|
||||
|
||||
Start by measuring the distance between the center pillar and the
|
||||
pillar next to the "A" label (which should also be pointing towards
|
||||
the "A" tower).
|
||||
|
||||

|
||||
|
||||
Then go counterclockwise and measure the distances between the center
|
||||
pillar and the other pillars (distance from center to pillar across
|
||||
from C label, distance from center to pillar with B label, etc.).
|
||||
|
||||

|
||||
|
||||
Enter these parameters into Klipper with a comma separated list of
|
||||
floating point numbers:
|
||||
```
|
||||
DELTA_ANALYZE CENTER_DISTS=<a_dist>,<far_c_dist>,<b_dist>,<far_a_dist>,<c_dist>,<far_b_dist>
|
||||
```
|
||||
Provide the values without spaces between them.
|
||||
|
||||
Then measure the distance between the A pillar and the pillar across
|
||||
from the C label.
|
||||
|
||||

|
||||
|
||||
Then go counterclockwise and measure the distance between the pillar
|
||||
across from C to the B pillar, the distance between the B pillar and
|
||||
the pillar across from A, and so on.
|
||||
|
||||

|
||||
|
||||
Enter these parameters into Klipper:
|
||||
```
|
||||
DELTA_ANALYZE OUTER_DISTS=<a_to_far_c>,<far_c_to_b>,<b_to_far_a>,<far_a_to_c>,<c_to_far_b>,<far_b_to_a>
|
||||
```
|
||||
|
||||
At this point it is okay to remove the object from the bed. The final
|
||||
measurements are of the pillars themselves. Measure the size of the
|
||||
center pillar along the A spoke, then the B spoke, and then the C
|
||||
spoke.
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
Enter them into Klipper:
|
||||
```
|
||||
DELTA_ANALYZE CENTER_PILLAR_WIDTHS=<a>,<b>,<c>
|
||||
```
|
||||
|
||||
The final measurements are of the outer pillars. Start by measuring
|
||||
the distance of the A pillar along the line from A to the pillar
|
||||
across from C.
|
||||
|
||||

|
||||
|
||||
Then go counterclockwise and measure the remaining outer pillars
|
||||
(pillar across from C along the line to B, B pillar along the line to
|
||||
pillar across from A, etc.).
|
||||
|
||||

|
||||
|
||||
And enter them into Klipper:
|
||||
```
|
||||
DELTA_ANALYZE OUTER_PILLAR_WIDTHS=<a>,<far_c>,<b>,<far_a>,<c>,<far_b>
|
||||
```
|
||||
|
||||
If the object was scaled to a smaller or larger size then provide the
|
||||
scale factor that was used when slicing the object:
|
||||
```
|
||||
DELTA_ANALYZE SCALE=1.0
|
||||
```
|
||||
(A scale value of 2.0 would mean the object is twice its original
|
||||
size, 0.5 would be half its original size.)
|
||||
|
||||
Finally, perform the enhanced delta calibration by running:
|
||||
```
|
||||
DELTA_ANALYZE CALIBRATE=extended
|
||||
```
|
||||
This command can take several minutes to complete. After completion it
|
||||
will calculate updated delta parameters (delta radius, tower angles,
|
||||
endstop positions, and arm lengths). Use the SAVE_CONFIG command to
|
||||
save and apply the settings:
|
||||
```
|
||||
SAVE_CONFIG
|
||||
```
|
||||
|
||||
The SAVE_CONFIG command will save both the updated delta parameters
|
||||
and information from the distance measurements. Future DELTA_CALIBRATE
|
||||
commands will also utilize this distance information. Do not attempt
|
||||
to reenter the raw distance measurements after running SAVE_CONFIG, as
|
||||
this command changes the printer configuration and the raw
|
||||
measurements no longer apply.
|
||||
|
||||
Additional notes
|
||||
----------------
|
||||
|
||||
* If the delta printer has good dimensional accuracy then the distance
|
||||
between any two pillars should be around 74mm and the width of every
|
||||
pillar should be around 9mm. (Specifically, the goal is for the
|
||||
distance between any two pillars minus the width of one of the
|
||||
pillars to be exactly 65mm.) Should there be a dimensional
|
||||
inaccuracy in the part then the DELTA_ANALYZE routine will calculate
|
||||
new delta parameters using both the distance measurements and the
|
||||
previous height measurements from the last DELTA_CALIBRATE command.
|
||||
|
||||
* DELTA_ANALYZE may produce delta parameters that are surprising. For
|
||||
example, it may suggest arm lengths that do not match the printer's
|
||||
actual arm lengths. Despite this, testing has shown that
|
||||
DELTA_ANALYZE often produces superior results. It is believed that
|
||||
the calculated delta parameters are able to account for slight
|
||||
errors elsewhere in the hardware. For example, small differences in
|
||||
arm length may result in a tilt to the effector and some of that
|
||||
tilt may be accounted for by adjusting the arm length parameters.
|
||||
125
docs/Endstop_Phase.md
Normal file
@@ -0,0 +1,125 @@
|
||||
This document describes Klipper's stepper phase adjusted endstop
|
||||
system. This functionality can improve the accuracy of traditional
|
||||
endstop switches. It is most useful when using a Trinamic stepper
|
||||
motor driver that has run-time configuration.
|
||||
|
||||
A typical endstop switch has an accuracy of around 100 microns. (Each
|
||||
time an axis is homed the switch may trigger slightly earlier or
|
||||
slightly later.) Although this is a relatively small error, it can
|
||||
result in unwanted artifacts. In particular, this positional deviation
|
||||
may be noticeable when printing the first layer of an object. In
|
||||
contrast, typical stepper motors can obtain significantly higher
|
||||
precision.
|
||||
|
||||
The stepper phase adjusted endstop mechanism can use the precision of
|
||||
the stepper motors to improve the precision of the endstop switches.
|
||||
When a stepper motor moves it cycles through a series of phases until
|
||||
in completes four "full steps". So, a stepper motor using 16
|
||||
micro-steps would have 64 phases and when moving in a positive
|
||||
direction it would cycle through phases: 0, 1, 2, ... 61, 62, 63, 0,
|
||||
1, 2, etc. Crucially, when the stepper motor is at a particular
|
||||
position on a linear rail it should always be at the same stepper
|
||||
phase. Thus, when a carriage triggers the endstop switch the stepper
|
||||
controlling that carriage should always be at the same stepper motor
|
||||
phase. Klipper's endstop phase system combines the stepper phase with
|
||||
the endstop trigger to improve the accuracy of the endstop.
|
||||
|
||||
In order to use this functionality it is necessary to be able to
|
||||
identify the phase of the stepper motor. If one is using Trinamic
|
||||
TMC2130, TMC2208, TMC2224 or TMC2660 drivers in run-time configuration
|
||||
mode (ie, not stand-alone mode) then Klipper can query the stepper
|
||||
phase from the driver. (It is also possible to use this system on
|
||||
traditional stepper drivers if one can reliably reset the stepper
|
||||
drivers - see below for details.)
|
||||
|
||||
Calibrating endstop phases
|
||||
==========================
|
||||
|
||||
If using Trinamic stepper motor drivers with run-time configuration
|
||||
then one can calibrate the endstop phases using the
|
||||
ENDSTOP_PHASE_CALIBRATE command. Start by adding the following to the
|
||||
config file:
|
||||
```
|
||||
[endstop_phase]
|
||||
```
|
||||
|
||||
Then RESTART the printer and run a `G28` command followed by an
|
||||
`ENDSTOP_PHASE_CALIBRATE` command. Then move the toolhead to a new
|
||||
location and run `G28` again. Try moving the toolhead to several
|
||||
different locations and rerun `G28` from each position. Run at least
|
||||
five `G28` commands.
|
||||
|
||||
After performing the above, the `ENDSTOP_PHASE_CALIBRATE` command will
|
||||
often report the same (or nearly the same) phase for the stepper. This
|
||||
phase can be saved in the config file so that all future G28 commands
|
||||
use that phase. (So, in future homing operations, Klipper will obtain
|
||||
the same position even if the endstop triggers a little earlier or a
|
||||
little later.)
|
||||
|
||||
To save the endstop phase for a particular stepper motor, run
|
||||
something like the following:
|
||||
```
|
||||
ENDSTOP_PHASE_CALIBRATE STEPPER=stepper_z
|
||||
```
|
||||
|
||||
Run the above for all the steppers one wishes to save. Typically, one
|
||||
would use this on stepper_z for cartesian and corexy printers, and for
|
||||
stepper_a, stepper_b, and stepper_c on delta printers. Finally, run
|
||||
the following to update the configuration file with the data:
|
||||
```
|
||||
SAVE_CONFIG
|
||||
```
|
||||
|
||||
Additional notes
|
||||
----------------
|
||||
|
||||
* This feature is most useful on delta printers and on the Z endstop
|
||||
of cartesian/corexy printers. It is possible to use this feature on
|
||||
the XY endstops of cartesian printers, but that isn't particularly
|
||||
useful as a minor error in X/Y endstop position is unlikely to
|
||||
impact print quality. It is not valid to use this feature on the XY
|
||||
endstops of corexy printers (as the XY position is not determined by
|
||||
a single stepper on corexy kinematics). It is not valid to use this
|
||||
feature on a printer using a "probe:z_virtual_endstop" Z endstop (as
|
||||
the stepper phase is only stable if the endstop is at a static
|
||||
location on a rail).
|
||||
|
||||
* After calibrating the endstop phase, if the endstop is later moved
|
||||
or adjusted then it will be necessary to recalibrate the endstop.
|
||||
Remove the calibration data from the config file and rerun the steps
|
||||
above.
|
||||
|
||||
* In order to use this system the endstop must be accurate enough to
|
||||
identify the stepper position within two "full steps". So, for
|
||||
example, if a stepper is using 16 micro-steps with a step distance
|
||||
of 0.005mm then the endstop must have an accuracy of at least
|
||||
0.160mm. If one gets "Endstop stepper_z incorrect phase" type error
|
||||
messages than in may be due to an endstop that is not sufficiently
|
||||
accurate. If recalibration does not help then disable endstop phase
|
||||
adjustments by removing them from the config file.
|
||||
|
||||
* If one is using a traditional stepper controlled Z axis (as on a
|
||||
cartesian or corexy printer) along with traditional bed leveling
|
||||
screws then it is also possible to use this system to arrange for
|
||||
each print layer to be performed on a "full step" boundary. To
|
||||
enable this feature be sure the G-Code slicer is configured with a
|
||||
layer height that is a multiple of a "full step", manually enable
|
||||
the endstop_align_zero option in the endstop_phase config section
|
||||
(see config/example-extras.cfg for further details), and then
|
||||
re-level the bed screws.
|
||||
|
||||
* It is possible to use this system with traditional (non-Trinamic)
|
||||
stepper motor drivers. However, doing this requires making sure that
|
||||
the stepper motor drivers are reset every time the micro-controller
|
||||
is reset. (If the two are always reset together then Klipper can
|
||||
determine the stepper phase by tracking the total number of steps it
|
||||
has commanded the stepper to move.) Currently, the only way to do
|
||||
this reliably is if both the micro-controller and stepper motor
|
||||
drivers are powered solely from USB and that USB power is provided
|
||||
from a host running on a Raspberry Pi. In this situation one can
|
||||
specify an mcu config with "restart_method: rpi_usb" - that option
|
||||
will arrange for the micro-controller to always be reset via a USB
|
||||
power reset, which would arrange for both the micro-controller and
|
||||
stepper motor drivers to be reset together. If using this mechanism,
|
||||
one would then need to manually configure the "endstop_phase" config
|
||||
sections (see config/example-extras.cfg for the details).
|
||||
171
docs/FAQ.md
@@ -4,15 +4,19 @@ Frequently asked questions
|
||||
1. [How can I donate to the project?](#how-can-i-donate-to-the-project)
|
||||
2. [How do I calculate the step_distance parameter in the printer config file?](#how-do-i-calculate-the-step_distance-parameter-in-the-printer-config-file)
|
||||
3. [Where's my serial port?](#wheres-my-serial-port)
|
||||
4. [The "make flash" command doesn't work](#the-make-flash-command-doesnt-work)
|
||||
5. [How do I change the serial baud rate?](#how-do-i-change-the-serial-baud-rate)
|
||||
6. [Can I run Klipper on something other than a Raspberry Pi 3?](#can-i-run-klipper-on-something-other-than-a-raspberry-pi-3)
|
||||
7. [Why can't I move the stepper before homing the printer?](#why-cant-i-move-the-stepper-before-homing-the-printer)
|
||||
8. [Why is the Z position_endstop set to 0.5 in the default configs?](#why-is-the-z-position_endstop-set-to-05-in-the-default-configs)
|
||||
9. [I converted my config from Marlin and the X/Y axes work fine, but I just get a screeching noise when homing the Z axis](#i-converted-my-config-from-marlin-and-the-xy-axes-work-fine-but-i-just-get-a-screeching-noise-when-homing-the-z-axis)
|
||||
10. [When I set "restart_method=command" my AVR device just hangs on a restart](#when-i-set-restart_methodcommand-my-avr-device-just-hangs-on-a-restart)
|
||||
11. [Will the heaters be left on if the Raspberry Pi crashes?](#will-the-heaters-be-left-on-if-the-raspberry-pi-crashes)
|
||||
12. [How do I upgrade to the latest software?](#how-do-i-upgrade-to-the-latest-software)
|
||||
4. [When the micro-controller restarts the device changes to /dev/ttyUSB1](#when-the-micro-controller-restarts-the-device-changes-to-devttyusb1)
|
||||
5. [The "make flash" command doesn't work](#the-make-flash-command-doesnt-work)
|
||||
6. [How do I change the serial baud rate?](#how-do-i-change-the-serial-baud-rate)
|
||||
7. [Can I run Klipper on something other than a Raspberry Pi 3?](#can-i-run-klipper-on-something-other-than-a-raspberry-pi-3)
|
||||
8. [Why can't I move the stepper before homing the printer?](#why-cant-i-move-the-stepper-before-homing-the-printer)
|
||||
9. [Why is the Z position_endstop set to 0.5 in the default configs?](#why-is-the-z-position_endstop-set-to-05-in-the-default-configs)
|
||||
10. [I converted my config from Marlin and the X/Y axes work fine, but I just get a screeching noise when homing the Z axis](#i-converted-my-config-from-marlin-and-the-xy-axes-work-fine-but-i-just-get-a-screeching-noise-when-homing-the-z-axis)
|
||||
11. [My TMC motor driver turns off in the middle of a print](#my-tmc-motor-driver-turns-off-in-the-middle-of-a-print)
|
||||
12. [I keep getting random "Lost communication with MCU" errors](#i-keep-getting-random-lost-communication-with-mcu-errors)
|
||||
13. [When I set "restart_method=command" my AVR device just hangs on a restart](#when-i-set-restart_methodcommand-my-avr-device-just-hangs-on-a-restart)
|
||||
14. [Will the heaters be left on if the Raspberry Pi crashes?](#will-the-heaters-be-left-on-if-the-raspberry-pi-crashes)
|
||||
15. [How do I convert a Marlin pin number to a Klipper pin name?](#how-do-i-convert-a-marlin-pin-number-to-a-klipper-pin-name)
|
||||
16. [How do I upgrade to the latest software?](#how-do-i-upgrade-to-the-latest-software)
|
||||
|
||||
### How can I donate to the project?
|
||||
|
||||
@@ -36,7 +40,7 @@ The general way to find a USB serial port is to run `ls -l
|
||||
/dev/serial/by-id/` from an ssh terminal on the host machine. It will
|
||||
likely produce output similar to the following:
|
||||
```
|
||||
lrwxrwxrwx 1 root root 13 Jan 3 22:15 usb-UltiMachine__ultimachine.com__RAMBo_12345678912345678912-if00 -> ../../ttyACM0
|
||||
lrwxrwxrwx 1 root root 13 Jun 1 21:12 usb-1a86_USB2.0-Serial-if00-port0 -> ../../ttyUSB0
|
||||
```
|
||||
|
||||
The name found in the above command is stable and it is possible to
|
||||
@@ -44,18 +48,28 @@ use it in the config file and while flashing the micro-controller
|
||||
code. For example, a flash command might look similar to:
|
||||
```
|
||||
sudo service klipper stop
|
||||
make flash FLASH_DEVICE=/dev/serial/by-id/usb-UltiMachine__ultimachine.com__RAMBo_12345678912345678912-if00
|
||||
make flash FLASH_DEVICE=/dev/serial/by-id/usb-1a86_USB2.0-Serial-if00-port0
|
||||
sudo service klipper start
|
||||
```
|
||||
and the updated config might look like:
|
||||
```
|
||||
[mcu]
|
||||
serial: /dev/serial/by-id/usb-UltiMachine__ultimachine.com__RAMBo_12345678912345678912-if00
|
||||
serial: /dev/serial/by-id/usb-1a86_USB2.0-Serial-if00-port0
|
||||
```
|
||||
|
||||
Be sure to copy-and-paste the name from the "ls" command that you ran
|
||||
above as the name will be different for each printer.
|
||||
|
||||
If you are using multiple micro-controllers and they do not have
|
||||
unique ids (common on boards with a CH340 USB chip) then follow the
|
||||
directions above using the directory `/dev/serial/by-path/` instead.
|
||||
|
||||
### When the micro-controller restarts the device changes to /dev/ttyUSB1
|
||||
|
||||
Follow the directions in the
|
||||
"[Where's my serial port?](#wheres-my-serial-port)" section to prevent
|
||||
this from occurring.
|
||||
|
||||
### The "make flash" command doesn't work
|
||||
|
||||
The code attempts to flash the device using the most common method for
|
||||
@@ -81,16 +95,17 @@ parameters - see the avrdude documentation for further information.
|
||||
|
||||
### How do I change the serial baud rate?
|
||||
|
||||
The default baud rate is 250000 in both the Klipper micro-controller
|
||||
configuration and in the Klipper host software. This works on almost
|
||||
all micro-controllers and it is the recommended setting. (Most online
|
||||
guides that refer to a baud rate of 115200 are outdated.)
|
||||
The recommended baud rate for Klipper is 250000. This baud rate works
|
||||
well on all micro-controller boards that Klipper supports. If you've
|
||||
found an online guide recommending a different baud rate, then ignore
|
||||
that part of the guide and continue with the default value of 250000.
|
||||
|
||||
If you need to change the baud rate, then the new rate will need to be
|
||||
configured in the micro-controller (during **make menuconfig**) and
|
||||
that updated code will need to be flashed to the micro-controller. The
|
||||
Klipper printer.cfg file will also need to be updated to match that
|
||||
baud rate (see the example.cfg file for details). For example:
|
||||
If you want to change the baud rate anyway, then the new rate will
|
||||
need to be configured in the micro-controller (during **make
|
||||
menuconfig**) and that updated code will need to be compiled and
|
||||
flashed to the micro-controller. The Klipper printer.cfg file will
|
||||
also need to be updated to match that baud rate (see the example.cfg
|
||||
file for details). For example:
|
||||
```
|
||||
[mcu]
|
||||
baud: 250000
|
||||
@@ -100,6 +115,11 @@ The baud rate shown on the OctoPrint web page has no impact on the
|
||||
internal Klipper micro-controller baud rate. Always set the OctoPrint
|
||||
baud rate to 250000 when using Klipper.
|
||||
|
||||
The Klipper micro-controller baud rate is not related to the baud rate
|
||||
of the micro-controller's bootloader. See the
|
||||
[bootloader document](Bootloaders.md) for additional information on
|
||||
bootloaders.
|
||||
|
||||
### Can I run Klipper on something other than a Raspberry Pi 3?
|
||||
|
||||
The recommended hardware is a Raspberry Pi 2 or a Raspberry
|
||||
@@ -143,6 +163,14 @@ Settings->GCODE Scripts
|
||||
If you want to move the head after a print finishes, consider adding
|
||||
the desired movement to the "custom g-code" section of your slicer.
|
||||
|
||||
If the printer requires some additional movement as part of the homing
|
||||
process itself (or fundamentally does not have a homing process) then
|
||||
consider using a homing_override section in the config file. If you
|
||||
need to move a stepper for diagnostic or debugging purposes then
|
||||
consider adding a force_move section to the config file. See
|
||||
[example-extras.cfg](../config/example-extras.cfg) for further details
|
||||
on these options.
|
||||
|
||||
### Why is the Z position_endstop set to 0.5 in the default configs?
|
||||
|
||||
For cartesian style printers the Z position_endstop specifies how far
|
||||
@@ -190,6 +218,42 @@ a higher speed. So, for a Z axis with a very precise step_distance the
|
||||
actual obtainable max_z_velocity may be smaller than what is
|
||||
configured in Marlin.
|
||||
|
||||
### My TMC motor driver turns off in the middle of a print
|
||||
|
||||
There have been reports of some TMC drivers being disabled in the
|
||||
middle of a print. (In particular, with the TMC2208 driver.) When this
|
||||
issue occurs, the stepper associated with the driver moves freely,
|
||||
while the print continues.
|
||||
|
||||
It is believed this may be due to "over current" detection within the
|
||||
TMC driver. Trinamic has indicated that this could occur if the driver
|
||||
is in "stealthChop mode" and an abrupt velocity change occurs. If you
|
||||
experience this problem during homing, consider using a slower homing
|
||||
speed. If you experience this problem in the middle of a print,
|
||||
consider using a lower square_corner_velocity setting.
|
||||
|
||||
### I keep getting random "Lost communication with MCU" errors
|
||||
|
||||
This is commonly caused by hardware errors on the USB connection
|
||||
between the host machine and the micro-controller. Things to look for:
|
||||
- Use a good quality USB cable between the host machine and
|
||||
micro-controller. Make sure the plugs are secure.
|
||||
- If using a Raspberry Pi, use a good quality power supply for the
|
||||
Raspberry Pi and use a good quality USB cable to connect that power
|
||||
supply to the Pi.
|
||||
- Make sure the printer's power supply is not being overloaded. (Power
|
||||
fluctuations to the micro-controller's USB chip may result in resets
|
||||
of that chip.)
|
||||
- There have been reports of high USB noise when both the printer's
|
||||
power supply and the host's 5V power supply are mixed. (If you find
|
||||
that the micro-controller powers on when either the printer's power
|
||||
supply is on or the USB cable is plugged in, then it indicates the
|
||||
5V power supplies are being mixed.) It may help to configure the
|
||||
micro-controller to use power from only one source. (Alternatively,
|
||||
if the micro-controller board can not configure its power source,
|
||||
one may modify a USB cable so that it does not carry 5V power
|
||||
between the host and micro-controller.)
|
||||
|
||||
### When I set "restart_method=command" my AVR device just hangs on a restart
|
||||
|
||||
Some old versions of the AVR bootloader have a known bug in watchdog
|
||||
@@ -216,6 +280,67 @@ off all heaters and stepper motors.
|
||||
See the "config_digital_out" command in the
|
||||
[MCU commands](MCU_Commands.md) document for further details.
|
||||
|
||||
In addition, the micro-controller software is configured with a
|
||||
minimum and maximum temperature range for each heater at startup (see
|
||||
the min_temp and max_temp parameters in the
|
||||
[example.cfg](../config/example.cfg) file for details). If the
|
||||
micro-controller detects that the temperature is outside of that range
|
||||
then it will also enter a "shutdown" state.
|
||||
|
||||
Separately, the host software also implements code to check that
|
||||
heaters and temperature sensors are functioning correctly. See the
|
||||
"verify_heater" section of the
|
||||
[example-extras.cfg](../config/example-extras.cfg) for further
|
||||
details.
|
||||
|
||||
### How do I convert a Marlin pin number to a Klipper pin name?
|
||||
|
||||
Short answer: In some cases one can use Klipper's `pin_map: arduino`
|
||||
feature. Otherwise, for "digital" pins, one method is to search for
|
||||
the requested pin in Marlin's fastio header files. The Atmega2560 and
|
||||
Atmega1280 chips use
|
||||
[fastio_1280.h](https://github.com/MarlinFirmware/Marlin/blob/1.1.9/Marlin/fastio_1280.h),
|
||||
while the Atmega644p and Atmega1284p chips use
|
||||
[fastio_644.h](https://github.com/MarlinFirmware/Marlin/blob/1.1.9/Marlin/fastio_644.h).
|
||||
For example, if you are looking to translate Marlin's digital pin
|
||||
number 23 on an atmega2560 then one could find the following line in
|
||||
Marlin's fastio_1280.h file:
|
||||
```
|
||||
#define DIO23_PIN PINA1
|
||||
```
|
||||
The `DIO23` indicates the line is for Marlin's pin 23 and the `PINA1`
|
||||
indicates the pin uses the hardware name of `PA1`. Klipper uses the
|
||||
hardware names (eg, `PA1`).
|
||||
|
||||
Long answer: Klipper uses the standard pin names defined by the
|
||||
micro-controller. On the Atmega chips these hardware pins have names
|
||||
like `PA4`, `PC7`, or `PD2`.
|
||||
|
||||
Long ago, the Arduino project decided to avoid using the standard
|
||||
hardware names in favor of their own pin names based on incrementing
|
||||
numbers - these Arduino names generally look like `D23` or `A14`. This
|
||||
was an unfortunate choice that has lead to a great deal of confusion.
|
||||
In particular the Arduino pin numbers frequently don't translate to
|
||||
the same hardware names. For example, `D21` is `PD0` on one common
|
||||
Arduino board, but is `PC7` on another common Arduino board.
|
||||
|
||||
In order to support 3d printers based on real Arduino boards, Klipper
|
||||
supports the Arduino pin aliases. This feature is enabled by adding
|
||||
`pin_map: arduino` to the [mcu] section of the config file. When these
|
||||
aliases are enabled, Klipper understands pin names that start with the
|
||||
prefix "ar" (eg, Arduino pin `D23` is Klipper alias `ar23`) and the
|
||||
prefix "analog" (eg, Arduino pin `A14` is Klipper alias `analog14`).
|
||||
Klipper does not use the Arduino names directly because we feel a name
|
||||
like D7 is too easily confused with the hardware name PD7.
|
||||
|
||||
Marlin primarily follows the Arduino pin numbering scheme. However,
|
||||
Marlin supports a few chips that Arduino does not support and in some
|
||||
cases it supports pins that Arduino boards do not expose. In these
|
||||
cases, Marlin chose their own pin numbering scheme. Klipper does not
|
||||
support these custom pin numbers - check Marlin's fastio headers (see
|
||||
above) to translate these pin numbers to their standard hardware
|
||||
names.
|
||||
|
||||
### How do I upgrade to the latest software?
|
||||
|
||||
The general way to upgrade is to ssh into the Raspberry Pi and run:
|
||||
@@ -230,6 +355,10 @@ Then one can recompile and flash the micro-controller code. For
|
||||
example:
|
||||
|
||||
```
|
||||
make menuconfig
|
||||
make clean
|
||||
make
|
||||
|
||||
sudo service klipper stop
|
||||
make flash FLASH_DEVICE=/dev/ttyACM0
|
||||
sudo service klipper start
|
||||
|
||||
128
docs/Features.md
Normal file → Executable file
@@ -20,12 +20,21 @@ Klipper has several compelling features:
|
||||
stepper event timing remains precise even at high speeds which
|
||||
improves overall stability.
|
||||
|
||||
* Klipper supports printers with multiple micro-controllers. For
|
||||
example, one micro-controller could be used to control an extruder,
|
||||
while another controls the printer's heaters, while a third controls
|
||||
the rest of the printer. The Klipper host software implements clock
|
||||
synchronization to account for clock drift between
|
||||
micro-controllers. No special code is needed to enable multiple
|
||||
micro-controllers - it just requires a few extra lines in the config
|
||||
file.
|
||||
|
||||
* Configuration via simple config file. There's no need to reflash the
|
||||
micro-controller to change a setting. All of Klipper's configuration
|
||||
is stored in a standard config file which can be easily edited. This
|
||||
makes it easier to setup and maintain the hardware.
|
||||
|
||||
* Portable code. Klipper works on both ARM and AVR
|
||||
* Portable code. Klipper works on ARM, AVR, and PRU based
|
||||
micro-controllers. Existing "reprap" style printers can run Klipper
|
||||
without hardware modification - just add a Raspberry Pi. Klipper's
|
||||
internal code layout makes it easier to support other
|
||||
@@ -33,37 +42,22 @@ Klipper has several compelling features:
|
||||
|
||||
* Simpler code. Klipper uses a very high level language (Python) for
|
||||
most code. The kinematics algorithms, the G-code parsing, the
|
||||
heating and thermistor algorithms, etc. are all written in
|
||||
Python. This makes it easier to develop new functionality.
|
||||
heating and thermistor algorithms, etc. are all written in Python.
|
||||
This makes it easier to develop new functionality.
|
||||
|
||||
* Advanced features:
|
||||
* Klipper implements the "pressure advance" algorithm for
|
||||
extruders. When properly tuned, pressure advance reduces extruder
|
||||
ooze.
|
||||
* Klipper supports printers with multiple micro-controllers. For
|
||||
example, one micro-controller could be used to control an
|
||||
extruder, while another could control the printer's heaters, while
|
||||
a third controls the rest of the printer. The Klipper host
|
||||
software implements clock synchronization to account for clock
|
||||
drift between micro-controllers. No special code is needed to
|
||||
enable multiple micro-controllers - it just requires a few extra
|
||||
lines in the config file.
|
||||
* Klipper also implements a novel "stepper phase endstop" algorithm
|
||||
that can dramatically improve the accuracy of typical endstop
|
||||
switches. When properly tuned it can improve a print's first layer
|
||||
bed adhesion.
|
||||
* Support for limiting the top speed of short "zigzag" moves to
|
||||
reduce printer vibration and noise. See the
|
||||
[kinematics](Kinematics.md) document for more information.
|
||||
* Klipper uses an "iterative solver" to calculate precise step times
|
||||
from simple kinematic equations. This makes porting Klipper to new
|
||||
types of robots easier and it keeps timing precise even with complex
|
||||
kinematics (no "line segmentation" is needed).
|
||||
|
||||
To get started with Klipper, read the [installation](Installation.md)
|
||||
guide.
|
||||
|
||||
Common features supported by Klipper
|
||||
====================================
|
||||
Additional features
|
||||
===================
|
||||
|
||||
Klipper supports many standard 3d printer features:
|
||||
|
||||
* Klipper implements the "pressure advance" algorithm for extruders.
|
||||
When properly tuned, pressure advance reduces extruder ooze.
|
||||
|
||||
* Works with Octoprint. This allows the printer to be controlled using
|
||||
a regular web-browser. The same Raspberry Pi that runs Klipper can
|
||||
also run Octoprint.
|
||||
@@ -72,16 +66,60 @@ Klipper supports many standard 3d printer features:
|
||||
typical "slicers" are supported. One may continue to use Slic3r,
|
||||
Cura, etc. with Klipper.
|
||||
|
||||
* Constant speed acceleration support. All printer moves will
|
||||
gradually accelerate from standstill to cruising speed and then
|
||||
decelerate back to a standstill.
|
||||
* Support for multiple extruders. Extruders with shared heaters and
|
||||
extruders on independent carriages (IDEX) are also supported.
|
||||
|
||||
* "Look-ahead" support. The incoming stream of G-Code movement
|
||||
commands are queued and analyzed - the acceleration between
|
||||
* Support for cartesian, delta, and corexy style printers.
|
||||
|
||||
* Automatic bed leveling support. Klipper can be configured for basic
|
||||
bed tilt detection or full mesh bed leveling. If the bed uses
|
||||
multiple Z steppers then Klipper can also level by independently
|
||||
manipulating the Z steppers. Most Z height probes are supported,
|
||||
including servo activated probes.
|
||||
|
||||
* Automatic delta calibration support. The calibration tool can
|
||||
perform basic height calibration as well as an enhanced X and Y
|
||||
dimension calibration. The calibration can be done with a Z height
|
||||
probe or via manual probing.
|
||||
|
||||
* Support for common temperature sensors (eg, common thermistors,
|
||||
AD595, PT100, MAX6675, MAX31855, MAX31856, MAX31865). Custom
|
||||
thermistors and custom analog temperature sensors can also be
|
||||
configured.
|
||||
|
||||
* Basic thermal heater protection enabled by default.
|
||||
|
||||
* Support for standard fans, nozzle fans, and temperature controlled
|
||||
fans. No need to keep fans running when the printer is idle.
|
||||
|
||||
* Support for run-time configuration of TMC2130, TMC2208, TMC2224, and
|
||||
TMC2660 stepper motor drivers. There is also support for current
|
||||
control of traditional stepper drivers via AD5206 and MCP4451
|
||||
digipots.
|
||||
|
||||
* Support for common LCD displays attached directly to the printer. A
|
||||
default menu is also available.
|
||||
|
||||
* Constant acceleration and "look-ahead" support. All printer moves
|
||||
will gradually accelerate from standstill to cruising speed and then
|
||||
decelerate back to a standstill. The incoming stream of G-Code
|
||||
movement commands are queued and analyzed - the acceleration between
|
||||
movements in a similar direction will be optimized to reduce print
|
||||
stalls and improve overall print time.
|
||||
|
||||
* Support for cartesian, delta, and corexy style printers.
|
||||
* Klipper implements a "stepper phase endstop" algorithm that can
|
||||
improve the accuracy of typical endstop switches. When properly
|
||||
tuned it can improve a print's first layer bed adhesion.
|
||||
|
||||
* Support for limiting the top speed of short "zigzag" moves to reduce
|
||||
printer vibration and noise. See the [kinematics](Kinematics.md)
|
||||
document for more information.
|
||||
|
||||
* Sample configuration files are available for many common printers.
|
||||
Check the [config directory](../config/) for a list.
|
||||
|
||||
To get started with Klipper, read the [installation](Installation.md)
|
||||
guide.
|
||||
|
||||
Step Benchmarks
|
||||
===============
|
||||
@@ -89,14 +127,20 @@ Step Benchmarks
|
||||
Below are the results of stepper performance tests. The numbers shown
|
||||
represent total number of steps per second on the micro-controller.
|
||||
|
||||
| Micro-controller | Fastest step rate | 3 steppers active |
|
||||
| ----------------- | ----------------- | ----------------- |
|
||||
| 20Mhz AVR | 189K | 125K |
|
||||
| 16Mhz AVR | 151K | 100K |
|
||||
| Arduino Due (ARM) | 382K | 337K |
|
||||
| Beaglebone PRU | 689K | 689K |
|
||||
| Micro-controller | Fastest step rate | 3 steppers active |
|
||||
| --------------------------- | ----------------- | ----------------- |
|
||||
| 16Mhz AVR | 151K | 100K |
|
||||
| 20Mhz AVR | 189K | 125K |
|
||||
| Arduino Zero (ARM SAMD21) | 234K | 217K |
|
||||
| STM32F103 | 333K | 300K |
|
||||
| Arduino Due (ARM SAM3X8E) | 410K | 397K |
|
||||
| Smoothieboard (ARM LPC1768) | 487K | 487K |
|
||||
| Smoothieboard (ARM LPC1769) | 584K | 584K |
|
||||
| SAM4E8E ARM | 638K | 638K |
|
||||
| Beaglebone PRU | 680K | 680K |
|
||||
|
||||
On AVR platforms, the highest achievable step rate is with just one
|
||||
stepper stepping. On the Due, the highest step rate is with two
|
||||
simultaneous steppers stepping. On the PRU, the highest step rate is
|
||||
with three simultaneous steppers.
|
||||
stepper stepping. On the STM32F103, Arduino Zero, and Due, the highest
|
||||
step rate is with two simultaneous steppers stepping. On the PRU,
|
||||
SAM4E8E, and LPC176x the highest step rate is with three simultaneous
|
||||
steppers.
|
||||
|
||||
158
docs/G-Codes.md
@@ -15,17 +15,21 @@ Klipper supports the following standard G-Code commands:
|
||||
- Set position: `G92 [X<pos>] [Y<pos>] [Z<pos>] [E<pos>]`
|
||||
- Set speed factor override percentage: `M220 S<percent>`
|
||||
- Set extrude factor override percentage: `M221 S<percent>`
|
||||
- Set acceleration: `M204 S<value>`
|
||||
- Get extruder temperature: `M105`
|
||||
- Set extruder temperature: `M104 [T<index>] [S<temperature>]`
|
||||
- Set extruder temperature and wait: `M109 [T<index>] S<temperature>`
|
||||
- Note: M109 always waits for temperature to settle at requested
|
||||
value
|
||||
- Set bed temperature: `M140 [S<temperature>]`
|
||||
- Set bed temperature and wait: `M190 S<temperature>`
|
||||
- Note: M190 always waits for temperature to settle at requested
|
||||
value
|
||||
- Set fan speed: `M106 S<value>`
|
||||
- Turn fan off: `M107`
|
||||
- Emergency stop: `M112`
|
||||
- Get current position: `M114`
|
||||
- Get firmware version: `M115`
|
||||
- Set home offset: `M206 [X<pos>] [Y<pos>] [Z<pos>]`
|
||||
|
||||
For further details on the above commands see the
|
||||
[RepRap G-Code documentation](http://reprap.org/wiki/G-code).
|
||||
@@ -36,6 +40,12 @@ their standard configurations. It is not a goal to support every
|
||||
possible G-Code command. Instead, Klipper prefers human readable
|
||||
["extended G-Code commands"](#extended-g-code-commands).
|
||||
|
||||
If one requires a less common G-Code command then it may be possible
|
||||
to implement it with a custom Klipper gcode_macro (see
|
||||
[example-extras.cfg](../config/example-extras.cfg) for details). For
|
||||
example, one might use this to implement: `G10`, `G11`, `G12`, `G29`,
|
||||
`G30`, `G31`, `M42`, `M80`, `M81`, etc.
|
||||
|
||||
## G-Code SD card commands
|
||||
|
||||
Klipper also supports the following standard G-Code commands if the
|
||||
@@ -48,6 +58,21 @@ Klipper also supports the following standard G-Code commands if the
|
||||
- Set SD position: `M26 S<offset>`
|
||||
- Report SD print status: `M27`
|
||||
|
||||
## G-Code display commands
|
||||
|
||||
The following standard G-Code commands are available if a "display"
|
||||
config section is enabled:
|
||||
- Display Message: `M117 <message>`
|
||||
- Set build percentage: `M73 P<percent>`
|
||||
|
||||
## Other available G-Code commands
|
||||
|
||||
The following standard G-Code commands are currently available, but
|
||||
using them is not recommended:
|
||||
- Offset axes: `M206 [X<offset>] [Y<offset>] [Z<offset>]` (Use
|
||||
SET_GCODE_OFFSET instead.)
|
||||
- Get Endstop Status: `M119` (Use QUERY_ENDSTOPS instead.)
|
||||
|
||||
# Extended G-Code Commands
|
||||
|
||||
Klipper uses "extended" G-Code commands for general configuration and
|
||||
@@ -64,6 +89,16 @@ The following standard commands are supported:
|
||||
verify that an endstop is working correctly.
|
||||
- `GET_POSITION`: Return information on the current location of the
|
||||
toolhead.
|
||||
- `SET_GCODE_OFFSET [X=<pos>|X_ADJUST=<adjust>]
|
||||
[Y=<pos>|Y_ADJUST=<adjust>] [Z=<pos>|Z_ADJUST=<adjust>]`: Set a
|
||||
positional offset to apply to future G-Code commands. This is
|
||||
commonly used to virtually change the Z bed offset or to set nozzle
|
||||
XY offsets when switching extruders. For example, if
|
||||
"SET_GCODE_OFFSET Z=0.2" is sent, then future G-Code moves will
|
||||
have 0.2mm added to their Z height. If the X_ADJUST style parameters
|
||||
are used, then the adjustment will be added to any existing offset
|
||||
(eg, "SET_GCODE_OFFSET Z=-0.2" followed by "SET_GCODE_OFFSET
|
||||
Z_ADJUST=0.3" would result in a total Z offset of 0.1).
|
||||
- `PID_CALIBRATE HEATER=<config_name> TARGET=<temperature>
|
||||
[WRITE_FILE=1]`: Perform a PID calibration test. The specified
|
||||
heater will be enabled until the specified target temperature is
|
||||
@@ -71,6 +106,18 @@ The following standard commands are supported:
|
||||
cycles. If the WRITE_FILE parameter is enabled, then the file
|
||||
/tmp/heattest.txt will be created with a log of all temperature
|
||||
samples taken during the test.
|
||||
- `TURN_OFF_HEATERS`: Turn off all heaters.
|
||||
- `SET_VELOCITY_LIMIT [VELOCITY=<value>] [ACCEL=<value>]
|
||||
[ACCEL_TO_DECEL=<value>] [SQUARE_CORNER_VELOCITY=<value>]`: Modify
|
||||
the printer's velocity limits. Note that one may only set values
|
||||
less than or equal to the limits specified in the config file.
|
||||
- `SET_PRESSURE_ADVANCE [EXTRUDER=<config_name>] [ADVANCE=<pressure_advance>]
|
||||
[ADVANCE_LOOKAHEAD_TIME=<pressure_advance_lookahead_time>]`:
|
||||
Set pressure advance parameters. If EXTRUDER is not specified, it
|
||||
defaults to the active extruder.
|
||||
- `STEPPER_BUZZ STEPPER=<config_name>`: Move the given stepper forward
|
||||
one mm and then backward one mm, repeated 10 times. This is a
|
||||
diagnostic tool to help verify stepper connectivity.
|
||||
- `RESTART`: This will cause the host software to reload its config
|
||||
and perform an internal reset. This command will not clear error
|
||||
state from the micro-controller (see FIRMWARE_RESTART) nor will it
|
||||
@@ -78,6 +125,10 @@ The following standard commands are supported:
|
||||
[the FAQ](FAQ.md#how-do-i-upgrade-to-the-latest-software)).
|
||||
- `FIRMWARE_RESTART`: This is similar to a RESTART command, but it
|
||||
also clears any error state from the micro-controller.
|
||||
- `SAVE_CONFIG`: This command will overwrite the main printer config
|
||||
file and restart the host software. This command is used in
|
||||
conjunction with other calibration commands to store the results of
|
||||
calibration tests.
|
||||
- `STATUS`: Report the Klipper host software status.
|
||||
- `HELP`: Report the list of available extended G-Code commands.
|
||||
|
||||
@@ -91,8 +142,8 @@ is enabled:
|
||||
|
||||
The following commands are available when a "servo" config section is
|
||||
enabled:
|
||||
- `SET_SERVO SERVO=config_name WIDTH=<seconds>`
|
||||
- `SET_SERVO SERVO=config_name ANGLE=<degrees>`
|
||||
- `SET_SERVO SERVO=config_name [WIDTH=<seconds>] [ENABLE=<0|1>]`
|
||||
- `SET_SERVO SERVO=config_name [ANGLE=<degrees>] [ENABLE=<0|1>]`
|
||||
|
||||
## Probe
|
||||
|
||||
@@ -102,26 +153,77 @@ enabled:
|
||||
- `QUERY_PROBE`: Report the current status of the probe ("triggered"
|
||||
or "open").
|
||||
|
||||
## BLTouch
|
||||
|
||||
The following command is available when a "bltouch" config section is
|
||||
enabled:
|
||||
- `BLTOUCH_DEBUG COMMAND=<command>`: This sends a command to the
|
||||
BLTouch. It may be useful for debugging. Available commands are:
|
||||
pin_down, touch_mode, pin_up, self_test, reset.
|
||||
|
||||
## Delta Calibration
|
||||
|
||||
The following commands are available when the "delta_calibrate" config
|
||||
section is enabled:
|
||||
- `DELTA_CALIBRATE`: This command will probe seven points on the bed
|
||||
and recommend updated endstop positions, tower angles, and radius.
|
||||
- `DELTA_CALIBRATE [METHOD=manual]`: This command will probe seven
|
||||
points on the bed and recommend updated endstop positions, tower
|
||||
angles, and radius.
|
||||
- `NEXT`: If manual bed probing is enabled, then one can use this
|
||||
command to move to the next probing point during a DELTA_CALIBRATE
|
||||
operation.
|
||||
- `DELTA_ANALYZE`: This command is used during enhanced delta
|
||||
calibration. See [Delta Calibrate](Delta_Calibrate.md) for details.
|
||||
|
||||
## Bed Tilt
|
||||
|
||||
The following commands are available when the "bed_tilt" config
|
||||
section is enabled:
|
||||
- `BED_TILT_CALIBRATE`: This command will probe the points specified
|
||||
in the config and then recommend updated x and y tilt adjustments.
|
||||
- `BED_TILT_CALIBRATE [METHOD=manual]`: This command will probe the
|
||||
points specified in the config and then recommend updated x and y
|
||||
tilt adjustments.
|
||||
- `NEXT`: If manual bed probing is enabled, then one can use this
|
||||
command to move to the next probing point during a
|
||||
BED_TILT_CALIBRATE operation.
|
||||
|
||||
## Mesh Bed Leveling
|
||||
|
||||
The following commands are available when the "bed_mesh" config
|
||||
section is enabled:
|
||||
- `BED_MESH_CALIBRATE [METHOD=manual]`: This command probes the bed
|
||||
using generated points specified by the parameters in the
|
||||
config. After probing, a mesh is generated and z-movement is
|
||||
adjusted according to the mesh.
|
||||
- `NEXT`: If manual bed probing is enabled, then one can use this
|
||||
command to move to the next probing point during a
|
||||
BED_MESH_CALIBRATE operation.
|
||||
- `BED_MESH_OUTPUT`: This command outputs the current probed z values
|
||||
and current mesh values to the terminal.
|
||||
- `BED_MESH_MAP`: This command probes the bed in a similar fashion
|
||||
to BED_MESH_CALIBRATE, however no mesh is generated. Instead,
|
||||
the probed z values are serialized to json and output to the
|
||||
terminal. This allows octoprint plugins to easily capture the
|
||||
data and generate maps approximating the bed's surface. Note
|
||||
that although no mesh is generated, any currently stored mesh
|
||||
will be cleared.
|
||||
- `BED_MESH_CLEAR`: This command clears the mesh and removes all
|
||||
z adjustment. It is recommended to put this in your end-gcode.
|
||||
- `BED_MESH_PROFILE LOAD=<name> SAVE=<name> REMOVE=<name>`: This
|
||||
command provides profile management for mesh state. LOAD will
|
||||
restore the mesh state from the profile matching the supplied name.
|
||||
SAVE will save the current mesh state to a profile matching the
|
||||
supplied name. Remove will delete the profile matching the
|
||||
supplied name from persistent memory. Note that after SAVE or
|
||||
REMOVE operations have been run the SAVE_CONFIG gcode must be run
|
||||
to make the changes to peristent memory permanent.
|
||||
|
||||
## Z Tilt
|
||||
|
||||
The following commands are available when the "z_tilt" config section
|
||||
is enabled:
|
||||
- `Z_TILT_ADJUST`: This command will probe the points specified in the
|
||||
config and then make independent adjustments to each Z stepper to
|
||||
compensate for tilt.
|
||||
|
||||
## Dual Carriages
|
||||
|
||||
The following command is available when the "dual_carriage" config
|
||||
@@ -129,3 +231,45 @@ section is enabled:
|
||||
- `SET_DUAL_CARRIAGE CARRIAGE=[0|1]`: This command will set the active
|
||||
carriage. It is typically invoked from the activate_gcode and
|
||||
deactivate_gcode fields in a multiple extruder configuration.
|
||||
|
||||
## TMC2130
|
||||
|
||||
The following command is available when the "tmc2130" config section
|
||||
is enabled:
|
||||
- `DUMP_TMC STEPPER=<name>`: This command will read the TMC2130 driver
|
||||
registers and report their values.
|
||||
|
||||
## Endstop adjustments by stepper phase
|
||||
|
||||
The following commands are available when an "endstop_phase" config
|
||||
section is enabled:
|
||||
- `ENDSTOP_PHASE_CALIBRATE [STEPPER=<config_name>]`: If no STEPPER
|
||||
parameter is provided then this command will reports statistics on
|
||||
endstop stepper phases during past homing operations. When a STEPPER
|
||||
parameter is provided it arranges for the given endstop phase
|
||||
setting to be written to the config file (in conjunction with the
|
||||
SAVE_CONFIG command).
|
||||
|
||||
## Force movement
|
||||
|
||||
The following commands are available when the "force_move" config
|
||||
section is enabled:
|
||||
- `FORCE_MOVE STEPPER=<config_name> DISTANCE=<value>
|
||||
VELOCITY=<value>`: This command will forcibly move the given stepper
|
||||
the given distance (in mm) at the given constant velocity (in
|
||||
mm/s). No acceleration is performed; no boundary checks are
|
||||
performed; no kinematic updates are made; other parallel steppers on
|
||||
an axis will not be moved. Use caution as an incorrect command could
|
||||
cause damage! Using this command will almost certainly place the
|
||||
low-level kinematics in an incorrect state; issue a G28 afterwards
|
||||
to reset the kinematics. This command is intended for low-level
|
||||
diagnostics and debugging.
|
||||
- `SET_KINEMATIC_POSITION [X=<value>] [Y=<value>] [Z=<value>]`: Force
|
||||
the low-level kinematic code to believe the toolhead is at the given
|
||||
cartesian position. This is a diagnostic and debugging command; use
|
||||
SET_GCODE_OFFSET and/or G92 for regular axis transformations. If an
|
||||
axis is not specified then it will default to the position that the
|
||||
head was last commanded to. Setting an incorrect or invalid position
|
||||
may lead to internal software errors. This command may invalidate
|
||||
future boundary checks; issue a G28 afterwards to reset the
|
||||
kinematics.
|
||||
|
||||
@@ -6,8 +6,8 @@ Raspberry Pi 2 or Raspberry Pi 3 computer be used as the host machine
|
||||
for other machines).
|
||||
|
||||
Klipper currently supports Atmel ATmega based micro-controllers,
|
||||
Arduino Due (Atmel SAM3x8e ARM micro-controller), and
|
||||
[Beaglebone PRU](beaglebone.md) based printers.
|
||||
Arduino Due (Atmel SAM3x8e ARM micro-controller), Smoothieboard (ARM
|
||||
LPC176x), and [Beaglebone PRU](beaglebone.md) based printers.
|
||||
|
||||
Prepping an OS image
|
||||
====================
|
||||
@@ -17,7 +17,7 @@ Raspberry Pi computer. Use OctoPi v0.14.0 or later - see the
|
||||
[octopi releases](https://github.com/guysoft/OctoPi/releases) for
|
||||
release information. One should verify that OctoPi boots and that the
|
||||
OctoPrint web server works. After connecting to the OctoPrint web
|
||||
page, follow the prompt to upgrade OctoPrint to v1.3.5 or later.
|
||||
page, follow the prompt to upgrade OctoPrint to v1.3.7 or later.
|
||||
|
||||
After installing OctoPi and upgrading OctoPrint, it will be necessary
|
||||
to ssh into the target machine to run a handful of system commands. If
|
||||
@@ -50,9 +50,9 @@ make menuconfig
|
||||
```
|
||||
|
||||
Select the appropriate micro-controller and review any other options
|
||||
provided. For boards with serial ports, the default baud rate is
|
||||
250000 (see the [FAQ](FAQ.md#how-do-i-change-the-serial-baud-rate) if
|
||||
changing). Once configured, run:
|
||||
provided. For boards with serial ports, the recommended baud rate is
|
||||
250000 (see the [FAQ](FAQ.md#how-do-i-change-the-serial-baud-rate)
|
||||
before changing). Once configured, run:
|
||||
|
||||
```
|
||||
make
|
||||
@@ -84,8 +84,9 @@ Under "Serial Connection" in "Additional serial ports" add
|
||||
"/tmp/printer". Then click "Save".
|
||||
|
||||
Enter the Settings tab again and under "Serial Connection" change the
|
||||
"Serial Port" setting to "/tmp/printer". Unselect the "Not only cancel
|
||||
ongoing prints but also disconnect..." checkbox. Click "Save".
|
||||
"Serial Port" setting to "/tmp/printer". Navigate to the "Behavior"
|
||||
sub-tab and select the "Cancel any ongoing prints but stay connected
|
||||
to the printer" option. Click "Save".
|
||||
|
||||
From the main page, under the "Connection" section (at the top left of
|
||||
the page) make sure the "Serial Port" is set to "/tmp/printer" and
|
||||
@@ -146,7 +147,7 @@ In addition to common g-code commands, Klipper supports a few extended
|
||||
commands - "status" and "restart" are examples of these commands. Use
|
||||
the "help" command to get a list of other extended commands.
|
||||
|
||||
After Klipper reports that the "printer is ready" go on to the
|
||||
After Klipper reports that the printer is ready go on to the
|
||||
[config check document](Config_checks.md) to perform some basic checks
|
||||
on the pin definitions in the config file.
|
||||
|
||||
|
||||
@@ -87,6 +87,10 @@ small junction speed is permitted.
|
||||
The junction speeds are determined using "approximated centripetal
|
||||
acceleration". Best
|
||||
[described by the author](https://onehossshay.wordpress.com/2011/09/24/improving_grbl_cornering_algorithm/).
|
||||
However, in Klipper, junction speeds are configured by specifying the
|
||||
desired speed that a 90° corner should have (the "square corner
|
||||
velocity"), and the junction speeds for other angles are derived from
|
||||
that.
|
||||
|
||||
Klipper implements look-ahead between moves that have similar extruder
|
||||
flow rates. Other moves are relatively rare and implementing
|
||||
@@ -139,15 +143,32 @@ tracked in millimeters, seconds, and in cartesian coordinate space.
|
||||
It's the task of the kinematic classes to convert from this generic
|
||||
coordinate system to the hardware specifics of the particular printer.
|
||||
|
||||
In general, the code determines each step time by first calculating
|
||||
where along the line of movement the head would be if a step is
|
||||
taken. It then calculates what time the head should be at that
|
||||
position. Determining the time along the line of movement can be done
|
||||
using the formulas for constant acceleration and constant velocity:
|
||||
Klipper uses an
|
||||
[iterative solver](https://en.wikipedia.org/wiki/Root-finding_algorithm)
|
||||
to generate the step times for each stepper. The code contains the
|
||||
formulas to calculate the ideal cartesian coordinates of the head at
|
||||
each moment in time, and it has the kinematic formulas to calculate
|
||||
the ideal stepper positions based on those cartesian coordinates. With
|
||||
these formulas, Klipper can determine the ideal time that the stepper
|
||||
should be at each step position. The given steps are then scheduled at
|
||||
these calculated times.
|
||||
|
||||
The key formula to determine how far a move should travel under
|
||||
constant acceleration is:
|
||||
```
|
||||
time = sqrt(2*distance/accel + (start_velocity/accel)^2) - start_velocity/accel
|
||||
time = distance/cruise_velocity
|
||||
move_distance = (start_velocity + .5 * accel * move_time) * move_time
|
||||
```
|
||||
and the key formula for movement with constant velocity is:
|
||||
```
|
||||
move_distance = cruise_velocity * move_time
|
||||
```
|
||||
|
||||
The key formulas for determining the cartesian coordinate of a move
|
||||
given a move distance is:
|
||||
```
|
||||
cartesian_x_position = start_x + move_distance * total_x_movement / total_movement
|
||||
cartesian_y_position = start_y + move_distance * total_y_movement / total_movement
|
||||
cartesian_z_position = start_z + move_distance * total_z_movement / total_movement
|
||||
```
|
||||
|
||||
Cartesian Robots
|
||||
@@ -157,54 +178,35 @@ Generating steps for cartesian printers is the simplest case. The
|
||||
movement on each axis is directly related to the movement in cartesian
|
||||
space.
|
||||
|
||||
Key formulas:
|
||||
```
|
||||
stepper_x_position = cartesian_x_position
|
||||
stepper_y_position = cartesian_y_position
|
||||
stepper_z_position = cartesian_z_position
|
||||
```
|
||||
|
||||
CoreXY Robots
|
||||
----------------
|
||||
|
||||
Generating steps on a CoreXY machine is only a little more complex
|
||||
than basic cartesian robots. The key formulas are:
|
||||
```
|
||||
stepper_a_position = cartesian_x_position + cartesian_y_position
|
||||
stepper_b_position = cartesian_x_position - cartesian_y_position
|
||||
stepper_z_position = cartesian_z_position
|
||||
```
|
||||
|
||||
Delta Robots
|
||||
------------
|
||||
|
||||
To generate step times on Delta printers it is necessary to correlate
|
||||
the movement in cartesian space with the movement on each stepper
|
||||
tower.
|
||||
|
||||
To simplify the math, for each stepper tower, the code calculates the
|
||||
location of a "virtual tower" that is along the line of movement.
|
||||
This virtual tower is chosen at the point where the line of movement
|
||||
(extended infinitely in both directions) would be closest to the
|
||||
actual tower.
|
||||
|
||||

|
||||
|
||||
It is then possible to calculate where the head will be along the line
|
||||
of movement after each step is taken on the virtual tower.
|
||||
|
||||

|
||||
|
||||
The key formula is Pythagoras's theorem:
|
||||
Step generation on a delta robot is based on Pythagoras's theorem:
|
||||
```
|
||||
distance_to_tower^2 = arm_length^2 - tower_height^2
|
||||
stepper_position = (sqrt(arm_length^2
|
||||
- (cartesian_x_position - tower_x_position)^2
|
||||
- (cartesian_y_position - tower_y_position)^2)
|
||||
+ cartesian_z_position)
|
||||
```
|
||||
|
||||
One complexity is that if the print head passes the virtual tower
|
||||
location then the stepper direction must be reversed. In this case
|
||||
forward steps will be taken at the start of the move and reverse steps
|
||||
will be taken at the end of the move.
|
||||
|
||||
### Delta movements beyond simple XY plane ###
|
||||
|
||||
Movement calculation is more complicated if a single move contains
|
||||
both XY movement and Z movement. These moves are rare, but they must
|
||||
still be handled correctly. A virtual tower along the line of movement
|
||||
is still calculated, but in this case the tower is not at a 90 degree
|
||||
angle relative to the line of movement:
|
||||
|
||||

|
||||
|
||||
The code continues to calculate step times using the same general
|
||||
scheme as delta moves within an XY plane, but the slope of the tower
|
||||
must also be used in the calculations.
|
||||
|
||||
Should the move contain only Z movement (ie, no XY movement at all)
|
||||
then the same math is used - just in this case the tower is parallel
|
||||
to the line of movement.
|
||||
|
||||
### Stepper motor acceleration limits ###
|
||||
|
||||
With delta kinematics it is possible for a move that is accelerating
|
||||
@@ -236,8 +238,10 @@ independently from the step time calculations of the print head
|
||||
movement.
|
||||
|
||||
Basic extruder movement is simple to calculate. The step time
|
||||
generation uses the same constant acceleration and constant velocity
|
||||
formulas that cartesian robots use.
|
||||
generation uses the same formulas that cartesian robots use:
|
||||
```
|
||||
stepper_position = requested_e_position
|
||||
```
|
||||
|
||||
### Pressure advance ###
|
||||
|
||||
@@ -264,7 +268,7 @@ through the nozzle orifice (as in
|
||||
key idea is that the relationship between filament, pressure, and flow
|
||||
rate can be modeled using a linear coefficient:
|
||||
```
|
||||
extra_filament = pressure_advance_coefficient * extruder_velocity
|
||||
stepper_position = requested_e_position + pressure_advance_coefficient * nominal_extruder_velocity
|
||||
```
|
||||
|
||||
See the [pressure advance](Pressure_Advance.md) document for
|
||||
|
||||
@@ -49,13 +49,6 @@ Common startup commands:
|
||||
and 255 indicating a full on state. This command may be useful for
|
||||
enabling CPU and nozzle cooling fans.
|
||||
|
||||
* `send_spi_message pin=%u msg=%*s` : This command can be used to
|
||||
transmit messages to a serial-peripheral-interface (SPI) component
|
||||
connected to the micro-controller. It has been used to configure the
|
||||
startup settings of AD5206 digipots. The 'pin' parameter specifies
|
||||
the chip select line to use during the transmission. The 'msg'
|
||||
indicates the binary message to transmit to the given chip.
|
||||
|
||||
Low-level micro-controller configuration
|
||||
========================================
|
||||
|
||||
@@ -182,6 +175,22 @@ This section lists some commonly used config commands.
|
||||
specifies the maximum number of steppers that this endstop may need
|
||||
to halt during a homing operation (see end_stop_home below).
|
||||
|
||||
* `config_spi oid=%c bus=%u pin=%u mode=%u rate=%u shutdown_msg=%*s` :
|
||||
This command creates an internal SPI object. It is used with
|
||||
spi_transfer and spi_send commands (see below). The "bus"
|
||||
identifies the SPI bus to use (if the micro-controller has more than
|
||||
one SPI bus available). The "pin" specifies the chip select (CS) pin
|
||||
for the device. The "mode" is the SPI mode (should be between 0 and
|
||||
3). The "rate" parameter specifies the SPI bus rate (in cycles per
|
||||
second). Finally, the "shutdown_msg" is an SPI command to send to
|
||||
the given device should the micro-controller go into a shutdown
|
||||
state.
|
||||
|
||||
* `config_spi_without_cs oid=%c bus=%u mode=%u rate=%u
|
||||
shutdown_msg=%*s` : This command is similar to config_spi, but
|
||||
without a CS pin definition. It is useful for SPI devices that do
|
||||
not have a chip select line.
|
||||
|
||||
Common commands
|
||||
===============
|
||||
|
||||
@@ -217,11 +226,11 @@ only of interest to developers looking to gain insight into Klipper.
|
||||
pins attached to thermistors controlling heaters - it can be used to
|
||||
check that a heater is within a temperature range.
|
||||
|
||||
* `get_status` : This command causes the micro-controller to generate
|
||||
a "status" response message. The host sends this command once a
|
||||
second to obtain the value of the micro-controller clock and to
|
||||
estimate the drift between host and micro-controller clocks. It
|
||||
enables the host to accurately estimate the micro-controller clock.
|
||||
* `get_clock` : This command causes the micro-controller to generate a
|
||||
"clock" response message. The host sends this command once a second
|
||||
to obtain the value of the micro-controller clock and to estimate
|
||||
the drift between host and micro-controller clocks. It enables the
|
||||
host to accurately estimate the micro-controller clock.
|
||||
|
||||
Stepper commands
|
||||
----------------
|
||||
@@ -283,3 +292,15 @@ It is the responsibility of the host to ensure that there is available
|
||||
space in the queue before sending a queue_step command. The host does
|
||||
this by calculating when each queue_step command completes and
|
||||
scheduling new queue_step commands accordingly.
|
||||
|
||||
SPI Commands
|
||||
------------
|
||||
|
||||
* `spi_transfer oid=%c data=%*s` : This command causes the
|
||||
micro-controller to send 'data' to the spi device specified by 'oid'
|
||||
and it generates a "spi_transfer_response" response message with the
|
||||
data returned during the transmission.
|
||||
|
||||
* `spi_send oid=%c data=%*s` : This command is similar to
|
||||
"spi_transfer", but it does not generate a "spi_transfer_response"
|
||||
message.
|
||||
|
||||
@@ -10,7 +10,12 @@ settings in the config file.
|
||||
|
||||
The Klipper configuration is stored in a simple text file on the host
|
||||
machine. The [config/example.cfg](../config/example.cfg) file serves
|
||||
as a reference for the config file. The
|
||||
as a reference for the config file. See the [Slicers](Slicers.md)
|
||||
document for information on configuring a slicer with Klipper. See the
|
||||
[Endstop Phase](Endstop_Phase.md) document for information on
|
||||
Klipper's "stepper phase adjusted endstop" system. See the
|
||||
[Delta Calibrate](Delta_Calibrate.md) document for information on
|
||||
calibrating delta printers. The
|
||||
[Pressure Advance](Pressure_Advance.md) document contains information
|
||||
on tuning the pressure advance config.
|
||||
|
||||
@@ -38,6 +43,6 @@ protocol between host and micro-controller. See also
|
||||
commands implemented in the micro-controller software.
|
||||
|
||||
See [debugging](Debugging.md) for information on how to test and debug
|
||||
Klipper.
|
||||
|
||||
See [todo](Todo.md) for information on possible future code features.
|
||||
Klipper. See [stm32f1](stm32f1.md) for information on the STM32F1
|
||||
micro-controller port. See [bootloaders](Bootloaders.md) for developer
|
||||
information on micro-controller flashing.
|
||||
|
||||
31
docs/Packaging.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# Packaging klipper
|
||||
|
||||
Klipper is somewhat of a packaging anomaly among python programs, as it doesn't
|
||||
use setuptools to build and install. Some notes regarding how best to package it
|
||||
are as follows:
|
||||
|
||||
## C modules
|
||||
|
||||
Klipper uses a C module to handle some kinematics calculations more quickly.
|
||||
This module needs to be compiled at packaging time to avoid introducing a
|
||||
runtime dependency on a compiler. To compile the C module, run `python2
|
||||
klippy/chelper/__init__.py`.
|
||||
|
||||
## Compiling python code
|
||||
|
||||
Many distributions have a policy of compiling all python code before packaging
|
||||
to improve startup time. You can do this by running `python2 -m compileall
|
||||
klippy`.
|
||||
|
||||
## Versioning
|
||||
|
||||
If you are building a package of Klipper from git, it is usual practice not to
|
||||
ship a .git directory, so the versioning must be handled without git. To do
|
||||
this, use the script shipped in `scripts/make_version.py` which should be run as
|
||||
follows: `python2 scripts/make_version.py YOURDISTRONAME > klippy/.version`.
|
||||
|
||||
## Sample packaging script
|
||||
|
||||
klipper-git is packaged for Arch Linux, and has a PKGBUILD (package build
|
||||
script) available at
|
||||
https://aur.archlinux.org/cgit/aur.git/tree/PKGBUILD?h=klipper-git.
|
||||
@@ -1,36 +1,36 @@
|
||||
This document provides information on tuning the "pressure advance"
|
||||
configuration variables for a particular nozzle and filament. The
|
||||
configuration variable for a particular nozzle and filament. The
|
||||
pressure advance feature can be helpful in reducing ooze. For more
|
||||
information on how pressure advance is implemented see the
|
||||
[kinematics](Kinematics.md) document.
|
||||
|
||||
Prerequisites
|
||||
=============
|
||||
|
||||
In order to tune the pressure advance setting the printer must be
|
||||
configured and operational. The tuning test involves printing objects
|
||||
and inspecting the differences between objects. In particular, the
|
||||
extruder
|
||||
[E steps](http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide#E_steps)
|
||||
and
|
||||
[nozzle temperature](http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide#Nozzle_Temperature)
|
||||
should be tuned prior to tuning pressure advance.
|
||||
|
||||
Tuning pressure advance
|
||||
=======================
|
||||
|
||||
Pressure advance does two useful things - it reduces ooze during
|
||||
non-extrude moves and it reduces blobbing during cornering. This guide
|
||||
uses the second feature (reducing blobbing during cornering) as a
|
||||
mechanism for measuring and tuning the pressure advance configuration.
|
||||
mechanism for tuning.
|
||||
|
||||
Start by changing the extruder section of the config file so that
|
||||
pressure_advance is set to 0.0. (Make sure to issue a RESTART command
|
||||
after each update to the config file so that the new configuration
|
||||
takes effect.) Then print at least 10 layers of a large hollow square
|
||||
at high speed (eg, 100mm/s). See
|
||||
[docs/prints/square.stl](prints/square.stl) file for an STL file that
|
||||
one may use. While the object is printing, make a note of which
|
||||
In order to calibrate pressure advance the printer must be configured
|
||||
and operational. The tuning test involves printing objects and
|
||||
inspecting the differences between objects. It is a good idea to read
|
||||
this document in full prior to running the test.
|
||||
|
||||
Use a slicer to generate g-code for the large hollow square found in
|
||||
[docs/prints/square.stl](prints/square.stl). Use a high speed (eg,
|
||||
100mm/s) and a coarse layer height (the layer height should be around
|
||||
75% of the nozzle diameter). It is fine to use a low infill (eg, 10%).
|
||||
|
||||
Prepare for the test by issuing the following G-Code commands:
|
||||
`SET_VELOCITY_LIMIT SQUARE_CORNER_VELOCITY=1 ACCEL=500` and
|
||||
`SET_PRESSURE_ADVANCE ADVANCE_LOOKAHEAD_TIME=0`. These commands make
|
||||
the nozzle travel slower through corners and they emphasize the
|
||||
effects of extruder pressure.
|
||||
|
||||
For the first print use a pressure advance of zero by running
|
||||
`SET_PRESSURE_ADVANCE ADVANCE=0.000`. Then print at least 10 layers of
|
||||
the test object. While the object is printing, make a note of which
|
||||
direction the head is moving during external perimeters. What many
|
||||
people see here is blobbing occurring at the corners - extra filament
|
||||
at the corner in the direction the head travels followed by a possible
|
||||
@@ -41,15 +41,13 @@ lack of filament on the side immediately after that corner:
|
||||
This blobbing is the result of pressure in the extruder being released
|
||||
as a blob when the head slows down to corner.
|
||||
|
||||
The next step is to set pressure_advance_lookahead_time to 0.0, slowly
|
||||
increase pressure_advance (eg, start with 0.05), and reprint the test
|
||||
object. (Be sure to issue RESTART between each config change.) The
|
||||
goal is to attempt to eliminate the blobbing during cornering. (With
|
||||
pressure advance, the extruder will retract when the head slows down,
|
||||
thus countering the pressure buildup and ideally eliminate the
|
||||
blobbing.)
|
||||
The next step is to increase pressure advance (start with
|
||||
`SET_PRESSURE_ADVANCE ADVANCE=0.050`) and reprint the test object.
|
||||
With pressure advance, the extruder will retract when the head slows
|
||||
down, thus countering the pressure buildup and ideally eliminate the
|
||||
blobbing.
|
||||
|
||||
If a test run is done with a pressure_advance setting that is too
|
||||
If a test run is done with a pressure advance setting that is too
|
||||
high, one typically sees a dimple in the corner followed by possible
|
||||
blobbing after the corner (too much filament is retracted during slow
|
||||
down and then too much filament is extruded during the following speed
|
||||
@@ -57,41 +55,89 @@ up after cornering):
|
||||
|
||||

|
||||
|
||||
The goal is to find the smallest pressure_advance value that results
|
||||
The goal is to find the smallest pressure advance value that results
|
||||
in good quality corners:
|
||||
|
||||

|
||||
|
||||
Typical pressure_advance values are between 0.05 and 0.20 (the high
|
||||
Typical pressure advance values are between 0.050 and 1.000 (the high
|
||||
end usually only with bowden extruders). If there is no significant
|
||||
improvement seen after increasing pressure_advance to 0.20, then
|
||||
improvement after gradually increasing pressure advance to 1.000, then
|
||||
pressure advance is unlikely to improve the quality of prints. Return
|
||||
to a default configuration with pressure_advance disabled.
|
||||
|
||||
It is not unusual for one corner of the test print to be consistently
|
||||
different than the other three corners. This typically occurs when the
|
||||
slicer arranges to always change Z height at that corner. If this
|
||||
occurs, then ignore that corner and tune pressure_advance using the
|
||||
other three corners.
|
||||
|
||||
Once a good pressure_advance value is found, return
|
||||
pressure_advance_lookahead_time to its default (0.010). This parameter
|
||||
controls how far in advance to check if a head slow-down is
|
||||
immediately followed by a speed-up - it reduces pointless pressure
|
||||
changes in the head. It's possible to tune this - higher values will
|
||||
decrease the number of pressure changes in the nozzle at the expense
|
||||
of permitting more blobbing during cornering. (Tuning this value is
|
||||
unlikely to impact ooze.) The default of 10ms should work well on most
|
||||
printers.
|
||||
to a default configuration with pressure advance disabled.
|
||||
|
||||
Although this tuning exercise directly improves the quality of
|
||||
corners, it's worth remembering that a good pressure advance
|
||||
configuration can reduce ooze throughout the print.
|
||||
configuration also reduces ooze throughout the print.
|
||||
|
||||
Finally, once pressure_advance is tuned in Klipper, it may still be
|
||||
useful to configure a small retract value in the slicer (eg, 0.75mm)
|
||||
and to utilize the slicer's "wipe on retract option" if available.
|
||||
These slicer settings may help counteract ooze caused by filament
|
||||
cohesion (filament pulled out of the nozzle due to the stickiness of
|
||||
the plastic). It is recommended to disable the slicer's "z-lift on
|
||||
retract" option.
|
||||
At the completion of this test, update the extruder's pressure_advance
|
||||
setting in the configuration file and issue a RESTART command. The
|
||||
RESTART command will also return the acceleration, cornering speeds,
|
||||
and look-ahead times to their normal values.
|
||||
|
||||
Important Notes
|
||||
===============
|
||||
|
||||
* The pressure advance value is dependent on the extruder, the nozzle,
|
||||
and the filament. It is common for filament from different
|
||||
manufactures or with different pigments to require significantly
|
||||
different pressure advance values. Therefore, one should calibrate
|
||||
pressure advance on each printer and with each spool of filament.
|
||||
|
||||
* Printing temperature and extrusion rates can impact pressure
|
||||
advance. Be sure to tune the extruder
|
||||
[E steps](http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide#E_steps)
|
||||
and
|
||||
[nozzle temperature](http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide#Nozzle_Temperature)
|
||||
prior to tuning pressure advance.
|
||||
|
||||
* It is not unusual for one corner of the test print to be
|
||||
consistently different than the other three corners. This typically
|
||||
occurs when the slicer arranges to always change Z height at that
|
||||
corner. If this occurs, then ignore that corner and tune pressure
|
||||
advance using the other three corners.
|
||||
|
||||
* Check for warping at the corners during the test prints (the corners
|
||||
detaching from the bed and rising a small distance upwards during
|
||||
the print). If one corner appears warped then ignore that corner
|
||||
when tuning. If significant warping is seen throughout the test then
|
||||
typical solutions are to reduce the slicer's first layer speed,
|
||||
adjust the bed temperature, and/or to use the slicer's brim feature.
|
||||
Pressure advance itself is unlikely to impact warping, but this
|
||||
tuning test is sensitive to it.
|
||||
|
||||
* If a high pressure advance value (eg, over 0.200) is used then one
|
||||
may find that the extruder skips when returning to the printer's
|
||||
normal acceleration. The pressure advance system accounts for
|
||||
pressure by pushing in extra filament during acceleration and
|
||||
retracting that filament during deceleration. With a high
|
||||
acceleration and high pressure advance the extruder may not have
|
||||
enough torque to push the required filament. If this occurs, either
|
||||
use a lower acceleration value or disable pressure advance.
|
||||
|
||||
* The pressure_advance_lookahead_time parameter controls how far in
|
||||
advance to check if a head slow-down is immediately followed by a
|
||||
speed-up - it reduces pointless pressure changes in the head. It is
|
||||
recommended to follow the steps above so that it is set to zero
|
||||
during tuning and to use the default (0.010) during normal prints.
|
||||
It is possible to tune this setting - higher values will reduce the
|
||||
amount of pressure change in the nozzle during cornering, but
|
||||
setting it too high can cause blobbing during cornering. (Tuning
|
||||
this value is unlikely to impact ooze.) The default of 10ms should
|
||||
work well on most printers.
|
||||
|
||||
* Once pressure advance is tuned in Klipper, it may still be useful to
|
||||
configure a small retract value in the slicer (eg, 0.75mm) and to
|
||||
utilize the slicer's "wipe on retract option" if available. These
|
||||
slicer settings may help counteract ooze caused by filament cohesion
|
||||
(filament pulled out of the nozzle due to the stickiness of the
|
||||
plastic). It is recommended to disable the slicer's "z-lift on
|
||||
retract" option.
|
||||
|
||||
* Configuring pressure advance results in extra extruder movement
|
||||
during move acceleration and deceleration. That extra movement is
|
||||
not further constrained by any other other configuration parameter.
|
||||
The pressure advance settings only impact extruder movement; they do
|
||||
not alter toolhead XYZ movement or look-ahead calculations. A change
|
||||
in pressure advance will not change the path or timing of the
|
||||
toolhead nor will it change the overall printing time.
|
||||
|
||||
@@ -174,20 +174,20 @@ message block:
|
||||
set_digital_out pin=86 value=1
|
||||
set_digital_out pin=85 value=0
|
||||
get_config
|
||||
get_status
|
||||
get_clock
|
||||
```
|
||||
|
||||
and encoded into the following eight VLQ integers:
|
||||
|
||||
```
|
||||
<id_set_digital_out><86><1><id_set_digital_out><85><0><id_get_config><id_get_status>
|
||||
<id_set_digital_out><86><1><id_set_digital_out><85><0><id_get_config><id_get_clock>
|
||||
```
|
||||
|
||||
In order to encode and parse the message contents, both the host and
|
||||
micro-controller must agree on the command ids and the number of
|
||||
parameters each command has. So, in the above example, both the host
|
||||
and micro-controller would know that "id_set_digital_out" is always
|
||||
followed by two parameters, and "id_get_config" and "id_get_status"
|
||||
followed by two parameters, and "id_get_config" and "id_get_clock"
|
||||
have zero parameters. The host and micro-controller share a "data
|
||||
dictionary" that maps the command descriptions (eg, "set_digital_out
|
||||
pin=%u value=%c") to their integer command-ids. When processing the
|
||||
|
||||
@@ -1,6 +1,40 @@
|
||||
History of Klipper releases. Please see
|
||||
[installation](Installation.md) for information on installing Klipper.
|
||||
|
||||
Klipper 0.7.0
|
||||
=============
|
||||
|
||||
Available on 20181220. Major changes in this release:
|
||||
* Klipper now supports "mesh" bed leveling
|
||||
* New support for "enhanced" delta calibration (calibrates print x/y
|
||||
dimensions on delta printers)
|
||||
* Support for run-time configuration of Trinamic stepper motor drivers
|
||||
(tmc2130, tmc2208, tmc2660)
|
||||
* Improved temperature sensor support: MAX6675, MAX31855, MAX31856,
|
||||
MAX31865, custom thermistors, common pt100 style sensors
|
||||
* Several new modules: temperature_fan, sx1509, force_move, mcp4451,
|
||||
z_tilt, quad_gantry_level, endstop_phase, bltouch
|
||||
* Several new commands added: SAVE_CONFIG, SET_PRESSURE_ADVANCE,
|
||||
SET_GCODE_OFFSET, SET_VELOCITY_LIMIT, STEPPER_BUZZ, TURN_OFF_HEATERS,
|
||||
M204, custom g-code macros
|
||||
* Expanded LCD display support:
|
||||
* Support for run-time menus
|
||||
* New display icons
|
||||
* Support for "uc1701" and "ssd1306" displays
|
||||
* Additional micro-controller support:
|
||||
* Klipper ported to: LPC176x (Smoothieboards), SAM4E8E (Duet2),
|
||||
SAMD21 (Arduino Zero), STM32F103 ("Blue pill" devices), atmega32u4
|
||||
* New Generic USB CDC driver implemented on AVR, LPC176x, SAMD21, and
|
||||
STM32F103
|
||||
* Performance improvements on ARM processors
|
||||
* The kinematics code was rewritten to use an "iterative solver"
|
||||
* New automatic test cases for the Klipper host software
|
||||
* Many new example config files for common off-the-shelf printers
|
||||
* Documentation updates for bootloaders, benchmarking,
|
||||
micro-controller porting, config checks, pin mapping, slicer
|
||||
settings, packaging, and more
|
||||
* Several bug fixes and code cleanups
|
||||
|
||||
Klipper 0.6.0
|
||||
=============
|
||||
|
||||
|
||||
71
docs/Slicers.md
Normal file
@@ -0,0 +1,71 @@
|
||||
This document provides some tips for configuring a "slicer"
|
||||
application for use with Klipper. Common slicers used with Klipper are
|
||||
Slic3r, Cura, Simplify3D, etc.
|
||||
|
||||
# Set the G-Code flavor to Marlin
|
||||
|
||||
Many slicers have an option to configure the "G-Code flavor". The
|
||||
default is frequently "Marlin" and that works well with Klipper. The
|
||||
"Smoothieware" setting also works well with Klipper.
|
||||
|
||||
# Klipper gcode_macro
|
||||
|
||||
Slicers will often allow one to configure "Start G-Code" and "End
|
||||
G-Code" sequences. It is often convenient to define custom macros in
|
||||
the Klipper config file instead - such as: `[gcode_macro START_PRINT]`
|
||||
and `[gcode_macro END_PRINT]`. Then one can just run START_PRINT and
|
||||
END_PRINT in the slicer's configuration. Defining these actions in the
|
||||
Klipper configuration may make it easier to tweak the printer's start
|
||||
and end steps as changes do not require re-slicing.
|
||||
|
||||
See the [example-extras.cfg](../config/example-extras.cfg) file for
|
||||
details on defining a gcode_macro.
|
||||
|
||||
# Large retraction settings may require tuning Klipper
|
||||
|
||||
The maximum speed and acceleration of retraction moves are controlled
|
||||
in Klipper by the `max_extrude_only_velocity` and
|
||||
`max_extrude_only_accel` config settings. These settings have a
|
||||
default value that should work well on many printers. However, if one
|
||||
has configured a large retraction in the slicer (eg, 5mm or greater)
|
||||
then one may find they limit the desired speed of retractions.
|
||||
|
||||
If using a large retraction, consider tuning Klipper's
|
||||
[pressure advance](Pressure_Advance.md) instead. Otherwise, if one
|
||||
finds the toolhead seems to "pause" during retraction and priming,
|
||||
then consider explicitly defining `max_extrude_only_velocity` and
|
||||
`max_extrude_only_accel` in the Klipper config file.
|
||||
|
||||
# Do not enable "coasting"
|
||||
|
||||
The "coasting" feature is likely to result in poor quality prints with
|
||||
Klipper. Consider using Klipper's
|
||||
[pressure advance](Pressure_Advance.md) instead.
|
||||
|
||||
Specifically, if the slicer dramatically changes the extrusion rate
|
||||
between moves then Klipper will perform deceleration and acceleration
|
||||
between moves. This is likely to make blobbing worse, not better.
|
||||
|
||||
In contrast, it is okay (and often helpful) to use a slicer's
|
||||
"retract" setting, "wipe" setting, and/or "wipe on retract" setting.
|
||||
|
||||
# Disable any "advanced extruder pressure" settings
|
||||
|
||||
Some slicers advertise an "advanced extruder pressure" capability. It
|
||||
is recommended to keep these options disabled when using Klipper as
|
||||
they are likely to result in poor quality prints. Consider using
|
||||
Klipper's [pressure advance](Pressure_Advance.md) instead.
|
||||
|
||||
Specifically, these slicer settings can instruct the firmware to make
|
||||
wild changes to the extrusion rate in the hope that the firmware will
|
||||
approximate those requests and the printer will roughly obtain a
|
||||
desirable extruder pressure. Klipper, however, utilizes precise
|
||||
kinematic calculations and timing. When Klipper is commanded to make
|
||||
significant changes to the extrusion rate it will plan out the
|
||||
corresponding changes to velocity, acceleration, and extruder
|
||||
movement - which is not the slicer's intent. The slicer may even
|
||||
command excessive extrusion rates to the point that it triggers
|
||||
Klipper's maximum extrusion cross-section check.
|
||||
|
||||
In contrast, it is okay (and often helpful) to use a slicer's
|
||||
"retract" setting, "wipe" setting, and/or "wipe on retract" setting.
|
||||
84
docs/Todo.md
@@ -1,84 +0,0 @@
|
||||
There are several features still to be implemented in Klipper. In no
|
||||
particular order:
|
||||
|
||||
Host user interaction
|
||||
=====================
|
||||
|
||||
* See if there is a better way to report errors. Octoprint sometimes
|
||||
doesn't highlight an error (one has to look in the terminal tab to
|
||||
find the error) and errors written to the log can be non-obvious to
|
||||
a user.
|
||||
|
||||
* Improve gcode interface:
|
||||
|
||||
* Provide a better way to handle print nozzle z offsets. The M206
|
||||
command is cryptic to use and it is too easy to set the value
|
||||
incorrectly or to forget to set it.
|
||||
|
||||
* Provide a way to temporarily disable endstop checks so that a user
|
||||
can issue commands that potentially move the head past
|
||||
position_min/position_max.
|
||||
|
||||
* Improve logging:
|
||||
|
||||
* Possibly collate and report the statistics messages in the log in a
|
||||
more friendly way.
|
||||
|
||||
* Possibly support a mechanism for the host to limit maximum velocity
|
||||
so that the mcu is never requested to step at a higher rate than it
|
||||
can support.
|
||||
|
||||
Safety features
|
||||
===============
|
||||
|
||||
* Support loading a valid step range into the micro-controller
|
||||
software after homing. This would provide a sanity check in the
|
||||
micro-controller that would reduce the risk of the host commanding a
|
||||
stepper motor past its valid step range. To maintain high
|
||||
efficiency, the micro-controller would only need to check
|
||||
periodically (eg, every 100ms) that the stepper is in range.
|
||||
|
||||
* Possibly support periodically querying the endstop switches and use
|
||||
multiple step ranges depending on the switch state. This would
|
||||
enable runtime endstop detection. (However, it's unclear if runtime
|
||||
endstop detection is a good idea because of spurious signals caused
|
||||
by electrical noise.)
|
||||
|
||||
Testing features
|
||||
================
|
||||
|
||||
* Complete the host based simulator. It's possible to compile the
|
||||
micro-controller for a "host simulator", but that simulator doesn't
|
||||
do anything currently. It would be useful to expand the code to
|
||||
support more error checks, kinematic simulations, and improved
|
||||
logging.
|
||||
|
||||
Documentation
|
||||
=============
|
||||
|
||||
* Add documentation describing how to perform bed-leveling accurately
|
||||
in Klipper. Improve description of stepper phase based bed leveling.
|
||||
|
||||
Hardware features
|
||||
=================
|
||||
|
||||
* Port to additional micro-controller architectures:
|
||||
* Smoothieboard / NXP LPC1769 (ARM cortex-M3)
|
||||
|
||||
* Support for additional kinematics: scara, etc.
|
||||
|
||||
* Possible support for touch panels attached to the micro-controller.
|
||||
(In general, it would be preferable to attach touch panels to the
|
||||
host system and have octoprint interact with the panel directly, but
|
||||
it would also be useful to handle panels already hardwired to the
|
||||
micro-controller.)
|
||||
|
||||
Misc features
|
||||
=============
|
||||
|
||||
* Possibly support a "feed forward PID" that takes into account the
|
||||
amount of plastic being extruded. If the extrude rate changes
|
||||
significantly during a print it can cause heating bumps that the PID
|
||||
overcompensates for. The temperature change due to the extrusion
|
||||
rate could be modeled to eliminate these bumps and make the
|
||||
extrusion temperature more consistent.
|
||||
@@ -71,9 +71,9 @@ make flash
|
||||
sudo service klipper start
|
||||
```
|
||||
|
||||
For the Replicape, it is also necessary to compile and install the
|
||||
micro-controller code for a Linux host process. Run "make menuconfig"
|
||||
a second time and configure it for a "Linux process":
|
||||
It is also necessary to compile and install the micro-controller code
|
||||
for a Linux host process. Run "make menuconfig" a second time and
|
||||
configure it for a "Linux process":
|
||||
```
|
||||
make menuconfig
|
||||
```
|
||||
|
||||
BIN
docs/img/delta-a-distance.jpg
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
docs/img/delta-a-pillar.jpg
Normal file
|
After Width: | Height: | Size: 31 KiB |
BIN
docs/img/delta-outer-distance.jpg
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
docs/img/delta-outer-pillar.jpg
Normal file
|
After Width: | Height: | Size: 24 KiB |
@@ -1,273 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="97.22496mm"
|
||||
height="32.550285mm"
|
||||
viewBox="0 0 344.49789 115.33566"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="delta-tower.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker6618"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Mend">
|
||||
<path
|
||||
transform="matrix(-0.4,0,0,-0.4,-4,0)"
|
||||
style="fill:#4b4b4b;fill-opacity:1;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
id="path6620"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Mend"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="marker6500"
|
||||
style="overflow:visible;"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path6502"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
style="fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1;fill:#4b4b4b;fill-opacity:1"
|
||||
transform="scale(0.4) rotate(180) translate(10,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible;"
|
||||
id="marker6082"
|
||||
refX="0.0"
|
||||
refY="0.0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Mend"
|
||||
inkscape:collect="always">
|
||||
<path
|
||||
transform="scale(0.4) rotate(180) translate(10,0)"
|
||||
style="fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1;fill:#4b4b4b;fill-opacity:1"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
id="path6084" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Mend"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow1Mend"
|
||||
style="overflow:visible;"
|
||||
inkscape:isstock="true"
|
||||
inkscape:collect="always">
|
||||
<path
|
||||
id="path5747"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
style="fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1;fill:#4b4b4b;fill-opacity:1"
|
||||
transform="scale(0.4) rotate(180) translate(10,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Mstart"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow1Mstart"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path5744"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
style="fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1;fill:#4b4b4b;fill-opacity:1"
|
||||
transform="scale(0.4) translate(10,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Mend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Mend-1"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true"
|
||||
inkscape:collect="always">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4329-1"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="matrix(-0.4,0,0,-0.4,-4,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker6082-9"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Mend"
|
||||
inkscape:collect="always">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
transform="matrix(-0.4,0,0,-0.4,-4,0)"
|
||||
style="fill:#4b4b4b;fill-opacity:1;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
id="path6084-2" />
|
||||
</marker>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1.75"
|
||||
inkscape:cx="172.24895"
|
||||
inkscape:cy="45.708959"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="928"
|
||||
inkscape:window-height="628"
|
||||
inkscape:window-x="162"
|
||||
inkscape:window-y="50"
|
||||
inkscape:window-maximized="0"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
showborder="false"
|
||||
inkscape:snap-global="false"
|
||||
showguides="false">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid3436" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-135.22429,-249.96955)">
|
||||
<ellipse
|
||||
style="fill:#4d4d4d;stroke:#4b4b4b;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:2, 1, 0.5, 1;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path4255"
|
||||
cx="353.79568"
|
||||
cy="327.87662"
|
||||
rx="4.2857141"
|
||||
ry="4.8571429" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1.00000006;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend)"
|
||||
d="M 181.50998,381.87664 359.22427,275.01949"
|
||||
id="path5510"
|
||||
inkscape:connector-curvature="0" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.00000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="371.22427"
|
||||
y="354.44806"
|
||||
id="text6058"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan6060"
|
||||
x="371.22427"
|
||||
y="354.44806">stepper</tspan><tspan
|
||||
sodipodi:role="line"
|
||||
x="371.22427"
|
||||
y="366.94806"
|
||||
id="tspan9337">tower</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.00000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="166.65283"
|
||||
y="304.16235"
|
||||
id="text6062"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan6064"
|
||||
x="166.65283"
|
||||
y="304.16235">line of movement</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:10.0000006px;line-height:125%;font-family:'DejaVu Sans';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;-inkscape-font-specification:'DejaVu Sans, Normal';font-stretch:normal;font-variant:normal;text-anchor:start;text-align:start;writing-mode:lr;"
|
||||
x="252.93855"
|
||||
y="384.16235"
|
||||
id="text6066"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan6068"
|
||||
x="252.93855"
|
||||
y="384.16235">move</tspan></text>
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1.00000006;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#marker6618)"
|
||||
d="m 382.65284,344.73378 c -0.19273,-13.52091 -9.87887,-14.83602 -20.57143,-14.85715"
|
||||
id="path6070"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker6500)"
|
||||
d="m 254.65284,374.44806 c 3.39239,-12.86009 -2.06023,-20.09154 -15.42857,-22.28571"
|
||||
id="path6072"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker6082)"
|
||||
d="m 257.50997,296.16234 c 31.05376,-3.13332 32.38959,-1.23784 42.28572,10.28572"
|
||||
id="path6074"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Mend-1)"
|
||||
d="m 219.61431,358.80126 57.78715,-34.48307"
|
||||
id="path3514-5"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:0.50000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
d="m 351.22427,323.59092 -20.57143,-32"
|
||||
id="path3358"
|
||||
inkscape:connector-curvature="0" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.00000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="244.36713"
|
||||
y="257.30521"
|
||||
id="text4460"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4462"
|
||||
x="244.36713"
|
||||
y="257.30521">virtual tower</tspan><tspan
|
||||
sodipodi:role="line"
|
||||
x="244.36713"
|
||||
y="269.80521"
|
||||
id="tspan5867">location</tspan></text>
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker6082-9)"
|
||||
d="m 310.90661,257.14111 c 21.29088,8.40268 18.35244,16.28958 20.57143,29.7143"
|
||||
id="path6074-6"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 8.2 KiB |
BIN
docs/img/delta_cal_e_step1.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
docs/img/delta_cal_e_step2.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
docs/img/delta_cal_e_step3.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
docs/img/delta_cal_e_step4.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
@@ -1,241 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="64.619751mm"
|
||||
height="27.45583mm"
|
||||
viewBox="0 0 228.96762 97.284438"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="virtual-tower.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker6618"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Mend">
|
||||
<path
|
||||
transform="matrix(-0.4,0,0,-0.4,-4,0)"
|
||||
style="fill:#4b4b4b;fill-opacity:1;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
id="path6620"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Mend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="marker6500"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path6502"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
style="fill:#4b4b4b;fill-opacity:1;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="matrix(-0.4,0,0,-0.4,-4,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Mend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Mend"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true"
|
||||
inkscape:collect="always">
|
||||
<path
|
||||
id="path5747"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
style="fill:#4b4b4b;fill-opacity:1;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="matrix(-0.4,0,0,-0.4,-4,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Mstart"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Mstart"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path5744"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
style="fill:#4b4b4b;fill-opacity:1;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="matrix(0.4,0,0,0.4,4,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Mend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Mend-1"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true"
|
||||
inkscape:collect="always">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4329-1"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="matrix(-0.4,0,0,-0.4,-4,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker6082"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Mend"
|
||||
inkscape:collect="always">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
transform="matrix(-0.4,0,0,-0.4,-4,0)"
|
||||
style="fill:#4b4b4b;fill-opacity:1;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
id="path6084" />
|
||||
</marker>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1.75"
|
||||
inkscape:cx="169.7719"
|
||||
inkscape:cy="-4.0565054"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="922"
|
||||
inkscape:window-height="628"
|
||||
inkscape:window-x="162"
|
||||
inkscape:window-y="50"
|
||||
inkscape:window-maximized="0"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
showborder="false"
|
||||
inkscape:snap-global="false"
|
||||
showguides="false">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid3436"
|
||||
originx="-14.085234"
|
||||
originy="-95.286988" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-149.30952,-172.73378)">
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend)"
|
||||
d="m 176.36712,256.16235 200.00001,-0.57143"
|
||||
id="path5510"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.00000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="-254.01012"
|
||||
y="369.20834"
|
||||
id="text6058"
|
||||
sodipodi:linespacing="125%"
|
||||
transform="matrix(-0.01833576,-0.99983189,0.99983189,-0.01833576,0,0)"
|
||||
inkscape:transform-center-x="-8.0000002"
|
||||
inkscape:transform-center-y="12.571429"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan10365"
|
||||
x="-254.01012"
|
||||
y="369.20834">virtual tower</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.00000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="148.36713"
|
||||
y="269.87662"
|
||||
id="text6062"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan6064"
|
||||
x="148.36713"
|
||||
y="269.87662">line of movement</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.00000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="237.50998"
|
||||
y="251.01949"
|
||||
id="text6066"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan6068"
|
||||
x="237.50998"
|
||||
y="251.01949">move</tspan></text>
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:7.00000048;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 358.08141,255.01949 0,-82.28571"
|
||||
id="path10351"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 220.36713,255.01949 357.50998,173.30521"
|
||||
id="path10373"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.00000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="200.36713"
|
||||
y="187.59093"
|
||||
id="text10375"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan10377"
|
||||
x="200.36713"
|
||||
y="187.59093">virtual arm</tspan></text>
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker6082)"
|
||||
d="m 261.76375,182.85539 c 22.73118,-0.70136 26.45506,3.7437 40.00001,18.28573"
|
||||
id="path6074"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Mend-1)"
|
||||
d="m 219.61431,255.37268 70.93001,0.37408"
|
||||
id="path3514-5"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 9.5 KiB |
|
Before Width: | Height: | Size: 5.7 KiB |
@@ -1,241 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="64.619751mm"
|
||||
height="27.45583mm"
|
||||
viewBox="0 0 228.96762 97.284438"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="xy+z-tower.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker6618"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Mend">
|
||||
<path
|
||||
transform="matrix(-0.4,0,0,-0.4,-4,0)"
|
||||
style="fill:#4b4b4b;fill-opacity:1;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
id="path6620"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Mend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="marker6500"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path6502"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
style="fill:#4b4b4b;fill-opacity:1;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="matrix(-0.4,0,0,-0.4,-4,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Mend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Mend"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true"
|
||||
inkscape:collect="always">
|
||||
<path
|
||||
id="path5747"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
style="fill:#4b4b4b;fill-opacity:1;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="matrix(-0.4,0,0,-0.4,-4,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Mstart"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Mstart"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path5744"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
style="fill:#4b4b4b;fill-opacity:1;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="matrix(0.4,0,0,0.4,4,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Mend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Mend-1"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true"
|
||||
inkscape:collect="always">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4329-1"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="matrix(-0.4,0,0,-0.4,-4,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker6082"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Mend"
|
||||
inkscape:collect="always">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
transform="matrix(-0.4,0,0,-0.4,-4,0)"
|
||||
style="fill:#4b4b4b;fill-opacity:1;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
id="path6084" />
|
||||
</marker>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1.75"
|
||||
inkscape:cx="169.7719"
|
||||
inkscape:cy="-4.0565054"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="922"
|
||||
inkscape:window-height="628"
|
||||
inkscape:window-x="162"
|
||||
inkscape:window-y="50"
|
||||
inkscape:window-maximized="0"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
showborder="false"
|
||||
inkscape:snap-global="false"
|
||||
showguides="false">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid3436"
|
||||
originx="-14.085234"
|
||||
originy="-95.286988" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-149.30952,-172.73378)">
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend)"
|
||||
d="m 176.36712,256.16235 200.00001,-0.57143"
|
||||
id="path5510"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.00000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="-119.27526"
|
||||
y="434.37329"
|
||||
id="text6058"
|
||||
sodipodi:linespacing="125%"
|
||||
transform="matrix(0.32454206,-0.94587127,0.94587127,0.32454206,0,0)"
|
||||
inkscape:transform-center-x="-3.9400734"
|
||||
inkscape:transform-center-y="14.789029"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan10365"
|
||||
x="-119.27526"
|
||||
y="434.37329">virtual tower</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.00000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="148.36713"
|
||||
y="269.87662"
|
||||
id="text6062"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan6064"
|
||||
x="148.36713"
|
||||
y="269.87662">line of movement</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.00000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="237.50998"
|
||||
y="251.01949"
|
||||
id="text6066"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan6068"
|
||||
x="237.50998"
|
||||
y="251.01949">move</tspan></text>
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:7.00000048;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 354.70239,255.76769 28.12779,-77.32895"
|
||||
id="path10351"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 220.36713,255.01949 380.93855,178.44807"
|
||||
id="path10373"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.00000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="200.36713"
|
||||
y="187.59093"
|
||||
id="text10375"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan10377"
|
||||
x="200.36713"
|
||||
y="187.59093">virtual arm</tspan></text>
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker6082)"
|
||||
d="m 261.76375,182.85539 c 22.73118,-0.70136 26.45506,3.7437 40.00001,18.28573"
|
||||
id="path6074"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Mend-1)"
|
||||
d="m 219.61431,255.37268 70.93001,0.37408"
|
||||
id="path3514-5"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 9.5 KiB |
|
Before Width: | Height: | Size: 6.5 KiB |
77
docs/prints/calibrate_size.scad
Normal file
@@ -0,0 +1,77 @@
|
||||
// Calibration object for delta sizing
|
||||
//
|
||||
// Generate STL using OpenSCAD:
|
||||
// openscad calibrate_size.scad -o calibrate_size.stl
|
||||
|
||||
base_radius = 70;
|
||||
base_height = 1.5;
|
||||
base_width = 8;
|
||||
cylinder_height = 5;
|
||||
cylinder_radius = 5;
|
||||
cylinder_outer_dist = 65;
|
||||
ridge_cut_radius = .5;
|
||||
text_height = 1;
|
||||
text_size = 5;
|
||||
spoke_angles = [0, 60, 120, 180, 240, 300];
|
||||
CUT=0.01;
|
||||
|
||||
// Circular ring around entire object (to help reduce warping)
|
||||
module base_ring() {
|
||||
difference() {
|
||||
cylinder(h=base_height, r=base_radius);
|
||||
translate([0, 0, -CUT])
|
||||
cylinder(h=base_height + 2*CUT, r=base_radius-base_width);
|
||||
}
|
||||
}
|
||||
|
||||
// The base ring plus the base spokes
|
||||
module base() {
|
||||
base_ring();
|
||||
// Spokes
|
||||
for (angle=spoke_angles)
|
||||
rotate([0, 0, angle])
|
||||
translate([-base_width/2, -CUT, 0])
|
||||
cube([base_width, base_radius-base_width+2*CUT, base_height]);
|
||||
}
|
||||
|
||||
// Cylinder that measurement ridges are cut out of
|
||||
module measuring_cylinder() {
|
||||
cut_width = cylinder_radius;
|
||||
difference() {
|
||||
cylinder(h=cylinder_height+CUT, r=cylinder_radius, $fn=60);
|
||||
for (angle=spoke_angles)
|
||||
rotate([0, 0, angle])
|
||||
translate([-cut_width, cylinder_radius - ridge_cut_radius, -CUT])
|
||||
cube([2*cut_width, cut_width, cylinder_height+3*CUT]);
|
||||
}
|
||||
}
|
||||
|
||||
// All the measuring cylinders around the ring
|
||||
module measuring_cylinders() {
|
||||
measuring_cylinder();
|
||||
for (angle=spoke_angles)
|
||||
rotate([0, 0, angle])
|
||||
translate([0, cylinder_outer_dist, 0])
|
||||
measuring_cylinder();
|
||||
}
|
||||
|
||||
// Text writing
|
||||
module write_text(angle, dist, msg) {
|
||||
text_offset = dist + 1 - text_size/2;
|
||||
rotate([0, 0, angle])
|
||||
translate([0, text_offset, base_height - CUT])
|
||||
linear_extrude(height=text_height + CUT)
|
||||
text(msg, size=text_size, halign="center");
|
||||
}
|
||||
|
||||
// Final object with text descriptions
|
||||
module calibration_object() {
|
||||
base();
|
||||
translate([0, 0, base_height-CUT])
|
||||
measuring_cylinders();
|
||||
write_text(120, cylinder_outer_dist - 20, "A");
|
||||
write_text(240, cylinder_outer_dist - 20, "B");
|
||||
write_text(0, cylinder_outer_dist - 20, "C");
|
||||
}
|
||||
|
||||
calibration_object();
|
||||
11622
docs/prints/calibrate_size.stl
Normal file
52
docs/stm32f1.md
Normal file
@@ -0,0 +1,52 @@
|
||||
This document describes how the STM32F1 port operates and how it can be used on
|
||||
STM32-based boards, such as the "Blue Pill". STM32 MCUs are not used on any
|
||||
Arduino boards, so their restrictions aren't as widely known and less straight
|
||||
forward compared to common Arduino compatible boards. There aren't any standard
|
||||
pin mappings either.
|
||||
|
||||
General considerations
|
||||
======================
|
||||
|
||||
The STM32 port currently requires an 8 MHz crystal for correct
|
||||
operation. The port is currently designed for and tested with
|
||||
STM32F103xB series MCUs, but it should work with any STM32F103 series
|
||||
MCUs with minimal changes.
|
||||
|
||||
Unlike Arduino-based boards, typically there is no automatic reset on serial
|
||||
connection with STM32 boards. Please use `restart_method: command` with the
|
||||
STM32F1 port.
|
||||
|
||||
Fixed pins
|
||||
==========
|
||||
|
||||
When using serial, the UART used for communication with the host is
|
||||
fixed to pins PA9 (TX) and PA10 (RX). When using USB, the PA11 (D-)
|
||||
and PA12 (D+) pins are reserved. The USB code assumes that PA12 (D+)
|
||||
has a fixed pullup resistor attached to it.
|
||||
|
||||
SWD pins (PA13/PA14) are enabled for debugging and cannot be used for
|
||||
any I/O. SPI uses pins PB13/PB14/PB15, but the pins can be used as
|
||||
general I/O if SPI is not used.
|
||||
|
||||
Digital I/O
|
||||
===========
|
||||
|
||||
All pins that aren't part of the fixed set can be used for digital I/O. Pins are
|
||||
referred to by their primary name, e.g. `PA1`. Do not try to use Arduino pin
|
||||
aliases in your configuration. See ST's datasheets for more details. The
|
||||
[STM32Duino](http://wiki.stm32duino.com/index.php?title=Blue_Pill) wiki has more
|
||||
info on the popular "Blue Pill" board.
|
||||
|
||||
Analog inputs
|
||||
=============
|
||||
|
||||
All ADC-capable pins can be used as analog inputs with the same naming as
|
||||
digital I/O pins. Small packages MCUs (e.g. LFQP48) have 10 channels (PA0-PA7,
|
||||
PB0-PB1), while larger package devices have 16 channels (PA0-PA7, PB0-PB1,
|
||||
PC0-PC5).
|
||||
|
||||
SPI
|
||||
===
|
||||
|
||||
SPI uses pin PB13 (SCK), PB14 (MISO) and PB15 (MOSI). The clock speed range is
|
||||
0.15..18 MHz. Chip select pins do not have any restrictions.
|
||||
@@ -1,190 +0,0 @@
|
||||
# Code for handling the kinematics of cartesian robots
|
||||
#
|
||||
# Copyright (C) 2016 Kevin O'Connor <kevin@koconnor.net>
|
||||
#
|
||||
# This file may be distributed under the terms of the GNU GPLv3 license.
|
||||
import logging
|
||||
import stepper, homing
|
||||
|
||||
StepList = (0, 1, 2)
|
||||
|
||||
class CartKinematics:
|
||||
def __init__(self, toolhead, printer, config):
|
||||
self.printer = printer
|
||||
self.steppers = [stepper.LookupMultiHomingStepper(
|
||||
printer, config.getsection('stepper_' + n))
|
||||
for n in ['x', 'y', 'z']]
|
||||
max_velocity, max_accel = toolhead.get_max_velocity()
|
||||
self.max_z_velocity = config.getfloat(
|
||||
'max_z_velocity', max_velocity, above=0., maxval=max_velocity)
|
||||
self.max_z_accel = config.getfloat(
|
||||
'max_z_accel', max_accel, above=0., maxval=max_accel)
|
||||
self.need_motor_enable = True
|
||||
self.limits = [(1.0, -1.0)] * 3
|
||||
# Setup stepper max halt velocity
|
||||
max_halt_velocity = toolhead.get_max_axis_halt()
|
||||
self.steppers[0].set_max_jerk(max_halt_velocity, max_accel)
|
||||
self.steppers[1].set_max_jerk(max_halt_velocity, max_accel)
|
||||
self.steppers[2].set_max_jerk(
|
||||
min(max_halt_velocity, self.max_z_velocity), max_accel)
|
||||
# Check for dual carriage support
|
||||
self.dual_carriage_axis = None
|
||||
self.dual_carriage_steppers = []
|
||||
if config.has_section('dual_carriage'):
|
||||
dc_config = config.getsection('dual_carriage')
|
||||
self.dual_carriage_axis = dc_config.getchoice(
|
||||
'axis', {'x': 0, 'y': 1})
|
||||
dc_stepper = stepper.LookupMultiHomingStepper(printer, dc_config)
|
||||
dc_stepper.set_max_jerk(max_halt_velocity, max_accel)
|
||||
self.dual_carriage_steppers = [
|
||||
self.steppers[self.dual_carriage_axis], dc_stepper]
|
||||
printer.lookup_object('gcode').register_command(
|
||||
'SET_DUAL_CARRIAGE', self.cmd_SET_DUAL_CARRIAGE,
|
||||
desc=self.cmd_SET_DUAL_CARRIAGE_help)
|
||||
def get_steppers(self, flags=""):
|
||||
if flags == "Z":
|
||||
return [self.steppers[2]]
|
||||
return list(self.steppers)
|
||||
def get_position(self):
|
||||
return [s.mcu_stepper.get_commanded_position() for s in self.steppers]
|
||||
def set_position(self, newpos, homing_axes):
|
||||
for i in StepList:
|
||||
s = self.steppers[i]
|
||||
s.set_position(newpos[i])
|
||||
if i in homing_axes:
|
||||
self.limits[i] = (s.position_min, s.position_max)
|
||||
def _home_axis(self, homing_state, axis, stepper):
|
||||
s = stepper
|
||||
# Determine moves
|
||||
if s.homing_positive_dir:
|
||||
pos = s.position_endstop - 1.5*(
|
||||
s.position_endstop - s.position_min)
|
||||
rpos = s.position_endstop - s.homing_retract_dist
|
||||
r2pos = rpos - s.homing_retract_dist
|
||||
else:
|
||||
pos = s.position_endstop + 1.5*(
|
||||
s.position_max - s.position_endstop)
|
||||
rpos = s.position_endstop + s.homing_retract_dist
|
||||
r2pos = rpos + s.homing_retract_dist
|
||||
# Initial homing
|
||||
homing_speed = s.homing_speed
|
||||
if axis == 2:
|
||||
homing_speed = min(homing_speed, self.max_z_velocity)
|
||||
homepos = [None, None, None, None]
|
||||
homepos[axis] = s.position_endstop
|
||||
coord = [None, None, None, None]
|
||||
coord[axis] = pos
|
||||
homing_state.home(coord, homepos, s.get_endstops(), homing_speed)
|
||||
# Retract
|
||||
coord[axis] = rpos
|
||||
homing_state.retract(coord, homing_speed)
|
||||
# Home again
|
||||
coord[axis] = r2pos
|
||||
homing_state.home(coord, homepos, s.get_endstops(),
|
||||
homing_speed/2.0, second_home=True)
|
||||
# Set final homed position
|
||||
coord[axis] = s.position_endstop + s.get_homed_offset()
|
||||
homing_state.set_homed_position(coord)
|
||||
def home(self, homing_state):
|
||||
# Each axis is homed independently and in order
|
||||
for axis in homing_state.get_axes():
|
||||
if axis == self.dual_carriage_axis:
|
||||
dc1, dc2 = self.dual_carriage_steppers
|
||||
altc = self.steppers[axis] == dc2
|
||||
self._activate_carriage(0)
|
||||
self._home_axis(homing_state, axis, dc1)
|
||||
self._activate_carriage(1)
|
||||
self._home_axis(homing_state, axis, dc2)
|
||||
self._activate_carriage(altc)
|
||||
else:
|
||||
self._home_axis(homing_state, axis, self.steppers[axis])
|
||||
def motor_off(self, print_time):
|
||||
self.limits = [(1.0, -1.0)] * 3
|
||||
for stepper in self.steppers:
|
||||
stepper.motor_enable(print_time, 0)
|
||||
for stepper in self.dual_carriage_steppers:
|
||||
stepper.motor_enable(print_time, 0)
|
||||
self.need_motor_enable = True
|
||||
def _check_motor_enable(self, print_time, move):
|
||||
need_motor_enable = False
|
||||
for i in StepList:
|
||||
if move.axes_d[i]:
|
||||
self.steppers[i].motor_enable(print_time, 1)
|
||||
need_motor_enable |= self.steppers[i].need_motor_enable
|
||||
self.need_motor_enable = need_motor_enable
|
||||
def _check_endstops(self, move):
|
||||
end_pos = move.end_pos
|
||||
for i in StepList:
|
||||
if (move.axes_d[i]
|
||||
and (end_pos[i] < self.limits[i][0]
|
||||
or end_pos[i] > self.limits[i][1])):
|
||||
if self.limits[i][0] > self.limits[i][1]:
|
||||
raise homing.EndstopMoveError(
|
||||
end_pos, "Must home axis first")
|
||||
raise homing.EndstopMoveError(end_pos)
|
||||
def check_move(self, move):
|
||||
limits = self.limits
|
||||
xpos, ypos = move.end_pos[:2]
|
||||
if (xpos < limits[0][0] or xpos > limits[0][1]
|
||||
or ypos < limits[1][0] or ypos > limits[1][1]):
|
||||
self._check_endstops(move)
|
||||
if not move.axes_d[2]:
|
||||
# Normal XY move - use defaults
|
||||
return
|
||||
# Move with Z - update velocity and accel for slower Z axis
|
||||
self._check_endstops(move)
|
||||
z_ratio = move.move_d / abs(move.axes_d[2])
|
||||
move.limit_speed(
|
||||
self.max_z_velocity * z_ratio, self.max_z_accel * z_ratio)
|
||||
def move(self, print_time, move):
|
||||
if self.need_motor_enable:
|
||||
self._check_motor_enable(print_time, move)
|
||||
for i in StepList:
|
||||
axis_d = move.axes_d[i]
|
||||
if not axis_d:
|
||||
continue
|
||||
step_const = self.steppers[i].step_const
|
||||
move_time = print_time
|
||||
start_pos = move.start_pos[i]
|
||||
axis_r = abs(axis_d) / move.move_d
|
||||
accel = move.accel * axis_r
|
||||
cruise_v = move.cruise_v * axis_r
|
||||
|
||||
# Acceleration steps
|
||||
if move.accel_r:
|
||||
accel_d = move.accel_r * axis_d
|
||||
step_const(move_time, start_pos, accel_d,
|
||||
move.start_v * axis_r, accel)
|
||||
start_pos += accel_d
|
||||
move_time += move.accel_t
|
||||
# Cruising steps
|
||||
if move.cruise_r:
|
||||
cruise_d = move.cruise_r * axis_d
|
||||
step_const(move_time, start_pos, cruise_d, cruise_v, 0.)
|
||||
start_pos += cruise_d
|
||||
move_time += move.cruise_t
|
||||
# Deceleration steps
|
||||
if move.decel_r:
|
||||
decel_d = move.decel_r * axis_d
|
||||
step_const(move_time, start_pos, decel_d, cruise_v, -accel)
|
||||
# Dual carriage support
|
||||
def _activate_carriage(self, carriage):
|
||||
toolhead = self.printer.lookup_object('toolhead')
|
||||
toolhead.get_last_move_time()
|
||||
dc_stepper = self.dual_carriage_steppers[carriage]
|
||||
dc_axis = self.dual_carriage_axis
|
||||
self.steppers[dc_axis] = dc_stepper
|
||||
extruder_pos = toolhead.get_position()[3]
|
||||
toolhead.set_position(self.get_position() + [extruder_pos])
|
||||
if self.limits[dc_axis][0] <= self.limits[dc_axis][1]:
|
||||
self.limits[dc_axis] = (
|
||||
dc_stepper.position_min, dc_stepper.position_max)
|
||||
self.need_motor_enable = True
|
||||
cmd_SET_DUAL_CARRIAGE_help = "Set which carriage is active"
|
||||
def cmd_SET_DUAL_CARRIAGE(self, params):
|
||||
gcode = self.printer.lookup_object('gcode')
|
||||
carriage = gcode.get_int('CARRIAGE', params)
|
||||
if carriage not in (0, 1):
|
||||
raise gcode.error("Invalid carriage")
|
||||
self._activate_carriage(carriage)
|
||||
gcode.reset_last_position()
|
||||
@@ -1,6 +1,6 @@
|
||||
# Wrapper around C helper code
|
||||
#
|
||||
# Copyright (C) 2016,2017 Kevin O'Connor <kevin@koconnor.net>
|
||||
# Copyright (C) 2016-2018 Kevin O'Connor <kevin@koconnor.net>
|
||||
#
|
||||
# This file may be distributed under the terms of the GNU GPLv3 license.
|
||||
import os, logging
|
||||
@@ -11,28 +11,28 @@ import cffi
|
||||
# c_helper.so compiling
|
||||
######################################################################
|
||||
|
||||
COMPILE_CMD = "gcc -Wall -g -O2 -shared -fPIC -o %s %s"
|
||||
SOURCE_FILES = ['stepcompress.c', 'serialqueue.c', 'pyhelper.c']
|
||||
COMPILE_CMD = ("gcc -Wall -g -O2 -shared -fPIC"
|
||||
" -flto -fwhole-program -fno-use-linker-plugin"
|
||||
" -o %s %s")
|
||||
SOURCE_FILES = [
|
||||
'pyhelper.c', 'serialqueue.c', 'stepcompress.c', 'itersolve.c',
|
||||
'kin_cartesian.c', 'kin_corexy.c', 'kin_delta.c', 'kin_extruder.c'
|
||||
]
|
||||
DEST_LIB = "c_helper.so"
|
||||
OTHER_FILES = ['list.h', 'serialqueue.h', 'pyhelper.h']
|
||||
OTHER_FILES = [
|
||||
'list.h', 'serialqueue.h', 'stepcompress.h', 'itersolve.h', 'pyhelper.h'
|
||||
]
|
||||
|
||||
defs_stepcompress = """
|
||||
struct stepcompress *stepcompress_alloc(uint32_t max_error
|
||||
, uint32_t queue_step_msgid, uint32_t set_next_step_dir_msgid
|
||||
, uint32_t invert_sdir, uint32_t oid);
|
||||
struct stepcompress *stepcompress_alloc(uint32_t oid);
|
||||
void stepcompress_fill(struct stepcompress *sc, uint32_t max_error
|
||||
, uint32_t invert_sdir, uint32_t queue_step_msgid
|
||||
, uint32_t set_next_step_dir_msgid);
|
||||
void stepcompress_free(struct stepcompress *sc);
|
||||
int stepcompress_reset(struct stepcompress *sc, uint64_t last_step_clock);
|
||||
int stepcompress_set_homing(struct stepcompress *sc, uint64_t homing_clock);
|
||||
int stepcompress_queue_msg(struct stepcompress *sc, uint32_t *data, int len);
|
||||
|
||||
int32_t stepcompress_push(struct stepcompress *sc, double step_clock
|
||||
, int32_t sdir);
|
||||
int32_t stepcompress_push_const(struct stepcompress *sc, double clock_offset
|
||||
, double step_offset, double steps, double start_sv, double accel);
|
||||
int32_t stepcompress_push_delta(struct stepcompress *sc
|
||||
, double clock_offset, double move_sd, double start_sv, double accel
|
||||
, double height, double startxy_sd, double arm_d, double movez_r);
|
||||
|
||||
struct steppersync *steppersync_alloc(struct serialqueue *sq
|
||||
, struct stepcompress **sc_list, int sc_num, int move_num);
|
||||
void steppersync_free(struct steppersync *ss);
|
||||
@@ -41,6 +41,43 @@ defs_stepcompress = """
|
||||
int steppersync_flush(struct steppersync *ss, uint64_t move_clock);
|
||||
"""
|
||||
|
||||
defs_itersolve = """
|
||||
struct move *move_alloc(void);
|
||||
void move_fill(struct move *m, double print_time
|
||||
, double accel_t, double cruise_t, double decel_t
|
||||
, double start_pos_x, double start_pos_y, double start_pos_z
|
||||
, double axes_d_x, double axes_d_y, double axes_d_z
|
||||
, double start_v, double cruise_v, double accel);
|
||||
int32_t itersolve_gen_steps(struct stepper_kinematics *sk, struct move *m);
|
||||
void itersolve_set_stepcompress(struct stepper_kinematics *sk
|
||||
, struct stepcompress *sc, double step_dist);
|
||||
double itersolve_calc_position_from_coord(struct stepper_kinematics *sk
|
||||
, double x, double y, double z);
|
||||
void itersolve_set_commanded_pos(struct stepper_kinematics *sk, double pos);
|
||||
double itersolve_get_commanded_pos(struct stepper_kinematics *sk);
|
||||
"""
|
||||
|
||||
defs_kin_cartesian = """
|
||||
struct stepper_kinematics *cartesian_stepper_alloc(char axis);
|
||||
"""
|
||||
|
||||
defs_kin_corexy = """
|
||||
struct stepper_kinematics *corexy_stepper_alloc(char type);
|
||||
"""
|
||||
|
||||
defs_kin_delta = """
|
||||
struct stepper_kinematics *delta_stepper_alloc(double arm2
|
||||
, double tower_x, double tower_y);
|
||||
"""
|
||||
|
||||
defs_kin_extruder = """
|
||||
struct stepper_kinematics *extruder_stepper_alloc(void);
|
||||
void extruder_move_fill(struct move *m, double print_time
|
||||
, double accel_t, double cruise_t, double decel_t, double start_pos
|
||||
, double start_v, double cruise_v, double accel
|
||||
, double extra_accel_v, double extra_decel_v);
|
||||
"""
|
||||
|
||||
defs_serialqueue = """
|
||||
#define MESSAGE_MAX 64
|
||||
struct pull_queue_message {
|
||||
@@ -56,11 +93,11 @@ defs_serialqueue = """
|
||||
void serialqueue_free_commandqueue(struct command_queue *cq);
|
||||
void serialqueue_send(struct serialqueue *sq, struct command_queue *cq
|
||||
, uint8_t *msg, int len, uint64_t min_clock, uint64_t req_clock);
|
||||
void serialqueue_encode_and_send(struct serialqueue *sq
|
||||
, struct command_queue *cq, uint32_t *data, int len
|
||||
, uint64_t min_clock, uint64_t req_clock);
|
||||
void serialqueue_pull(struct serialqueue *sq, struct pull_queue_message *pqm);
|
||||
void serialqueue_pull(struct serialqueue *sq
|
||||
, struct pull_queue_message *pqm);
|
||||
void serialqueue_set_baud_adjust(struct serialqueue *sq, double baud_adjust);
|
||||
void serialqueue_set_receive_window(struct serialqueue *sq
|
||||
, int receive_window);
|
||||
void serialqueue_set_clock_est(struct serialqueue *sq, double est_freq
|
||||
, double last_clock_time, uint64_t last_clock);
|
||||
void serialqueue_get_stats(struct serialqueue *sq, char *buf, int len);
|
||||
@@ -73,6 +110,15 @@ defs_pyhelper = """
|
||||
double get_monotonic(void);
|
||||
"""
|
||||
|
||||
defs_std = """
|
||||
void free(void*);
|
||||
"""
|
||||
|
||||
defs_all = [
|
||||
defs_pyhelper, defs_serialqueue, defs_std, defs_stepcompress, defs_itersolve,
|
||||
defs_kin_cartesian, defs_kin_corexy, defs_kin_delta, defs_kin_extruder
|
||||
]
|
||||
|
||||
# Return the list of file modification times
|
||||
def get_mtimes(srcdir, filelist):
|
||||
out = []
|
||||
@@ -107,9 +153,8 @@ def get_ffi():
|
||||
check_build_code(srcdir, DEST_LIB, SOURCE_FILES, COMPILE_CMD
|
||||
, OTHER_FILES)
|
||||
FFI_main = cffi.FFI()
|
||||
FFI_main.cdef(defs_stepcompress)
|
||||
FFI_main.cdef(defs_serialqueue)
|
||||
FFI_main.cdef(defs_pyhelper)
|
||||
for d in defs_all:
|
||||
FFI_main.cdef(d)
|
||||
FFI_lib = FFI_main.dlopen(os.path.join(srcdir, DEST_LIB))
|
||||
# Setup error logging
|
||||
def logging_callback(msg):
|
||||
@@ -126,7 +171,7 @@ def get_ffi():
|
||||
|
||||
HC_COMPILE_CMD = "gcc -Wall -g -O2 -o %s %s -lusb"
|
||||
HC_SOURCE_FILES = ['hub-ctrl.c']
|
||||
HC_SOURCE_DIR = '../lib/hub-ctrl'
|
||||
HC_SOURCE_DIR = '../../lib/hub-ctrl'
|
||||
HC_TARGET = "hub-ctrl"
|
||||
HC_CMD = "sudo %s/hub-ctrl -h 0 -P 2 -p %d"
|
||||
|
||||
@@ -135,3 +180,7 @@ def run_hub_ctrl(enable_power):
|
||||
hubdir = os.path.join(srcdir, HC_SOURCE_DIR)
|
||||
check_build_code(hubdir, HC_TARGET, HC_SOURCE_FILES, HC_COMPILE_CMD)
|
||||
os.system(HC_CMD % (hubdir, enable_power))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
get_ffi()
|
||||
46
klippy/chelper/compiler.h
Normal file
@@ -0,0 +1,46 @@
|
||||
#ifndef __COMPILER_H
|
||||
#define __COMPILER_H
|
||||
// Low level definitions for C languange and gcc compiler.
|
||||
|
||||
#define barrier() __asm__ __volatile__("": : :"memory")
|
||||
|
||||
#define likely(x) __builtin_expect(!!(x), 1)
|
||||
#define unlikely(x) __builtin_expect(!!(x), 0)
|
||||
|
||||
#define noinline __attribute__((noinline))
|
||||
#ifndef __always_inline
|
||||
#define __always_inline inline __attribute__((always_inline))
|
||||
#endif
|
||||
#define __visible __attribute__((externally_visible))
|
||||
#define __noreturn __attribute__((noreturn))
|
||||
|
||||
#define PACKED __attribute__((packed))
|
||||
#ifndef __aligned
|
||||
#define __aligned(x) __attribute__((aligned(x)))
|
||||
#endif
|
||||
#ifndef __section
|
||||
#define __section(S) __attribute__((section(S)))
|
||||
#endif
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
|
||||
#define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1)
|
||||
#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask))
|
||||
#define ALIGN_DOWN(x,a) ((x) & ~((typeof(x))(a)-1))
|
||||
|
||||
#define container_of(ptr, type, member) ({ \
|
||||
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
|
||||
(type *)( (char *)__mptr - offsetof(type,member) );})
|
||||
|
||||
#define __stringify_1(x) #x
|
||||
#define __stringify(x) __stringify_1(x)
|
||||
|
||||
#define ___PASTE(a,b) a##b
|
||||
#define __PASTE(a,b) ___PASTE(a,b)
|
||||
|
||||
#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
|
||||
#define DIV_ROUND_CLOSEST(x, divisor)({ \
|
||||
typeof(divisor) __divisor = divisor; \
|
||||
(((x) + ((__divisor) / 2)) / (__divisor)); \
|
||||
})
|
||||
|
||||
#endif // compiler.h
|
||||
238
klippy/chelper/itersolve.c
Normal file
@@ -0,0 +1,238 @@
|
||||
// Iterative solver for kinematic moves
|
||||
//
|
||||
// Copyright (C) 2018 Kevin O'Connor <kevin@koconnor.net>
|
||||
//
|
||||
// This file may be distributed under the terms of the GNU GPLv3 license.
|
||||
|
||||
#include <math.h> // sqrt
|
||||
#include <stdlib.h> // malloc
|
||||
#include <string.h> // memset
|
||||
#include "compiler.h" // __visible
|
||||
#include "itersolve.h" // struct coord
|
||||
#include "pyhelper.h" // errorf
|
||||
#include "stepcompress.h" // queue_append_start
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Kinematic moves
|
||||
****************************************************************/
|
||||
|
||||
struct move * __visible
|
||||
move_alloc(void)
|
||||
{
|
||||
struct move *m = malloc(sizeof(*m));
|
||||
memset(m, 0, sizeof(*m));
|
||||
return m;
|
||||
}
|
||||
|
||||
// Populate a 'struct move' with a velocity trapezoid
|
||||
void __visible
|
||||
move_fill(struct move *m, double print_time
|
||||
, double accel_t, double cruise_t, double decel_t
|
||||
, double start_pos_x, double start_pos_y, double start_pos_z
|
||||
, double axes_d_x, double axes_d_y, double axes_d_z
|
||||
, double start_v, double cruise_v, double accel)
|
||||
{
|
||||
// Setup velocity trapezoid
|
||||
m->print_time = print_time;
|
||||
m->move_t = accel_t + cruise_t + decel_t;
|
||||
m->accel_t = accel_t;
|
||||
m->cruise_t = cruise_t;
|
||||
m->cruise_start_d = accel_t * .5 * (cruise_v + start_v);
|
||||
m->decel_start_d = m->cruise_start_d + cruise_t * cruise_v;
|
||||
|
||||
// Setup for accel/cruise/decel phases
|
||||
m->cruise_v = cruise_v;
|
||||
m->accel.c1 = start_v;
|
||||
m->accel.c2 = .5 * accel;
|
||||
m->decel.c1 = cruise_v;
|
||||
m->decel.c2 = -m->accel.c2;
|
||||
|
||||
// Setup for move_get_coord()
|
||||
m->start_pos.x = start_pos_x;
|
||||
m->start_pos.y = start_pos_y;
|
||||
m->start_pos.z = start_pos_z;
|
||||
double inv_move_d = 1. / sqrt(axes_d_x*axes_d_x + axes_d_y*axes_d_y
|
||||
+ axes_d_z*axes_d_z);
|
||||
m->axes_r.x = axes_d_x * inv_move_d;
|
||||
m->axes_r.y = axes_d_y * inv_move_d;
|
||||
m->axes_r.z = axes_d_z * inv_move_d;
|
||||
}
|
||||
|
||||
// Find the distance travel during acceleration/deceleration
|
||||
static inline double
|
||||
move_eval_accel(struct move_accel *ma, double move_time)
|
||||
{
|
||||
return (ma->c1 + ma->c2 * move_time) * move_time;
|
||||
}
|
||||
|
||||
// Return the distance moved given a time in a move
|
||||
inline double
|
||||
move_get_distance(struct move *m, double move_time)
|
||||
{
|
||||
if (unlikely(move_time < m->accel_t))
|
||||
// Acceleration phase of move
|
||||
return move_eval_accel(&m->accel, move_time);
|
||||
move_time -= m->accel_t;
|
||||
if (likely(move_time <= m->cruise_t))
|
||||
// Cruising phase
|
||||
return m->cruise_start_d + m->cruise_v * move_time;
|
||||
// Deceleration phase
|
||||
move_time -= m->cruise_t;
|
||||
return m->decel_start_d + move_eval_accel(&m->decel, move_time);
|
||||
}
|
||||
|
||||
// Return the XYZ coordinates given a time in a move
|
||||
inline struct coord
|
||||
move_get_coord(struct move *m, double move_time)
|
||||
{
|
||||
double move_dist = move_get_distance(m, move_time);
|
||||
return (struct coord) {
|
||||
.x = m->start_pos.x + m->axes_r.x * move_dist,
|
||||
.y = m->start_pos.y + m->axes_r.y * move_dist,
|
||||
.z = m->start_pos.z + m->axes_r.z * move_dist };
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Iterative solver
|
||||
****************************************************************/
|
||||
|
||||
struct timepos {
|
||||
double time, position;
|
||||
};
|
||||
|
||||
// Find step using "false position" method
|
||||
static struct timepos
|
||||
itersolve_find_step(struct stepper_kinematics *sk, struct move *m
|
||||
, struct timepos low, struct timepos high
|
||||
, double target)
|
||||
{
|
||||
sk_callback calc_position = sk->calc_position;
|
||||
struct timepos best_guess = high;
|
||||
low.position -= target;
|
||||
high.position -= target;
|
||||
if (!high.position)
|
||||
// The high range was a perfect guess for the next step
|
||||
return best_guess;
|
||||
int high_sign = signbit(high.position);
|
||||
if (high_sign == signbit(low.position))
|
||||
// The target is not in the low/high range - return low range
|
||||
return (struct timepos){ low.time, target };
|
||||
for (;;) {
|
||||
double guess_time = ((low.time*high.position - high.time*low.position)
|
||||
/ (high.position - low.position));
|
||||
if (fabs(guess_time - best_guess.time) <= .000000001)
|
||||
break;
|
||||
best_guess.time = guess_time;
|
||||
best_guess.position = calc_position(sk, m, guess_time);
|
||||
double guess_position = best_guess.position - target;
|
||||
int guess_sign = signbit(guess_position);
|
||||
if (guess_sign == high_sign) {
|
||||
high.time = guess_time;
|
||||
high.position = guess_position;
|
||||
} else {
|
||||
low.time = guess_time;
|
||||
low.position = guess_position;
|
||||
}
|
||||
}
|
||||
return best_guess;
|
||||
}
|
||||
|
||||
// Generate step times for a stepper during a move
|
||||
int32_t __visible
|
||||
itersolve_gen_steps(struct stepper_kinematics *sk, struct move *m)
|
||||
{
|
||||
struct stepcompress *sc = sk->sc;
|
||||
sk_callback calc_position = sk->calc_position;
|
||||
double half_step = .5 * sk->step_dist;
|
||||
double mcu_freq = stepcompress_get_mcu_freq(sc);
|
||||
struct timepos last = { 0., sk->commanded_pos }, low = last, high = last;
|
||||
double seek_time_delta = 0.000100;
|
||||
int sdir = stepcompress_get_step_dir(sc);
|
||||
struct queue_append qa = queue_append_start(sc, m->print_time, .5);
|
||||
for (;;) {
|
||||
// Determine if next step is in forward or reverse direction
|
||||
double dist = high.position - last.position;
|
||||
if (fabs(dist) < half_step) {
|
||||
seek_new_high_range:
|
||||
if (high.time >= m->move_t)
|
||||
// At end of move
|
||||
break;
|
||||
// Need to increase next step search range
|
||||
low = high;
|
||||
high.time = last.time + seek_time_delta;
|
||||
seek_time_delta += seek_time_delta;
|
||||
if (high.time > m->move_t)
|
||||
high.time = m->move_t;
|
||||
high.position = calc_position(sk, m, high.time);
|
||||
continue;
|
||||
}
|
||||
int next_sdir = dist > 0.;
|
||||
if (unlikely(next_sdir != sdir)) {
|
||||
// Direction change
|
||||
if (fabs(dist) < half_step + .000000001)
|
||||
// Only change direction if going past midway point
|
||||
goto seek_new_high_range;
|
||||
if (last.time >= low.time && high.time > last.time) {
|
||||
// Must seek new low range to avoid re-finding previous time
|
||||
high.time = (last.time + high.time) * .5;
|
||||
high.position = calc_position(sk, m, high.time);
|
||||
continue;
|
||||
}
|
||||
int ret = queue_append_set_next_step_dir(&qa, next_sdir);
|
||||
if (ret)
|
||||
return ret;
|
||||
sdir = next_sdir;
|
||||
}
|
||||
// Find step
|
||||
double target = last.position + (sdir ? half_step : -half_step);
|
||||
struct timepos next = itersolve_find_step(sk, m, low, high, target);
|
||||
// Add step at given time
|
||||
int ret = queue_append(&qa, next.time * mcu_freq);
|
||||
if (ret)
|
||||
return ret;
|
||||
seek_time_delta = next.time - last.time;
|
||||
if (seek_time_delta < .000000001)
|
||||
seek_time_delta = .000000001;
|
||||
last.position = target + (sdir ? half_step : -half_step);
|
||||
last.time = next.time;
|
||||
low = next;
|
||||
if (last.time >= high.time)
|
||||
// The high range is no longer valid - recalculate it
|
||||
goto seek_new_high_range;
|
||||
}
|
||||
queue_append_finish(qa);
|
||||
sk->commanded_pos = last.position;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __visible
|
||||
itersolve_set_stepcompress(struct stepper_kinematics *sk
|
||||
, struct stepcompress *sc, double step_dist)
|
||||
{
|
||||
sk->sc = sc;
|
||||
sk->step_dist = step_dist;
|
||||
}
|
||||
|
||||
double __visible
|
||||
itersolve_calc_position_from_coord(struct stepper_kinematics *sk
|
||||
, double x, double y, double z)
|
||||
{
|
||||
struct move m;
|
||||
memset(&m, 0, sizeof(m));
|
||||
move_fill(&m, 0., 0., 1., 0., x, y, z, 0., 1., 0., 0., 1., 0.);
|
||||
return sk->calc_position(sk, &m, 0.);
|
||||
}
|
||||
|
||||
void __visible
|
||||
itersolve_set_commanded_pos(struct stepper_kinematics *sk, double pos)
|
||||
{
|
||||
sk->commanded_pos = pos;
|
||||
}
|
||||
|
||||
double __visible
|
||||
itersolve_get_commanded_pos(struct stepper_kinematics *sk)
|
||||
{
|
||||
return sk->commanded_pos;
|
||||
}
|
||||
49
klippy/chelper/itersolve.h
Normal file
@@ -0,0 +1,49 @@
|
||||
#ifndef ITERSOLVE_H
|
||||
#define ITERSOLVE_H
|
||||
|
||||
#include <stdint.h> // uint32_t
|
||||
|
||||
struct coord {
|
||||
double x, y, z;
|
||||
};
|
||||
|
||||
struct move_accel {
|
||||
double c1, c2;
|
||||
};
|
||||
|
||||
struct move {
|
||||
double print_time, move_t;
|
||||
double accel_t, cruise_t;
|
||||
double cruise_start_d, decel_start_d;
|
||||
double cruise_v;
|
||||
struct move_accel accel, decel;
|
||||
struct coord start_pos, axes_r;
|
||||
};
|
||||
|
||||
struct move *move_alloc(void);
|
||||
void move_fill(struct move *m, double print_time
|
||||
, double accel_t, double cruise_t, double decel_t
|
||||
, double start_pos_x, double start_pos_y, double start_pos_z
|
||||
, double axes_d_x, double axes_d_y, double axes_d_z
|
||||
, double start_v, double cruise_v, double accel);
|
||||
double move_get_distance(struct move *m, double move_time);
|
||||
struct coord move_get_coord(struct move *m, double move_time);
|
||||
|
||||
struct stepper_kinematics;
|
||||
typedef double (*sk_callback)(struct stepper_kinematics *sk, struct move *m
|
||||
, double move_time);
|
||||
struct stepper_kinematics {
|
||||
double step_dist, commanded_pos;
|
||||
struct stepcompress *sc;
|
||||
sk_callback calc_position;
|
||||
};
|
||||
|
||||
int32_t itersolve_gen_steps(struct stepper_kinematics *sk, struct move *m);
|
||||
void itersolve_set_stepcompress(struct stepper_kinematics *sk
|
||||
, struct stepcompress *sc, double step_dist);
|
||||
double itersolve_calc_position_from_coord(struct stepper_kinematics *sk
|
||||
, double x, double y, double z);
|
||||
void itersolve_set_commanded_pos(struct stepper_kinematics *sk, double pos);
|
||||
double itersolve_get_commanded_pos(struct stepper_kinematics *sk);
|
||||
|
||||
#endif // itersolve.h
|
||||
46
klippy/chelper/kin_cartesian.c
Normal file
@@ -0,0 +1,46 @@
|
||||
// Cartesian kinematics stepper pulse time generation
|
||||
//
|
||||
// Copyright (C) 2018 Kevin O'Connor <kevin@koconnor.net>
|
||||
//
|
||||
// This file may be distributed under the terms of the GNU GPLv3 license.
|
||||
|
||||
#include <stdlib.h> // malloc
|
||||
#include <string.h> // memset
|
||||
#include "compiler.h" // __visible
|
||||
#include "itersolve.h" // move_get_coord
|
||||
#include "pyhelper.h" // errorf
|
||||
|
||||
static double
|
||||
cart_stepper_x_calc_position(struct stepper_kinematics *sk, struct move *m
|
||||
, double move_time)
|
||||
{
|
||||
return move_get_coord(m, move_time).x;
|
||||
}
|
||||
|
||||
static double
|
||||
cart_stepper_y_calc_position(struct stepper_kinematics *sk, struct move *m
|
||||
, double move_time)
|
||||
{
|
||||
return move_get_coord(m, move_time).y;
|
||||
}
|
||||
|
||||
static double
|
||||
cart_stepper_z_calc_position(struct stepper_kinematics *sk, struct move *m
|
||||
, double move_time)
|
||||
{
|
||||
return move_get_coord(m, move_time).z;
|
||||
}
|
||||
|
||||
struct stepper_kinematics * __visible
|
||||
cartesian_stepper_alloc(char axis)
|
||||
{
|
||||
struct stepper_kinematics *sk = malloc(sizeof(*sk));
|
||||
memset(sk, 0, sizeof(*sk));
|
||||
if (axis == 'x')
|
||||
sk->calc_position = cart_stepper_x_calc_position;
|
||||
else if (axis == 'y')
|
||||
sk->calc_position = cart_stepper_y_calc_position;
|
||||
else if (axis == 'z')
|
||||
sk->calc_position = cart_stepper_z_calc_position;
|
||||
return sk;
|
||||
}
|
||||
38
klippy/chelper/kin_corexy.c
Normal file
@@ -0,0 +1,38 @@
|
||||
// CoreXY kinematics stepper pulse time generation
|
||||
//
|
||||
// Copyright (C) 2018 Kevin O'Connor <kevin@koconnor.net>
|
||||
//
|
||||
// This file may be distributed under the terms of the GNU GPLv3 license.
|
||||
|
||||
#include <stdlib.h> // malloc
|
||||
#include <string.h> // memset
|
||||
#include "compiler.h" // __visible
|
||||
#include "itersolve.h" // struct stepper_kinematics
|
||||
|
||||
static double
|
||||
corexy_stepper_plus_calc_position(struct stepper_kinematics *sk, struct move *m
|
||||
, double move_time)
|
||||
{
|
||||
struct coord c = move_get_coord(m, move_time);
|
||||
return c.x + c.y;
|
||||
}
|
||||
|
||||
static double
|
||||
corexy_stepper_minus_calc_position(struct stepper_kinematics *sk, struct move *m
|
||||
, double move_time)
|
||||
{
|
||||
struct coord c = move_get_coord(m, move_time);
|
||||
return c.x - c.y;
|
||||
}
|
||||
|
||||
struct stepper_kinematics * __visible
|
||||
corexy_stepper_alloc(char type)
|
||||
{
|
||||
struct stepper_kinematics *sk = malloc(sizeof(*sk));
|
||||
memset(sk, 0, sizeof(*sk));
|
||||
if (type == '+')
|
||||
sk->calc_position = corexy_stepper_plus_calc_position;
|
||||
else if (type == '-')
|
||||
sk->calc_position = corexy_stepper_minus_calc_position;
|
||||
return sk;
|
||||
}
|
||||
39
klippy/chelper/kin_delta.c
Normal file
@@ -0,0 +1,39 @@
|
||||
// Delta kinematics stepper pulse time generation
|
||||
//
|
||||
// Copyright (C) 2018 Kevin O'Connor <kevin@koconnor.net>
|
||||
//
|
||||
// This file may be distributed under the terms of the GNU GPLv3 license.
|
||||
|
||||
#include <math.h> // sqrt
|
||||
#include <stddef.h> // offsetof
|
||||
#include <stdlib.h> // malloc
|
||||
#include <string.h> // memset
|
||||
#include "compiler.h" // __visible
|
||||
#include "itersolve.h" // struct stepper_kinematics
|
||||
|
||||
struct delta_stepper {
|
||||
struct stepper_kinematics sk;
|
||||
double arm2, tower_x, tower_y;
|
||||
};
|
||||
|
||||
static double
|
||||
delta_stepper_calc_position(struct stepper_kinematics *sk, struct move *m
|
||||
, double move_time)
|
||||
{
|
||||
struct delta_stepper *ds = container_of(sk, struct delta_stepper, sk);
|
||||
struct coord c = move_get_coord(m, move_time);
|
||||
double dx = ds->tower_x - c.x, dy = ds->tower_y - c.y;
|
||||
return sqrt(ds->arm2 - dx*dx - dy*dy) + c.z;
|
||||
}
|
||||
|
||||
struct stepper_kinematics * __visible
|
||||
delta_stepper_alloc(double arm2, double tower_x, double tower_y)
|
||||
{
|
||||
struct delta_stepper *ds = malloc(sizeof(*ds));
|
||||
memset(ds, 0, sizeof(*ds));
|
||||
ds->arm2 = arm2;
|
||||
ds->tower_x = tower_x;
|
||||
ds->tower_y = tower_y;
|
||||
ds->sk.calc_position = delta_stepper_calc_position;
|
||||
return &ds->sk;
|
||||
}
|
||||
54
klippy/chelper/kin_extruder.c
Normal file
@@ -0,0 +1,54 @@
|
||||
// Extruder stepper pulse time generation
|
||||
//
|
||||
// Copyright (C) 2018 Kevin O'Connor <kevin@koconnor.net>
|
||||
//
|
||||
// This file may be distributed under the terms of the GNU GPLv3 license.
|
||||
|
||||
#include <stdlib.h> // malloc
|
||||
#include <string.h> // memset
|
||||
#include "compiler.h" // __visible
|
||||
#include "itersolve.h" // struct stepper_kinematics
|
||||
#include "pyhelper.h" // errorf
|
||||
|
||||
static double
|
||||
extruder_calc_position(struct stepper_kinematics *sk, struct move *m
|
||||
, double move_time)
|
||||
{
|
||||
return m->start_pos.x + move_get_distance(m, move_time);
|
||||
}
|
||||
|
||||
struct stepper_kinematics * __visible
|
||||
extruder_stepper_alloc(void)
|
||||
{
|
||||
struct stepper_kinematics *sk = malloc(sizeof(*sk));
|
||||
memset(sk, 0, sizeof(*sk));
|
||||
sk->calc_position = extruder_calc_position;
|
||||
return sk;
|
||||
}
|
||||
|
||||
// Populate a 'struct move' with an extruder velocity trapezoid
|
||||
void __visible
|
||||
extruder_move_fill(struct move *m, double print_time
|
||||
, double accel_t, double cruise_t, double decel_t
|
||||
, double start_pos
|
||||
, double start_v, double cruise_v, double accel
|
||||
, double extra_accel_v, double extra_decel_v)
|
||||
{
|
||||
// Setup velocity trapezoid
|
||||
m->print_time = print_time;
|
||||
m->move_t = accel_t + cruise_t + decel_t;
|
||||
m->accel_t = accel_t;
|
||||
m->cruise_t = cruise_t;
|
||||
m->cruise_start_d = accel_t * (.5 * (cruise_v + start_v) + extra_accel_v);
|
||||
m->decel_start_d = m->cruise_start_d + cruise_t * cruise_v;
|
||||
|
||||
// Setup for accel/cruise/decel phases
|
||||
m->cruise_v = cruise_v;
|
||||
m->accel.c1 = start_v + extra_accel_v;
|
||||
m->accel.c2 = .5 * accel;
|
||||
m->decel.c1 = cruise_v + extra_decel_v;
|
||||
m->decel.c2 = -m->accel.c2;
|
||||
|
||||
// Setup start distance
|
||||
m->start_pos.x = start_pos;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
// Helper functions for C / Python interface
|
||||
//
|
||||
// Copyright (C) 2016 Kevin O'Connor <kevin@koconnor.net>
|
||||
// Copyright (C) 2016-2018 Kevin O'Connor <kevin@koconnor.net>
|
||||
//
|
||||
// This file may be distributed under the terms of the GNU GPLv3 license.
|
||||
|
||||
@@ -10,14 +10,15 @@
|
||||
#include <stdio.h> // fprintf
|
||||
#include <string.h> // strerror
|
||||
#include <time.h> // struct timespec
|
||||
#include "compiler.h" // __visible
|
||||
#include "pyhelper.h" // get_monotonic
|
||||
|
||||
// Return the monotonic system time as a double
|
||||
double
|
||||
double __visible
|
||||
get_monotonic(void)
|
||||
{
|
||||
struct timespec ts;
|
||||
int ret = clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
int ret = clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
|
||||
if (ret) {
|
||||
report_errno("clock_gettime", ret);
|
||||
return 0.;
|
||||
@@ -41,7 +42,7 @@ default_logger(const char *msg)
|
||||
|
||||
static void (*python_logging_callback)(const char *msg) = default_logger;
|
||||
|
||||
void
|
||||
void __visible
|
||||
set_python_logging_callback(void (*func)(const char *))
|
||||
{
|
||||
python_logging_callback = func;
|
||||
@@ -1,9 +1,6 @@
|
||||
#ifndef PYHELPER_H
|
||||
#define PYHELPER_H
|
||||
|
||||
#define likely(x) __builtin_expect(!!(x), 1)
|
||||
#define unlikely(x) __builtin_expect(!!(x), 0)
|
||||
|
||||
double get_monotonic(void);
|
||||
struct timespec fill_time(double time);
|
||||
void set_python_logging_callback(void (*func)(const char *));
|
||||
@@ -1,6 +1,6 @@
|
||||
// Serial port command queuing
|
||||
//
|
||||
// Copyright (C) 2016 Kevin O'Connor <kevin@koconnor.net>
|
||||
// Copyright (C) 2016-2018 Kevin O'Connor <kevin@koconnor.net>
|
||||
//
|
||||
// This file may be distributed under the terms of the GNU GPLv3 license.
|
||||
//
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <string.h> // memset
|
||||
#include <termios.h> // tcflush
|
||||
#include <unistd.h> // pipe
|
||||
#include "compiler.h" // __visible
|
||||
#include "list.h" // list_add_tail
|
||||
#include "pyhelper.h" // get_monotonic
|
||||
#include "serialqueue.h" // struct queue_message
|
||||
@@ -357,18 +358,19 @@ struct serialqueue {
|
||||
pthread_cond_t cond;
|
||||
int receive_waiting;
|
||||
// Baud / clock tracking
|
||||
int receive_window;
|
||||
double baud_adjust, idle_time;
|
||||
double est_freq, last_clock_time;
|
||||
uint64_t last_clock;
|
||||
double last_receive_sent_time;
|
||||
// Retransmit support
|
||||
uint64_t send_seq, receive_seq;
|
||||
uint64_t ignore_nak_seq, retransmit_seq, rtt_sample_seq;
|
||||
uint64_t ignore_nak_seq, last_ack_seq, retransmit_seq, rtt_sample_seq;
|
||||
struct list_head sent_queue;
|
||||
double srtt, rttvar, rto;
|
||||
// Pending transmission message queues
|
||||
struct list_head pending_queues;
|
||||
int ready_bytes, stalled_bytes, need_ack_bytes;
|
||||
int ready_bytes, stalled_bytes, need_ack_bytes, last_ack_bytes;
|
||||
uint64_t need_kick_clock;
|
||||
// Received messages
|
||||
struct list_head receive_queue;
|
||||
@@ -393,7 +395,7 @@ struct serialqueue {
|
||||
#define IDLE_QUERY_TIME 1.0
|
||||
|
||||
#define DEBUG_QUEUE_SENT 100
|
||||
#define DEBUG_QUEUE_RECEIVE 20
|
||||
#define DEBUG_QUEUE_RECEIVE 100
|
||||
|
||||
// Create a series of empty messages and add them to a list
|
||||
static void
|
||||
@@ -458,6 +460,7 @@ update_receive_seq(struct serialqueue *sq, double eventtime, uint64_t rseq)
|
||||
if (rseq == sent_seq) {
|
||||
// Found sent message corresponding with the received sequence
|
||||
sq->last_receive_sent_time = sent->receive_time;
|
||||
sq->last_ack_bytes = sent->len;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -509,10 +512,14 @@ handle_message(struct serialqueue *sq, double eventtime, int len)
|
||||
if (rseq != sq->receive_seq)
|
||||
// New sequence number
|
||||
update_receive_seq(sq, eventtime, rseq);
|
||||
else if (len == MESSAGE_MIN && rseq > sq->ignore_nak_seq
|
||||
&& !list_empty(&sq->sent_queue))
|
||||
// Duplicate sequence number in an empty message is a nak
|
||||
pollreactor_update_timer(&sq->pr, SQPT_RETRANSMIT, PR_NOW);
|
||||
if (len == MESSAGE_MIN) {
|
||||
// Ack/nak message
|
||||
if (sq->last_ack_seq < rseq)
|
||||
sq->last_ack_seq = rseq;
|
||||
else if (rseq > sq->ignore_nak_seq && !list_empty(&sq->sent_queue))
|
||||
// Duplicate Ack is a Nak - do fast retransmit
|
||||
pollreactor_update_timer(&sq->pr, SQPT_RETRANSMIT, PR_NOW);
|
||||
}
|
||||
|
||||
if (len > MESSAGE_MIN) {
|
||||
// Add message to receive queue
|
||||
@@ -690,11 +697,18 @@ build_and_send_command(struct serialqueue *sq, double eventtime)
|
||||
static double
|
||||
check_send_command(struct serialqueue *sq, double eventtime)
|
||||
{
|
||||
if ((sq->send_seq - sq->receive_seq >= MESSAGE_SEQ_MASK
|
||||
|| (sq->need_ack_bytes - 2*MESSAGE_MAX) * sq->baud_adjust > sq->srtt)
|
||||
if (sq->send_seq - sq->receive_seq >= MESSAGE_SEQ_MASK
|
||||
&& sq->receive_seq != (uint64_t)-1)
|
||||
// Need an ack before more messages can be sent
|
||||
return PR_NEVER;
|
||||
if (sq->send_seq > sq->receive_seq && sq->receive_window) {
|
||||
int need_ack_bytes = sq->need_ack_bytes + MESSAGE_MAX;
|
||||
if (sq->last_ack_seq < sq->receive_seq)
|
||||
need_ack_bytes += sq->last_ack_bytes;
|
||||
if (need_ack_bytes > sq->receive_window)
|
||||
// Wait for ack from past messages before sending next message
|
||||
return PR_NEVER;
|
||||
}
|
||||
|
||||
// Check for stalled messages now ready
|
||||
double idletime = eventtime > sq->idle_time ? eventtime : sq->idle_time;
|
||||
@@ -726,7 +740,8 @@ check_send_command(struct serialqueue *sq, double eventtime)
|
||||
uint64_t req_clock = qm->req_clock;
|
||||
if (req_clock == BACKGROUND_PRIORITY_CLOCK)
|
||||
req_clock = (uint64_t)(
|
||||
(sq->idle_time - sq->last_clock_time + MIN_BACKGROUND_DELTA)
|
||||
(sq->idle_time - sq->last_clock_time
|
||||
+ MIN_REQTIME_DELTA + MIN_BACKGROUND_DELTA)
|
||||
* sq->est_freq) + sq->last_clock;
|
||||
if (req_clock < min_ready_clock)
|
||||
min_ready_clock = req_clock;
|
||||
@@ -783,7 +798,7 @@ background_thread(void *data)
|
||||
}
|
||||
|
||||
// Create a new 'struct serialqueue' object
|
||||
struct serialqueue *
|
||||
struct serialqueue * __visible
|
||||
serialqueue_alloc(int serial_fd, int write_only)
|
||||
{
|
||||
struct serialqueue *sq = malloc(sizeof(*sq));
|
||||
@@ -845,7 +860,7 @@ fail:
|
||||
}
|
||||
|
||||
// Request that the background thread exit
|
||||
void
|
||||
void __visible
|
||||
serialqueue_exit(struct serialqueue *sq)
|
||||
{
|
||||
pollreactor_do_exit(&sq->pr);
|
||||
@@ -856,7 +871,7 @@ serialqueue_exit(struct serialqueue *sq)
|
||||
}
|
||||
|
||||
// Free all resources associated with a serialqueue
|
||||
void
|
||||
void __visible
|
||||
serialqueue_free(struct serialqueue *sq)
|
||||
{
|
||||
if (!sq)
|
||||
@@ -881,7 +896,7 @@ serialqueue_free(struct serialqueue *sq)
|
||||
}
|
||||
|
||||
// Allocate a 'struct command_queue'
|
||||
struct command_queue *
|
||||
struct command_queue * __visible
|
||||
serialqueue_alloc_commandqueue(void)
|
||||
{
|
||||
struct command_queue *cq = malloc(sizeof(*cq));
|
||||
@@ -892,7 +907,7 @@ serialqueue_alloc_commandqueue(void)
|
||||
}
|
||||
|
||||
// Free a 'struct command_queue'
|
||||
void
|
||||
void __visible
|
||||
serialqueue_free_commandqueue(struct command_queue *cq)
|
||||
{
|
||||
if (!cq)
|
||||
@@ -942,7 +957,7 @@ serialqueue_send_batch(struct serialqueue *sq, struct command_queue *cq
|
||||
|
||||
// Schedule the transmission of a message on the serial port at a
|
||||
// given time and priority.
|
||||
void
|
||||
void __visible
|
||||
serialqueue_send(struct serialqueue *sq, struct command_queue *cq
|
||||
, uint8_t *msg, int len, uint64_t min_clock, uint64_t req_clock)
|
||||
{
|
||||
@@ -974,7 +989,7 @@ serialqueue_encode_and_send(struct serialqueue *sq, struct command_queue *cq
|
||||
|
||||
// Return a message read from the serial port (or wait for one if none
|
||||
// available)
|
||||
void
|
||||
void __visible
|
||||
serialqueue_pull(struct serialqueue *sq, struct pull_queue_message *pqm)
|
||||
{
|
||||
pthread_mutex_lock(&sq->lock);
|
||||
@@ -1008,7 +1023,7 @@ exit:
|
||||
pthread_mutex_unlock(&sq->lock);
|
||||
}
|
||||
|
||||
void
|
||||
void __visible
|
||||
serialqueue_set_baud_adjust(struct serialqueue *sq, double baud_adjust)
|
||||
{
|
||||
pthread_mutex_lock(&sq->lock);
|
||||
@@ -1016,9 +1031,17 @@ serialqueue_set_baud_adjust(struct serialqueue *sq, double baud_adjust)
|
||||
pthread_mutex_unlock(&sq->lock);
|
||||
}
|
||||
|
||||
void __visible
|
||||
serialqueue_set_receive_window(struct serialqueue *sq, int receive_window)
|
||||
{
|
||||
pthread_mutex_lock(&sq->lock);
|
||||
sq->receive_window = receive_window;
|
||||
pthread_mutex_unlock(&sq->lock);
|
||||
}
|
||||
|
||||
// Set the estimated clock rate of the mcu on the other end of the
|
||||
// serial port
|
||||
void
|
||||
void __visible
|
||||
serialqueue_set_clock_est(struct serialqueue *sq, double est_freq
|
||||
, double last_clock_time, uint64_t last_clock)
|
||||
{
|
||||
@@ -1030,7 +1053,7 @@ serialqueue_set_clock_est(struct serialqueue *sq, double est_freq
|
||||
}
|
||||
|
||||
// Return a string buffer containing statistics for the serial port
|
||||
void
|
||||
void __visible
|
||||
serialqueue_get_stats(struct serialqueue *sq, char *buf, int len)
|
||||
{
|
||||
struct serialqueue stats;
|
||||
@@ -1052,7 +1075,7 @@ serialqueue_get_stats(struct serialqueue *sq, char *buf, int len)
|
||||
}
|
||||
|
||||
// Extract old messages stored in the debug queues
|
||||
int
|
||||
int __visible
|
||||
serialqueue_extract_old(struct serialqueue *sq, int sentq
|
||||
, struct pull_queue_message *q, int max)
|
||||
{
|
||||
@@ -1,6 +1,6 @@
|
||||
// Stepper pulse schedule compression
|
||||
//
|
||||
// Copyright (C) 2016,2017 Kevin O'Connor <kevin@koconnor.net>
|
||||
// Copyright (C) 2016-2018 Kevin O'Connor <kevin@koconnor.net>
|
||||
//
|
||||
// This file may be distributed under the terms of the GNU GPLv3 license.
|
||||
//
|
||||
@@ -11,17 +11,18 @@
|
||||
// add parameters such that 'count' pulses occur, with each step event
|
||||
// calculating the next step event time using:
|
||||
// next_wake_time = last_wake_time + interval; interval += add
|
||||
// This code is writtin in C (instead of python) for processing
|
||||
// This code is written in C (instead of python) for processing
|
||||
// efficiency - the repetitive integer math is vastly faster in C.
|
||||
|
||||
#include <math.h> // sqrt
|
||||
#include <stddef.h> // offsetof
|
||||
#include <stdint.h> // uint32_t
|
||||
#include <stdio.h> // fprintf
|
||||
#include <stdlib.h> // malloc
|
||||
#include <string.h> // memset
|
||||
#include "compiler.h" // DIV_ROUND_UP
|
||||
#include "pyhelper.h" // errorf
|
||||
#include "serialqueue.h" // struct queue_message
|
||||
#include "stepcompress.h" // stepcompress_alloc
|
||||
|
||||
#define CHECK_LINES 1
|
||||
#define QUEUE_START_SIZE 1024
|
||||
@@ -44,12 +45,10 @@ struct stepcompress {
|
||||
* Step compression
|
||||
****************************************************************/
|
||||
|
||||
#define DIV_UP(n,d) (((n) + (d) - 1) / (d))
|
||||
|
||||
static inline int32_t
|
||||
idiv_up(int32_t n, int32_t d)
|
||||
{
|
||||
return (n>=0) ? DIV_UP(n,d) : (n/d);
|
||||
return (n>=0) ? DIV_ROUND_UP(n,d) : (n/d);
|
||||
}
|
||||
|
||||
static inline int32_t
|
||||
@@ -116,7 +115,7 @@ compress_bisect_add(struct stepcompress *sc)
|
||||
int32_t nextaddfactor = nextcount*(nextcount-1)/2;
|
||||
int32_t c = add*nextaddfactor;
|
||||
if (nextmininterval*nextcount < nextpoint.minp - c)
|
||||
nextmininterval = DIV_UP(nextpoint.minp - c, nextcount);
|
||||
nextmininterval = DIV_ROUND_UP(nextpoint.minp - c, nextcount);
|
||||
if (nextmaxinterval*nextcount > nextpoint.maxp - c)
|
||||
nextmaxinterval = (nextpoint.maxp - c) / nextcount;
|
||||
if (nextmininterval > nextmaxinterval)
|
||||
@@ -187,8 +186,6 @@ compress_bisect_add(struct stepcompress *sc)
|
||||
* Step compress checking
|
||||
****************************************************************/
|
||||
|
||||
#define ERROR_RET -989898989
|
||||
|
||||
// Verify that a given 'step_move' matches the actual step times
|
||||
static int
|
||||
check_line(struct stepcompress *sc, struct step_move move)
|
||||
@@ -230,25 +227,31 @@ check_line(struct stepcompress *sc, struct step_move move)
|
||||
****************************************************************/
|
||||
|
||||
// Allocate a new 'stepcompress' object
|
||||
struct stepcompress *
|
||||
stepcompress_alloc(uint32_t max_error, uint32_t queue_step_msgid
|
||||
, uint32_t set_next_step_dir_msgid, uint32_t invert_sdir
|
||||
, uint32_t oid)
|
||||
struct stepcompress * __visible
|
||||
stepcompress_alloc(uint32_t oid)
|
||||
{
|
||||
struct stepcompress *sc = malloc(sizeof(*sc));
|
||||
memset(sc, 0, sizeof(*sc));
|
||||
sc->max_error = max_error;
|
||||
list_init(&sc->msg_queue);
|
||||
sc->queue_step_msgid = queue_step_msgid;
|
||||
sc->set_next_step_dir_msgid = set_next_step_dir_msgid;
|
||||
sc->oid = oid;
|
||||
sc->sdir = -1;
|
||||
sc->invert_sdir = !!invert_sdir;
|
||||
return sc;
|
||||
}
|
||||
|
||||
// Fill message id information
|
||||
void __visible
|
||||
stepcompress_fill(struct stepcompress *sc, uint32_t max_error
|
||||
, uint32_t invert_sdir, uint32_t queue_step_msgid
|
||||
, uint32_t set_next_step_dir_msgid)
|
||||
{
|
||||
sc->max_error = max_error;
|
||||
sc->invert_sdir = !!invert_sdir;
|
||||
sc->queue_step_msgid = queue_step_msgid;
|
||||
sc->set_next_step_dir_msgid = set_next_step_dir_msgid;
|
||||
}
|
||||
|
||||
// Free memory associated with a 'stepcompress' object
|
||||
void
|
||||
void __visible
|
||||
stepcompress_free(struct stepcompress *sc)
|
||||
{
|
||||
if (!sc)
|
||||
@@ -329,7 +332,7 @@ set_next_step_dir(struct stepcompress *sc, int sdir)
|
||||
}
|
||||
|
||||
// Reset the internal state of the stepcompress object
|
||||
int
|
||||
int __visible
|
||||
stepcompress_reset(struct stepcompress *sc, uint64_t last_step_clock)
|
||||
{
|
||||
int ret = stepcompress_flush(sc, UINT64_MAX);
|
||||
@@ -341,7 +344,7 @@ stepcompress_reset(struct stepcompress *sc, uint64_t last_step_clock)
|
||||
}
|
||||
|
||||
// Indicate the stepper is in homing mode (or done homing if zero)
|
||||
int
|
||||
int __visible
|
||||
stepcompress_set_homing(struct stepcompress *sc, uint64_t homing_clock)
|
||||
{
|
||||
int ret = stepcompress_flush(sc, UINT64_MAX);
|
||||
@@ -352,7 +355,7 @@ stepcompress_set_homing(struct stepcompress *sc, uint64_t homing_clock)
|
||||
}
|
||||
|
||||
// Queue an mcu command to go out in order with stepper commands
|
||||
int
|
||||
int __visible
|
||||
stepcompress_queue_msg(struct stepcompress *sc, uint32_t *data, int len)
|
||||
{
|
||||
int ret = stepcompress_flush(sc, UINT64_MAX);
|
||||
@@ -374,22 +377,34 @@ stepcompress_set_time(struct stepcompress *sc
|
||||
sc->mcu_freq = mcu_freq;
|
||||
}
|
||||
|
||||
double
|
||||
stepcompress_get_mcu_freq(struct stepcompress *sc)
|
||||
{
|
||||
return sc->mcu_freq;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
stepcompress_get_oid(struct stepcompress *sc)
|
||||
{
|
||||
return sc->oid;
|
||||
}
|
||||
|
||||
int
|
||||
stepcompress_get_step_dir(struct stepcompress *sc)
|
||||
{
|
||||
return sc->sdir;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Queue management
|
||||
****************************************************************/
|
||||
|
||||
struct queue_append {
|
||||
struct stepcompress *sc;
|
||||
uint32_t *qnext, *qend, last_step_clock_32;
|
||||
double clock_offset;
|
||||
};
|
||||
|
||||
// Maximium clock delta between messages in the queue
|
||||
#define CLOCK_DIFF_MAX (3<<28)
|
||||
|
||||
// Create a cursor for inserting clock times into the queue
|
||||
static inline struct queue_append
|
||||
inline struct queue_append
|
||||
queue_append_start(struct stepcompress *sc, double print_time, double adjust)
|
||||
{
|
||||
double print_clock = (print_time - sc->mcu_time_offset) * sc->mcu_freq;
|
||||
@@ -400,7 +415,7 @@ queue_append_start(struct stepcompress *sc, double print_time, double adjust)
|
||||
}
|
||||
|
||||
// Finalize a cursor created with queue_append_start()
|
||||
static inline void
|
||||
inline void
|
||||
queue_append_finish(struct queue_append qa)
|
||||
{
|
||||
qa.sc->queue_next = qa.qnext;
|
||||
@@ -454,7 +469,7 @@ queue_append_slow(struct stepcompress *sc, double rel_sc)
|
||||
}
|
||||
|
||||
// Add a clock time to the queue (flushing the queue if needed)
|
||||
static inline int
|
||||
inline int
|
||||
queue_append(struct queue_append *qa, double step_clock)
|
||||
{
|
||||
double rel_sc = step_clock + qa->clock_offset;
|
||||
@@ -476,233 +491,20 @@ queue_append(struct queue_append *qa, double step_clock)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Motion to step conversions
|
||||
****************************************************************/
|
||||
|
||||
// Common suffixes: _sd is step distance (a unit length the same
|
||||
// distance the stepper moves on each step), _sv is step velocity (in
|
||||
// units of step distance per time), _sd2 is step distance squared, _r
|
||||
// is ratio (scalar usually between 0.0 and 1.0). Times are in
|
||||
// seconds and acceleration is in units of step distance per second
|
||||
// squared.
|
||||
|
||||
// Wrapper around sqrt() to handle small negative numbers
|
||||
static double
|
||||
_safe_sqrt(double v)
|
||||
inline int
|
||||
queue_append_set_next_step_dir(struct queue_append *qa, int sdir)
|
||||
{
|
||||
// Due to floating point truncation, it's possible to get a small
|
||||
// negative number - treat it as zero.
|
||||
if (v < -0.001)
|
||||
errorf("safe_sqrt of %.9f", v);
|
||||
return 0.;
|
||||
}
|
||||
static inline double safe_sqrt(double v) {
|
||||
return likely(v >= 0.) ? sqrt(v) : _safe_sqrt(v);
|
||||
}
|
||||
|
||||
// Schedule a step event at the specified step_clock time
|
||||
int32_t
|
||||
stepcompress_push(struct stepcompress *sc, double print_time, int32_t sdir)
|
||||
{
|
||||
int ret = set_next_step_dir(sc, !!sdir);
|
||||
if (ret)
|
||||
return ret;
|
||||
struct queue_append qa = queue_append_start(sc, print_time, 0.5);
|
||||
ret = queue_append(&qa, 0.);
|
||||
if (ret)
|
||||
return ret;
|
||||
queue_append_finish(qa);
|
||||
return sdir ? 1 : -1;
|
||||
}
|
||||
|
||||
// Schedule 'steps' number of steps at constant acceleration. If
|
||||
// acceleration is zero (ie, constant velocity) it uses the formula:
|
||||
// step_time = print_time + step_num/start_sv
|
||||
// Otherwise it uses the formula:
|
||||
// step_time = (print_time + sqrt(2*step_num/accel + (start_sv/accel)**2)
|
||||
// - start_sv/accel)
|
||||
int32_t
|
||||
stepcompress_push_const(
|
||||
struct stepcompress *sc, double print_time
|
||||
, double step_offset, double steps, double start_sv, double accel)
|
||||
{
|
||||
// Calculate number of steps to take
|
||||
int sdir = 1;
|
||||
if (steps < 0) {
|
||||
sdir = 0;
|
||||
steps = -steps;
|
||||
step_offset = -step_offset;
|
||||
}
|
||||
int count = steps + .5 - step_offset;
|
||||
if (count <= 0 || count > 10000000) {
|
||||
if (count && steps) {
|
||||
errorf("push_const invalid count %d %f %f %f %f %f"
|
||||
, sc->oid, print_time, step_offset, steps
|
||||
, start_sv, accel);
|
||||
return ERROR_RET;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
struct stepcompress *sc = qa->sc;
|
||||
uint64_t old_last_step_clock = sc->last_step_clock;
|
||||
sc->queue_next = qa->qnext;
|
||||
int ret = set_next_step_dir(sc, sdir);
|
||||
if (ret)
|
||||
return ret;
|
||||
int res = sdir ? count : -count;
|
||||
|
||||
// Calculate each step time
|
||||
if (!accel) {
|
||||
// Move at constant velocity (zero acceleration)
|
||||
struct queue_append qa = queue_append_start(sc, print_time, .5);
|
||||
double inv_cruise_sv = sc->mcu_freq / start_sv;
|
||||
double pos = (step_offset + .5) * inv_cruise_sv;
|
||||
while (count--) {
|
||||
ret = queue_append(&qa, pos);
|
||||
if (ret)
|
||||
return ret;
|
||||
pos += inv_cruise_sv;
|
||||
}
|
||||
queue_append_finish(qa);
|
||||
} else {
|
||||
// Move with constant acceleration
|
||||
double inv_accel = 1. / accel;
|
||||
double accel_time = start_sv * inv_accel * sc->mcu_freq;
|
||||
struct queue_append qa = queue_append_start(
|
||||
sc, print_time, 0.5 - accel_time);
|
||||
double accel_multiplier = 2. * inv_accel * sc->mcu_freq * sc->mcu_freq;
|
||||
double pos = (step_offset + .5)*accel_multiplier + accel_time*accel_time;
|
||||
while (count--) {
|
||||
double v = safe_sqrt(pos);
|
||||
int ret = queue_append(&qa, accel_multiplier >= 0. ? v : -v);
|
||||
if (ret)
|
||||
return ret;
|
||||
pos += accel_multiplier;
|
||||
}
|
||||
queue_append_finish(qa);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// Schedule steps using delta kinematics
|
||||
static int32_t
|
||||
_stepcompress_push_delta(
|
||||
struct stepcompress *sc, int sdir
|
||||
, double print_time, double move_sd, double start_sv, double accel
|
||||
, double height, double startxy_sd, double arm_sd, double movez_r)
|
||||
{
|
||||
// Calculate number of steps to take
|
||||
double movexy_r = movez_r ? sqrt(1. - movez_r*movez_r) : 1.;
|
||||
double arm_sd2 = arm_sd * arm_sd;
|
||||
double endxy_sd = startxy_sd - movexy_r*move_sd;
|
||||
double end_height = safe_sqrt(arm_sd2 - endxy_sd*endxy_sd);
|
||||
int count = (end_height + movez_r*move_sd - height) * (sdir ? 1. : -1.) + .5;
|
||||
if (count <= 0 || count > 10000000) {
|
||||
if (count) {
|
||||
errorf("push_delta invalid count %d %d %f %f %f %f %f %f %f %f"
|
||||
, sc->oid, count, print_time, move_sd, start_sv, accel
|
||||
, height, startxy_sd, arm_sd, movez_r);
|
||||
return ERROR_RET;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int ret = set_next_step_dir(sc, sdir);
|
||||
if (ret)
|
||||
return ret;
|
||||
int res = sdir ? count : -count;
|
||||
|
||||
// Calculate each step time
|
||||
height += (sdir ? .5 : -.5);
|
||||
if (!accel) {
|
||||
// Move at constant velocity (zero acceleration)
|
||||
struct queue_append qa = queue_append_start(sc, print_time, .5);
|
||||
double inv_cruise_sv = sc->mcu_freq / start_sv;
|
||||
if (!movez_r) {
|
||||
// Optimized case for common XY only moves (no Z movement)
|
||||
while (count--) {
|
||||
double v = safe_sqrt(arm_sd2 - height*height);
|
||||
double pos = startxy_sd + (sdir ? -v : v);
|
||||
int ret = queue_append(&qa, pos * inv_cruise_sv);
|
||||
if (ret)
|
||||
return ret;
|
||||
height += (sdir ? 1. : -1.);
|
||||
}
|
||||
} else if (!movexy_r) {
|
||||
// Optimized case for Z only moves
|
||||
double pos = ((sdir ? height-end_height : end_height-height)
|
||||
* inv_cruise_sv);
|
||||
while (count--) {
|
||||
int ret = queue_append(&qa, pos);
|
||||
if (ret)
|
||||
return ret;
|
||||
pos += inv_cruise_sv;
|
||||
}
|
||||
} else {
|
||||
// General case (handles XY+Z moves)
|
||||
double start_pos = movexy_r*startxy_sd, zoffset = movez_r*startxy_sd;
|
||||
while (count--) {
|
||||
double relheight = movexy_r*height - zoffset;
|
||||
double v = safe_sqrt(arm_sd2 - relheight*relheight);
|
||||
double pos = start_pos + movez_r*height + (sdir ? -v : v);
|
||||
int ret = queue_append(&qa, pos * inv_cruise_sv);
|
||||
if (ret)
|
||||
return ret;
|
||||
height += (sdir ? 1. : -1.);
|
||||
}
|
||||
}
|
||||
queue_append_finish(qa);
|
||||
} else {
|
||||
// Move with constant acceleration
|
||||
double start_pos = movexy_r*startxy_sd, zoffset = movez_r*startxy_sd;
|
||||
double inv_accel = 1. / accel;
|
||||
start_pos += 0.5 * start_sv*start_sv * inv_accel;
|
||||
struct queue_append qa = queue_append_start(
|
||||
sc, print_time, 0.5 - start_sv * inv_accel * sc->mcu_freq);
|
||||
double accel_multiplier = 2. * inv_accel * sc->mcu_freq * sc->mcu_freq;
|
||||
while (count--) {
|
||||
double relheight = movexy_r*height - zoffset;
|
||||
double v = safe_sqrt(arm_sd2 - relheight*relheight);
|
||||
double pos = start_pos + movez_r*height + (sdir ? -v : v);
|
||||
v = safe_sqrt(pos * accel_multiplier);
|
||||
int ret = queue_append(&qa, accel_multiplier >= 0. ? v : -v);
|
||||
if (ret)
|
||||
return ret;
|
||||
height += (sdir ? 1. : -1.);
|
||||
}
|
||||
queue_append_finish(qa);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int32_t
|
||||
stepcompress_push_delta(
|
||||
struct stepcompress *sc, double print_time, double move_sd
|
||||
, double start_sv, double accel
|
||||
, double height, double startxy_sd, double arm_sd, double movez_r)
|
||||
{
|
||||
double reversexy_sd = startxy_sd + arm_sd*movez_r;
|
||||
if (reversexy_sd <= 0.)
|
||||
// All steps are in down direction
|
||||
return _stepcompress_push_delta(
|
||||
sc, 0, print_time, move_sd, start_sv, accel
|
||||
, height, startxy_sd, arm_sd, movez_r);
|
||||
double movexy_r = movez_r ? sqrt(1. - movez_r*movez_r) : 1.;
|
||||
if (reversexy_sd >= move_sd * movexy_r)
|
||||
// All steps are in up direction
|
||||
return _stepcompress_push_delta(
|
||||
sc, 1, print_time, move_sd, start_sv, accel
|
||||
, height, startxy_sd, arm_sd, movez_r);
|
||||
// Steps in both up and down direction
|
||||
int res1 = _stepcompress_push_delta(
|
||||
sc, 1, print_time, reversexy_sd / movexy_r, start_sv, accel
|
||||
, height, startxy_sd, arm_sd, movez_r);
|
||||
if (res1 == ERROR_RET)
|
||||
return res1;
|
||||
int res2 = _stepcompress_push_delta(
|
||||
sc, 0, print_time, move_sd, start_sv, accel
|
||||
, height + res1, startxy_sd, arm_sd, movez_r);
|
||||
if (res2 == ERROR_RET)
|
||||
return res2;
|
||||
return res1 + res2;
|
||||
qa->qnext = sc->queue_next;
|
||||
qa->qend = sc->queue_end;
|
||||
qa->last_step_clock_32 = sc->last_step_clock;
|
||||
qa->clock_offset -= sc->last_step_clock - old_last_step_clock;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -730,7 +532,7 @@ struct steppersync {
|
||||
};
|
||||
|
||||
// Allocate a new 'steppersync' object
|
||||
struct steppersync *
|
||||
struct steppersync * __visible
|
||||
steppersync_alloc(struct serialqueue *sq, struct stepcompress **sc_list
|
||||
, int sc_num, int move_num)
|
||||
{
|
||||
@@ -751,7 +553,7 @@ steppersync_alloc(struct serialqueue *sq, struct stepcompress **sc_list
|
||||
}
|
||||
|
||||
// Free memory associated with a 'steppersync' object
|
||||
void
|
||||
void __visible
|
||||
steppersync_free(struct steppersync *ss)
|
||||
{
|
||||
if (!ss)
|
||||
@@ -763,7 +565,7 @@ steppersync_free(struct steppersync *ss)
|
||||
}
|
||||
|
||||
// Set the conversion rate of 'print_time' to mcu clock
|
||||
void
|
||||
void __visible
|
||||
steppersync_set_time(struct steppersync *ss, double time_offset, double mcu_freq)
|
||||
{
|
||||
int i;
|
||||
@@ -799,7 +601,7 @@ heap_replace(struct steppersync *ss, uint64_t req_clock)
|
||||
}
|
||||
|
||||
// Find and transmit any scheduled steps prior to the given 'move_clock'
|
||||
int
|
||||
int __visible
|
||||
steppersync_flush(struct steppersync *ss, uint64_t move_clock)
|
||||
{
|
||||
// Flush each stepcompress to the specified move_clock
|
||||
40
klippy/chelper/stepcompress.h
Normal file
@@ -0,0 +1,40 @@
|
||||
#ifndef STEPCOMPRESS_H
|
||||
#define STEPCOMPRESS_H
|
||||
|
||||
#include <stdint.h> // uint32_t
|
||||
|
||||
#define ERROR_RET -989898989
|
||||
|
||||
struct stepcompress *stepcompress_alloc(uint32_t oid);
|
||||
void stepcompress_fill(struct stepcompress *sc, uint32_t max_error
|
||||
, uint32_t invert_sdir, uint32_t queue_step_msgid
|
||||
, uint32_t set_next_step_dir_msgid);
|
||||
void stepcompress_free(struct stepcompress *sc);
|
||||
int stepcompress_reset(struct stepcompress *sc, uint64_t last_step_clock);
|
||||
int stepcompress_set_homing(struct stepcompress *sc, uint64_t homing_clock);
|
||||
int stepcompress_queue_msg(struct stepcompress *sc, uint32_t *data, int len);
|
||||
double stepcompress_get_mcu_freq(struct stepcompress *sc);
|
||||
uint32_t stepcompress_get_oid(struct stepcompress *sc);
|
||||
int stepcompress_get_step_dir(struct stepcompress *sc);
|
||||
|
||||
struct queue_append {
|
||||
struct stepcompress *sc;
|
||||
uint32_t *qnext, *qend, last_step_clock_32;
|
||||
double clock_offset;
|
||||
};
|
||||
struct queue_append queue_append_start(
|
||||
struct stepcompress *sc, double print_time, double adjust);
|
||||
void queue_append_finish(struct queue_append qa);
|
||||
int queue_append(struct queue_append *qa, double step_clock);
|
||||
int queue_append_set_next_step_dir(struct queue_append *qa, int sdir);
|
||||
|
||||
struct serialqueue;
|
||||
struct steppersync *steppersync_alloc(
|
||||
struct serialqueue *sq, struct stepcompress **sc_list, int sc_num
|
||||
, int move_num);
|
||||
void steppersync_free(struct steppersync *ss);
|
||||
void steppersync_set_time(struct steppersync *ss, double time_offset
|
||||
, double mcu_freq);
|
||||
int steppersync_flush(struct steppersync *ss, uint64_t move_clock);
|
||||
|
||||
#endif // stepcompress.h
|
||||
@@ -1,11 +1,10 @@
|
||||
# Micro-controller clock synchronization
|
||||
#
|
||||
# Copyright (C) 2016,2017 Kevin O'Connor <kevin@koconnor.net>
|
||||
# Copyright (C) 2016-2018 Kevin O'Connor <kevin@koconnor.net>
|
||||
#
|
||||
# This file may be distributed under the terms of the GNU GPLv3 license.
|
||||
import logging, threading, math
|
||||
import logging, math
|
||||
|
||||
COMM_TIMEOUT = 3.5
|
||||
RTT_AGE = .000010 / (60. * 60.)
|
||||
DECAY = 1. / 30.
|
||||
TRANSMIT_EXTRA = .001
|
||||
@@ -14,8 +13,9 @@ class ClockSync:
|
||||
def __init__(self, reactor):
|
||||
self.reactor = reactor
|
||||
self.serial = None
|
||||
self.status_timer = self.reactor.register_timer(self._status_event)
|
||||
self.status_cmd = None
|
||||
self.get_clock_timer = self.reactor.register_timer(self._get_clock_event)
|
||||
self.get_clock_cmd = None
|
||||
self.queries_pending = 0
|
||||
self.mcu_freq = 1.
|
||||
self.last_clock = 0
|
||||
self.clock_est = (0., 0., 0.)
|
||||
@@ -38,14 +38,14 @@ class ClockSync:
|
||||
self.time_avg = params['#sent_time']
|
||||
self.clock_est = (self.time_avg, self.clock_avg, self.mcu_freq)
|
||||
self.prediction_variance = (.001 * self.mcu_freq)**2
|
||||
# Enable periodic get_status timer
|
||||
self.status_cmd = serial.lookup_command('get_status')
|
||||
# Enable periodic get_clock timer
|
||||
self.get_clock_cmd = serial.lookup_command('get_clock')
|
||||
for i in range(8):
|
||||
params = self.status_cmd.send_with_response(response='status')
|
||||
self._handle_status(params)
|
||||
params = self.get_clock_cmd.send_with_response(response='clock')
|
||||
self._handle_clock(params)
|
||||
self.reactor.pause(0.100)
|
||||
serial.register_callback(self._handle_status, 'status')
|
||||
self.reactor.update_timer(self.status_timer, self.reactor.NOW)
|
||||
serial.register_callback(self._handle_clock, 'clock')
|
||||
self.reactor.update_timer(self.get_clock_timer, self.reactor.NOW)
|
||||
def connect_file(self, serial, pace=False):
|
||||
self.serial = serial
|
||||
self.mcu_freq = serial.msgparser.get_constant_float('CLOCK_FREQ')
|
||||
@@ -54,11 +54,15 @@ class ClockSync:
|
||||
if pace:
|
||||
freq = self.mcu_freq
|
||||
serial.set_clock_est(freq, self.reactor.monotonic(), 0)
|
||||
# MCU clock querying (status callback invoked from background thread)
|
||||
def _status_event(self, eventtime):
|
||||
self.status_cmd.send()
|
||||
return eventtime + 1.0
|
||||
def _handle_status(self, params):
|
||||
# MCU clock querying (_handle_clock is invoked from background thread)
|
||||
def _get_clock_event(self, eventtime):
|
||||
self.get_clock_cmd.send()
|
||||
self.queries_pending += 1
|
||||
# Use an unusual time for the next event so clock messages
|
||||
# don't resonate with other periodic events.
|
||||
return eventtime + .9839
|
||||
def _handle_clock(self, params):
|
||||
self.queries_pending = 0
|
||||
# Extend clock to 64bit
|
||||
last_clock = self.last_clock
|
||||
clock = (last_clock & ~0xffffffff) | params['clock']
|
||||
@@ -136,10 +140,8 @@ class ClockSync:
|
||||
if clock_diff & 0x80000000:
|
||||
return last_clock + 0x100000000 - clock_diff
|
||||
return last_clock - clock_diff
|
||||
def is_active(self, eventtime):
|
||||
print_time = self.estimated_print_time(eventtime)
|
||||
last_clock_print_time = self.clock_to_print_time(self.last_clock)
|
||||
return print_time < last_clock_print_time + COMM_TIMEOUT
|
||||
def is_active(self):
|
||||
return self.queries_pending <= 4
|
||||
def dump_debug(self):
|
||||
sample_time, clock, freq = self.clock_est
|
||||
return ("clocksync state: mcu_freq=%d last_clock=%d"
|
||||
|
||||
258
klippy/configfile.py
Normal file
@@ -0,0 +1,258 @@
|
||||
# Code for reading and writing the Klipper config file
|
||||
#
|
||||
# Copyright (C) 2016-2018 Kevin O'Connor <kevin@koconnor.net>
|
||||
#
|
||||
# This file may be distributed under the terms of the GNU GPLv3 license.
|
||||
import os, re, time, logging, ConfigParser, StringIO
|
||||
|
||||
error = ConfigParser.Error
|
||||
|
||||
class sentinel:
|
||||
pass
|
||||
|
||||
class ConfigWrapper:
|
||||
error = ConfigParser.Error
|
||||
def __init__(self, printer, fileconfig, access_tracking, section):
|
||||
self.printer = printer
|
||||
self.fileconfig = fileconfig
|
||||
self.access_tracking = access_tracking
|
||||
self.section = section
|
||||
def get_printer(self):
|
||||
return self.printer
|
||||
def get_name(self):
|
||||
return self.section
|
||||
def _get_wrapper(self, parser, option, default,
|
||||
minval=None, maxval=None, above=None, below=None):
|
||||
if (default is not sentinel
|
||||
and not self.fileconfig.has_option(self.section, option)):
|
||||
return default
|
||||
self.access_tracking[(self.section.lower(), option.lower())] = 1
|
||||
try:
|
||||
v = parser(self.section, option)
|
||||
except self.error as e:
|
||||
raise
|
||||
except:
|
||||
raise error("Unable to parse option '%s' in section '%s'" % (
|
||||
option, self.section))
|
||||
if minval is not None and v < minval:
|
||||
raise error(
|
||||
"Option '%s' in section '%s' must have minimum of %s" % (
|
||||
option, self.section, minval))
|
||||
if maxval is not None and v > maxval:
|
||||
raise error(
|
||||
"Option '%s' in section '%s' must have maximum of %s" % (
|
||||
option, self.section, maxval))
|
||||
if above is not None and v <= above:
|
||||
raise error("Option '%s' in section '%s' must be above %s" % (
|
||||
option, self.section, above))
|
||||
if below is not None and v >= below:
|
||||
raise self.error("Option '%s' in section '%s' must be below %s" % (
|
||||
option, self.section, below))
|
||||
return v
|
||||
def get(self, option, default=sentinel):
|
||||
return self._get_wrapper(self.fileconfig.get, option, default)
|
||||
def getint(self, option, default=sentinel, minval=None, maxval=None):
|
||||
return self._get_wrapper(
|
||||
self.fileconfig.getint, option, default, minval, maxval)
|
||||
def getfloat(self, option, default=sentinel,
|
||||
minval=None, maxval=None, above=None, below=None):
|
||||
return self._get_wrapper(self.fileconfig.getfloat, option, default,
|
||||
minval, maxval, above, below)
|
||||
def getboolean(self, option, default=sentinel):
|
||||
return self._get_wrapper(self.fileconfig.getboolean, option, default)
|
||||
def getchoice(self, option, choices, default=sentinel):
|
||||
c = self.get(option, default)
|
||||
if c not in choices:
|
||||
raise error("Choice '%s' for option '%s' in section '%s'"
|
||||
" is not a valid choice" % (c, option, self.section))
|
||||
return choices[c]
|
||||
def getsection(self, section):
|
||||
return ConfigWrapper(self.printer, self.fileconfig,
|
||||
self.access_tracking, section)
|
||||
def has_section(self, section):
|
||||
return self.fileconfig.has_section(section)
|
||||
def get_prefix_sections(self, prefix):
|
||||
return [self.getsection(s) for s in self.fileconfig.sections()
|
||||
if s.startswith(prefix)]
|
||||
def get_prefix_options(self, prefix):
|
||||
return [o for o in self.fileconfig.options(self.section)
|
||||
if o.startswith(prefix)]
|
||||
|
||||
AUTOSAVE_HEADER = """
|
||||
#*# <---------------------- SAVE_CONFIG ---------------------->
|
||||
#*# DO NOT EDIT THIS BLOCK OR BELOW. The contents are auto-generated.
|
||||
#*#
|
||||
"""
|
||||
|
||||
class PrinterConfig:
|
||||
def __init__(self, printer):
|
||||
self.printer = printer
|
||||
self.autosave = None
|
||||
gcode = self.printer.lookup_object('gcode')
|
||||
gcode.register_command("SAVE_CONFIG", self.cmd_SAVE_CONFIG,
|
||||
desc=self.cmd_SAVE_CONFIG_help)
|
||||
def _read_config_file(self, filename):
|
||||
try:
|
||||
f = open(filename, 'rb')
|
||||
data = f.read()
|
||||
f.close()
|
||||
except:
|
||||
msg = "Unable to open config file %s" % (filename,)
|
||||
logging.exception(msg)
|
||||
raise error(msg)
|
||||
return data.replace('\r\n', '\n')
|
||||
def _find_autosave_data(self, data):
|
||||
regular_data = data
|
||||
autosave_data = ""
|
||||
pos = data.find(AUTOSAVE_HEADER)
|
||||
if pos >= 0:
|
||||
regular_data = data[:pos]
|
||||
autosave_data = data[pos + len(AUTOSAVE_HEADER):].strip()
|
||||
# Check for errors and strip line prefixes
|
||||
if "\n#*# " in regular_data:
|
||||
logging.warn("Can't read autosave from config file"
|
||||
" - autosave state corrupted")
|
||||
return data, ""
|
||||
out = [""]
|
||||
for line in autosave_data.split('\n'):
|
||||
if ((not line.startswith("#*#")
|
||||
or (len(line) >= 4 and not line.startswith("#*# ")))
|
||||
and autosave_data):
|
||||
logging.warn("Can't read autosave from config file"
|
||||
" - modifications after header")
|
||||
return data, ""
|
||||
out.append(line[4:])
|
||||
out.append("")
|
||||
return regular_data, "\n".join(out)
|
||||
comment_r = re.compile('[#;].*$')
|
||||
value_r = re.compile('[^A-Za-z0-9_].*$')
|
||||
def _strip_duplicates(self, data, config):
|
||||
fileconfig = config.fileconfig
|
||||
# Comment out fields in 'data' that are defined in 'config'
|
||||
lines = data.split('\n')
|
||||
section = None
|
||||
is_dup_field = False
|
||||
for lineno, line in enumerate(lines):
|
||||
pruned_line = self.comment_r.sub('', line).rstrip()
|
||||
if not pruned_line:
|
||||
continue
|
||||
if pruned_line[0].isspace():
|
||||
if is_dup_field:
|
||||
lines[lineno] = '#' + lines[lineno]
|
||||
continue
|
||||
is_dup_field = False
|
||||
if pruned_line[0] == '[':
|
||||
section = pruned_line[1:-1].strip()
|
||||
continue
|
||||
field = self.value_r.sub('', pruned_line)
|
||||
if config.fileconfig.has_option(section, field):
|
||||
is_dup_field = True
|
||||
lines[lineno] = '#' + lines[lineno]
|
||||
return "\n".join(lines)
|
||||
def _build_config_wrapper(self, data):
|
||||
# Strip trailing comments from config
|
||||
lines = data.split('\n')
|
||||
for i, line in enumerate(lines):
|
||||
pos = line.find('#')
|
||||
if pos >= 0:
|
||||
lines[i] = line[:pos]
|
||||
data = '\n'.join(lines)
|
||||
# Read and process config file
|
||||
sfile = StringIO.StringIO(data)
|
||||
fileconfig = ConfigParser.RawConfigParser()
|
||||
fileconfig.readfp(sfile)
|
||||
return ConfigWrapper(self.printer, fileconfig, {}, 'printer')
|
||||
def _build_config_string(self, config):
|
||||
sfile = StringIO.StringIO()
|
||||
config.fileconfig.write(sfile)
|
||||
return sfile.getvalue().strip()
|
||||
def read_config(self, filename):
|
||||
return self._build_config_wrapper(self._read_config_file(filename))
|
||||
def read_main_config(self):
|
||||
filename = self.printer.get_start_args()['config_file']
|
||||
data = self._read_config_file(filename)
|
||||
regular_data, autosave_data = self._find_autosave_data(data)
|
||||
regular_config = self._build_config_wrapper(regular_data)
|
||||
autosave_data = self._strip_duplicates(autosave_data, regular_config)
|
||||
self.autosave = self._build_config_wrapper(autosave_data)
|
||||
return self._build_config_wrapper(regular_data + autosave_data)
|
||||
def check_unused_options(self, config):
|
||||
fileconfig = config.fileconfig
|
||||
objects = dict(self.printer.lookup_objects())
|
||||
# Determine all the fields that have been accessed
|
||||
access_tracking = dict(config.access_tracking)
|
||||
for section in self.autosave.fileconfig.sections():
|
||||
for option in self.autosave.fileconfig.options(section):
|
||||
access_tracking[(section.lower(), option.lower())] = 1
|
||||
# Validate that there are no undefined parameters in the config file
|
||||
valid_sections = { s: 1 for s, o in access_tracking }
|
||||
for section_name in fileconfig.sections():
|
||||
section = section_name.lower()
|
||||
if section not in valid_sections and section not in objects:
|
||||
raise error("Section '%s' is not a valid config section" % (
|
||||
section,))
|
||||
for option in fileconfig.options(section_name):
|
||||
option = option.lower()
|
||||
if (section, option) not in access_tracking:
|
||||
raise error("Option '%s' is not valid in section '%s'" % (
|
||||
option, section))
|
||||
def log_config(self, config):
|
||||
lines = ["===== Config file =====",
|
||||
self._build_config_string(config),
|
||||
"======================="]
|
||||
self.printer.set_rollover_info("config", "\n".join(lines))
|
||||
# Autosave functions
|
||||
def set(self, section, option, value):
|
||||
if not self.autosave.fileconfig.has_section(section):
|
||||
self.autosave.fileconfig.add_section(section)
|
||||
svalue = str(value)
|
||||
self.autosave.fileconfig.set(section, option, svalue)
|
||||
logging.info("save_config: set [%s] %s = %s", section, option, svalue)
|
||||
def remove_section(self, section):
|
||||
self.autosave.fileconfig.remove_section(section)
|
||||
cmd_SAVE_CONFIG_help = "Overwrite config file and restart"
|
||||
def cmd_SAVE_CONFIG(self, params):
|
||||
if not self.autosave.fileconfig.sections():
|
||||
return
|
||||
gcode = self.printer.lookup_object('gcode')
|
||||
# Create string containing autosave data
|
||||
autosave_data = self._build_config_string(self.autosave)
|
||||
lines = [('#*# ' + l).strip()
|
||||
for l in autosave_data.split('\n')]
|
||||
lines.insert(0, "\n" + AUTOSAVE_HEADER.rstrip())
|
||||
lines.append("")
|
||||
autosave_data = '\n'.join(lines)
|
||||
# Read in and validate current config file
|
||||
cfgname = self.printer.get_start_args()['config_file']
|
||||
try:
|
||||
data = self._read_config_file(cfgname)
|
||||
regular_data, old_autosave_data = self._find_autosave_data(data)
|
||||
config = self._build_config_wrapper(regular_data)
|
||||
except error as e:
|
||||
msg = "Unable to parse existing config on SAVE_CONFIG"
|
||||
logging.exception(msg)
|
||||
raise gcode.error(msg)
|
||||
regular_data = self._strip_duplicates(regular_data, self.autosave)
|
||||
data = regular_data.rstrip() + autosave_data
|
||||
# Determine filenames
|
||||
datestr = time.strftime("-%Y%m%d_%H%M%S")
|
||||
backup_name = cfgname + datestr
|
||||
temp_name = cfgname + "_autosave"
|
||||
if cfgname.endswith(".cfg"):
|
||||
backup_name = cfgname[:-4] + datestr + ".cfg"
|
||||
temp_name = cfgname[:-4] + "_autosave.cfg"
|
||||
# Create new config file with temporary name and swap with main config
|
||||
logging.info("SAVE_CONFIG to '%s' (backup in '%s')",
|
||||
cfgname, backup_name)
|
||||
try:
|
||||
f = open(temp_name, 'wb')
|
||||
f.write(data)
|
||||
f.close()
|
||||
os.rename(cfgname, backup_name)
|
||||
os.rename(temp_name, cfgname)
|
||||
except:
|
||||
msg = "Unable to write config file during SAVE_CONFIG"
|
||||
logging.exception(msg)
|
||||
raise gcode.error(msg)
|
||||
# Request a restart
|
||||
gcode.request_restart('restart')
|
||||
@@ -14,7 +14,7 @@ help_txt = """
|
||||
PINS : Load pin name aliases (eg, "PINS arduino")
|
||||
DELAY : Send a command at a clock time (eg, "DELAY 9999 get_uptime")
|
||||
FLOOD : Send a command many times (eg, "FLOOD 22 .01 get_uptime")
|
||||
SUPPRESS : Suppress a response message (eg, "SUPPRESS stats")
|
||||
SUPPRESS : Suppress a response message (eg, "SUPPRESS analog_in_state 4")
|
||||
SET : Create a local variable (eg, "SET myvar 123.4")
|
||||
STATS : Report serial statistics
|
||||
LIST : List available mcu commands, local commands, and local variables
|
||||
@@ -33,6 +33,7 @@ class KeyboardReader:
|
||||
def __init__(self, ser, reactor):
|
||||
self.ser = ser
|
||||
self.reactor = reactor
|
||||
self.start_time = reactor.monotonic()
|
||||
self.clocksync = clocksync.ClockSync(self.reactor)
|
||||
self.fd = sys.stdin.fileno()
|
||||
util.set_nonblock(self.fd)
|
||||
@@ -40,7 +41,7 @@ class KeyboardReader:
|
||||
self.pins = None
|
||||
self.data = ""
|
||||
reactor.register_fd(self.fd, self.process_kbd)
|
||||
self.connect_timer = reactor.register_timer(self.connect, reactor.NOW)
|
||||
reactor.register_callback(self.connect)
|
||||
self.local_commands = {
|
||||
"PINS": self.command_PINS, "SET": self.command_SET,
|
||||
"DELAY": self.command_DELAY, "FLOOD": self.command_FLOOD,
|
||||
@@ -52,19 +53,30 @@ class KeyboardReader:
|
||||
self.output(help_txt)
|
||||
self.output("="*20 + " attempting to connect " + "="*20)
|
||||
self.ser.connect()
|
||||
msgparser = self.ser.msgparser
|
||||
self.output("Loaded %d commands (%s / %s)" % (
|
||||
len(msgparser.messages_by_id),
|
||||
msgparser.version, msgparser.build_versions))
|
||||
self.output("MCU config: %s" % (" ".join(
|
||||
["%s=%s" % (k, v) for k, v in msgparser.config.items()])))
|
||||
self.clocksync.connect(self.ser)
|
||||
self.ser.handle_default = self.handle_default
|
||||
self.mcu_freq = self.ser.msgparser.get_constant_float('CLOCK_FREQ')
|
||||
mcu_type = self.ser.msgparser.get_constant('MCU')
|
||||
self.ser.register_callback(self.handle_output, '#output')
|
||||
self.mcu_freq = msgparser.get_constant_float('CLOCK_FREQ')
|
||||
mcu_type = msgparser.get_constant('MCU')
|
||||
self.pins = pins.PinResolver(mcu_type, validate_aliases=False)
|
||||
self.reactor.unregister_timer(self.connect_timer)
|
||||
self.output("="*20 + " connected " + "="*20)
|
||||
return self.reactor.NEVER
|
||||
def output(self, msg):
|
||||
sys.stdout.write("%s\n" % (msg,))
|
||||
sys.stdout.flush()
|
||||
def handle_default(self, params):
|
||||
self.output(self.ser.msgparser.format_params(params))
|
||||
tdiff = params['#receive_time'] - self.start_time
|
||||
self.output("%07.3f: %s" % (
|
||||
tdiff, self.ser.msgparser.format_params(params)))
|
||||
def handle_output(self, params):
|
||||
tdiff = params['#receive_time'] - self.start_time
|
||||
self.output("%07.3f: %s: %s" % (tdiff, params['#name'], params['#msg']))
|
||||
def handle_suppress(self, params):
|
||||
pass
|
||||
def update_evals(self, eventtime):
|
||||
@@ -182,7 +194,6 @@ class KeyboardReader:
|
||||
self.ser.send(msg)
|
||||
except msgproto.error as e:
|
||||
self.output("Error: %s" % (str(e),))
|
||||
return None
|
||||
self.data = kbdlines[-1]
|
||||
|
||||
def main():
|
||||
|
||||
161
klippy/corexy.py
@@ -1,161 +0,0 @@
|
||||
# Code for handling the kinematics of corexy robots
|
||||
#
|
||||
# Copyright (C) 2017 Kevin O'Connor <kevin@koconnor.net>
|
||||
#
|
||||
# This file may be distributed under the terms of the GNU GPLv3 license.
|
||||
import logging, math
|
||||
import stepper, homing
|
||||
|
||||
StepList = (0, 1, 2)
|
||||
|
||||
class CoreXYKinematics:
|
||||
def __init__(self, toolhead, printer, config):
|
||||
self.steppers = [
|
||||
stepper.PrinterHomingStepper(
|
||||
printer, config.getsection('stepper_x')),
|
||||
stepper.PrinterHomingStepper(
|
||||
printer, config.getsection('stepper_y')),
|
||||
stepper.LookupMultiHomingStepper(
|
||||
printer, config.getsection('stepper_z'))]
|
||||
self.steppers[0].mcu_endstop.add_stepper(self.steppers[1].mcu_stepper)
|
||||
self.steppers[1].mcu_endstop.add_stepper(self.steppers[0].mcu_stepper)
|
||||
max_velocity, max_accel = toolhead.get_max_velocity()
|
||||
self.max_z_velocity = config.getfloat(
|
||||
'max_z_velocity', max_velocity, above=0., maxval=max_velocity)
|
||||
self.max_z_accel = config.getfloat(
|
||||
'max_z_accel', max_accel, above=0., maxval=max_accel)
|
||||
self.need_motor_enable = True
|
||||
self.limits = [(1.0, -1.0)] * 3
|
||||
# Setup stepper max halt velocity
|
||||
max_halt_velocity = toolhead.get_max_axis_halt()
|
||||
max_xy_halt_velocity = max_halt_velocity * math.sqrt(2.)
|
||||
self.steppers[0].set_max_jerk(max_xy_halt_velocity, max_accel)
|
||||
self.steppers[1].set_max_jerk(max_xy_halt_velocity, max_accel)
|
||||
self.steppers[2].set_max_jerk(
|
||||
min(max_halt_velocity, self.max_z_velocity), self.max_z_accel)
|
||||
def get_steppers(self, flags=""):
|
||||
if flags == "Z":
|
||||
return [self.steppers[2]]
|
||||
return list(self.steppers)
|
||||
def get_position(self):
|
||||
pos = [s.mcu_stepper.get_commanded_position() for s in self.steppers]
|
||||
return [0.5 * (pos[0] + pos[1]), 0.5 * (pos[0] - pos[1]), pos[2]]
|
||||
def set_position(self, newpos, homing_axes):
|
||||
pos = (newpos[0] + newpos[1], newpos[0] - newpos[1], newpos[2])
|
||||
for i in StepList:
|
||||
s = self.steppers[i]
|
||||
s.set_position(pos[i])
|
||||
if i in homing_axes:
|
||||
self.limits[i] = (s.position_min, s.position_max)
|
||||
def home(self, homing_state):
|
||||
# Each axis is homed independently and in order
|
||||
for axis in homing_state.get_axes():
|
||||
s = self.steppers[axis]
|
||||
# Determine moves
|
||||
if s.homing_positive_dir:
|
||||
pos = s.position_endstop - 1.5*(
|
||||
s.position_endstop - s.position_min)
|
||||
rpos = s.position_endstop - s.homing_retract_dist
|
||||
r2pos = rpos - s.homing_retract_dist
|
||||
else:
|
||||
pos = s.position_endstop + 1.5*(
|
||||
s.position_max - s.position_endstop)
|
||||
rpos = s.position_endstop + s.homing_retract_dist
|
||||
r2pos = rpos + s.homing_retract_dist
|
||||
# Initial homing
|
||||
homing_speed = s.homing_speed
|
||||
if axis == 2:
|
||||
homing_speed = min(homing_speed, self.max_z_velocity)
|
||||
homepos = [None, None, None, None]
|
||||
homepos[axis] = s.position_endstop
|
||||
coord = [None, None, None, None]
|
||||
coord[axis] = pos
|
||||
homing_state.home(coord, homepos, s.get_endstops(), homing_speed)
|
||||
# Retract
|
||||
coord[axis] = rpos
|
||||
homing_state.retract(coord, homing_speed)
|
||||
# Home again
|
||||
coord[axis] = r2pos
|
||||
homing_state.home(coord, homepos, s.get_endstops(),
|
||||
homing_speed/2.0, second_home=True)
|
||||
if axis == 2:
|
||||
# Support endstop phase detection on Z axis
|
||||
coord[axis] = s.position_endstop + s.get_homed_offset()
|
||||
homing_state.set_homed_position(coord)
|
||||
def motor_off(self, print_time):
|
||||
self.limits = [(1.0, -1.0)] * 3
|
||||
for stepper in self.steppers:
|
||||
stepper.motor_enable(print_time, 0)
|
||||
self.need_motor_enable = True
|
||||
def _check_motor_enable(self, print_time, move):
|
||||
if move.axes_d[0] or move.axes_d[1]:
|
||||
self.steppers[0].motor_enable(print_time, 1)
|
||||
self.steppers[1].motor_enable(print_time, 1)
|
||||
if move.axes_d[2]:
|
||||
self.steppers[2].motor_enable(print_time, 1)
|
||||
need_motor_enable = False
|
||||
for i in StepList:
|
||||
need_motor_enable |= self.steppers[i].need_motor_enable
|
||||
self.need_motor_enable = need_motor_enable
|
||||
def _check_endstops(self, move):
|
||||
end_pos = move.end_pos
|
||||
for i in StepList:
|
||||
if (move.axes_d[i]
|
||||
and (end_pos[i] < self.limits[i][0]
|
||||
or end_pos[i] > self.limits[i][1])):
|
||||
if self.limits[i][0] > self.limits[i][1]:
|
||||
raise homing.EndstopMoveError(
|
||||
end_pos, "Must home axis first")
|
||||
raise homing.EndstopMoveError(end_pos)
|
||||
def check_move(self, move):
|
||||
limits = self.limits
|
||||
xpos, ypos = move.end_pos[:2]
|
||||
if (xpos < limits[0][0] or xpos > limits[0][1]
|
||||
or ypos < limits[1][0] or ypos > limits[1][1]):
|
||||
self._check_endstops(move)
|
||||
if not move.axes_d[2]:
|
||||
# Normal XY move - use defaults
|
||||
return
|
||||
# Move with Z - update velocity and accel for slower Z axis
|
||||
self._check_endstops(move)
|
||||
z_ratio = move.move_d / abs(move.axes_d[2])
|
||||
move.limit_speed(
|
||||
self.max_z_velocity * z_ratio, self.max_z_accel * z_ratio)
|
||||
def move(self, print_time, move):
|
||||
if self.need_motor_enable:
|
||||
self._check_motor_enable(print_time, move)
|
||||
sxp = move.start_pos[0]
|
||||
syp = move.start_pos[1]
|
||||
move_start_pos = (sxp + syp, sxp - syp, move.start_pos[2])
|
||||
exp = move.end_pos[0]
|
||||
eyp = move.end_pos[1]
|
||||
axes_d = ((exp + eyp) - move_start_pos[0],
|
||||
(exp - eyp) - move_start_pos[1], move.axes_d[2])
|
||||
for i in StepList:
|
||||
axis_d = axes_d[i]
|
||||
if not axis_d:
|
||||
continue
|
||||
step_const = self.steppers[i].step_const
|
||||
move_time = print_time
|
||||
start_pos = move_start_pos[i]
|
||||
axis_r = abs(axis_d) / move.move_d
|
||||
accel = move.accel * axis_r
|
||||
cruise_v = move.cruise_v * axis_r
|
||||
|
||||
# Acceleration steps
|
||||
if move.accel_r:
|
||||
accel_d = move.accel_r * axis_d
|
||||
step_const(move_time, start_pos, accel_d,
|
||||
move.start_v * axis_r, accel)
|
||||
start_pos += accel_d
|
||||
move_time += move.accel_t
|
||||
# Cruising steps
|
||||
if move.cruise_r:
|
||||
cruise_d = move.cruise_r * axis_d
|
||||
step_const(move_time, start_pos, cruise_d, cruise_v, 0.)
|
||||
start_pos += cruise_d
|
||||
move_time += move.cruise_t
|
||||
# Deceleration steps
|
||||
if move.decel_r:
|
||||
decel_d = move.decel_r * axis_d
|
||||
step_const(move_time, start_pos, decel_d, cruise_v, -accel)
|
||||
285
klippy/delta.py
@@ -1,285 +0,0 @@
|
||||
# Code for handling the kinematics of linear delta robots
|
||||
#
|
||||
# Copyright (C) 2016,2017 Kevin O'Connor <kevin@koconnor.net>
|
||||
#
|
||||
# This file may be distributed under the terms of the GNU GPLv3 license.
|
||||
import math, logging
|
||||
import stepper, homing
|
||||
|
||||
StepList = (0, 1, 2)
|
||||
|
||||
# Slow moves once the ratio of tower to XY movement exceeds SLOW_RATIO
|
||||
SLOW_RATIO = 3.
|
||||
|
||||
class DeltaKinematics:
|
||||
def __init__(self, toolhead, printer, config):
|
||||
stepper_configs = [config.getsection('stepper_' + n)
|
||||
for n in ['a', 'b', 'c']]
|
||||
stepper_a = stepper.PrinterHomingStepper(printer, stepper_configs[0])
|
||||
stepper_b = stepper.PrinterHomingStepper(
|
||||
printer, stepper_configs[1],
|
||||
default_position=stepper_a.position_endstop)
|
||||
stepper_c = stepper.PrinterHomingStepper(
|
||||
printer, stepper_configs[2],
|
||||
default_position=stepper_a.position_endstop)
|
||||
self.steppers = [stepper_a, stepper_b, stepper_c]
|
||||
self.need_motor_enable = self.need_home = True
|
||||
self.radius = radius = config.getfloat('delta_radius', above=0.)
|
||||
arm_length_a = stepper_configs[0].getfloat('arm_length', above=radius)
|
||||
self.arm_lengths = arm_lengths = [
|
||||
sconfig.getfloat('arm_length', arm_length_a, above=radius)
|
||||
for sconfig in stepper_configs]
|
||||
self.arm2 = [arm**2 for arm in arm_lengths]
|
||||
self.endstops = [s.position_endstop + math.sqrt(arm2 - radius**2)
|
||||
for s, arm2 in zip(self.steppers, self.arm2)]
|
||||
self.limit_xy2 = -1.
|
||||
self.max_z = min([s.position_endstop for s in self.steppers])
|
||||
self.min_z = config.getfloat('minimum_z_position', 0, maxval=self.max_z)
|
||||
self.limit_z = min([ep - arm
|
||||
for ep, arm in zip(self.endstops, arm_lengths)])
|
||||
logging.info(
|
||||
"Delta max build height %.2fmm (radius tapered above %.2fmm)" % (
|
||||
self.max_z, self.limit_z))
|
||||
# Setup stepper max halt velocity
|
||||
self.max_velocity, self.max_accel = toolhead.get_max_velocity()
|
||||
self.max_z_velocity = config.getfloat(
|
||||
'max_z_velocity', self.max_velocity,
|
||||
above=0., maxval=self.max_velocity)
|
||||
max_halt_velocity = toolhead.get_max_axis_halt()
|
||||
for s in self.steppers:
|
||||
s.set_max_jerk(max_halt_velocity, self.max_accel)
|
||||
# Determine tower locations in cartesian space
|
||||
self.angles = [sconfig.getfloat('angle', angle)
|
||||
for sconfig, angle in zip(stepper_configs,
|
||||
[210., 330., 90.])]
|
||||
self.towers = [(math.cos(math.radians(angle)) * radius,
|
||||
math.sin(math.radians(angle)) * radius)
|
||||
for angle in self.angles]
|
||||
# Find the point where an XY move could result in excessive
|
||||
# tower movement
|
||||
half_min_step_dist = min([s.step_dist for s in self.steppers]) * .5
|
||||
min_arm_length = min(arm_lengths)
|
||||
def ratio_to_dist(ratio):
|
||||
return (ratio * math.sqrt(min_arm_length**2 / (ratio**2 + 1.)
|
||||
- half_min_step_dist**2)
|
||||
+ half_min_step_dist)
|
||||
self.slow_xy2 = (ratio_to_dist(SLOW_RATIO) - radius)**2
|
||||
self.very_slow_xy2 = (ratio_to_dist(2. * SLOW_RATIO) - radius)**2
|
||||
self.max_xy2 = min(radius, min_arm_length - radius,
|
||||
ratio_to_dist(4. * SLOW_RATIO) - radius)**2
|
||||
logging.info(
|
||||
"Delta max build radius %.2fmm (moves slowed past %.2fmm and %.2fmm)"
|
||||
% (math.sqrt(self.max_xy2), math.sqrt(self.slow_xy2),
|
||||
math.sqrt(self.very_slow_xy2)))
|
||||
self.set_position([0., 0., 0.], ())
|
||||
def get_steppers(self, flags=""):
|
||||
return list(self.steppers)
|
||||
def _cartesian_to_actuator(self, coord):
|
||||
return [math.sqrt(self.arm2[i] - (self.towers[i][0] - coord[0])**2
|
||||
- (self.towers[i][1] - coord[1])**2) + coord[2]
|
||||
for i in StepList]
|
||||
def _actuator_to_cartesian(self, pos):
|
||||
return actuator_to_cartesian(self.towers, self.arm2, pos)
|
||||
def get_position(self):
|
||||
spos = [s.mcu_stepper.get_commanded_position() for s in self.steppers]
|
||||
return self._actuator_to_cartesian(spos)
|
||||
def set_position(self, newpos, homing_axes):
|
||||
pos = self._cartesian_to_actuator(newpos)
|
||||
for i in StepList:
|
||||
self.steppers[i].set_position(pos[i])
|
||||
self.limit_xy2 = -1.
|
||||
if tuple(homing_axes) == StepList:
|
||||
self.need_home = False
|
||||
def home(self, homing_state):
|
||||
# All axes are homed simultaneously
|
||||
homing_state.set_axes([0, 1, 2])
|
||||
endstops = [es for s in self.steppers for es in s.get_endstops()]
|
||||
s = self.steppers[0] # Assume homing speed same for all steppers
|
||||
# Initial homing
|
||||
homing_speed = min(s.homing_speed, self.max_z_velocity)
|
||||
homepos = [0., 0., self.max_z, None]
|
||||
coord = list(homepos)
|
||||
coord[2] = -1.5 * math.sqrt(max(self.arm2)-self.max_xy2)
|
||||
homing_state.home(coord, homepos, endstops, homing_speed)
|
||||
# Retract
|
||||
coord[2] = homepos[2] - s.homing_retract_dist
|
||||
homing_state.retract(coord, homing_speed)
|
||||
# Home again
|
||||
coord[2] -= s.homing_retract_dist
|
||||
homing_state.home(coord, homepos, endstops,
|
||||
homing_speed/2.0, second_home=True)
|
||||
# Set final homed position
|
||||
spos = [ep + s.get_homed_offset()
|
||||
for ep, s in zip(self.endstops, self.steppers)]
|
||||
homing_state.set_homed_position(self._actuator_to_cartesian(spos))
|
||||
def motor_off(self, print_time):
|
||||
self.limit_xy2 = -1.
|
||||
for stepper in self.steppers:
|
||||
stepper.motor_enable(print_time, 0)
|
||||
self.need_motor_enable = self.need_home = True
|
||||
def _check_motor_enable(self, print_time):
|
||||
for i in StepList:
|
||||
self.steppers[i].motor_enable(print_time, 1)
|
||||
self.need_motor_enable = False
|
||||
def check_move(self, move):
|
||||
end_pos = move.end_pos
|
||||
xy2 = end_pos[0]**2 + end_pos[1]**2
|
||||
if xy2 <= self.limit_xy2 and not move.axes_d[2]:
|
||||
# Normal XY move
|
||||
return
|
||||
if self.need_home:
|
||||
raise homing.EndstopMoveError(end_pos, "Must home first")
|
||||
limit_xy2 = self.max_xy2
|
||||
if end_pos[2] > self.limit_z:
|
||||
limit_xy2 = min(limit_xy2, (self.max_z - end_pos[2])**2)
|
||||
if xy2 > limit_xy2 or end_pos[2] < self.min_z or end_pos[2] > self.max_z:
|
||||
raise homing.EndstopMoveError(end_pos)
|
||||
if move.axes_d[2]:
|
||||
move.limit_speed(self.max_z_velocity, move.accel)
|
||||
limit_xy2 = -1.
|
||||
# Limit the speed/accel of this move if is is at the extreme
|
||||
# end of the build envelope
|
||||
extreme_xy2 = max(xy2, move.start_pos[0]**2 + move.start_pos[1]**2)
|
||||
if extreme_xy2 > self.slow_xy2:
|
||||
r = 0.5
|
||||
if extreme_xy2 > self.very_slow_xy2:
|
||||
r = 0.25
|
||||
max_velocity = self.max_velocity
|
||||
if move.axes_d[2]:
|
||||
max_velocity = self.max_z_velocity
|
||||
move.limit_speed(max_velocity * r, self.max_accel * r)
|
||||
limit_xy2 = -1.
|
||||
self.limit_xy2 = min(limit_xy2, self.slow_xy2)
|
||||
def move(self, print_time, move):
|
||||
if self.need_motor_enable:
|
||||
self._check_motor_enable(print_time)
|
||||
axes_d = move.axes_d
|
||||
move_d = move.move_d
|
||||
movexy_r = 1.
|
||||
movez_r = 0.
|
||||
inv_movexy_d = 1. / move_d
|
||||
if not axes_d[0] and not axes_d[1]:
|
||||
# Z only move
|
||||
movez_r = axes_d[2] * inv_movexy_d
|
||||
movexy_r = inv_movexy_d = 0.
|
||||
elif axes_d[2]:
|
||||
# XY+Z move
|
||||
movexy_d = math.sqrt(axes_d[0]**2 + axes_d[1]**2)
|
||||
movexy_r = movexy_d * inv_movexy_d
|
||||
movez_r = axes_d[2] * inv_movexy_d
|
||||
inv_movexy_d = 1. / movexy_d
|
||||
|
||||
origx, origy, origz = move.start_pos[:3]
|
||||
|
||||
accel = move.accel
|
||||
cruise_v = move.cruise_v
|
||||
accel_d = move.accel_r * move_d
|
||||
cruise_d = move.cruise_r * move_d
|
||||
decel_d = move.decel_r * move_d
|
||||
|
||||
for i in StepList:
|
||||
# Calculate a virtual tower along the line of movement at
|
||||
# the point closest to this stepper's tower.
|
||||
towerx_d = self.towers[i][0] - origx
|
||||
towery_d = self.towers[i][1] - origy
|
||||
vt_startxy_d = (towerx_d*axes_d[0] + towery_d*axes_d[1])*inv_movexy_d
|
||||
tangentxy_d2 = towerx_d**2 + towery_d**2 - vt_startxy_d**2
|
||||
vt_arm_d = math.sqrt(self.arm2[i] - tangentxy_d2)
|
||||
vt_startz = origz
|
||||
|
||||
# Generate steps
|
||||
step_delta = self.steppers[i].step_delta
|
||||
move_time = print_time
|
||||
if accel_d:
|
||||
step_delta(move_time, accel_d, move.start_v, accel,
|
||||
vt_startz, vt_startxy_d, vt_arm_d, movez_r)
|
||||
vt_startz += accel_d * movez_r
|
||||
vt_startxy_d -= accel_d * movexy_r
|
||||
move_time += move.accel_t
|
||||
if cruise_d:
|
||||
step_delta(move_time, cruise_d, cruise_v, 0.,
|
||||
vt_startz, vt_startxy_d, vt_arm_d, movez_r)
|
||||
vt_startz += cruise_d * movez_r
|
||||
vt_startxy_d -= cruise_d * movexy_r
|
||||
move_time += move.cruise_t
|
||||
if decel_d:
|
||||
step_delta(move_time, decel_d, cruise_v, -accel,
|
||||
vt_startz, vt_startxy_d, vt_arm_d, movez_r)
|
||||
# Helper functions for DELTA_CALIBRATE script
|
||||
def get_stable_position(self):
|
||||
return [int((ep - s.mcu_stepper.get_commanded_position())
|
||||
/ s.mcu_stepper.get_step_dist() + .5)
|
||||
* s.mcu_stepper.get_step_dist()
|
||||
for ep, s in zip(self.endstops, self.steppers)]
|
||||
def get_calibrate_params(self):
|
||||
return {
|
||||
'endstop_a': self.steppers[0].position_endstop,
|
||||
'endstop_b': self.steppers[1].position_endstop,
|
||||
'endstop_c': self.steppers[2].position_endstop,
|
||||
'angle_a': self.angles[0], 'angle_b': self.angles[1],
|
||||
'angle_c': self.angles[2], 'radius': self.radius,
|
||||
'arm_a': self.arm_lengths[0], 'arm_b': self.arm_lengths[1],
|
||||
'arm_c': self.arm_lengths[2] }
|
||||
|
||||
|
||||
######################################################################
|
||||
# Matrix helper functions for 3x1 matrices
|
||||
######################################################################
|
||||
|
||||
def matrix_cross(m1, m2):
|
||||
return [m1[1] * m2[2] - m1[2] * m2[1],
|
||||
m1[2] * m2[0] - m1[0] * m2[2],
|
||||
m1[0] * m2[1] - m1[1] * m2[0]]
|
||||
|
||||
def matrix_dot(m1, m2):
|
||||
return m1[0] * m2[0] + m1[1] * m2[1] + m1[2] * m2[2]
|
||||
|
||||
def matrix_magsq(m1):
|
||||
return m1[0]**2 + m1[1]**2 + m1[2]**2
|
||||
|
||||
def matrix_add(m1, m2):
|
||||
return [m1[0] + m2[0], m1[1] + m2[1], m1[2] + m2[2]]
|
||||
|
||||
def matrix_sub(m1, m2):
|
||||
return [m1[0] - m2[0], m1[1] - m2[1], m1[2] - m2[2]]
|
||||
|
||||
def matrix_mul(m1, s):
|
||||
return [m1[0]*s, m1[1]*s, m1[2]*s]
|
||||
|
||||
def actuator_to_cartesian(towers, arm2, pos):
|
||||
# Find nozzle position using trilateration (see wikipedia)
|
||||
carriage1 = list(towers[0]) + [pos[0]]
|
||||
carriage2 = list(towers[1]) + [pos[1]]
|
||||
carriage3 = list(towers[2]) + [pos[2]]
|
||||
|
||||
s21 = matrix_sub(carriage2, carriage1)
|
||||
s31 = matrix_sub(carriage3, carriage1)
|
||||
|
||||
d = math.sqrt(matrix_magsq(s21))
|
||||
ex = matrix_mul(s21, 1. / d)
|
||||
i = matrix_dot(ex, s31)
|
||||
vect_ey = matrix_sub(s31, matrix_mul(ex, i))
|
||||
ey = matrix_mul(vect_ey, 1. / math.sqrt(matrix_magsq(vect_ey)))
|
||||
ez = matrix_cross(ex, ey)
|
||||
j = matrix_dot(ey, s31)
|
||||
|
||||
x = (arm2[0] - arm2[1] + d**2) / (2. * d)
|
||||
y = (arm2[0] - arm2[2] - x**2 + (x-i)**2 + j**2) / (2. * j)
|
||||
z = -math.sqrt(arm2[0] - x**2 - y**2)
|
||||
|
||||
ex_x = matrix_mul(ex, x)
|
||||
ey_y = matrix_mul(ey, y)
|
||||
ez_z = matrix_mul(ez, z)
|
||||
return matrix_add(carriage1, matrix_add(ex_x, matrix_add(ey_y, ez_z)))
|
||||
|
||||
def get_position_from_stable(spos, params):
|
||||
angles = [params['angle_a'], params['angle_b'], params['angle_c']]
|
||||
radius = params['radius']
|
||||
radius2 = radius**2
|
||||
towers = [(math.cos(angle) * radius, math.sin(angle) * radius)
|
||||
for angle in map(math.radians, angles)]
|
||||
arm2 = [a**2 for a in [params['arm_a'], params['arm_b'], params['arm_c']]]
|
||||
endstops = [params['endstop_a'], params['endstop_b'], params['endstop_c']]
|
||||
pos = [es + math.sqrt(a2 - radius2) - p
|
||||
for es, a2, p in zip(endstops, arm2, spos)]
|
||||
return actuator_to_cartesian(towers, arm2, pos)
|
||||