Archives

All posts for the month February, 2013

So I have been using the loststone prototype for about a month, I have only been using my store bought mouse when I screw something up 🙂

Aside from the occasional physical issue, mainly the buttons falling off, I have only been having one issue. Sensitivity. If I set the CPI high enough(ex 4500) for the courser to travel the full length of the monitor with a reasonable spin of the ball, It is next to impossible to move the courser over a specific character on the first try. Some times even the 4th or 5th try, VERY annoying. Setting the CPI low enough(ex 540) for really nice small movements and it takes multiple turns of the ball to move the full length of the screen.

I originally thought that some very complicated math would be required to solve this issue. So I figured I would start out small to get an idea of what I needed to do to accelerate the courser across the screen when moved fast enough and yet still allow small intricate movements. Much to my amazement the first equation I came up with did exactly what I needed it to do.

After some tweaking of the denominator and CPI values I came up with the CPI at 540 and the following equation.

f(x) = ( |x| / 40 + 1) * x

f(x) = x
f(x) = ( |x| / 60 + 1) * x
f(x) = ( |x| / 40 + 1) * x
f(x) = ( |x| / 20 + 1) * x

The red plot is the raw sensor input(both x and y coordinates). The rest are different values for the denominator, I am currently using the blue one.

One of the reasons this works so well is the way that rounding is done when casting a float to an int in C++. Well actually there is no rounding. For example if we solve for x = 6 we end up with 1.15 * 6 = 6.9 which when cast to and int is simply 6. When x = 7 we end up with 1.175 * 7 = 8.225 which then becomes 8. So the 6 smallest movements are not actually changed. And when the values do start changing it is a smooth progression to larger numbers.

Share Button

dc_power_supply

I have been meaning to get a DC power supply for my work bench. In the passed I have used computer power supplies in a pinch. I figured with a little tweaking it would make a pretty good general DC power supply. I attached a switch i had lying around to pins 15 and 16 (pin-outs) and then attached pins 1, 2, 4, 6, 10, 11, 17 and 18 to a dual row terminal strip. The terminal strip I had has 8 positions so I figured I would do 2 of each voltage, 3.3V, 5V, 12V and GND. I didn’t bother with the -12V

So far it is working well. Especially since it cost me $0.

The folks at Dangerous Prototypes have a really nice kit you can get at seedstudio.com. Even though I just through this together I will still probably get one. They put in some resetable fuses which is nice. You also wont need to chop up the cables. And at $14 you cant go wrong.

Share Button

The HID report descriptor of the USBMouse interface is functional but minimalistic. I spent some time looking into HID descriptors and came up with a new descriptor which adds support for the following.

  1. Horizontal scrolling.
  2. A fourth and fifth mouse buttons (Forward and back by default).
  3. 16bit X and Y values

I don’t think I even like horizontal scrolling, maybe I just have to get used to it. Not sure what i am going to use the extra buttons for but there there if I need them. The 16bit  X and Y values eliminate the need for some nasty logic that broke up X and Y values larger/smaller than 127/-127 into multiple reports. I was planning on redoing that logic, I don’t think it was doing exactly what I wanted it to do. That would have been some nasty code though. By changing it to support 16bit values a single report can hold any number the ADNS-9500 can output( 32767/-32768) I still don’t have the scroll multiplier report. I don’t think I need that if I want the numbers to be larger I can always just bump up the CPI when in scrolling mode.

 

The new HID report Descriptor is as follows.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
//
// Wheel Mouse - simplified version - 5 button, vertical and horizontal wheel
//
// Input report - 6 bytes
//
//     Byte | D7   D6   D5   D4      D3      D2      D1      D0
//    ------+---------------------------------------------------------------------
//      0   |  0    0    0    Forward  Back    Middle  Right   Left (Buttons)
//      1   |                       X High
//      2   |                       X Low
//      3   |                       Y High
//      4   |                       Y Low
//      5   |                   Vertical Wheel
//      6   |               Horizontal (Tilt) Wheel
//
// Feature report - 1 byte
//
//     Byte | D7   D6   D5   D4   |  D3      D2  |   D1      D0
//    ------+---------------------+--------------+----------------
//      0   |  0    0    0    0   |  Horizontal  |    Vertical
//                                    (Resolution multiplier)
//
// Reference
//    Wheel.docx in "Enhanced Wheel Support in Windows Vista" on MS WHDC
//    http://www.microsoft.com/whdc/device/input/wheel.mspx
//
static uint8_t reportDescriptor[] = {
    0x05, 0x01,        // USAGE_PAGE (Generic Desktop)
    0x09, 0x02,        // USAGE (Mouse)
    0xa1, 0x01,        // COLLECTION (Application)
    0x09, 0x02,        //   USAGE (Mouse)
    0xa1, 0x02,        //   COLLECTION (Logical)
    0x09, 0x01,        //     USAGE (Pointer)
    0xa1, 0x00,        //     COLLECTION (Physical)
                       // ------------------------------  Buttons
    0x05, 0x09,        //       USAGE_PAGE (Button)
    0x19, 0x01,        //       USAGE_MINIMUM (Button 1)
    0x29, 0x05,        //       USAGE_MAXIMUM (Button 5)
    0x15, 0x00,        //       LOGICAL_MINIMUM (0)
    0x25, 0x01,        //       LOGICAL_MAXIMUM (1)
    0x75, 0x01,        //       REPORT_SIZE (1)
    0x95, 0x05,        //       REPORT_COUNT (5)
    0x81, 0x02,        //       INPUT (Data,Var,Abs)
                       // ------------------------------  Padding
    0x75, 0x03,        //       REPORT_SIZE (3)
    0x95, 0x01,        //       REPORT_COUNT (1)
    0x81, 0x03,        //       INPUT (Cnst,Var,Abs)
                       // ------------------------------  X,Y position
    0x05, 0x01,        //       USAGE_PAGE (Generic Desktop)
    0x09, 0x30,        //       USAGE (X)
    0x09, 0x31,        //       USAGE (Y)
    0x16, 0x00, 0x81,  //       LOGICAL_MINIMUM (-32768)
    0x26, 0xff, 0x7f,  //       LOGICAL_MAXIMUM (32767)
    0x75, 0x10,        //       REPORT_SIZE (16)
    0x95, 0x02,        //       REPORT_COUNT (2)
    0x81, 0x06,        //       INPUT (Data,Var,Rel)
    0xa1, 0x02,        //       COLLECTION (Logical)
                       // ------------------------------  Vertical wheel res multiplier
    0x09, 0x48,        //         USAGE (Resolution Multiplier)
    0x15, 0x00,        //         LOGICAL_MINIMUM (0)
    0x25, 0x01,        //         LOGICAL_MAXIMUM (1)
    0x35, 0x01,        //         PHYSICAL_MINIMUM (1)
    0x45, 0x04,        //         PHYSICAL_MAXIMUM (4)
    0x75, 0x02,        //         REPORT_SIZE (2)
    0x95, 0x01,        //         REPORT_COUNT (1)
    0xa4,              //         PUSH
    0xb1, 0x02,        //         FEATURE (Data,Var,Abs)
                       // ------------------------------  Vertical wheel
    0x09, 0x38,        //         USAGE (Wheel)
    0x15, 0x81,        //         LOGICAL_MINIMUM (-127)
    0x25, 0x7f,        //         LOGICAL_MAXIMUM (127)
    0x35, 0x00,        //         PHYSICAL_MINIMUM (0)        - reset physical
    0x45, 0x00,        //         PHYSICAL_MAXIMUM (0)
    0x75, 0x08,        //         REPORT_SIZE (8)
    0x81, 0x06,        //         INPUT (Data,Var,Rel)
    0xc0,              //       END_COLLECTION
    0xa1, 0x02,        //       COLLECTION (Logical)
                       // ------------------------------  Horizontal wheel res multiplier
    0x09, 0x48,        //         USAGE (Resolution Multiplier)
    0xb4,              //         POP
    0xb1, 0x02,        //         FEATURE (Data,Var,Abs)
                       // ------------------------------  Padding for Feature report
    0x35, 0x00,        //         PHYSICAL_MINIMUM (0)        - reset physical
    0x45, 0x00,        //         PHYSICAL_MAXIMUM (0)
    0x75, 0x04,        //         REPORT_SIZE (4)
    0xb1, 0x03,        //         FEATURE (Cnst,Var,Abs)
                       // ------------------------------  Horizontal wheel
    0x05, 0x0c,        //         USAGE_PAGE (Consumer Devices)
    0x0a, 0x38, 0x02,  //         USAGE (AC Pan)
    0x15, 0x81,        //         LOGICAL_MINIMUM (-127)
    0x25, 0x7f,        //         LOGICAL_MAXIMUM (127)
    0x75, 0x08,        //         REPORT_SIZE (8)
    0x81, 0x06,        //         INPUT (Data,Var,Rel)
    0xc0,              //       END_COLLECTION
    0xc0,              //     END_COLLECTION
    0xc0,              //   END_COLLECTION
    0xc0               // END_COLLECTION
};

White paper from Microft with a bref description and some examples.
http://www.microsoft.com/whdc/device/input/wheel.mspx

Many usfuall doc’s and the “HID Description tool” its not a very user friendly tool but helps with coming up with the hex codes.
http://www.usb.org/developers/hidpage/

This is a wonderful tutorial on HID descriptors short but nice explanations and examples.
http://www.frank-zhao.com/cache/hid_tutorial_1.php

USB in a nutshell? That’s one big nutshell! Well actually its barley scratching the surface but this is usually my goto when i want to know something.
http://www.beyondlogic.org/usbnutshell/usb1.shtml

Share Button