{"id":4596,"date":"2020-07-31T09:48:07","date_gmt":"2020-07-31T14:48:07","guid":{"rendered":"http:\/\/www.paleotechnologist.net\/?p=4596"},"modified":"2020-07-31T09:48:10","modified_gmt":"2020-07-31T14:48:10","slug":"diy-scroll-wheel","status":"publish","type":"post","link":"https:\/\/www.paleotechnologist.net\/?p=4596","title":{"rendered":"DIY scroll wheel"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">For almost thirty years, I&#8217;ve preferred <a rel=\"noreferrer noopener\" aria-label=\"trackballs  (opens in a new tab)\" href=\"https:\/\/www.logitech.com\/en-us\/product\/trackman-marble-business\" target=\"_blank\">trackballs <\/a>to traditional mice. Flipping the mouse geometry upside-down means that you can give the trackball a spin to move the cursor quickly, without having to bother with picking up the mouse and moving it back onto the mousepad over and over. Also, more importantly, trackballs don&#8217;t need to move around like a traditional mouse does, and so take up a lot less desktop real estate. It&#8217;s like having a mouse with an infinitely large mousepad and an infinitely long arm. I honestly don&#8217;t know why traditional mice are still a thing.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"687\" height=\"600\" src=\"https:\/\/www.paleotechnologist.net\/wp-content\/uploads\/2020\/07\/trackman-marble.png\" alt=\"\" class=\"wp-image-4601\" srcset=\"https:\/\/www.paleotechnologist.net\/wp-content\/uploads\/2020\/07\/trackman-marble.png 687w, https:\/\/www.paleotechnologist.net\/wp-content\/uploads\/2020\/07\/trackman-marble-300x262.png 300w\" sizes=\"auto, (max-width: 687px) 100vw, 687px\" \/><figcaption>A Logitech Trackman Marble(tm).<br>Image shamelessly snagged from Logitech&#8217;s site. (<a rel=\"noreferrer noopener\" aria-label=\"Go buy one. They're good (opens in a new tab)\" href=\"https:\/\/www.logitech.com\/en-us\/product\/trackman-marble-business\" target=\"_blank\">Go buy one. They&#8217;re good<\/a>.)<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The one drawback to trackballs, however, is that they generally don&#8217;t come with scroll wheel functionality of any kind. And while the scroll wheel is still not up there with the left and right mouse buttons in terms of importance on a PC, there are still far too many apps that require it, and a lot more than can make good use of it. The map in Skyrim, for example, can be zoomed to some extent &#8212; but only with a scroll wheel. Zooming the view in and out in X-Plane, while possible using the keyboard, is much faster and more intuitive using a wheel input. Also, all of the many knob-based inputs in a typical simulator cockpit can be used with a scroll wheel if the mouse cursor is on them. This is a lot more realistic than trying to click on the correct edge of the image of a multi-function knob on your screen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Scroll wheel functionality would be useful &#8212; but the hassle of moving back to a traditional mouse just isn&#8217;t worth it. (I brought in my own Logitech Marble Mouse to work so I wouldn&#8217;t have to use a traditional mouse.)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Boards like the <a rel=\"noreferrer noopener\" aria-label=\"Arduino Leonardo (opens in a new tab)\" href=\"https:\/\/www.arduino.cc\/en\/Main\/Arduino_BoardLeonardo\" target=\"_blank\">Arduino Leonardo<\/a> now make this a very easy problem to solve! The Leonardo can implement a &#8220;HID&#8221; (Human Interface Device) via USB, and can appear as a USB keyboard and\/or USB mouse to a host computer. Since it&#8217;s pretty straightforward to get an Arduino to read a quadrature encoder (see code below), a few lines of code are all that&#8217;s needed to get it emulating a scroll wheel.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.amazon.com\/gp\/product\/B07BN3DGBS\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"Here's the encoder I used (opens in a new tab)\">Here&#8217;s the encoder I used<\/a> &#8212; any similar quadrature (relative position \/ &#8220;jog dial&#8221;) encoder should work.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Hookup is almost as simple as it gets: 5V to 5V, Ground to Ground, then pick GPIO pins to use for switch (the pushbutton), data, and clock. (Really, phase A and phase B.) I used pins 2, 7, and 8 (more or less arbitrarily), but as long as your pin choices match the ones you set in the code below, it should work.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s the code (designed for an Arduino Leonardo).<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/Simple scroll wheel implementation for Arduino Leonardo and similar\n\/\/Uses quadrature encoder and USB HID library\n\/\/CC-BY-NC 2020, M. Eric Carr \/ eric at paleotechnologist dot net\n\n#include&lt;Mouse.h>\n\nconst int SWITCHPIN = 2; \/\/Push switch function of encoder (for future use)\nconst int DATAPIN = 7;   \/\/Phase A of encoder\nconst int CLOCKPIN = 8;  \/\/Phase B of encoder\n\nvoid setup() {\n  pinMode(SWITCHPIN, INPUT); \/\/For future use\n  pinMode(DATAPIN, INPUT);\n  pinMode(CLOCKPIN, INPUT);\n  }\n\nvoid loop() {\n  \/\/Quick-and-dirty quadrature tracking. Counts when A high and B changed;\n  \/\/this should produce one count per set of four quadratures.\n  \/\/TODO: Give this a little hysteresis by not incrementing and decrementing\n  \/\/the count at the same place in the cycle.\n\n  \/\/DO NOT PUT SIGNIFICANT DELAYS IN THIS LOOP; it relies on running fast enough\n  \/\/to not miss any transitions. 1ms delay may be too much. 10ms can cause problems.\n  \/\/There are four transitions per \"click\" of the dial; if you spin it quickly,\n  \/\/you could go through several dozen transitions in a fraction of a second, causing\n  \/\/the count to be in error if this loop is too slow.\n\n  static int oldA=0,oldB=0;\n  int a,b;\n\n  a=digitalRead(DATAPIN);\n  b=digitalRead(CLOCKPIN);\n\n  if(oldA!=a || oldB!=b){\n\n    if(a==HIGH){\n      if(b==LOW &amp;&amp; oldB==HIGH){Mouse.move(0,0,1);}  \/\/Scroll up\n      if(b==HIGH &amp;&amp; oldB==LOW){Mouse.move(0,0,-1);} \/\/Scroll down\n      }\n\n    oldA=a;\n    oldB=b;\n\n    }\/\/if\n\n  }\/\/loop()\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"> Once everything was wired and tested, I modified a <a href=\"https:\/\/www.thingiverse.com\/thing:678872\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"Leonardo case I found on Thingiverse (opens in a new tab)\">Leonardo case I found on Thingiverse<\/a> to expand the lid, allowing space for the encoder. It&#8217;s even somewhat ergonomic, considering it&#8217;s a prototype&#8230;<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"576\" src=\"https:\/\/www.paleotechnologist.net\/wp-content\/uploads\/2020\/07\/2020-07-31-10.01.45-1024x576.jpg\" alt=\"\" class=\"wp-image-4599\" srcset=\"https:\/\/www.paleotechnologist.net\/wp-content\/uploads\/2020\/07\/2020-07-31-10.01.45-1024x576.jpg 1024w, https:\/\/www.paleotechnologist.net\/wp-content\/uploads\/2020\/07\/2020-07-31-10.01.45-300x169.jpg 300w, https:\/\/www.paleotechnologist.net\/wp-content\/uploads\/2020\/07\/2020-07-31-10.01.45-768x432.jpg 768w, https:\/\/www.paleotechnologist.net\/wp-content\/uploads\/2020\/07\/2020-07-31-10.01.45-1536x864.jpg 1536w, https:\/\/www.paleotechnologist.net\/wp-content\/uploads\/2020\/07\/2020-07-31-10.01.45-2048x1152.jpg 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption>The Leonardo is more-or-less Uno sized,<br>but with a microUSB cable instead of Type B.<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"576\" src=\"https:\/\/www.paleotechnologist.net\/wp-content\/uploads\/2020\/07\/2020-07-31-10.04.30-1024x576.jpg\" alt=\"\" class=\"wp-image-4600\" srcset=\"https:\/\/www.paleotechnologist.net\/wp-content\/uploads\/2020\/07\/2020-07-31-10.04.30-1024x576.jpg 1024w, https:\/\/www.paleotechnologist.net\/wp-content\/uploads\/2020\/07\/2020-07-31-10.04.30-300x169.jpg 300w, https:\/\/www.paleotechnologist.net\/wp-content\/uploads\/2020\/07\/2020-07-31-10.04.30-768x432.jpg 768w, https:\/\/www.paleotechnologist.net\/wp-content\/uploads\/2020\/07\/2020-07-31-10.04.30-1536x864.jpg 1536w, https:\/\/www.paleotechnologist.net\/wp-content\/uploads\/2020\/07\/2020-07-31-10.04.30-2048x1152.jpg 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption>The completed scroll wheel prototype. It doesn&#8217;t look like much, but it&#8217;s certainly useful.<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Happy scrolling!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>An Arduino Leonardo can be used to add scroll wheel functionality if your mouse doesn&#8217;t have it. Here&#8217;s how. <a href=\"https:\/\/www.paleotechnologist.net\/?p=4596\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_exactmetrics_skip_tracking":false,"footnotes":""},"categories":[267,249,216,210,226,475],"tags":[506,498,623,618,622,616,535,538,614,615,620,617,619],"class_list":["post-4596","post","type-post","status-publish","format-standard","hentry","category-arduino","category-c","category-coding","category-digital","category-how-to","category-user-interface-design","tag-3d-printing","tag-arduino","tag-arduino-leonardo","tag-hid","tag-leonardo","tag-mouse","tag-quadrature","tag-quadrature-encoder","tag-scroll","tag-scroll-wheel","tag-trackman","tag-usb","tag-usb-hid"],"_links":{"self":[{"href":"https:\/\/www.paleotechnologist.net\/index.php?rest_route=\/wp\/v2\/posts\/4596","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.paleotechnologist.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.paleotechnologist.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.paleotechnologist.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.paleotechnologist.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4596"}],"version-history":[{"count":7,"href":"https:\/\/www.paleotechnologist.net\/index.php?rest_route=\/wp\/v2\/posts\/4596\/revisions"}],"predecessor-version":[{"id":4606,"href":"https:\/\/www.paleotechnologist.net\/index.php?rest_route=\/wp\/v2\/posts\/4596\/revisions\/4606"}],"wp:attachment":[{"href":"https:\/\/www.paleotechnologist.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4596"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.paleotechnologist.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4596"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.paleotechnologist.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4596"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}