ソースを参照

add trackball page

Thomas Buck 1年前
コミット
2a7098e9a5
100個のファイルの変更586行の追加27行の削除
  1. 1
    0
      input/blog/2015/2015_12_20_serialgamepad.md
  2. 1
    0
      input/blog/2016/2016_07_24_usb_host_cppm.md
  3. 1
    0
      input/blog/2022/2022_11_28_ergodox_repair.md
  4. 18
    0
      input/projects/input_devices.md
  5. 484
    0
      input/projects/input_devices/trackball_v1.md
  6. 28
    27
      input/texts/tex_beetle.md
  7. 12
    0
      macros.py
  8. 41
    0
      static/css/style.css
  9. バイナリ
      static/img/pi_pico_pinout.png
  10. バイナリ
      static/img/pi_pico_pinout_small.png
  11. バイナリ
      static/img/pmw3360_breakout_1.jpg
  12. バイナリ
      static/img/pmw3360_breakout_1_small.jpg
  13. バイナリ
      static/img/pmw3360_breakout_2.jpg
  14. バイナリ
      static/img/pmw3360_breakout_2_small.jpg
  15. バイナリ
      static/img/pmw3360_breakout_3.jpg
  16. バイナリ
      static/img/pmw3360_breakout_3_small.jpg
  17. バイナリ
      static/img/pmw3360_data_orange.png
  18. バイナリ
      static/img/pmw3360_data_orange_small.png
  19. バイナリ
      static/img/pmw3360_data_white.png
  20. バイナリ
      static/img/pmw3360_data_white_small.png
  21. バイナリ
      static/img/pmw3360_datasheet_1.png
  22. バイナリ
      static/img/pmw3360_datasheet_1_small.png
  23. バイナリ
      static/img/pmw3360_datasheet_2.png
  24. バイナリ
      static/img/pmw3360_datasheet_2_small.png
  25. バイナリ
      static/img/pmw3360_dimensions_1.png
  26. バイナリ
      static/img/pmw3360_dimensions_1_small.png
  27. バイナリ
      static/img/pmw3360_dimensions_2.png
  28. バイナリ
      static/img/pmw3360_dimensions_2_small.png
  29. バイナリ
      static/img/pmw3360_dimensions_3.png
  30. バイナリ
      static/img/pmw3360_dimensions_3_small.png
  31. バイナリ
      static/img/pmw3360_dimensions_4.png
  32. バイナリ
      static/img/pmw3360_dimensions_4_small.png
  33. バイナリ
      static/img/pmw3360_dimensions_5.png
  34. バイナリ
      static/img/pmw3360_dimensions_5_small.png
  35. バイナリ
      static/img/pmw3360_dimensions_6.png
  36. バイナリ
      static/img/pmw3360_dimensions_6_small.png
  37. バイナリ
      static/img/pmw3360_frames.png
  38. バイナリ
      static/img/pmw3360_frames_small.png
  39. バイナリ
      static/img/pmw3360_order.png
  40. バイナリ
      static/img/pmw3360_order_small.png
  41. バイナリ
      static/img/trackball_scad_1.png
  42. バイナリ
      static/img/trackball_scad_1_small.png
  43. バイナリ
      static/img/trackball_scad_2.png
  44. バイナリ
      static/img/trackball_scad_2_small.png
  45. バイナリ
      static/img/trackball_v1_1.jpg
  46. バイナリ
      static/img/trackball_v1_10.jpg
  47. バイナリ
      static/img/trackball_v1_10_small.jpg
  48. バイナリ
      static/img/trackball_v1_11.jpg
  49. バイナリ
      static/img/trackball_v1_11_small.jpg
  50. バイナリ
      static/img/trackball_v1_12.jpg
  51. バイナリ
      static/img/trackball_v1_12_small.jpg
  52. バイナリ
      static/img/trackball_v1_13.jpg
  53. バイナリ
      static/img/trackball_v1_13_small.jpg
  54. バイナリ
      static/img/trackball_v1_14.jpg
  55. バイナリ
      static/img/trackball_v1_14_small.jpg
  56. バイナリ
      static/img/trackball_v1_15.jpg
  57. バイナリ
      static/img/trackball_v1_15_small.jpg
  58. バイナリ
      static/img/trackball_v1_16.jpg
  59. バイナリ
      static/img/trackball_v1_16_small.jpg
  60. バイナリ
      static/img/trackball_v1_17.jpg
  61. バイナリ
      static/img/trackball_v1_17_small.jpg
  62. バイナリ
      static/img/trackball_v1_18.jpg
  63. バイナリ
      static/img/trackball_v1_18_small.jpg
  64. バイナリ
      static/img/trackball_v1_19.jpg
  65. バイナリ
      static/img/trackball_v1_19_small.jpg
  66. バイナリ
      static/img/trackball_v1_1_small.jpg
  67. バイナリ
      static/img/trackball_v1_2.jpg
  68. バイナリ
      static/img/trackball_v1_20.jpg
  69. バイナリ
      static/img/trackball_v1_20_small.jpg
  70. バイナリ
      static/img/trackball_v1_21.jpg
  71. バイナリ
      static/img/trackball_v1_21_small.jpg
  72. バイナリ
      static/img/trackball_v1_22.jpg
  73. バイナリ
      static/img/trackball_v1_22_small.jpg
  74. バイナリ
      static/img/trackball_v1_23.jpg
  75. バイナリ
      static/img/trackball_v1_23_small.jpg
  76. バイナリ
      static/img/trackball_v1_24.jpg
  77. バイナリ
      static/img/trackball_v1_24_small.jpg
  78. バイナリ
      static/img/trackball_v1_25.jpg
  79. バイナリ
      static/img/trackball_v1_25_small.jpg
  80. バイナリ
      static/img/trackball_v1_26.jpg
  81. バイナリ
      static/img/trackball_v1_26_small.jpg
  82. バイナリ
      static/img/trackball_v1_27.jpg
  83. バイナリ
      static/img/trackball_v1_27_small.jpg
  84. バイナリ
      static/img/trackball_v1_28.jpg
  85. バイナリ
      static/img/trackball_v1_28_small.jpg
  86. バイナリ
      static/img/trackball_v1_29.jpg
  87. バイナリ
      static/img/trackball_v1_29_small.jpg
  88. バイナリ
      static/img/trackball_v1_2_small.jpg
  89. バイナリ
      static/img/trackball_v1_3.jpg
  90. バイナリ
      static/img/trackball_v1_30.jpg
  91. バイナリ
      static/img/trackball_v1_30_small.jpg
  92. バイナリ
      static/img/trackball_v1_31.jpg
  93. バイナリ
      static/img/trackball_v1_31_small.jpg
  94. バイナリ
      static/img/trackball_v1_32.jpg
  95. バイナリ
      static/img/trackball_v1_32_small.jpg
  96. バイナリ
      static/img/trackball_v1_33.jpg
  97. バイナリ
      static/img/trackball_v1_33_small.jpg
  98. バイナリ
      static/img/trackball_v1_3_small.jpg
  99. バイナリ
      static/img/trackball_v1_4.jpg
  100. 0
    0
      static/img/trackball_v1_4_small.jpg

+ 1
- 0
input/blog/2015/2015_12_20_serialgamepad.md ファイルの表示

@@ -7,6 +7,7 @@ flattr: true
7 7
 github: https://github.com/xythobuz/SerialGamepad
8 8
 parent: projects
9 9
 show_in_quadcopters: true
10
+show_in_input_devices: true
10 11
 position: 50
11 12
 ---
12 13
 

+ 1
- 0
input/blog/2016/2016_07_24_usb_host_cppm.md ファイルの表示

@@ -7,6 +7,7 @@ flattr: true
7 7
 github: https://github.com/xythobuz/Saitek-X52-PPM
8 8
 parent: projects
9 9
 show_in_quadcopters: true
10
+show_in_input_devices: true
10 11
 position: 80
11 12
 ---
12 13
 

+ 1
- 0
input/blog/2022/2022_11_28_ergodox_repair.md ファイルの表示

@@ -3,6 +3,7 @@ post: Ergodox Infinity Repair
3 3
 description: Kit-built open-source split ergonomic keyboard
4 4
 date: 2022-11-28
5 5
 comments: true
6
+show_in_input_devices: true
6 7
 ---
7 8
 
8 9
 It occurs to me that I never really wrote about my [Ergodox Infinity](https://deskthority.net/wiki/Infinity_ErgoDox) keyboard on here.

+ 18
- 0
input/projects/input_devices.md ファイルの表示

@@ -0,0 +1,18 @@
1
+title: Input Devices
2
+description: Mechanical Keyboards and other Human-Machine-Interfaces
3
+parent: projects
4
+position: 15
5
+---
6
+
7
+One of the recurring topics in my projects are different kind of input devices.
8
+Here you can find all pages in this category.
9
+
10
+<!--%
11
+printInputDevicesMenu()
12
+%-->
13
+
14
+The following pages are also related to this topic.
15
+
16
+<!--%
17
+printInputDevicesRelatedMenu()
18
+%-->

+ 484
- 0
input/projects/input_devices/trackball_v1.md ファイルの表示

@@ -0,0 +1,484 @@
1
+title: Trackball
2
+description: 3D printed mouse replacement with Raspberry Pi Pico and PMW3360
3
+parent: input_devices
4
+git: https://git.xythobuz.de/thomas/Trackball
5
+github: https://github.com/xythobuz/Trackball
6
+date: 2023-02-12
7
+comments: true
8
+---
9
+
10
+<!--% backToParent() %-->
11
+
12
+For some years I have been using Trackballs from Logitech, first the [M570](https://amzn.to/3XhSuRO) and then the [MX Ergo](https://amzn.to/3xdp3pd).
13
+But of course we could also build our own!
14
+
15
+So because [Philipp](https://www.phschoen.de/) and I were already looking into building a keyboard with a trackball included, I decided to first get my feet wet by building a stand-alone version.
16
+
17
+<!--%
18
+lightgallery([
19
+    [ "img/trackball_v1_27.jpg", "Front of second version" ],
20
+    [ "img/trackball_v1_33.jpg", "Inside view of second version" ],
21
+    [ "img/trackball_v1_12.jpg", "First completed Trackball" ],
22
+])
23
+%-->
24
+
25
+It's made with a PMW3360 optical mouse sensor and a Raspberry Pi Pico.
26
+The case is 3D printed and was designed in OpenSCAD.
27
+
28
+<!--%
29
+lightgallery([
30
+    [ "img/trackball_scad_2.png", "Explosion drawing of assembled parts" ],
31
+    [ "img/trackball_scad_1.png", "Close up view of lens distancing and roller holder" ],
32
+])
33
+%-->
34
+
35
+As usual the project is released as free and open-source software / hardware.
36
+You can find everything you need to build it yourself in [the git repository](https://git.xythobuz.de/thomas/Trackball)!
37
+
38
+### Table Of Contents
39
+
40
+ * [Part Selection](trackball_v1.html#part_selection)
41
+ * [3D Design](trackball_v1.html#3d_design)
42
+ * [Firmware Development](trackball_v1.html#firmware_devel)
43
+ * [Wiring](trackball_v1.html#wiring)
44
+ * [Sensor Problems](trackball_v1.html#sensor_problems)
45
+ * [First Prototype](trackball_v1.html#first_prototype)
46
+ * [Improvements](trackball_v1.html#improvements)
47
+ * [User Experience](trackball_v1.html#user_experience)
48
+ * [License](trackball_v1.html#license)
49
+ * [More Pictures](trackball_v1.html#more_pictures)
50
+
51
+## Part Selection
52
+<a class="anchor" name="part_selection"></a>
53
+
54
+Before embarking on this project some decisions and orders had to be made.
55
+
56
+To control everything I decided to go with the [Raspberry Pi Pico](https://www.raspberrypi.com/products/raspberry-pi-pico/) / [RP2040](https://www.raspberrypi.com/products/rp2040/) microcontroller board.
57
+It is the hot new thing on the block and I wanted to try out both the hardware and the SDK.
58
+It's also used extensively in the DIY keyboard community and already has great support in lots of open source software.
59
+
60
+Another big question was which mouse sensor to use.
61
+There are different types of sensor, either "optical" using an IR LED, or "laser".
62
+Common choices for DIY projects are the [PMW3360](https://www.tindie.com/products/jkicklighter/pmw3360-motion-sensor/) or [PMW3389](https://www.tindie.com/products/jkicklighter/pmw3389-motion-sensor/) optical sensors, or the [ADNS-9800](https://www.tindie.com/products/jkicklighter/adns-9800-laser-motion-sensor/) laser sensor.
63
+All of them are available on breakout boards from JACK Enterprises on Tindie.
64
+Unfortunately the shipping costs to Europe are very high, so I had to find another solution.
65
+
66
+Apparently the requirements for trackballs are not as high as for gaming mouses, they are normally used with much lower resolutions.
67
+Because of this, and also because of price and availability, I decided to go for the PMW3360.
68
+The chip can be bought on [AliExpress](https://www.aliexpress.com/w/wholesale-pmw3360.html), including the lens assembly, for around 15€.
69
+
70
+To properly use it also requires some kind of breakout board with a voltage regulator, as the sensor needs ~2V supply voltage.
71
+Fortunately the IOs can be used with 3.3V devices like the RP2040.
72
+Many designs can be found [on GitHub](https://github.com/search?q=pmw3360), like ["Ogen" from JeremyBois](https://github.com/JeremyBois/Ogen) or ["PMW3360" from kbjunky](https://github.com/kbjunky/PMW3360).
73
+
74
+I decided to go with ["pmw3360-breakout" by jfedor2](https://github.com/jfedor2/pmw3360-breakout).
75
+It is the most minimalistic and it also includes all required files to get the board pre-assembled from [JLCPCB](https://jlcpcb.com/).
76
+With their usual promo I got 5 boards produced and assembled for just 15.65€, including shipping.
77
+This is unbelievable to me.
78
+
79
+<!--%
80
+lightgallery([
81
+    [ "img/pmw3360_order.png", "Screenshot of JLCPCB order" ],
82
+    [ "img/pmw3360_breakout_3.jpg", "Top of PMW3360 breakout board" ],
83
+    [ "img/pmw3360_breakout_2.jpg", "Bottom of PMW3360 breakout board, with lens" ],
84
+])
85
+%-->
86
+
87
+To be able to call this a trackball, we also need some kind of ball or sphere of course.
88
+Many people go with the smallest regulation billard balls with a diameter of 38mm.
89
+These can be sourced relatively easily and are usualy flat enough, so I got some.
90
+This turned out to be a bit of a problem, however, more on that later.
91
+
92
+<!--%
93
+lightgallery([
94
+    [ "img/trackball_v1_16.jpg", "Small billard balls, case" ],
95
+    [ "img/trackball_v1_17.jpg", "Small billard balls" ],
96
+])
97
+%-->
98
+
99
+To get the ball rolling smoothly we also need some kind of mount or bearing surface.
100
+There are different options for this, nicely detailed on [Reddit](https://www.reddit.com/r/ErgoMechKeyboards/comments/yyu4ra/trackball_bearings_a_comparison_of_cheap_rollers/) and [GitHub](https://github.com/Wimads/Trackball-mousekeys-add-on-for-Skeletyl) by "Wimads".
101
+Because of this I decided to go with Si3N4 static bearing balls with a diameter of 3mm.
102
+I got 20 [from eBay](https://www.ebay.de/itm/304376943632?var=603428120198) for ~5€.
103
+
104
+For the switches I decided to go with Cherry MX keyboard switches, simply because I had them available.
105
+They are not optimal with their long key travel, I plan to change it in the future, but you also kinda get used to them.
106
+
107
+<!--%
108
+tableHelper([ "align-right", "align-right", "align-last-right", "align-right monospaced"],
109
+    [ "Part", "Count", "Description", "Cost" ], [
110
+        [ "µC", "1x", ("Raspberry Pi Pico", "https://www.raspberrypi.com/products/raspberry-pi-pico/"), "4.10€" ],
111
+        [ "Sensor", "1x", ("PMW3360 (chip and lens)", "https://www.aliexpress.com/item/4000904265601.html"), "11.83€" ],
112
+        [ "PCB", "1x", ("PMW3360 Breakout Board", "https://github.com/jfedor2/pmw3360-breakout"), "3.13€" ],
113
+        [ "Ball", "1x", ("38mm billard ball", "https://www.ebay.de/itm/222457101403"), "1.37€" ],
114
+        [ "Bearing", "3x", ("Si3N4 3mm sphere", "https://www.ebay.de/itm/304376943632?var=603428120198"), "0.72€" ],
115
+        [ "Switch", "4x", ("Cherry MX compatible", "https://www.aliexpress.com/item/1005003803920093.html"), "1.03€" ],
116
+        [ "Keycap", "4x", "From old keycap set", "0.00€" ],
117
+        [ "Insert", "4x", "M3 od=5mm l=6mm", "0.00€" ],
118
+        [ "Screw", "4x", "M3 l=8mm", "0.00€" ],
119
+        [ "Screw", "8x", "M2 l=6mm", "0.00€" ],
120
+        [ "Screw", "3x", "Grub screw M3 l>=4mm", "0.00€" ],
121
+        [ "", "", "Sum", "22.18€" ]
122
+    ]
123
+)
124
+%-->
125
+
126
+*Note*: some parts are only sold in bulk.
127
+Therefore, if you only want to build a single trackball, it will be more expensive than the sum listed above.
128
+What you see on top is the actual price I paid for the parts, reduced to the amount required for a single device.
129
+Also some parts, like screws or 3D printing materials, I consider as normal parts of a workshop, so they are not added to the cost either.
130
+
131
+## 3D Design
132
+<a class="anchor" name="3d_design"></a>
133
+
134
+The most important part of the 3D design is the mounting of the sensor and lens assembly in relation to the tracking surface, in our case the ball.
135
+The datasheet has lots of dimensional drawings which kind of hide all the important measurements somewhere in there.
136
+
137
+<!--%
138
+lightgallery([
139
+    [ "img/pmw3360_dimensions_1.png", "PMW3360 dimensional drawings, 1/6" ],
140
+    [ "img/pmw3360_dimensions_2.png", "PMW3360 dimensional drawings, 2/6" ],
141
+    [ "img/pmw3360_dimensions_3.png", "PMW3360 dimensional drawings, 3/6" ],
142
+])
143
+%-->
144
+
145
+I took great care and tried to design everything according to the specifications.
146
+
147
+<!--%
148
+lightgallery([
149
+    [ "img/pmw3360_dimensions_4.png", "PMW3360 dimensional drawings, 4/6" ],
150
+    [ "img/pmw3360_dimensions_5.png", "PMW3360 dimensional drawings, 5/6" ],
151
+    [ "img/pmw3360_dimensions_6.png", "PMW3360 dimensional drawings, 6/6" ],
152
+])
153
+%-->
154
+
155
+The static bearing balls are push-fit mounted inside the "roller holders".
156
+Printing this part is a bit tricky.
157
+Including the ball it should have a total height of 10mm.
158
+With my FDM printer it was 0.1mm too small, so I added an adjustment parameter in the design.
159
+Later iterations were always printed on SLA printers, where the adjustment had to be set back to zero.
160
+
161
+So if you want the distance to be perfect, measure the printed and assembled part and adjust accordingly.
162
+Although I think small deviations shouldn't matter too much.
163
+The sensor has a relatively large range of useable distances.
164
+
165
+<!--%
166
+lightgallery([
167
+    [ "img/trackball_scad_2.png", "Explosion drawing of assembled parts" ],
168
+    [ "img/trackball_scad_1.png", "Close up view of lens distancing and roller holder" ],
169
+])
170
+%-->
171
+
172
+The roller holders are kept in place with a grub screw for each.
173
+Then the sensor can be screwed into the top housing first, followed by the Pi.
174
+The bottom part is just a lid, without any parts screwed into it.
175
+
176
+Unfortunately the design is relatively unwieldy in OpenSCAD.
177
+Even the preview render takes dozens of seconds, with a very sluggish UI afterwards.
178
+Rendering takes ¾ of an hour on my machine.
179
+For development the `$fn` parameter can be set to a lower value.
180
+That helps somewhat.
181
+
182
+## Firmware Development
183
+<a class="anchor" name="firmware_devel"></a>
184
+
185
+Before designing and printing the complete device I made a small test bed to hold the sensor and ball.
186
+
187
+<!--%
188
+lightgallery([
189
+    [ "img/trackball_v1_1.jpg", "First sensor case prototype, with ball" ],
190
+    [ "img/trackball_v1_2.jpg", "First sensor case prototype, no ball" ],
191
+    [ "img/trackball_v1_3.jpg", "Sensor in first case prototype" ],
192
+])
193
+%-->
194
+
195
+With this initial "engineering sample" built I could continue with development of the firmware.
196
+This was basically my christmas holiday project in 2022.
197
+
198
+Interfacing with the PMW3360 chip is a bit more difficult than I initially expected.
199
+Of course everything is confidential and proprietary, but you can find [leaked datasheets on the internet](https://d3s5r33r268y59.cloudfront.net/datasheets/9604/2017-05-07-18-19-11/PMS0058-PMW3360DM-T2QU-DS-R1.50-26092016._20161202173741.pdf).
200
+It describes everything pretty well, including pinout and electrical characteristics, which were already taken care of in the breakout board.
201
+And it also describes the SPI communication interface.
202
+The only problematic part is the so-called SROM.
203
+
204
+<!--%
205
+lightgallery([
206
+    [ "img/pmw3360_datasheet_1.png", "Excerpt of PMW3360 datasheet, Power Up" ],
207
+    [ "img/pmw3360_datasheet_2.png", "Excerpt of PMW3360 datasheet, SROM Download" ],
208
+])
209
+%-->
210
+
211
+The chip requires a binary blob to be loaded on every power up, otherwise it won't work.
212
+Fortunately this was also leaked or sniffed (I'm not sure), version 4 is available [here](https://github.com/mrjohnk/PMW3360DM-T2QU/blob/master/Arduino%20Examples/PMW3360DM-polling/SROM_0x04_Arduino.ino) or [here](https://github.com/SunjunKim/PMW3360/blob/master/src/PMW3360.cpp), for example.
213
+So I've included it in my firmware as well.
214
+Not all of the fancy functionality is included in this V4 firmware blob, but it is enough for normal mouse operation.
215
+
216
+Contrary to that I'm very happy with the RP2040 / Raspberry Pi Pico ecosystem.
217
+The hardware seems well documented without having to go completely in-depth into the CPU datasheets.
218
+And the SDK similarly seems well thought-out and implemented.
219
+
220
+I was especially delighted with the ability to simply use a second Pico as a debugging dongle instead of needing an ST-Link or similar hardware.
221
+
222
+<!--%
223
+lightgallery([
224
+    [ "img/trackball_v1_4.jpg", "Debugging with two Pi Picos" ],
225
+])
226
+%-->
227
+
228
+For the USB device implementation the Pico SDK includes [TinuyUSB](https://github.com/hathach/tinyusb).
229
+From the Pico SDK I based my work on their [HID Composite example](https://github.com/raspberrypi/pico-examples/tree/master/usb/device/dev_hid_composite) ported from TinyUSB, as well as the [CDC MSC example](https://github.com/hathach/tinyusb/tree/master/examples/device/cdc_msc) directly from TinyUSB.
230
+
231
+This was very comfortable to use.
232
+From [a past project](2015_12_20_serialgamepad.html) I'm familiar with the pain of writing custom USB HID descriptors.
233
+Fortunately this is all handled by TinyUSB.
234
+You just need to pass the appropriate delta values for the mouse axes.
235
+
236
+I combined the examples to have the device act simultaneously as a human input device, and serial port and mass storage device for debugging.
237
+Of course I only developed and tested the device on my Linux machines initially.
238
+But I have now also tested it with Windows, and it works fine there as well.
239
+All functionality can be accessed without any driver installation.
240
+
241
+For the debug mass storage I also had to add some kind of file system.
242
+To do this I used [the FatFs library](https://github.com/abbrev/fatfs).
243
+I simply reserved a bunch of memory in RAM that acts as the disk device.
244
+Before it is mounted by the user, the disk is formatted and filled with the required data.
245
+Then the host can mount it and read the files.
246
+
247
+## Wiring
248
+<a class="anchor" name="wiring"></a>
249
+
250
+Wiring up the device is very easy, especially because the RP2040 provides great flexibility in its use of the GPIOs and the hardware periphery, in our case SPI.
251
+
252
+<!--%
253
+lightgallery([
254
+    [ "img/pi_pico_pinout.png", "Raspberry Pi Pico pinout" ],
255
+])
256
+%-->
257
+
258
+The SPI interface of the PMW3360 needs to be connected to one of the SPI interfaces of the Pico.
259
+But which one you use is not important and can easily be changed in the code.
260
+By default it uses the standard SPI0 pins.
261
+
262
+<div class="textwrap"><pre>
263
+GPIO 16 (pin 21) MISO -> MISO on PMW3360 board
264
+GPIO 17 (pin 22) CS   -> NCS on PMW3360 board
265
+GPIO 18 (pin 24) SCK  -> SCK on PMW3360 board
266
+GPIO 19 (pin 25) MOSI -> MOSI on PMW3360 board
267
+GPIO 20 (pin 26)      -> MOTION on PMW3360 board
268
+   3.3v (pin 36)      -> VCC on PMW3360 board
269
+    GND (pin 38)      -> GND on PMW3360 board
270
+GPIO 21 (pin 27)      -> Switch (back button)
271
+GPIO 22 (pin 29)      -> Switch (middle button)
272
+GPIO 26 (pin 31)      -> Switch (left button)
273
+GPIO 27 (pin 32)      -> Switch (right button)
274
+</pre></div>
275
+
276
+The switches use the internal pull-up resistors in the RP2040 GPIOs.
277
+So they should be wired active-low, with their common connection to GND.
278
+
279
+## Sensor Problems
280
+<a class="anchor" name="sensor_problems"></a>
281
+
282
+With the firmware mostly done I hoped to be able to use the device immediately.
283
+But it didn't quite work.
284
+When I ran my finger over the lens the sensor moved erratically, but no movement was seen with the white ball I initially tested with.
285
+Only after switching to other colors I noticed that they behave differently.
286
+So there was some investigation required.
287
+
288
+Besides the X and Y values you get a bunch of other stuff with each sensor data sample.
289
+I added functionality to dump these and made a small Python script to visualize them.
290
+
291
+<!--%
292
+lightgallery([
293
+    [ "img/pmw3360_data_white.png", "Data capture of white ball" ],
294
+    [ "img/pmw3360_data_orange.png", "Data capture of orange ball" ],
295
+])
296
+%-->
297
+
298
+With the white ball you see no movement at all, with the right ball there is movement, but there is no immediately obvious difference in the other datapoints.
299
+
300
+The PMW3360 also has a "Frame Capture" mode.
301
+This can be used to grab a full picture of what the image sensor is seeing.
302
+Using it overwrites the SROM firmware, so the sensor has to be re-initialized afterwards.
303
+I had some problems with this mode.
304
+For some reason I'm not able to properly reset the sensor after capturing a frame.
305
+It no longer reports the correct SROM ID and only a power-cycle fixes it.
306
+But the frame data can be read properly and I made a Python script to visualize it.
307
+
308
+<!--%
309
+lightgallery([
310
+    [ "img/pmw3360_frames.png", "Frame capture with no ball, white ball and orange ball" ],
311
+])
312
+%-->
313
+
314
+I'm not sure what exactly is going on with the strange lines visible in the pictures.
315
+I can't find any bug on the visualization side, but I won't rule that out fully.
316
+But like with the data visualization above, there is no obvious difference between the different colored balls.
317
+
318
+While producing some pretty pictures, this approach of analyzing the data didn't really bring us any closer to a working trackball.
319
+
320
+But then Philipp had the idea that saved the day.
321
+From the factory the PMW3360 sensors come with two small pieces of kapton tape over the optical inlet and outlet holes in the chip package.
322
+Removing them solved all issues.
323
+
324
+<!--%
325
+lightgallery([
326
+    [ "img/pmw3360_breakout_1.jpg", "Bottom of PMW3360 breakout board, without lens. Note the kapton tape which needs to be removed!" ],
327
+])
328
+%-->
329
+
330
+Now all billard balls work fine, regardless of their colour.
331
+Even the white ball works without any problems.
332
+With the electronics and the firmware ready, we could now move on to refining the mechanics.
333
+
334
+## First Prototype
335
+<a class="anchor" name="first_prototype"></a>
336
+
337
+The first top case was printed on Philipps [Anycubic Photon Mono 4K](https://www.anycubic.com/products/photon-mono-4k) SLA printer with [Anycubic Standard Resin + Grey](https://amzn.to/3RSLslf).
338
+This turned out to not be the best choice.
339
+The resin is very brittle after curing, so after pressing the switches in for the first time, and pulling on them, small parts of the print immediately broke off.
340
+So I had to super-glue the switches in place.
341
+
342
+<!--%
343
+lightgallery([
344
+    [ "img/trackball_v1_6.jpg", "Top of first case print" ],
345
+    [ "img/trackball_v1_7.jpg", "Sensor mounted inside first case print" ],
346
+    [ "img/trackball_v1_5.jpg", "Side of first case print" ],
347
+])
348
+%-->
349
+
350
+Also because it's not a thermo plastic, the heat melt inserts can not be placed in the usual way.
351
+We also used super glue for these, which worked great.
352
+
353
+<!--%
354
+lightgallery([
355
+    [ "img/trackball_v1_8.jpg", "Philipp soldering the switches" ],
356
+    [ "img/trackball_v1_9.jpg", "Front of completed first version" ],
357
+    [ "img/trackball_v1_10.jpg", "Back side of completed first version" ],
358
+])
359
+%-->
360
+
361
+The PETG printed bottom case was very slippery on a hard table surface.
362
+So I cut a piece of self-adhesive spongy rubber to the proper size and put it on the bottom.
363
+This increases friction by a fair amount, but is not yet optimal.
364
+I will have to try out some other materials.
365
+
366
+<!--%
367
+lightgallery([
368
+    [ "img/trackball_v1_13.jpg", "Before adding spongy rubber on the bottom" ],
369
+    [ "img/trackball_v1_14.jpg", "After adding spongy rubber on the bottom" ],
370
+])
371
+%-->
372
+
373
+And there we go, a finished and working trackball.
374
+
375
+<!--%
376
+lightgallery([
377
+    [ "img/trackball_v1_15.jpg", "Looking into sensor of first version" ],
378
+    [ "img/trackball_v1_11.jpg", "First completed Trackball" ],
379
+])
380
+%-->
381
+
382
+## Improvements
383
+<a class="anchor" name="improvements"></a>
384
+
385
+For the second iteration we didn't do that many changes in the 3D design.
386
+The button orientation has been overhauled.
387
+This time we sat down and actually tried to find good positions using measurements on our hands.
388
+Also the Pi Pico is no longer mounted in the bottom shell, therefore removing the need of long cables to be able to disassemble the device.
389
+
390
+This time I printed the top case on my recently acquired [Sparkmaker](sparkmaker_repair.html) SLA printer, with [Anycubic ABS-like Resin black](https://amzn.to/3Xphpmu).
391
+
392
+<!--%
393
+lightgallery([
394
+    [ "img/trackball_v1_19.jpg", "Printing the second case" ],
395
+    [ "img/trackball_v1_22.jpg", "Sensor mounted in case" ],
396
+])
397
+%-->
398
+
399
+One useful aspect of the PMW3360 lens assembly are the two mounting posts.
400
+They can be heated to firmly keep them in place.
401
+
402
+> **Recommendation**: The lens can be permanently secured to the chip package by melting the lens’ guide posts over the chip with heat staking process.
403
+Please refer to the application note *PMS0122‐LM19‐LSI‐AN* for more details.
404
+
405
+Instead of the official (confidential 🙄) method I recommend simply heating a screw or other piece of metal for 5 seconds with a lighter, then pressing it lightly on the post.
406
+Make sure everything is clean and the kapto tape removed between sensor and lens.
407
+You can see the before and after in the pictures below.
408
+
409
+<!--%
410
+lightgallery([
411
+    [ "img/trackball_v1_20.jpg", "PMW3360 before melting lens posts" ],
412
+    [ "img/trackball_v1_21.jpg", "PMW3360 after melting lens posts" ],
413
+])
414
+%-->
415
+
416
+Apart from that nothing much has changed.
417
+The heat melt inserts are still super-glued in place.
418
+
419
+<!--%
420
+lightgallery([
421
+    [ "img/trackball_v1_28.jpg", "Left side of second version" ],
422
+    [ "img/trackball_v1_33.jpg", "Inside view of second version" ],
423
+    [ "img/trackball_v1_26.jpg", "Back right of second version" ],
424
+])
425
+%-->
426
+
427
+And I used the same rubber mat for the underside.
428
+It works good enough that I didn't yet bother with a replacement.
429
+
430
+<!--%
431
+lightgallery([
432
+    [ "img/trackball_v1_24.jpg", "Looking into sensor of second version" ],
433
+    [ "img/trackball_v1_23.jpg", "Underside of second version" ],
434
+])
435
+%-->
436
+
437
+## User Experience
438
+<a class="anchor" name="user_experience"></a>
439
+
440
+I have been using these Trackballs for about six weeks at the time of this writing.
441
+From a software and electronics perspective they work absolutely fine.
442
+No disconnects, jumping cursor or any strange behaviour was observable.
443
+So I'm very happy with that.
444
+
445
+Ufortunately using them is also quite literally painful.
446
+They don't score high in terms of ergonomics, at all.
447
+The second version, with some more thought put into the placement and orientation of the switches, is an improvement, but there's still a long way to go.
448
+
449
+But using a device each day that I've built completely myself, from the grounds up in pretty much all aspects, brings me a lot of joy.
450
+I highly recommend it.
451
+
452
+## License
453
+<a class="anchor" name="license"></a>
454
+
455
+The Trackball is licensed under the [GNU General Public License](https://www.gnu.org/licenses/gpl-3.0.en.html).
456
+
457
+    This program is free software: you can redistribute it and/or modify
458
+    it under the terms of the GNU General Public License as published by
459
+    the Free Software Foundation, either version 3 of the License, or
460
+    (at your option) any later version.
461
+
462
+    This program is distributed in the hope that it will be useful,
463
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
464
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
465
+    GNU General Public License for more details.
466
+
467
+    See <http://www.gnu.org/licenses/>.
468
+
469
+## More Pictures
470
+<a class="anchor" name="more_pictures"></a>
471
+
472
+<div class="collapse">Some more photographs I didn't use above.</div>
473
+<div class="collapsecontent">
474
+<!--%
475
+lightgallery([
476
+    [ "img/trackball_v1_25.jpg", "Back right of second version" ],
477
+    [ "img/trackball_v1_18.jpg", "Printing the second case, badly lit" ],
478
+    [ "img/trackball_v1_29.jpg", "Second version, badly lit" ],
479
+    [ "img/trackball_v1_30.jpg", "Second version, badly lit" ],
480
+    [ "img/trackball_v1_31.jpg", "Second version, badly lit" ],
481
+    [ "img/trackball_v1_32.jpg", "Second version, badly lit" ],
482
+])
483
+%-->
484
+</div>

+ 28
- 27
input/texts/tex_beetle.md ファイルの表示

@@ -1,4 +1,7 @@
1 1
 title: Tex Beetle Review
2
+description: My first mechanical keyboard
3
+date: 2013-06-23
4
+show_in_input_devices: true
2 5
 parent: none
3 6
 comments: true
4 7
 flattr: true
@@ -6,19 +9,31 @@ flattr: true
6 9
 
7 10
 On June 5th I ordered the [Tex Beetle][texbeetle] from [MechanicalKeyboards.com][shop]. It shipped one day later and after about two weeks I received a notification from the German customs office. Including import sales tax and shipping, I had to pay 160 Euros.
8 11
 
9
-[![Photo][overviewSmall]][overview]
10
-[![Photo][small]][big]
12
+<!--%
13
+lightgallery([
14
+    [ "img/tex/overview.jpg", "" ],
15
+    [ "img/mekeybo.jpg", "" ],
16
+])
17
+%-->
11 18
 
12 19
 The CNC-machined top half and the weight of 760g leave a very solid impression. A gold-plated (duh!) and pretty long Mini-USB cable with an angled connector and a Tex cable tie are included.
13 20
 
14
-[![Photo][cableTieSmall]][cableTie]
15
-[![Photo][flatSmall]][flat]
21
+<!--%
22
+lightgallery([
23
+    [ "img/tex/cableTie.jpg", "" ],
24
+    [ "img/tex/flat.jpg", "" ],
25
+])
26
+%-->
16 27
 
17 28
 There are seven LEDs, indicating special fuction modes, on the underside, although the keyboard only uses five of them. That's probably because the plastic shell is a re-used part from the LED-illuminated version.
18 29
 
19
-[![Photo][backSmall]][back]
20
-[![Photo][backBigSmall]][backBig]
21
-[![Photo][compareSmall]][compare]
30
+<!--%
31
+lightgallery([
32
+    [ "img/tex/back.jpg", "" ],
33
+    [ "img/tex/backBig.jpg", "" ],
34
+    [ "img/tex/compare.jpg", "" ],
35
+])
36
+%-->
22 37
 
23 38
 With the five usable function modes (L1 - L5), you can swap Caps Lock and left CTRL, swap the Windows key and the left FN key, swap escape and the tilde, swap backspace and delete or activate the Windows key lock.
24 39
 
@@ -26,8 +41,12 @@ Their state is preserved, even after unplugging the keyboard, and can be toggled
26 41
 
27 42
 To keep the layout a bit more similar to the default Apple Special Keys, I activated L2, switching left FN and Win. I also changed the respectivce keys, using a [Macgyvered Keypuller][pull].
28 43
 
29
-[![Photo][keypullerSmall]][keypuller]
30
-[![Photo][switchSmall]][switch]
44
+<!--%
45
+lightgallery([
46
+    [ "img/tex/keypuller.jpg", "" ],
47
+    [ "img/tex/switch.jpg", "" ],
48
+])
49
+%-->
31 50
 
32 51
 Also note the [non-standard staggering][stagger] in the first row. This causes some missed keys for me currently, but I think this will get better soon.
33 52
 
@@ -38,21 +57,3 @@ All in all, I'm very happy with this choice for my very first mechanical keyboar
38 57
  [shop]: http://mechanicalkeyboards.com
39 58
  [texbeetle]: http://mechanicalkeyboards.com/shop/index.php?l=product_detail&p=377
40 59
  [official]: http://www.tex-design.com.tw/main.html
41
- [small]: img/mekeybo_small.jpg
42
- [big]: img/mekeybo.jpg
43
- [backSmall]: img/tex/back_small.jpg
44
- [back]: img/tex/back.jpg
45
- [backBigSmall]: img/tex/backBig_small.jpg
46
- [backBig]: img/tex/backBig.jpg
47
- [cableTieSmall]: img/tex/cableTie_small.jpg
48
- [cableTie]: img/tex/cableTie.jpg
49
- [compareSmall]: img/tex/compare_small.jpg
50
- [compare]: img/tex/compare.jpg
51
- [keypullerSmall]: img/tex/keypuller_small.jpg
52
- [keypuller]: img/tex/keypuller.jpg
53
- [switchSmall]: img/tex/switch_small.jpg
54
- [switch]: img/tex/switch.jpg
55
- [overviewSmall]: img/tex/overview_small.jpg
56
- [overview]: img/tex/overview.jpg
57
- [flatSmall]: img/tex/flat_small.jpg
58
- [flat]: img/tex/flat.jpg

+ 12
- 0
macros.py ファイルの表示

@@ -174,6 +174,18 @@ def print3DPrintingMenu():
174 174
     for p in mpages:
175 175
         printMenuItem(p, False, True, True)
176 176
 
177
+def printInputDevicesMenu():
178
+    mpages = [p for p in pages if p.get("parent", "") == "input_devices" and p.lang == "en"]
179
+    mpages.sort(key=lambda p: [p.get("date", "9999-01-01")], reverse = True)
180
+    for p in mpages:
181
+        printMenuItem(p, False, True, True)
182
+
183
+def printInputDevicesRelatedMenu():
184
+    mpages = [p for p in pages if p.get("show_in_input_devices", "false") == "true"]
185
+    mpages.sort(key=lambda p: [p.get("date", "9999-01-01")], reverse = True)
186
+    for p in mpages:
187
+        printMenuItem(p, False, True, True)
188
+
177 189
 def printSmarthomeMenu():
178 190
     mpages = [p for p in pages if p.get("parent", "") == "smarthome" and p.lang == "en"]
179 191
     mpages.sort(key=lambda p: int(p["position"]))

+ 41
- 0
static/css/style.css ファイルの表示

@@ -266,6 +266,29 @@ span.font-small {
266 266
     border-radius: 10px;
267 267
 }
268 268
 
269
+blockquote {
270
+    position: relative;
271
+    padding: 1em 0.5em;
272
+    border-left-width: 10px;
273
+    border-left-style: solid;
274
+}
275
+
276
+blockquote:before {
277
+    position: absolute;
278
+    content: open-quote;
279
+    font-size: 4em;
280
+}
281
+
282
+blockquote:before {
283
+    position: absolute;
284
+    content: open-quote;
285
+    font-size: 4em;
286
+}
287
+
288
+blockquote p {
289
+    margin: 0 0 0 2em;
290
+}
291
+
269 292
 /* colors */
270 293
 
271 294
 body, #nav, .collapsecontent {
@@ -325,6 +348,15 @@ s {
325 348
     background-color: #999999;
326 349
 }
327 350
 
351
+blockquote {
352
+    background: #DEDEDE;
353
+    border-left-color: #444444;
354
+}
355
+
356
+blockquote:before, blockquote:after {
357
+    color: #444444;
358
+}
359
+
328 360
 /* dark mode */
329 361
 @media (prefers-color-scheme: dark) {
330 362
     body, #nav, .collapsecontent {
@@ -390,4 +422,13 @@ s {
390 422
     .collapseactive, .collapse:hover {
391 423
         background-color: #424242;
392 424
     }
425
+
426
+    blockquote {
427
+        background: #252525;
428
+        border-left-color: #888888;
429
+    }
430
+
431
+    blockquote:before, blockquote:after {
432
+        color: #888888;
433
+    }
393 434
 }

バイナリ
static/img/pi_pico_pinout.png ファイルの表示


バイナリ
static/img/pi_pico_pinout_small.png ファイルの表示


バイナリ
static/img/pmw3360_breakout_1.jpg ファイルの表示


バイナリ
static/img/pmw3360_breakout_1_small.jpg ファイルの表示


バイナリ
static/img/pmw3360_breakout_2.jpg ファイルの表示


バイナリ
static/img/pmw3360_breakout_2_small.jpg ファイルの表示


バイナリ
static/img/pmw3360_breakout_3.jpg ファイルの表示


バイナリ
static/img/pmw3360_breakout_3_small.jpg ファイルの表示


バイナリ
static/img/pmw3360_data_orange.png ファイルの表示


バイナリ
static/img/pmw3360_data_orange_small.png ファイルの表示


バイナリ
static/img/pmw3360_data_white.png ファイルの表示


バイナリ
static/img/pmw3360_data_white_small.png ファイルの表示


バイナリ
static/img/pmw3360_datasheet_1.png ファイルの表示


バイナリ
static/img/pmw3360_datasheet_1_small.png ファイルの表示


バイナリ
static/img/pmw3360_datasheet_2.png ファイルの表示


バイナリ
static/img/pmw3360_datasheet_2_small.png ファイルの表示


バイナリ
static/img/pmw3360_dimensions_1.png ファイルの表示


バイナリ
static/img/pmw3360_dimensions_1_small.png ファイルの表示


バイナリ
static/img/pmw3360_dimensions_2.png ファイルの表示


バイナリ
static/img/pmw3360_dimensions_2_small.png ファイルの表示


バイナリ
static/img/pmw3360_dimensions_3.png ファイルの表示


バイナリ
static/img/pmw3360_dimensions_3_small.png ファイルの表示


バイナリ
static/img/pmw3360_dimensions_4.png ファイルの表示


バイナリ
static/img/pmw3360_dimensions_4_small.png ファイルの表示


バイナリ
static/img/pmw3360_dimensions_5.png ファイルの表示


バイナリ
static/img/pmw3360_dimensions_5_small.png ファイルの表示


バイナリ
static/img/pmw3360_dimensions_6.png ファイルの表示


バイナリ
static/img/pmw3360_dimensions_6_small.png ファイルの表示


バイナリ
static/img/pmw3360_frames.png ファイルの表示


バイナリ
static/img/pmw3360_frames_small.png ファイルの表示


バイナリ
static/img/pmw3360_order.png ファイルの表示


バイナリ
static/img/pmw3360_order_small.png ファイルの表示


バイナリ
static/img/trackball_scad_1.png ファイルの表示


バイナリ
static/img/trackball_scad_1_small.png ファイルの表示


バイナリ
static/img/trackball_scad_2.png ファイルの表示


バイナリ
static/img/trackball_scad_2_small.png ファイルの表示


バイナリ
static/img/trackball_v1_1.jpg ファイルの表示


バイナリ
static/img/trackball_v1_10.jpg ファイルの表示


バイナリ
static/img/trackball_v1_10_small.jpg ファイルの表示


バイナリ
static/img/trackball_v1_11.jpg ファイルの表示


バイナリ
static/img/trackball_v1_11_small.jpg ファイルの表示


バイナリ
static/img/trackball_v1_12.jpg ファイルの表示


バイナリ
static/img/trackball_v1_12_small.jpg ファイルの表示


バイナリ
static/img/trackball_v1_13.jpg ファイルの表示


バイナリ
static/img/trackball_v1_13_small.jpg ファイルの表示


バイナリ
static/img/trackball_v1_14.jpg ファイルの表示


バイナリ
static/img/trackball_v1_14_small.jpg ファイルの表示


バイナリ
static/img/trackball_v1_15.jpg ファイルの表示


バイナリ
static/img/trackball_v1_15_small.jpg ファイルの表示


バイナリ
static/img/trackball_v1_16.jpg ファイルの表示


バイナリ
static/img/trackball_v1_16_small.jpg ファイルの表示


バイナリ
static/img/trackball_v1_17.jpg ファイルの表示


バイナリ
static/img/trackball_v1_17_small.jpg ファイルの表示


バイナリ
static/img/trackball_v1_18.jpg ファイルの表示


バイナリ
static/img/trackball_v1_18_small.jpg ファイルの表示


バイナリ
static/img/trackball_v1_19.jpg ファイルの表示


バイナリ
static/img/trackball_v1_19_small.jpg ファイルの表示


バイナリ
static/img/trackball_v1_1_small.jpg ファイルの表示


バイナリ
static/img/trackball_v1_2.jpg ファイルの表示


バイナリ
static/img/trackball_v1_20.jpg ファイルの表示


バイナリ
static/img/trackball_v1_20_small.jpg ファイルの表示


バイナリ
static/img/trackball_v1_21.jpg ファイルの表示


バイナリ
static/img/trackball_v1_21_small.jpg ファイルの表示


バイナリ
static/img/trackball_v1_22.jpg ファイルの表示


バイナリ
static/img/trackball_v1_22_small.jpg ファイルの表示


バイナリ
static/img/trackball_v1_23.jpg ファイルの表示


バイナリ
static/img/trackball_v1_23_small.jpg ファイルの表示


バイナリ
static/img/trackball_v1_24.jpg ファイルの表示


バイナリ
static/img/trackball_v1_24_small.jpg ファイルの表示


バイナリ
static/img/trackball_v1_25.jpg ファイルの表示


バイナリ
static/img/trackball_v1_25_small.jpg ファイルの表示


バイナリ
static/img/trackball_v1_26.jpg ファイルの表示


バイナリ
static/img/trackball_v1_26_small.jpg ファイルの表示


バイナリ
static/img/trackball_v1_27.jpg ファイルの表示


バイナリ
static/img/trackball_v1_27_small.jpg ファイルの表示


バイナリ
static/img/trackball_v1_28.jpg ファイルの表示


バイナリ
static/img/trackball_v1_28_small.jpg ファイルの表示


バイナリ
static/img/trackball_v1_29.jpg ファイルの表示


バイナリ
static/img/trackball_v1_29_small.jpg ファイルの表示


バイナリ
static/img/trackball_v1_2_small.jpg ファイルの表示


バイナリ
static/img/trackball_v1_3.jpg ファイルの表示


バイナリ
static/img/trackball_v1_30.jpg ファイルの表示


バイナリ
static/img/trackball_v1_30_small.jpg ファイルの表示


バイナリ
static/img/trackball_v1_31.jpg ファイルの表示


バイナリ
static/img/trackball_v1_31_small.jpg ファイルの表示


バイナリ
static/img/trackball_v1_32.jpg ファイルの表示


バイナリ
static/img/trackball_v1_32_small.jpg ファイルの表示


バイナリ
static/img/trackball_v1_33.jpg ファイルの表示


バイナリ
static/img/trackball_v1_33_small.jpg ファイルの表示


バイナリ
static/img/trackball_v1_3_small.jpg ファイルの表示


バイナリ
static/img/trackball_v1_4.jpg ファイルの表示


+ 0
- 0
static/img/trackball_v1_4_small.jpg ファイルの表示


変更されたファイルが多すぎるため、一部のファイルは表示されません

読み込み中…
キャンセル
保存