add server and schematics
This commit is contained in:
parent
70e43af646
commit
3429752313
2
LICENSE
2
LICENSE
@ -1,6 +1,6 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) <year> <copyright holders>
|
Copyright (c) 2022 Error
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
62
README.md
62
README.md
@ -1,3 +1,63 @@
|
|||||||
# SCRoIP
|
# SCRoIP
|
||||||
|
|
||||||
Slot Car Racing over IP
|
Slot Car Racing over IP
|
||||||
|
|
||||||
|
A remote control for a slot car racing track to play with it over the LAN. It's unnecessary complicated and inefficient, but at least it supports IPv6. Ladies, Gentlemen and everyone else, start your engines.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
scroipserver [-h] [-4 V4_HOST | -6 V6_HOST] [-p PORT] config
|
||||||
|
|
||||||
|
positional arguments:
|
||||||
|
|
||||||
|
config
|
||||||
|
: path to the configuration file
|
||||||
|
|
||||||
|
options:
|
||||||
|
|
||||||
|
-h
|
||||||
|
--help
|
||||||
|
: show this help message and exit
|
||||||
|
|
||||||
|
-4 V4_HOST
|
||||||
|
--v4-host V4_HOST
|
||||||
|
: host name or IPv4 address
|
||||||
|
|
||||||
|
-6 V6_HOST
|
||||||
|
--v6-host V6_HOST
|
||||||
|
: host name or IPv6 address
|
||||||
|
|
||||||
|
-p PORT
|
||||||
|
--port PORT
|
||||||
|
: TCP port to listen to
|
||||||
|
|
||||||
|
## Config Parameters
|
||||||
|
|
||||||
|
### Network `[network]`
|
||||||
|
|
||||||
|
legacy
|
||||||
|
: use IPv4 (`True`) or IPv6 (`False`)
|
||||||
|
|
||||||
|
v4_host
|
||||||
|
: IPv4 address of the server (ignored when `legacy` is `True`)
|
||||||
|
|
||||||
|
v6_host
|
||||||
|
: IPv6 address of the server (ignored when `legacy` is `False`)
|
||||||
|
|
||||||
|
port
|
||||||
|
: TCP port the server listens on
|
||||||
|
|
||||||
|
### Thresholds `[thresholds]`
|
||||||
|
|
||||||
|
min
|
||||||
|
: traffic threshold for the lowest throttle level
|
||||||
|
|
||||||
|
max
|
||||||
|
: traffic threshold for the maximum throttle level
|
||||||
|
|
||||||
|
stop_when_exceeded
|
||||||
|
: when set to `True`, the controller will stop applying throttle when the `max` threshold is exceeded
|
||||||
|
|
||||||
|
### Pins `[pins]`
|
||||||
|
|
||||||
|
Mapping of the controlls `a0`, `a1`, `a2`, `s0`, `s1`, `s2` and `s3` to the raspberry pi's GPIO pins (using their BCM numbers).
|
||||||
|
19
example.conf
Normal file
19
example.conf
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
[network]
|
||||||
|
legacy = False
|
||||||
|
v4_host = 127.0.0.1
|
||||||
|
v6_host = ::1
|
||||||
|
port = 4223
|
||||||
|
|
||||||
|
[thresholds]
|
||||||
|
min = 1
|
||||||
|
max = 100
|
||||||
|
stop_when_exceeded = True
|
||||||
|
|
||||||
|
[pins]
|
||||||
|
a0 = 4
|
||||||
|
a1 = 3
|
||||||
|
a2 = 2
|
||||||
|
s0 = 22
|
||||||
|
s1 = 10
|
||||||
|
s2 = 27
|
||||||
|
s3 = 17
|
4
schematics/analog-controller/.gitignore
vendored
Normal file
4
schematics/analog-controller/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
*.aux
|
||||||
|
*.dvi
|
||||||
|
*.log
|
||||||
|
*.pdf
|
64
schematics/analog-controller/carrera.svg
Normal file
64
schematics/analog-controller/carrera.svg
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
|
<!-- This file was generated by dvisvgm 2.13.3 -->
|
||||||
|
<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='1151.558811pt' height='616.470693pt' viewBox='-210.027861 -216.00015 1151.558811 616.470693'>
|
||||||
|
<defs>
|
||||||
|
<clipPath id='clip1'>
|
||||||
|
<path d='M223.2184 49.9492V26.1367H191.4684V49.9492ZM207.3434 49.9492C213.9184 49.9492 219.2504 44.6172 219.2504 38.043C219.2504 31.4648 213.9184 26.1367 207.3434 26.1367C200.7694 26.1367 195.4374 31.4648 195.4374 38.043C195.4374 44.6172 200.7694 49.9492 207.3434 49.9492ZM207.3434 38.043' clip-rule='evenodd'/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
<style type='text/css'>
|
||||||
|
<![CDATA[@font-face{font-family:cmsy10;src:url(data:application/x-font-woff;base64,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) format('woff');}
|
||||||
|
@font-face{font-family:cmmi10;src:url(data:application/x-font-woff;base64,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) format('woff');}
|
||||||
|
@font-face{font-family:cmr10;src:url(data:application/x-font-woff;base64,d09GRgABAAAAAAz0AA4AAAAAEOgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAABRAAAABoAAAAckY/re09TLzIAAAFgAAAARAAAAFZVrH/vY21hcAAAAaQAAABsAAABalGu+fxjdnQgAAACEAAAAAgAAAAIAAsCeWZwZ20AAAIYAAABsQAAAmUPtC+nZ2x5ZgAAA8wAAAdTAAAJXKv5jJ9oZWFkAAALIAAAADEAAAA2IJdQNWhoZWEAAAtUAAAAHgAAACQGjANPaG10eAAAC3QAAAAvAAAANBnUAfZsb2NhAAALpAAAABwAAAAcCvINYG1heHAAAAvAAAAAIAAAACABKwDjbmFtZQAAC+AAAAC6AAABF/mHrhdwb3N0AAAMnAAAACYAAAA8AJEA+3ByZXAAAAzEAAAALgAAAC6w8isUeNpjYGBgZACCy9vuzQDR9960FcJoAF1hCIMAAHjaY2Bk8mecwMDKwMDUxbSHgYGhB0IzPmAwZGQCijKwMjPAACMQc8A4AWmuKUBKW1GN6d1/NoYopoMMwVA1DADGiQpoeNpjYGBgZoBgGQZGBhBIAfIYwXwWBg8gzcfAwcDEwMagzWDCYMZgweCrqPb/P1Bcm8EAwf9/4/+V/5f/X/q/794zqDlIgJGNAS7IyAQkmNAVoPBArmFgYWVj52DgZOBiwAK4GYYcAACdOxLo/+oAAAAhAnl42l1Ru05bQRDdDQ8DgcTYIDnaFLOZkALvhTZIIK4uwsh2YzlC2o1c5GJcwAdQIFGD9msGaChTpE2DkAskPoFPiJSZNYmiNDs7s3POmTNLypGqd2m956lzFkjhboNmm34npNpFgAfS9Y1GRtrBIy02M3rlun2/j8FmNOVOGkB5z1vKQ0bTTqAW7bl/Mj+D4T7/yzwHg5Zmmp5aZyE9hMB8M25p8DWjWXf9QV+xOlwNBoYU01Tc9cdUyv+W5lxtGbY2M5p3cCEiP5gGaGqtjUDTnzqkej6OYgly+WysDSamrD/JRHBhMl3VVC0zvnZwn+wsOtikSnPgAQ6wVZ6Ch+OjCYX0LYkyS0OEg9gqMULEJIdCTjl3sj8pUD6ShDFvktLOuGGtgXHkNTCozdMcvsxmU9tbhzB+EUfw3S/Gkg4+sqE2RoTYjlgKYAKRkFFVvqHGcy+LAbnU/jMQJWB5+u1fJwKtOzYRL2VtnWOMFYKe3zbf+WXF3apc50Whu3dVNVTplOZDL2ff4xFPj4XhoLHgzed9f6NA7Q2LGw2aA8GQ3o3e/9FadcRV3gsf2W81s7EWAAAAeNpVlV2IG9cVx+8dSTP6Wkl3JM1IWkmj0ehbWs1qRhpJu1rtbhdvFm92s+5i4sRNHCfb+KONXUgc23Egbhrogx9abNLSQFPjYGgoLXe0DXkrcV9MIPNQCiqlfS5uoQ+B0IfS3fRcyVmSF+nO0YDO+f3/538Rh1SEcI17D7mQgJo2RvpgJLi5fxs27/n7YOTi4IhsFyt7WHkk8K7/DUaY1U2ikrJJNBX7Hj18yL138LLKnUKIQ70vf8v9iXsCRVEMNRAN6RSZNOBQt4FpXKeRMfUZNOpQj2FLuI7sQIiINNafbxVVo62ppJ2PEzUfM1USMzoE/wLLqnr4z8rhI1XFico/KjgBz48ePyM3Kn/5L/wZzCDCP1ZRDa2jURihOo05NKdT3sG0rlP/mCYdmozYRVynyLEbuG4Xk0S0w3y/j+xYGHqo9WmOjPxR1O9DN7hdbnJaXuDjMTmLTaNrdVz5UrnUaXeHLtOQZCkeE0JYw59V4ses1Bvt4lzm9Nw1q/jn4low4BWUSnpGW5/xB/xrFbzy7smGFbq6c+f93W7ztZ3bh5/0Vgc/f9uq9SRve7V36ycrqwPG7hnQ4wOYRUIy6qNRCMMcMw4VDcrr1AOjJHTqG1PJsZMwgOSDrl3QPj8DB6lPPYR6J62XNF6LG10S4+s4bhlyR8uXgGWJJ8NrT7WzyzntUMutZLibondFSR38NysqLpciZrkWQqwPA/p4AH000Bx6HY2KrA/kUKJT2aFpwAmtNHU6M2aUYxFbAaqCQ8sGFSK04tCKbuvQYAz62kfJfLEg96kCbNMqsKUVkZaga1QE/vk5KBBiq2X4lsV9YSapwNvzrWU8dHdgkDwIwPhbkwdhCEcgH8YhHFe7Gi/AhG9dXGivJMRr3zlxMS0KREsn/S5yvLGyfuETrwu/mk4G/cKp32+dM+fXalb25CuX15NpV2o2ruB564W1c6+PvQHxd5sh73T2GvjpU5h9CQ3RXTTqMS9VHdrQqeFQTaezDg3qlMDcU3ct67QzprpD9QgN58aE+hzq02mYFewSgFl0qMzqLsdeASg6qLYfJA2DQQkTqrC5P+ZRLJPXqj0oIrtRBT3n+tQg+yW9swg1e1YDWGjY79skSMSRzyVPXTrEX0GSJoy0x4AEIKOx6iJmjzwYoCxZ33y3VMb54fal45svZyQ5PYxvaaWFtLKQCId94cbiYL1ePZWYLauylL+6++yN00/iF2JnFwfbT/UT6YxkqBlzaU03OBfn97qe2Tp9vFBxK+lUNp1de/bV7eVzYdjNNPjoL9x9lEFZyJo8uGnEMy95HBqAOACaypiiSRyEDbsAdKIKzOlNwlJCIMSn/jWnBl7CZkcjA9zE4IOJ+lGwdKIdrz5/phpvJ/b23Dwf9B462M9/8cX9pzNTU2eeVvBDn+Dlgod1RcFXDm8xnd1HOueRhizURW+jUZppXQDhdJp3WHKBlIIOHse0B9Yfsx2oGxRFbBN0VRyqRChh0kK8BZgn7D6MEEBE/CgvxNIFnUlsEqqCxUU75GNRU0iDtt0+1cm+rGiIaetjCUhAzWinzbJFzh8pNLU/N33IC9F8k2MRxESeBBCvvTNbNsvRYaqbFiPZtcG5u6WVY6WT11/7dfWqVJJnXKK0UBsqIsmt4Y3ExqXFYqAyJyWklL704Jdnbm3kfnj2zM2XDv8gpuNe/cX61sKwuPdiYRXxR3z8KACECpAJJvouGmUYoybEN5sX07ZOU2PacmgrQjmGIjZZDI4VbC9QCgEyVs85dgfgeDmAEySJTLE5sbqnScQVnz8QiqVyhaI5Wf0oTGhNXVyWjyjIknzk3HKpLMhZ19TXkMgfGCe6vRMvvXn7+vc3Ni82AsOfvrl78kYrurN3I0LSoeeXV5+7gj9V5+cWnuh8e2HnzPC5b+2eXV9qBWsbP3jy7KWdY1bcqG0HZjKFuLWxOzy/CjlQRMh1mfsNGkASXEajCPjWzlZMEzZ7FCvNGYYBDGy1AxW3Q7sGdUdoCogMv3bbaACg5djLMHjSDxYgIqScRvaj5cqAeaPFbh1kp9j1M+jbbg98LzECTQzGZwhILMRpkwgH6TvEjAKAbtQk39iMDmlbixhOvBDAnwt+8cOElXSTZuFC4kKhSdz4c28wIPwHJ61E8XsXi/AjnD6M+jx/+yv3boSHHTkMhsXZENuX0KwY5mYPbktR7vrBH7/aIS4MJ0/owOHmWUY24OM+9wC2pod+hEYq22nLhPEpb7CkDAOHvk7FMUvOHJMflqUaYZcCDUJ+RihiRexQrLPreAEAVdnmx+GCgNX4KCwlhYkbKIaw83f7bHVSKrxRNOGNBvkYBUUlV271Jo4pwkUQAmRW92t5KGc5mcVeqazJj11z5KtpMna5+0m/1y1VdkKb9Tn7rZv2XD2dyvA7Fcnt9SfVu8RrtW5s77zR073ir9R7phTyDy6t7lnn79w5b+2t1mqDlH9Gat/jwxs/+/HW5StXX9l8/51jYf7e/wEfdzxCAHjaY2BkYGAAYu/c97Lx/DZfGeSZXwBFGO69aSuE0zL/1zLnMx0EcjkYmECiAGePDPkAAAB42mNgZGBgOvh/LUMU8xQGIGDOZ2BkQAW8AGo4A+IAAHjaY8xhUGQAAkZfBgZmTgYLxi8M6kAcCcRGQKwFxDJQWot5CoMq0yUGHQDx0grcAAAAACoAKgAqAGIAyAEMAYoCMAJ+Aw4DjgQcBK4AAQAAAA0APwAGAAAAAAACAAEAAgAWAAABAACgAAAAAHjaRY09CsJAEIW/GOMviJVY7gUSkm0CqaxyAAsLO5E1CCaBTVJ5DA/gAbykk2XRXYb3zczjDbDgRsD4JszZeg5RnD1HrHl5nkn3kW0wXYp/45wjhxzYe47Y8fQ8Y8WbI4aKgQcXLBxNNTwuAiUtDb1TKw4jVzUJqWghdaWWefbrc2JXWiZaPmXb9GVrK6N0kqpCXWubjZrHeaxTLY6ThFo67u6UkrAxnpOx3b1tVJZI8z+DC+AL+L8lKAAAeNpjYGLAD3iBmJGBiYGPQZhBhEGUQYxBnEGSQZrBgGE+AAsCAY0AALgB/4WwAY0AS7AIUFixAQGOWbFGBitYIbAQWUuwFFJYIbCAWR2wBitcWFmwFCsAAA==) format('woff');}
|
||||||
|
text.f0 {font-family:cmsy10;font-size:9.96264px}
|
||||||
|
text.f1 {font-family:cmmi10;font-size:9.96264px}
|
||||||
|
text.f2 {font-family:cmr10;font-size:9.96264px}
|
||||||
|
]]>
|
||||||
|
</style>
|
||||||
|
<g id='page1' transform='matrix(3 0 0 3 0 0)'>
|
||||||
|
<path d='M101.043 45.1289V-11.5664C101.043-25.7383 143.5625-4.4805 143.5625 9.6953V16.7813M108.1289 45.1289V9.6953C108.1289 2.6094 108.1289 2.6094 122.3047 9.6953C136.4766 16.7813 136.4766 16.7813 136.4766 23.8672V45.1289C136.4766 52.2148 136.4766 52.2148 129.3906 52.2148H115.2148C108.1289 52.2148 108.1289 52.2148 108.1289 45.1289M129.3906 40.875C129.3906 36.9609 126.2187 33.7891 122.3047 33.7891C118.3906 33.7891 115.2148 36.9609 115.2148 40.875S118.3906 47.9648 122.3047 47.9648C126.2187 47.9648 129.3906 44.7891 129.3906 40.875ZM123.7187 28.1211C123.7187 25.7734 121.8164 23.8672 119.4687 23.8672C117.1211 23.8672 115.2148 25.7734 115.2148 28.1211S117.1211 32.3711 119.4687 32.3711C121.8164 32.3711 123.7187 30.4688 123.7187 28.1211ZM120.8867 18.1992C120.8867 16.6328 119.6172 15.3633 118.0508 15.3633S115.2148 16.6328 115.2148 18.1992S116.4844 21.0352 118.0508 21.0352S120.8867 19.7656 120.8867 18.1992ZM101.043 45.1289C101.043 59.3008 101.043 59.3008 115.2148 59.3008H299.4724C313.6444 59.3008 313.6444 59.3008 313.6444 45.1289V-11.5664C313.6444-25.7383 271.1254-4.4805 271.1254 9.6953V16.7813M306.5584 45.1289V9.6953C306.5584 2.6094 306.5584 2.6094 292.3824 9.6953C278.2114 16.7813 278.2114 16.7813 278.2114 23.8672V45.1289C278.2114 52.2148 278.2114 52.2148 285.2964 52.2148H299.4724C306.5584 52.2148 306.5584 52.2148 306.5584 45.1289M299.4724 40.875C299.4724 36.9609 296.2964 33.7891 292.3824 33.7891S285.2964 36.9609 285.2964 40.875S288.4684 47.9648 292.3824 47.9648S299.4724 44.7891 299.4724 40.875ZM299.4724 28.1211C299.4724 25.7734 297.5664 23.8672 295.2184 23.8672C292.8714 23.8672 290.9684 25.7734 290.9684 28.1211S292.8714 32.3711 295.2184 32.3711C297.5664 32.3711 299.4724 30.4688 299.4724 28.1211ZM299.4724 18.1992C299.4724 16.6328 298.2034 15.3633 296.6364 15.3633C295.0704 15.3633 293.8004 16.6328 293.8004 18.1992S295.0704 21.0352 296.6364 21.0352C298.2034 21.0352 299.4724 19.7656 299.4724 18.1992ZM171.9102 16.7813L178.9964 23.8672C181.8324 26.7031 181.8324 26.7031 184.6684 26.7031H230.0194C232.8554 26.7031 232.8554 26.7031 235.6914 23.8672L242.7774 16.7813M149.2344 59.3008L152.0664 56.4688C154.9023 53.6328 154.9023 53.6328 157.7383 53.6328H256.9494C259.7854 53.6328 259.7854 53.6328 262.6214 56.4688L265.4534 59.3008M140.7305 2.6094C169.0742 8.2773 245.6134 8.2773 273.9574 2.6094M133.6406-4.4805L142.1445-18.6523C159.1523-46.9998 255.5354-46.9998 272.5434-18.6523L281.0464-4.4805M272.5434-18.6523C264.0394-35.6598 150.6484-35.6598 142.1445-18.6523M122.3047-11.5664V-32.8238H123.7227V-10.7148M123.7227-30.5588H156.7461M123.7227-19.2187H142.4297M292.3824-11.5664V-32.8238H290.9644V-10.7148M290.9644-30.5588H257.9414M290.9644-19.2187H272.2574M108.1289 59.3008V64.97266H136.4766V59.3008M306.5584 59.3008V64.97266H278.2114V59.3008' stroke='#bfbfbf' fill='none' stroke-width='.3985'/>
|
||||||
|
<path d='M-12.1836-48.8128L15.8398-55.8168C19.8437-56.8168 20.7227-55.2618 17.8047-52.3438C1.8281-36.3668 1.8281-36.3668 11.4023-26.7968C11.9883-26.2109 12.0898-25.1836 11.6289-24.4961C3.957-12.9844 3.957-12.9844 11.4023-5.5352C11.9883-4.9531 12.0898-3.9219 11.6289-3.2344C3.957 8.2773 3.957 8.2773 11.4023 15.7266C11.9883 16.3086 12.0898 17.3398 11.6289 18.0234C3.957 29.5391 3.957 29.5391 19.0508 53.0156C21.2812 56.4883 19.7461 59.3008 15.6172 59.3008H-11.957C-16.0859 59.3008-20.3672 56.0898-21.5234 52.1289C-34.3126 8.2773-34.3126 8.2773-29.1016-24.7344C-28.4566-28.8128-26.2734-35.0198-24.2266-38.6058L-23.1367-40.5118C-21.0898-44.0938-16.1836-47.8088-12.1836-48.8128ZM-5.2578-50.5428V-67.5508L-13.7617-65.4258V-66.8438L6.082-71.8008V-70.3868L-2.4219-68.2578V-51.2498' stroke='#bfbfbf' fill='none' stroke-width='.3985' stroke-miterlimit='10'/>
|
||||||
|
<path d='M-40.6916 106.0234V125.9648M-12.3438-28.5738M-12.3438 30.9531V101.8203H-22.5508M-40.6916 101.8203H-30.4846M-40.6916 130.168H-33.6056M-33.6056 130.168H-26.5156V105.7891M-26.5156 97.8555V-34.2418H-19.4297M-19.4297-34.2418H-12.3438M3.5312 1.1914V101.8203H171.9102V52.2148V46.8281M171.9102 15.082V9.6953H203.3754M211.3124 9.6953H242.7774V15.082M242.7774 46.8281V52.2148V130.168H-26.5156M186.0824 9.6953V23.8672M186.0824 23.8672V38.043M186.0824 38.043H223.2184M191.4684 38.043H228.6054M228.6054 38.043V23.8672M228.6054 23.8672V9.6953' stroke='#000' fill='none' stroke-width='.3985' stroke-miterlimit='10'/>
|
||||||
|
<text class='f2' x='72.696413' y='73.475155' transform='matrix(1 0 0 1 -124.6559 30.8378)'>+</text>
|
||||||
|
<path d='M-39.1056 101.8203C-39.1056 100.9453-39.8126 100.2344-40.6916 100.2344C-41.5666 100.2344-42.2776 100.9453-42.2776 101.8203C-42.2776 102.6992-41.5666 103.4102-40.6916 103.4102C-39.8126 103.4102-39.1056 102.6992-39.1056 101.8203Z' fill='#fff'/>
|
||||||
|
<path d='M-39.1056 101.8203C-39.1056 100.9453-39.8126 100.2344-40.6916 100.2344C-41.5666 100.2344-42.2776 100.9453-42.2776 101.8203C-42.2776 102.6992-41.5666 103.4102-40.6916 103.4102C-39.8126 103.4102-39.1056 102.6992-39.1056 101.8203Z' stroke='#000' fill='none' stroke-width='.3985' stroke-miterlimit='10'/>
|
||||||
|
<path d='M-39.1056 130.168C-39.1056 129.293-39.8126 128.582-40.6916 128.582C-41.5666 128.582-42.2776 129.293-42.2776 130.168C-42.2776 131.0469-41.5666 131.7578-40.6916 131.7578C-39.8126 131.7578-39.1056 131.0469-39.1056 130.168Z' fill='#fff'/>
|
||||||
|
<path d='M-39.1056 130.168C-39.1056 129.293-39.8126 128.582-40.6916 128.582C-41.5666 128.582-42.2776 129.293-42.2776 130.168C-42.2776 131.0469-41.5666 131.7578-40.6916 131.7578C-39.8126 131.7578-39.1056 131.0469-39.1056 130.168Z' stroke='#000' fill='none' stroke-width='.3985' stroke-miterlimit='10'/>
|
||||||
|
<path d='M-40.6916 121.75H-42.6756L-40.6916 125.9648L-38.7066 121.75Z'/>
|
||||||
|
<path d='M-40.6916 121.75H-42.6756L-40.6916 125.9648L-38.7066 121.75Z' stroke='#000' fill='none' stroke-width='.3985' stroke-miterlimit='10'/>
|
||||||
|
<text class='f2' x='72.696413' y='73.475155' transform='matrix(1 0 0 1 -142.7057 45.9238)'>14</text>
|
||||||
|
<text class='f1' x='82.659091' y='73.475155' transform='matrix(1 0 0 1 -142.7057 45.9238)'>.</text>
|
||||||
|
<text class='f2' x='85.4265' y='73.475155' transform='matrix(1 0 0 1 -142.7057 45.9238)'>8</text>
|
||||||
|
<text class='f1' x='90.407839' y='73.475155' transform='matrix(1 0 0 1 -142.7057 45.9238)'>V</text>
|
||||||
|
<text class='f0' x='72.696413' y='73.475155' transform='matrix(1 0 0 1 -124.6559 59.1848)'>−</text>
|
||||||
|
<path d='M-30.4846 101.8203H-28.1056C-28.1056 100.9453-27.3946 100.2344-26.5156 100.2344C-25.6406 100.2344-24.9297 100.9453-24.9297 101.8203H-22.5508M-26.5156 97.8555V99.8359M-26.5156 100.6328V105.7891' stroke='#000' fill='none' stroke-width='.3985' stroke-miterlimit='10' stroke-linejoin='bevel'/>
|
||||||
|
<path d='M-12.3438-28.9728L-6.3906-26.9098L-18.2969-23.5781L-6.3906-20.25L-18.2969-16.9219L-6.3906-13.5898L-18.2969-10.2617L-6.3906-6.9336L-18.2969-3.6055L-6.3906-.2734L-18.2969 3.0547L-6.3906 6.3828L-18.2969 9.7148L-6.3906 13.043L-18.2969 16.3711L-6.3906 19.6992L-18.2969 23.0313L-6.3906 26.3594L-18.2969 29.6875L-12.3438 31.3516' stroke='#000' fill='none' stroke-width='.797' stroke-miterlimit='10' stroke-linejoin='bevel'/>
|
||||||
|
<path d='M3.5312 1.1914H-3.2813' stroke='#000' fill='none' stroke-width='.797' stroke-miterlimit='10' stroke-linejoin='bevel'/>
|
||||||
|
<path d='M-6.39063 1.191406C-5.09766 1.449218-2.765626 1.968749-1.21094 3.13281C-2.503907 1.707031-2.503907 .671874-1.21094-.75C-2.765626 .414062-5.09766 .933593-6.39063 1.191406Z'/>
|
||||||
|
<text class='f2' x='72.696413' y='73.475155' transform='matrix(1 0 0 1 -65.97014 -70.13967)'>30<tspan x='84.319491'>Ω</tspan></text>
|
||||||
|
<path d='M-24.9297 130.168C-24.9297 129.293-25.6406 128.582-26.5156 128.582C-27.3946 128.582-28.1056 129.293-28.1056 130.168C-28.1056 131.0469-27.3946 131.7578-26.5156 131.7578C-25.6406 131.7578-24.9297 131.0469-24.9297 130.168Z'/>
|
||||||
|
<path d='M-24.9297 130.168C-24.9297 129.293-25.6406 128.582-26.5156 128.582C-27.3946 128.582-28.1056 129.293-28.1056 130.168C-28.1056 131.0469-27.3946 131.7578-26.5156 131.7578C-25.6406 131.7578-24.9297 131.0469-24.9297 130.168Z' stroke='#000' fill='none' stroke-width='.3985' stroke-miterlimit='10'/>
|
||||||
|
<path d='M-10.7578-34.2418C-10.7578-35.1208-11.4688-35.8278-12.3438-35.8278S-13.9297-35.1208-13.9297-34.2418C-13.9297-33.3668-13.2188-32.6558-12.3438-32.6558S-10.7578-33.3668-10.7578-34.2418Z'/>
|
||||||
|
<path d='M-10.7578-34.2418C-10.7578-35.1208-11.4688-35.8278-12.3438-35.8278S-13.9297-35.1208-13.9297-34.2418C-13.9297-33.3668-13.2188-32.6558-12.3438-32.6558S-10.7578-33.3668-10.7578-34.2418Z' stroke='#000' fill='none' stroke-width='.3985' stroke-miterlimit='10'/>
|
||||||
|
<path d='M171.9102 47.2266L165.957 44.1484L177.8634 38.793L165.957 33.4336L177.8634 28.0781L165.957 22.7188L177.8634 17.3594L171.9102 14.6836' stroke='#000' fill='none' stroke-width='.797' stroke-miterlimit='10' stroke-linejoin='bevel'/>
|
||||||
|
<text class='f2' x='72.696413' y='73.475155' transform='matrix(1 0 0 1 69.4716 -40.3754)'>6</text>
|
||||||
|
<text class='f1' x='77.677752' y='73.475155' transform='matrix(1 0 0 1 69.4716 -40.3754)'>.</text>
|
||||||
|
<text class='f2' x='80.445161' y='73.475155' transform='matrix(1 0 0 1 69.4716 -40.3754)'>8<tspan x='87.086899'>Ω</tspan></text>
|
||||||
|
<path d='M203.3754-2.2109V21.6016M211.3124-2.2109V21.6016' stroke='#000' fill='none' stroke-width='.797' stroke-miterlimit='10'/>
|
||||||
|
<text class='f2' x='72.696413' y='73.475155' transform='matrix(1 0 0 1 122.7806 -80.09378)'>22</text>
|
||||||
|
<text class='f1' x='82.659091' y='73.475155' transform='matrix(1 0 0 1 122.7806 -80.09378)'>nF</text>
|
||||||
|
<path d='M242.7774 14.6836L248.7304 17.7578L236.8244 23.1172L248.7304 28.4766L236.8244 33.832L248.7304 39.1914L236.8244 44.5469L242.7774 47.2266' stroke='#000' fill='none' stroke-width='.797' stroke-miterlimit='10' stroke-linejoin='bevel'/>
|
||||||
|
<text class='f2' x='72.696413' y='73.475155' transform='matrix(1 0 0 1 178.2376 -40.3754)'>6</text>
|
||||||
|
<text class='f1' x='77.677752' y='73.475155' transform='matrix(1 0 0 1 178.2376 -40.3754)'>.</text>
|
||||||
|
<text class='f2' x='80.445161' y='73.475155' transform='matrix(1 0 0 1 178.2376 -40.3754)'>8<tspan x='87.086899'>Ω</tspan></text>
|
||||||
|
<path d='M187.6714 9.6953C187.6714 8.8164 186.9614 8.1094 186.0824 8.1094C185.2074 8.1094 184.4964 8.8164 184.4964 9.6953C184.4964 10.5703 185.2074 11.2813 186.0824 11.2813C186.9614 11.2813 187.6714 10.5703 187.6714 9.6953Z'/>
|
||||||
|
<path d='M187.6714 9.6953C187.6714 8.8164 186.9614 8.1094 186.0824 8.1094C185.2074 8.1094 184.4964 8.8164 184.4964 9.6953C184.4964 10.5703 185.2074 11.2813 186.0824 11.2813C186.9614 11.2813 187.6714 10.5703 187.6714 9.6953Z' stroke='#000' fill='none' stroke-width='.3985' stroke-miterlimit='10'/>
|
||||||
|
<path d='M223.2184 43.9961V32.0898H191.4684V43.9961Z' clip-path='url(#clip1)' fill-rule='evenodd'/>
|
||||||
|
<path d='M223.2184 43.9961V32.0898H191.4684V43.9961Z' stroke='#000' fill='none' stroke-width='.797' stroke-miterlimit='10' clip-path='url(#clip1)'/>
|
||||||
|
<path d='M207.3434 49.9492C213.9184 49.9492 219.2504 44.6172 219.2504 38.043C219.2504 31.4648 213.9184 26.1367 207.3434 26.1367C200.7694 26.1367 195.4374 31.4648 195.4374 38.043C195.4374 44.6172 200.7694 49.9492 207.3434 49.9492Z' fill='#fff'/>
|
||||||
|
<path d='M207.3434 49.9492C213.9184 49.9492 219.2504 44.6172 219.2504 38.043C219.2504 31.4648 213.9184 26.1367 207.3434 26.1367C200.7694 26.1367 195.4374 31.4648 195.4374 38.043C195.4374 44.6172 200.7694 49.9492 207.3434 49.9492Z' stroke='#000' fill='none' stroke-width='.797' stroke-miterlimit='10'/>
|
||||||
|
<text class='f2' x='72.696413' y='73.475155' transform='matrix(1 0 0 1 130.0806 -32.0295)'>M</text>
|
||||||
|
<path d='M230.1914 9.6953C230.1914 8.8164 229.4804 8.1094 228.6054 8.1094C227.7264 8.1094 227.0154 8.8164 227.0154 9.6953C227.0154 10.5703 227.7264 11.2813 228.6054 11.2813C229.4804 11.2813 230.1914 10.5703 230.1914 9.6953Z'/>
|
||||||
|
<path d='M230.1914 9.6953C230.1914 8.8164 229.4804 8.1094 228.6054 8.1094C227.7264 8.1094 227.0154 8.8164 227.0154 9.6953C227.0154 10.5703 227.7264 11.2813 228.6054 11.2813C229.4804 11.2813 230.1914 10.5703 230.1914 9.6953Z' stroke='#000' fill='none' stroke-width='.3985' stroke-miterlimit='10'/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 22 KiB |
121
schematics/analog-controller/carrera.tex
Normal file
121
schematics/analog-controller/carrera.tex
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
\documentclass[tikz]{standalone}
|
||||||
|
\usepackage{circuitikz}
|
||||||
|
\usepackage{siunitx}
|
||||||
|
|
||||||
|
\begin{document}
|
||||||
|
\begin{tikzpicture}
|
||||||
|
%car
|
||||||
|
\draw[color=lightgray]
|
||||||
|
% left wheel housing
|
||||||
|
(1,1) -- ++(0,2)
|
||||||
|
.. controls +(0,0.5) and +(0,0.5) .. ++(1.5,-0.75)
|
||||||
|
-- ++(0,-0.25)
|
||||||
|
% left light
|
||||||
|
(1.25,1) -- ++(0,1.25)
|
||||||
|
.. controls +(0,0.25) .. ++(0.5,0)
|
||||||
|
.. controls +(0.5,-0.25) .. ++(0.5,-0.5)
|
||||||
|
-- ++(0,-0.75)
|
||||||
|
.. controls +(0,-0.25) .. ++(-0.25,-0.25)
|
||||||
|
-- ++(-0.5,0)
|
||||||
|
.. controls +(-0.25,0) .. ++(-0.25,0.25)
|
||||||
|
++(0.5,0.15) circle[radius=0.25]
|
||||||
|
++(-0.1,0.45) circle[radius=0.15]
|
||||||
|
++(-0.05,0.35) circle[radius=0.1]
|
||||||
|
% floor
|
||||||
|
(1,1) .. controls +(0,-0.5) .. ++(0.5,-0.5)
|
||||||
|
-- ++(6.5,0)
|
||||||
|
.. controls +(0.5,0) .. ++(0.5,0.5)
|
||||||
|
% right wheel housing
|
||||||
|
-- ++(0,2)
|
||||||
|
.. controls +(0,0.5) and +(0,0.5) .. ++(-1.5,-0.75)
|
||||||
|
-- ++(0,-0.25)
|
||||||
|
% right light
|
||||||
|
(8.25,1) -- ++(0,1.25)
|
||||||
|
.. controls +(0,0.25) .. ++(-0.5,0)
|
||||||
|
.. controls +(-0.5,-0.25) .. ++(-0.5,-0.5)
|
||||||
|
-- ++(0,-0.75)
|
||||||
|
.. controls +(0,-0.25) .. ++(0.25,-0.25)
|
||||||
|
-- ++(0.5,0)
|
||||||
|
.. controls +(0.25,0) .. ++(0.25,0.25)
|
||||||
|
++(-0.5,0.15) circle[radius=0.25]
|
||||||
|
++(0.1,0.45) circle[radius=0.15]
|
||||||
|
++(0.05,0.35) circle[radius=0.1]
|
||||||
|
% ventilation
|
||||||
|
(3.5,2) -- ++(0.25,-0.25)
|
||||||
|
.. controls +(0.1,-0.1) .. ++(0.2,-0.1)
|
||||||
|
-- ++(1.6,0)
|
||||||
|
.. controls +(0.1,0) .. ++(0.2,0.1)
|
||||||
|
-- ++(0.25,0.25)
|
||||||
|
(2.7,0.5) -- ++(0.1,0.1)
|
||||||
|
.. controls +(0.1,0.1) .. ++(0.2,0.1)
|
||||||
|
-- ++(3.5,0)
|
||||||
|
.. controls +(0.1,0) .. ++(0.2,-0.1)
|
||||||
|
-- ++(0.1,-0.1)
|
||||||
|
%cockpit
|
||||||
|
(2.4,2.5) .. controls +(1,-0.2) and +(-1,-0.2) .. ++(4.7,0)
|
||||||
|
(2.15,2.75) -- ++(0.3,0.5)
|
||||||
|
.. controls +(0.6,1) and +(-0.6,1) .. ++(4.6,0)
|
||||||
|
-- ++(0.3,-0.5)
|
||||||
|
++(-0.3,0.5) .. controls +(-0.3,0.6) and +(0.3,0.6) .. ++(-4.6,0)
|
||||||
|
%spoiler
|
||||||
|
(1.75,3) -- ++(0,0.75)
|
||||||
|
-- ++(0.05,0)
|
||||||
|
-- ++ (0,-0.78)
|
||||||
|
++(0,0.7) -- ++(1.165,0)
|
||||||
|
++(-1.165,-0.4) -- ++(0.66,0)
|
||||||
|
(7.75,3) -- ++(0,0.75)
|
||||||
|
-- ++(-0.05,0)
|
||||||
|
-- ++ (0,-0.78)
|
||||||
|
++(0,0.7) -- ++(-1.165,0)
|
||||||
|
++(1.165,-0.4) -- ++(-0.66,0)
|
||||||
|
%wheels
|
||||||
|
(1.25,0.5) -- ++(0,-0.2)
|
||||||
|
-- ++(1,0)
|
||||||
|
-- ++(0,0.2)
|
||||||
|
(8.25,0.5) -- ++(0,-0.2)
|
||||||
|
-- ++(-1,0)
|
||||||
|
-- ++(0,0.2);
|
||||||
|
%controller
|
||||||
|
\draw[color=lightgray]
|
||||||
|
(-3.25,4.25) [rounded corners=7.5] -- ++(1.5,0.375)
|
||||||
|
[rounded corners=1.5] .. controls +(-0.75,-0.75) .. ++(-0.375,-1.125)
|
||||||
|
.. controls +(-0.3,-0.45) .. ++(0,-0.75)
|
||||||
|
.. controls +(-0.3,-0.45) .. ++(0,-0.75)
|
||||||
|
[rounded corners=7.5] .. controls +(-0.3,-0.45) .. ++(0.375,-1.5)
|
||||||
|
-- ++(-1.5,0)
|
||||||
|
.. controls +(-0.525,1.8) .. ++(-0.3,3.225)
|
||||||
|
-- cycle
|
||||||
|
[sharp corners] ++(0.5,0.125) -- ++(0,0.6)
|
||||||
|
-- ++(-0.3,-0.075)
|
||||||
|
-- ++(0,0.05)
|
||||||
|
-- ++(0.7,0.175)
|
||||||
|
-- ++(0,-0.05)
|
||||||
|
-- ++(-0.3,-0.075)
|
||||||
|
-- ++(0,-0.6);
|
||||||
|
|
||||||
|
%circuit
|
||||||
|
\draw (-4, -1) node[anchor=east] {$+$}
|
||||||
|
to[open, v=${14.8V}$, voltage=straight, o-o] ++(0,-1)
|
||||||
|
node[anchor=east] {$-$}
|
||||||
|
(-3.5,-1) node[jump crossing](tmpX){}
|
||||||
|
(-3,3.6) to[pR, name=poti, resistors/width=1.5, resistors/zigs=9, l=$\SI{30}{\ohm}$ ] ++(0,-2.1)
|
||||||
|
-- ++(0,-2.5)
|
||||||
|
-- (tmpX.east)
|
||||||
|
(-4,-1) -- (tmpX.west)
|
||||||
|
(-4,-2) to[short, -*] ++(0.5,0)
|
||||||
|
-- (tmpX.south)
|
||||||
|
(tmpX.north) -- (-3.5,3.8)
|
||||||
|
to[short, -*] ++(0.5,0)
|
||||||
|
(poti.wiper) -- (poti.wiper |- 42,-1)
|
||||||
|
-- (3.5,-1)
|
||||||
|
-- ++(0,1.75)
|
||||||
|
to[R=$\SI{6,8}{\ohm}$] ++(0,1.5)
|
||||||
|
to[C=$22nF$, name=cap] ++(2.5,0)
|
||||||
|
to[R=$\SI{6,8}{\ohm}$] ++(0,-1.5)
|
||||||
|
-- ++(0,-2.75)
|
||||||
|
-- ++(-9.5,0)
|
||||||
|
(cap.center) ++(-0.75,0) to[short, *-] ++(0,-1)
|
||||||
|
to[Telmech=M] ++(1.5,0)
|
||||||
|
to[short, -*] ++(0,1);
|
||||||
|
\end{tikzpicture}
|
||||||
|
\end{document}
|
4
schematics/scroip-controller/.gitignore
vendored
Normal file
4
schematics/scroip-controller/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
*.aux
|
||||||
|
*.dvi
|
||||||
|
*.log
|
||||||
|
*.pdf
|
1268
schematics/scroip-controller/scroip.svg
Normal file
1268
schematics/scroip-controller/scroip.svg
Normal file
File diff suppressed because it is too large
Load Diff
After Width: | Height: | Size: 220 KiB |
230
schematics/scroip-controller/scroip.tex
Normal file
230
schematics/scroip-controller/scroip.tex
Normal file
@ -0,0 +1,230 @@
|
|||||||
|
\documentclass[tikz]{standalone}
|
||||||
|
\usepackage{circuitikz}
|
||||||
|
\usepackage{siunitx}
|
||||||
|
|
||||||
|
\begin{document}
|
||||||
|
\begin{tikzpicture}
|
||||||
|
% V_in and 1st R
|
||||||
|
\draw (0,0) node[anchor=south] {$V_{in}$}
|
||||||
|
to[short, o-] (0,-1)
|
||||||
|
to[R=\SI{1}{\ohm}, -*] (0, -3);
|
||||||
|
\foreach \i in {0,1,...,15}
|
||||||
|
{
|
||||||
|
\ifnum \i < 15
|
||||||
|
% next R + connection between them
|
||||||
|
\draw (\i*2,-3) to[short, *-] ++(1,0)
|
||||||
|
-- ++(0,2)
|
||||||
|
-- ++(1,0)
|
||||||
|
to[R=\SI{1}{\ohm}] ++(0, -2);
|
||||||
|
\else
|
||||||
|
\draw (\i*2,-3) to[short, *-] ++(2,0)
|
||||||
|
-- (32,-23);
|
||||||
|
\fi
|
||||||
|
% optocoupler
|
||||||
|
\draw (\i*2,-3) -- ++(0, -1)
|
||||||
|
+(-0.1,0) rectangle +(1.1,-1)
|
||||||
|
(\i*2, -4) -- ++(0,-0.2)
|
||||||
|
node[nigfete, scale=0.3, rotate=90, anchor=D](nigfet1){}
|
||||||
|
(\i*2+1, -4) -- ++(0,-0.2)
|
||||||
|
node[nigfete, xscale=-0.3, yscale=0.3, rotate=90, anchor=D](nigfet2){}
|
||||||
|
(nigfet1.G) -- (nigfet2.G)
|
||||||
|
(nigfet1.S) -- (nigfet2.S)
|
||||||
|
(\i*2, -5) -- ++(0,0.2)
|
||||||
|
to[D*, name=controldiode, diodes/scale=0.25] (\i*2+1, -4.8)
|
||||||
|
-- (\i*2+1, -5);
|
||||||
|
\draw[-{Stealth[scale=0.4]}] (controldiode.n) -- ++(0.05,0.12)
|
||||||
|
-- ++(-0.1,-0.04)
|
||||||
|
-- ++(0.05,0.12);
|
||||||
|
% wires between R and optocoupler
|
||||||
|
\node at (\i*2, -3.5)[jump crossing](X){};
|
||||||
|
\draw (\i*2+1, -4) to[short, -*] ++(0,0.5)
|
||||||
|
-- (X.east)
|
||||||
|
(X.west) -- (\i*2-0.5, -3.5)
|
||||||
|
(\i*2+1, -3.5) -- +(0.5,0);
|
||||||
|
}
|
||||||
|
\draw (31.5,-3.5) -- (31.5,-20.5);
|
||||||
|
% demux
|
||||||
|
\tikzset{demuxl/.style={muxdemux, muxdemux def={Lh=4, Rh=8, NL=1, NB=3, NR=8}}}
|
||||||
|
\draw (6,-5) -- ++(0,-3)
|
||||||
|
node[demuxl, rotate=90, anchor=brpin 4](demux0){\rotatebox{-90}{demux 0}};
|
||||||
|
\tikzset{demuxr/.style={muxdemux, muxdemux def={Lh=4, Rh=8, NL=1, NB=0, NT=3, NR=8}}}
|
||||||
|
\draw (22,-5) -- ++(0,-3)
|
||||||
|
node[demuxr, rotate=90, anchor=brpin 4](demux1){\rotatebox{-90}{demux 1}};
|
||||||
|
\foreach \j in {0,1}
|
||||||
|
{
|
||||||
|
\foreach \i in {1,2,...,8}
|
||||||
|
{
|
||||||
|
\ifnum \i < 4
|
||||||
|
\draw (demux\j.brpin \i) -- ++(0,\i/2)
|
||||||
|
-- (\i*2-2+\j*16,-8+\i/2)
|
||||||
|
-- (\i*2-2+\j*16,-5);
|
||||||
|
\else
|
||||||
|
\ifnum \i > 4
|
||||||
|
\draw (demux\j.brpin \i) -- ++(0,4.5-\i/2)
|
||||||
|
-- (\i*2-2+16*\j,-3.5-\i/2)
|
||||||
|
-- (\i*2-2+16*\j,-5);
|
||||||
|
\fi
|
||||||
|
\fi
|
||||||
|
\draw (\i*2-1+\j*16,-5) -- ++(0, -0.5);
|
||||||
|
|
||||||
|
\pgfmathparse{int(\i + \j)}
|
||||||
|
\ifnum \pgfmathresult < 9
|
||||||
|
\draw (\i*2+\j*16,-5.5) node[jump crossing](tmpX){}
|
||||||
|
(tmpX.west) -- (\i*2-1+\j*16,-5.5)
|
||||||
|
(tmpX.east) to[short, -*] (\i*2+1+\j*16,-5.5);
|
||||||
|
\else
|
||||||
|
\draw (31,-5.5) -- ++(0,-7.5)
|
||||||
|
-- ++(-1,0)
|
||||||
|
-- (30,-19)
|
||||||
|
(31,-13) to[R, l_=$R_1$, *-] ++(0, -2)
|
||||||
|
node[ground]{};
|
||||||
|
\fi
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
\node at (13, 42 |- demux0.bpin 1)[jump crossing](X0_1){};
|
||||||
|
\node at (13.5, 42 |- demux0.bpin 1)[jump crossing](X0_2){};
|
||||||
|
\node at (13.5, 42 |- demux0.bpin 2)[jump crossing](X1_2){};
|
||||||
|
\draw (demux0.bpin 1) -- (X0_1.west)
|
||||||
|
(X0_1.east) -- (X0_2.west)
|
||||||
|
(X0_2.east) -- (demux1.tpin 1)
|
||||||
|
(demux0.bpin 2) -- (X1_2.west)
|
||||||
|
(X1_2.east) -- (demux1.tpin 2)
|
||||||
|
(demux0.bpin 3) -- (demux1.tpin 3);
|
||||||
|
\node at (12.5, -11)[jump crossing](X0_1){};
|
||||||
|
\node at (12.5, -11.5)[jump crossing](X0_2){};
|
||||||
|
\node at (13, -11.5)[jump crossing](X1_2){};
|
||||||
|
\draw (11, -10.5) to[short, -*] (12.5, -10.5)
|
||||||
|
(11, -11) -- (X0_1.west)
|
||||||
|
(X0_1.east) to[short, -*] (13, -11)
|
||||||
|
(11, -11.5) -- (X0_2.west)
|
||||||
|
(X0_2.east) -- (X1_2.west)
|
||||||
|
(X1_2.east) to[short, -*] (13.5, -11.5);
|
||||||
|
|
||||||
|
\foreach \i in {1,2,3}
|
||||||
|
{
|
||||||
|
\draw (demux0.lpin 1 |- 42,-10-\i/2) node[jump crossing](tmpX){}
|
||||||
|
(12+\i/2, 42 |- demux0.bpin \i) to[short, *-] (12+\i/2,-10-\i/2)
|
||||||
|
(11, -10-\i/2) -- (tmpX.east);
|
||||||
|
\pgfmathparse{int(\i-1)};
|
||||||
|
\draw (tmpX.west) to[short, -o] (-0.5,-10-\i/2)
|
||||||
|
node[anchor=east] {$A_\pgfmathresult$};
|
||||||
|
}
|
||||||
|
|
||||||
|
\draw (demux0.lpin 1) -- (demux0.lpin 1 |- 42, -12)
|
||||||
|
to[short, -o] (-0.5,-12)
|
||||||
|
node[anchor=east] {$S_0$};
|
||||||
|
\node at (12.5, -12.5)[jump crossing](X0){};
|
||||||
|
\node at (13, -12.5)[jump crossing](X1){};
|
||||||
|
\node at (13.5, -12.5)[jump crossing](X2){};
|
||||||
|
\draw (demux1.lpin 1) -- (demux1.lpin 1 |- 42, -12.5)
|
||||||
|
-- (X2.east)
|
||||||
|
(X2.west) -- (X1.east)
|
||||||
|
(X1.west) -- (X0.east)
|
||||||
|
(X0.west) to[short, -o] (-0.5,-12.5)
|
||||||
|
node[anchor=east] {$S_1$};
|
||||||
|
\node at (12.5, -13)[jump crossing](X0){};
|
||||||
|
\node at (13, -13)[jump crossing](X1){};
|
||||||
|
\node at (13.5, -13)[jump crossing](X2){};
|
||||||
|
\draw (25, -16) node[demuxl, rotate=-90, anchor=brpin 4](demux2){\rotatebox{90}{demux 2}};
|
||||||
|
\draw (-0.5,-13) node[anchor=east] {$S_2$}
|
||||||
|
to[short, o-] (X0.west)
|
||||||
|
(X0.east) -- (X1.west)
|
||||||
|
(X1.east) -- (X2.west)
|
||||||
|
(X2.east) -- (demux2.lpin 1 |- 42, -13)
|
||||||
|
-- (demux2.lpin 1);
|
||||||
|
\draw (9, -16) node[demuxr, rotate=-90, anchor=brpin 4](demux3){\rotatebox{90}{demux 3}};
|
||||||
|
\draw (-0.5,-13.5) node[anchor=east] {$S_3$}
|
||||||
|
to[short, o-] (demux3.lpin 1 |- 42,-13.5)
|
||||||
|
-- (demux3.lpin 1);
|
||||||
|
|
||||||
|
\node at (13, 42 |- demux2.bpin 1)[jump crossing](X0_1){};
|
||||||
|
\node at (13.5, 42 |- demux2.bpin 1)[jump crossing](X0_2){};
|
||||||
|
\node at (13.5, 42 |- demux2.bpin 2)[jump crossing](X1_2){};
|
||||||
|
\draw (demux3.tpin 1) -- (X0_1.west)
|
||||||
|
(X0_1.east) -- (X0_2.west)
|
||||||
|
(X0_2.east) -- (demux2.bpin 1)
|
||||||
|
(demux3.tpin 2) -- (X1_2.west)
|
||||||
|
(X1_2.east) -- (demux2.bpin 2)
|
||||||
|
(demux3.tpin 3) -- (demux2.bpin 3)
|
||||||
|
(12.5, 42 |- demux2.bpin 1) to[short, *-] (12.5, -10.5)
|
||||||
|
(13, 42 |- demux2.bpin 2) to[short, *-] (13, -11)
|
||||||
|
(13.5, 42 |- demux2.bpin 3) to[short, *-] (13.5, -11.5);
|
||||||
|
|
||||||
|
\foreach \i in {0,1,...,15}
|
||||||
|
{
|
||||||
|
\node at (31 - \i*2, -20.5)[jump crossing](X){};
|
||||||
|
\draw (32 - \i*2,-23) -- ++(-1,0)
|
||||||
|
to[R=\SI{1}{\ohm}, -] ++(0, 2)
|
||||||
|
-- ++(0,1)
|
||||||
|
++(-1,-0.5) -- (X.west)
|
||||||
|
(X.east) -- (31.5 - \i*2, -20.5);
|
||||||
|
\ifnum \i < 15
|
||||||
|
\draw (30 - \i*2,-23) -- ++(0,2)
|
||||||
|
to[short, -*] ++(1,0)
|
||||||
|
(30 - \i*2,-20) to[short, -*] ++(0,-0.5)
|
||||||
|
(30 - \i*2, -20.5) -- ++(-0.5,0);
|
||||||
|
\else
|
||||||
|
\draw (30 - \i*2,-20) -- ++(0,-0.5);
|
||||||
|
\fi
|
||||||
|
% optocoupler
|
||||||
|
\draw (31.1 - \i*2,-20) rectangle +(-1.2,1)
|
||||||
|
++(-0.1,0) -- ++(0,0.2)
|
||||||
|
node[nigfete, scale=-0.3, rotate=90, anchor=D](nigfet1){}
|
||||||
|
(31 - 1 - \i*2,-20) -- ++(0,0.2)
|
||||||
|
node[nigfete, xscale=0.3, yscale=-0.3, rotate=90, anchor=D](nigfet2){}
|
||||||
|
(nigfet1.G) -- (nigfet2.G)
|
||||||
|
(nigfet1.S) -- (nigfet2.S)
|
||||||
|
(31 - \i*2,-19) -- ++(0, -0.2)
|
||||||
|
to[D*, name=controldiode, diodes/scale=0.25] ++(-1,0)
|
||||||
|
-- ++(0,0.2);
|
||||||
|
\draw[-{Stealth[scale=0.4]}] (controldiode.n) -- ++(-0.05,-0.12)
|
||||||
|
-- ++(0.1,0.04)
|
||||||
|
-- ++(-0.05,-0.12);
|
||||||
|
|
||||||
|
\ifnum \i > 0
|
||||||
|
\node at (31 - \i*2,-18.5)[jump crossing](X){};
|
||||||
|
\draw (X.west) -- (30 - \i*2,-18.5)
|
||||||
|
(X.east) -- (32 - \i*2,-18.5);
|
||||||
|
\fi
|
||||||
|
\ifnum \i < 15
|
||||||
|
\draw (30 - \i*2,-19) to[short, -*] ++(0,0.5);
|
||||||
|
\else
|
||||||
|
\draw (30 - \i*2,-19) -- ++(0,0.5);
|
||||||
|
\fi
|
||||||
|
}
|
||||||
|
|
||||||
|
\foreach \j in {2,3}
|
||||||
|
{
|
||||||
|
\foreach \i in {1,2,...,8}
|
||||||
|
{
|
||||||
|
\ifnum \i < 4
|
||||||
|
\pgfmathparse{\i==1 && \j==2?int(1):int(0)}
|
||||||
|
\ifnum \pgfmathresult = 1
|
||||||
|
\draw (30,-16.5) node[jump crossing](tmpX){}
|
||||||
|
(demux2.brpin 1) -- ++(0,-\i/2)
|
||||||
|
-- (tmpX.west)
|
||||||
|
(tmpX.east) -- (65-16*\j-2*\i, -16-\i/2)
|
||||||
|
-- (65-16*\j-2*\i, -19);
|
||||||
|
\else
|
||||||
|
\draw (demux\j.brpin \i) -- ++(0,-\i/2)
|
||||||
|
-- (65-16*\j-2*\i, -16-\i/2)
|
||||||
|
-- (65-16*\j-2*\i, -19);
|
||||||
|
\fi
|
||||||
|
\else
|
||||||
|
\ifnum \i > 4
|
||||||
|
\draw (demux\j.brpin \i) -- ++(0,-4.5+\i/2)
|
||||||
|
-- (65-16*\j-2*\i, -20.5+\i/2)
|
||||||
|
-- (65-16*\j-2*\i, -19);
|
||||||
|
\else
|
||||||
|
\draw (demux\j.brpin 4) -- (57-16*\j, -19);
|
||||||
|
\fi
|
||||||
|
\fi
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\draw (-1,0) node[anchor=south] {$V_{out}$}
|
||||||
|
to[short, o-] ++(0,-3.5)
|
||||||
|
-- ++(0.5,0);
|
||||||
|
|
||||||
|
\end{tikzpicture}
|
||||||
|
\end{document}
|
268
server.py
Normal file
268
server.py
Normal file
@ -0,0 +1,268 @@
|
|||||||
|
from argparse import ArgumentParser, Namespace
|
||||||
|
from configparser import ConfigParser
|
||||||
|
from math import ceil
|
||||||
|
from RPi import GPIO
|
||||||
|
from socket import AF_INET6, timeout
|
||||||
|
from socketserver import BaseRequestHandler, TCPServer
|
||||||
|
from time import clock_gettime_ns, CLOCK_REALTIME
|
||||||
|
|
||||||
|
|
||||||
|
class SCRoIPRequestHandler(BaseRequestHandler):
|
||||||
|
"""
|
||||||
|
Request handler for the Slot Car Racing over IP server
|
||||||
|
"""
|
||||||
|
def setup(self):
|
||||||
|
self.request.settimeout(0.1)
|
||||||
|
|
||||||
|
def handle(self):
|
||||||
|
self.data = b'init'
|
||||||
|
self.last = clock_gettime_ns(CLOCK_REALTIME)
|
||||||
|
self.traffic_counter = 0
|
||||||
|
|
||||||
|
while self.data != b'':
|
||||||
|
try:
|
||||||
|
self.data = self.request.recv(4096)
|
||||||
|
self.traffic_counter += len(self.data)
|
||||||
|
except (TimeoutError, timeout):
|
||||||
|
pass
|
||||||
|
|
||||||
|
time = clock_gettime_ns(CLOCK_REALTIME)
|
||||||
|
diff = time - self.last
|
||||||
|
if (diff > 100000000):
|
||||||
|
self.last = time
|
||||||
|
traffic: float = self.traffic_counter / diff * 1000000000
|
||||||
|
print(f"{traffic} Bytes/s")
|
||||||
|
self.server.set_throttle(traffic)
|
||||||
|
self.server.apply_throttle()
|
||||||
|
self.traffic_counter = 0
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
class SCRoIPServer(TCPServer):
|
||||||
|
"""
|
||||||
|
A TCP server that supports both IPv6 and IPv4 and holds config parameters for the SCRoIPRequestHandler
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self,
|
||||||
|
address: str,
|
||||||
|
port: int,
|
||||||
|
legacy: bool,
|
||||||
|
thresholds: dict,
|
||||||
|
pinconfig: dict):
|
||||||
|
if not legacy:
|
||||||
|
self.address_family = AF_INET6
|
||||||
|
super(SCRoIPServer, self).__init__((address, port), SCRoIPRequestHandler)
|
||||||
|
self.thresholds: dict = thresholds
|
||||||
|
self.pinconfig: dict = pinconfig
|
||||||
|
self.throttle: int = 0
|
||||||
|
GPIO.setmode(GPIO.BCM)
|
||||||
|
for pin in pinconfig.values():
|
||||||
|
GPIO.setup(pin, GPIO.OUT)
|
||||||
|
GPIO.output(pin, False)
|
||||||
|
|
||||||
|
def set_throttle(self,
|
||||||
|
traffic: float) -> int:
|
||||||
|
throttle: int = ceil((traffic - self.thresholds['min']) / self.thresholds['step'])
|
||||||
|
if throttle < 0 or (throttle > 32 and self.thresholds['stop']):
|
||||||
|
throttle = 0
|
||||||
|
elif throttle > 32:
|
||||||
|
throttle = 32
|
||||||
|
self.throttle = throttle
|
||||||
|
return throttle
|
||||||
|
|
||||||
|
def apply_throttle(self) -> None:
|
||||||
|
pins: dict = {'a0': False,
|
||||||
|
'a1': False,
|
||||||
|
'a2': False,
|
||||||
|
's0': False,
|
||||||
|
's1': False,
|
||||||
|
's2': False,
|
||||||
|
's3': False}
|
||||||
|
|
||||||
|
if self.throttle > 0:
|
||||||
|
if (self.throttle - 1) % 2 == 0:
|
||||||
|
pins['a0'] = True
|
||||||
|
if (self.throttle - 1) % 4 < 2:
|
||||||
|
pins['a1'] = True
|
||||||
|
if (self.throttle - 1) % 8 < 4:
|
||||||
|
pins['a2'] = True
|
||||||
|
if self.throttle > 24:
|
||||||
|
pins['s0'] = True
|
||||||
|
elif self.throttle > 16:
|
||||||
|
pins['s1'] = True
|
||||||
|
elif self.throttle > 8:
|
||||||
|
pins['s2'] = True
|
||||||
|
else:
|
||||||
|
pins['s3'] = True
|
||||||
|
|
||||||
|
for pin in pins.keys():
|
||||||
|
GPIO.output(self.pinconfig[pin], pins[pin])
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
# UI Helper Functions
|
||||||
|
|
||||||
|
def get_argparser() -> ArgumentParser:
|
||||||
|
"""
|
||||||
|
Initialize a parser to parse the argumets with which the programm has been invoced with and return it
|
||||||
|
"""
|
||||||
|
parser: ArgumentParser = ArgumentParser(prog='scroipserver',
|
||||||
|
description='run a Slot Car Racing over IP (SCRoIP) server')
|
||||||
|
group = parser.add_mutually_exclusive_group(required=False)
|
||||||
|
group.add_argument('-4', '--v4-host',
|
||||||
|
action='store',
|
||||||
|
type=str,
|
||||||
|
help='host name or IPv4 address')
|
||||||
|
group.add_argument('-6', '--v6-host',
|
||||||
|
action='store',
|
||||||
|
type=str,
|
||||||
|
help='host name or IPv6 address')
|
||||||
|
parser.add_argument('-p', '--port',
|
||||||
|
action='store',
|
||||||
|
type=int,
|
||||||
|
metavar='PORT',
|
||||||
|
help='TCP port to listen to')
|
||||||
|
parser.add_argument('config',
|
||||||
|
action='store',
|
||||||
|
type=str,
|
||||||
|
help='path to the configuration file')
|
||||||
|
return parser
|
||||||
|
|
||||||
|
def get_config(args: Namespace) -> dict:
|
||||||
|
"""
|
||||||
|
read the config file,
|
||||||
|
merge its contents with what was specified as command line parameters
|
||||||
|
and return the configuration as a dict;
|
||||||
|
Raise an exeption if invalid parameters were specified;
|
||||||
|
|
||||||
|
values from args overwrite values from the config file
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
with open(args.config, 'r') as f:
|
||||||
|
configfile: ConfigParser = ConfigParser()
|
||||||
|
configfile.read_file(f)
|
||||||
|
except:
|
||||||
|
raise Exception(f"error: {args.config} could not be opened")
|
||||||
|
|
||||||
|
config: dict = {'network':{},
|
||||||
|
'pins':{},
|
||||||
|
'thresholds':{}}
|
||||||
|
|
||||||
|
# get ip address
|
||||||
|
if args.v6_host:
|
||||||
|
config['network']['legacy'] = False
|
||||||
|
config['network']['ip_address'] = args.v6_host
|
||||||
|
elif args.v4_host:
|
||||||
|
config['network']['legacy'] = True
|
||||||
|
config['network']['ip_address'] = args.v4_host
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
legacy: bool = configfile.getboolean('network', 'legacy', fallback=None)
|
||||||
|
v4: str = configfile.get('network', 'v4_host', fallback=None)
|
||||||
|
v6: str = configfile.get('network', 'v6_host', fallback=None)
|
||||||
|
except:
|
||||||
|
raise Exception('error: invalid values in config file')
|
||||||
|
if legacy is True:
|
||||||
|
if v4 is not None:
|
||||||
|
config['network']['legacy'] = True
|
||||||
|
config['network']['ip_address'] = v4
|
||||||
|
else:
|
||||||
|
raise Exception('error: legacy is set to True but no v4_host was specified')
|
||||||
|
elif legacy is False:
|
||||||
|
if v6 is not None:
|
||||||
|
config['network']['legacy'] = False
|
||||||
|
config['network']['ip_address'] = v6
|
||||||
|
else:
|
||||||
|
raise Exception('error: legacy is set to False but no v6_host was specified')
|
||||||
|
else: #legacy is None
|
||||||
|
if v4 is not None and v6 is not None:
|
||||||
|
raise Exception('error: legacy is not set')
|
||||||
|
elif v4 is not None:
|
||||||
|
config['network']['legacy'] = True
|
||||||
|
config['network']['ip_address'] = v4
|
||||||
|
elif v6 is not None:
|
||||||
|
config['network']['legacy'] = False
|
||||||
|
config['network']['ip_address'] = v6
|
||||||
|
else:
|
||||||
|
raise Exception('error: no ip adress was specified')
|
||||||
|
|
||||||
|
#get port
|
||||||
|
if args.port:
|
||||||
|
port: int = args.port
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
port: int = configfile.getint('network', 'port', fallback=None)
|
||||||
|
except:
|
||||||
|
raise Exception('error: invalid values in config file')
|
||||||
|
if port is None:
|
||||||
|
raise Exception('error: no port was specified')
|
||||||
|
if not port in range(0, 65535):
|
||||||
|
raise Exception('error: invalid port number')
|
||||||
|
else:
|
||||||
|
config['network']['port'] = port
|
||||||
|
|
||||||
|
#get thresholds
|
||||||
|
try:
|
||||||
|
min: int = configfile.getint('thresholds', 'min', fallback=None)
|
||||||
|
max: int = configfile.getint('thresholds', 'max', fallback=None)
|
||||||
|
stop: bool = configfile.get('thresholds', 'stop_when_exceeded', fallback=None)
|
||||||
|
except:
|
||||||
|
raise Exception('error: invalid thresholds config')
|
||||||
|
if min > max:
|
||||||
|
raise Exception('error: min threshold is greater than max threshold')
|
||||||
|
else:
|
||||||
|
config['thresholds']['min'] = min
|
||||||
|
config['thresholds']['max'] = max
|
||||||
|
config['thresholds']['stop'] = stop
|
||||||
|
config['thresholds']['step'] = (max - min) / 32
|
||||||
|
|
||||||
|
#get pin map
|
||||||
|
try:
|
||||||
|
a0: int = configfile.getint('pins', 'a0', fallback=None)
|
||||||
|
a1: int = configfile.getint('pins', 'a1', fallback=None)
|
||||||
|
a2: int = configfile.getint('pins', 'a2', fallback=None)
|
||||||
|
s0: int = configfile.getint('pins', 's0', fallback=None)
|
||||||
|
s1: int = configfile.getint('pins', 's1', fallback=None)
|
||||||
|
s2: int = configfile.getint('pins', 's2', fallback=None)
|
||||||
|
s3: int = configfile.getint('pins', 's3', fallback=None)
|
||||||
|
except:
|
||||||
|
raise Exception('error: could not read pin configuration')
|
||||||
|
for pin in [a0, a1, a2, s0, s1, s2, s3]:
|
||||||
|
if pin not in range(1, 28):
|
||||||
|
raise Exception('error: invalid gpio pin number specified')
|
||||||
|
config['pins']['a0'] = a0
|
||||||
|
config['pins']['a1'] = a1
|
||||||
|
config['pins']['a2'] = a2
|
||||||
|
config['pins']['s0'] = s0
|
||||||
|
config['pins']['s1'] = s1
|
||||||
|
config['pins']['s2'] = s2
|
||||||
|
config['pins']['s3'] = s3
|
||||||
|
|
||||||
|
return config
|
||||||
|
|
||||||
|
# Main
|
||||||
|
if __name__ == '__main__':
|
||||||
|
parser: ArgumentParser = get_argparser()
|
||||||
|
args: Namespace = parser.parse_args()
|
||||||
|
|
||||||
|
try:
|
||||||
|
config: dict = get_config(args)
|
||||||
|
except Exception as error:
|
||||||
|
parser.print_usage()
|
||||||
|
print(error)
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
try:
|
||||||
|
with SCRoIPServer(config['network']['ip_address'],
|
||||||
|
config['network']['port'],
|
||||||
|
config['network']['legacy'],
|
||||||
|
config['thresholds'],
|
||||||
|
config['pins']) as server:
|
||||||
|
try:
|
||||||
|
server.serve_forever()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print('\nexiting...')
|
||||||
|
server.shutdown()
|
||||||
|
GPIO.cleanup()
|
||||||
|
except:
|
||||||
|
print('error: server could not be started')
|
Loading…
Reference in New Issue
Block a user