User Tools

Site Tools


doc:appunti:android:bluetooth_keboard

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
Last revisionBoth sides next revision
doc:appunti:android:bluetooth_keboard [2020/01/31 17:21] – [Key Layout] niccolodoc:appunti:android:bluetooth_keboard [2020/02/04 10:36] – [Using OsmAnd with a Remote Controller] niccolo
Line 1: Line 1:
 ====== Using OsmAnd with a Remote Controller ====== ====== Using OsmAnd with a Remote Controller ======
  
-I'm an early joiner of the **OpenStreetMap** project, so I'm a big fan of the **OsmAnd** app. It is my preferred choice for **motorbike on-board navigation**.+[{{.:osmadn:osmand-remote-controller.jpg?380 |OsmAnd paierd with a Bluetooth remote controller}}] 
 +I'm an early joiner of the **[[https://www.openstreetmap.org|OpenStreetMap]]** project, so I'm a big fan of the **[[https://play.google.com/store/apps/details?id=net.osmand|OsmAnd]]** app. It is my preferred choice for **motorbike on-board navigation**.
  
-A long-standing issue was the impossiblity to operate the map while **wearing gloves**. To be clear: panning and zooming on the Android touchscreen is impossibile. Here we explore the possibility to use a little Bluetooth remote controller to get at least the **basic pan/zoom functions**; in short: **it could work!** +A long-standing issue was the impossiblity to operate the map while **wearing gloves**. To be clear: panning and zooming on the Android touchscreen using gloves is impossibile. Here we explore the possibility to use a little Bluetooth remote controller to get at least the **basic pan/zoom functions**; in short: **it could work!**
- +
-In OsmAnd you have to enable: Hamburger menu => **Configure profile** => General settings => **External input devices** => **Keyboard**.+
  
 ===== The Mocute Universal Wireless Remote Controller ===== ===== The Mocute Universal Wireless Remote Controller =====
  
-[{{ .:osmadn:mocute-remote-controller.jpg?320|The Mocute Remote Controller}}] +[{{ .:osmadn:mocute-remote-controller.jpg?280|The Mocute Remote Controller}}] 
-It is a low-cost (5-10 euros) **Bluetooth** device. It has an internal **rechargeable battery** which should last about 10 hours. the small size is quite convenient for using it on the **handlebar** of a motorbike, the biggest problem being to be **not water-proof**.+It is a low-cost (5-10 euros) **Bluetooth** device, sold under different brands. At present (Jan 2020) you can find it on **Amazon** or **Aliexpress.com** under the generic terms //Android gamepad Bluetooth controller//. It has an internal **rechargeable battery** which should last about 10 hours. The small size is quite convenient for using it on the **handlebar** of a motorbike, the biggest problem being to be **not water-proof**.
  
 | {{:img:pros_icon.png?nolink&36|}}  | **Low price** (5-10 €).\\ **Very small** size.  | | {{:img:pros_icon.png?nolink&36|}}  | **Low price** (5-10 €).\\ **Very small** size.  |
Line 36: Line 35:
  
 Generally speaking, an Android input device generates a different hardware **ScanCode** when you press each different key. Using an appropriate **keylayout file**, each ScanCode is translated into an **Android KeyCode**, which is sent to the application. For example: the Mocute controller generates the **ScanCode 114** when you press the **A button**, looking at **/system/usr/keylayout/Generic.kl** the scancode is translated into the mnemonic **KEYCODE_VOLUME_DOWN** (which in turn is the decimal value 25) and sent to the app. The app decides what to do with that key press. Generally speaking, an Android input device generates a different hardware **ScanCode** when you press each different key. Using an appropriate **keylayout file**, each ScanCode is translated into an **Android KeyCode**, which is sent to the application. For example: the Mocute controller generates the **ScanCode 114** when you press the **A button**, looking at **/system/usr/keylayout/Generic.kl** the scancode is translated into the mnemonic **KEYCODE_VOLUME_DOWN** (which in turn is the decimal value 25) and sent to the app. The app decides what to do with that key press.
- 
-===== Default key mapping ===== 
- 
-The Mocute-032 controller has a little slide switch with two positions: **GAME** and **KEY**. Each mode generates different **ScanCodes** for the four buttons. Also **the joystick operates differently**: in KEY mode it emulates four digital switches (keyboard keys), while in GAME mode it operates as an **analog joystick** with **two axis**. 
- 
-[{{.:osmadn:mocute-gamepad-keys.jpg?360|Key mapping in GAME mode}}] 
- 
-==== The joystick in GAME mode ==== 
- 
-In **GAME mode**, each **axis position** is reported as a **floating point number** ragining from **-1.0** to **1.0**, where the **zero** is at the **central position**. When the joystick is pushed near to one side, an **Android KeyCode** is generated. This means that beside the axes position, an appropriate KEYCODE_DPAD_UP, KEYCODE_DPAD_DOWN, KEYCODE_DPAD_LEFT or KEYCODE_DPAD_RIGHT is sent to the application. In this case the device **does not generate any ScanCode**. 
- 
-You can see **joystick axes values** with apps like **[[https://play.google.com/store/apps/details?id=ru.elron.gamepadtester|Gamepad tester]]**. You can see **key events** (ScanCodes and KeyCodes) with apps like **[[https://play.google.com/store/apps/details?id=aws.apps.keyeventdisplay|KeyEvent Display]]**. 
- 
-^        ^  KEY Mode                    ^^^  GAME Mode           ^^^ 
-^ ^ ScanCode  ^ Android key code  ^^ ScanCode  ^ Android key code  ^^ 
-^ UP      163 |  87 | KEYCODE_MEDIA_NEXT          | AXIS Y 0x01 -0.8  |   19 | KEYCODE_DPAD_UP     | 
-^ DOWN    165 |  88 | KEYCODE_MEDIA_PREVIOUS      | AXIS Y 0x01  1.0  |   20 | KEYCODE_DPAD_DOWN   | 
-^ LEFT    208 |  90 | KEYCODE_MEDIA_FAST_FORWARD  | AXIS X 0x00 -1.0  |   21 | KEYCODE_DPAD_LEFT   | 
-^ RIGHT  |  168 |  89 | KEYCODE_MEDIA_REWIND        | AXIS X 0x00  0.8  |   22 | KEYCODE_DPAD_RIGHT  | 
-^ A      |  114 |  25 | KEYCODE_VOLUME_DOWN                       304 |   96 | KEYCODE_BUTTON_A    | 
-^ B      |   28 |  66 | KEYCODE_ENTER                             305 |   97 | KEYCODE_BUTTON_B    | 
-^ X      |  115 |  24 | KEYCODE_VOLUME_UP                         307 |   99 | KEYCODE_BUTTON_X    | 
-^ Y      |  158 |   4 | KEYCODE_BACK                |               308 |  100 | KEYCODE_BUTTON_Y    | 
  
 ===== Android Key Layouts ===== ===== Android Key Layouts =====
Line 82: Line 58:
 </file> </file>
  
-**OsmAnd 3.5.5** supports some external input devices, to use the Mocute controller we need to enable the **keyboard external input device**. At the moment the only recognized KeyCodes are:+===== Mocute default key mapping =====
  
-^  OsmAnd KeyCodes                  ^^ +The Mocute-032 controller has a little slide switch with two positions: **GAME** and **KEY**. Each mode generates different **ScanCodes** for the four buttons. **The joystick operates differently**: in KEY mode it emulates four digital switches (keyboard keys which generate the ScanCode), while in GAME mode it operates as an **analog joystick** with **two axis** (without generating a ScanCode). 
-^ KEYCODE_DPAD_RIGHT | Scroll right  + 
-KEYCODE_DPAD_LEFT  | Scroll left   +[{{.:osmadn:mocute-gamepad-keys.jpg?360|Key mapping in GAME mode}}] 
-KEYCODE_DPAD_UP    | Scroll up     + 
-KEYCODE_DPAD_DOWN  | Scroll down   +==== The joystick in GAME mode ==== 
-KEYCODE_PLUS       | Zoom in       + 
-KEYCODE_MINUS      | Zoom out      |+In **GAME mode**, each **axis position** is reported as a **floating point number** ragining from **-1.0** to **1.0**, where the **zero** is at the **central position**. When the joystick is pushed near to one side, an **Android KeyCode** is generated. This means that beside the axes position, an appropriate KEYCODE_DPAD_UP, KEYCODE_DPAD_DOWN, KEYCODE_DPAD_LEFT or KEYCODE_DPAD_RIGHT is sent to the application. The Android app receives a KeyCode, but the device **does not generate any ScanCode**. 
 + 
 +You can see **joystick axes values** with apps like **[[https://play.google.com/store/apps/details?id=ru.elron.gamepadtester|Gamepad tester]]**. You can see **key events** (ScanCodes and KeyCodes) with apps like **[[https://play.google.com/store/apps/details?id=aws.apps.keyeventdisplay|KeyEvent Display]]**. 
 + 
 +^        ^  KEY Mode                    ^^^  GAME Mode           ^^^ 
 +^ ^ ScanCode  ^ Android key code  ^^ ScanCode  ^ Android key code  ^^ 
 +^ UP      163 |  87 | KEYCODE_MEDIA_NEXT          | AXIS Y 0x01 -0.8  |   19 | KEYCODE_DPAD_UP     | 
 +^ DOWN    165 |  88 | KEYCODE_MEDIA_PREVIOUS      | AXIS Y 0x01  1.0  |   20 | KEYCODE_DPAD_DOWN   | 
 +^ LEFT    208 |  90 | KEYCODE_MEDIA_FAST_FORWARD  | AXIS X 0x00 -1.0  |   21 | KEYCODE_DPAD_LEFT   | 
 +^ RIGHT  |  168 |  89 | KEYCODE_MEDIA_REWIND        | AXIS X 0x00  0.8  |   22 | KEYCODE_DPAD_RIGHT 
 +^ A      |  114 |  25 | KEYCODE_VOLUME_DOWN                       304 |   96 | KEYCODE_BUTTON_A    | 
 +^ B      |   28 |  66 | KEYCODE_ENTER                             305 |   97 | KEYCODE_BUTTON_B    | 
 +^ X      |  115 |  24 | KEYCODE_VOLUME_UP                         307 |   99 | KEYCODE_BUTTON_X    | 
 +^ Y      |  158 |   4 | KEYCODE_BACK                |               308 |  100 | KEYCODE_BUTTON_Y    | 
 + 
 +===== Connecting the external input device to OsmAnd ===== 
 + 
 +**OsmAnd 3.5.5** supports some external input devices, to use the Mocute controller we need to enable the generic keyboard external input device; from the Menu button => **Configure profile** => General settings => **External input devices** => **Keyboard**. 
 + 
 +At the moment OsmAnd recognized only a few KeyCodes
 + 
 +Android KeyCode    OsmAnd Action  ^ 
 +KEYCODE_DPAD_RIGHT | Scroll right   
 +KEYCODE_DPAD_LEFT  | Scroll left    
 +KEYCODE_DPAD_UP    | Scroll up      
 +KEYCODE_DPAD_DOWN  | Scroll down    
 +KEYCODE_PLUS       | Zoom in        
 +KEYCODE_MINUS      | Zoom out       |
  
 ===== Remapping the controller keys (root required) ===== ===== Remapping the controller keys (root required) =====
Line 99: Line 102:
   - Associate the **X** button to **zoom in**, and **Y** button to **zoom out**.   - Associate the **X** button to **zoom in**, and **Y** button to **zoom out**.
  
-In theory - to remap the functions of our controller - it should be possible to provide a **specific keylayout file** for just this controller, just giving it the name **Vendor_ffff_Product_0000.kl** (see the vendor and product read from the ''/proc/bus/input/devices'' pseudofile). Unfortunately this does not work, may be because ffff and 0000 are not valid values.+In theory - to remap the functions of our controller - it should be possible to provide a **specific keylayout file** for just this controller: Android's instructions say to simply create a file with the name **Vendor_ffff_Product_0000.kl** (see the vendor and product read from the ''/proc/bus/input/devices'' pseudofile). Unfortunately this does not work, may be because ffff and 0000 are not valid ID values.
  
 So we have to change the **Generic.kl** file, redefining some ScanCodes and axis (the rest of the file must remain untouched): So we have to change the **Generic.kl** file, redefining some ScanCodes and axis (the rest of the file must remain untouched):
Line 110: Line 113:
 </file> </file>
  
 +This change have the side effect to remap all the external keyboards that we will connect to our Android device!
 ===== Key Mapping Test ===== ===== Key Mapping Test =====
  
 Using the **[[https://play.google.com/store/apps/details?id=aws.apps.keyeventdisplay|KeyEvent Display]]** Android app, you can see what **ScanCode** and what associated **Android key code** is generated by each key pressed. Using the **[[https://play.google.com/store/apps/details?id=aws.apps.keyeventdisplay|KeyEvent Display]]** Android app, you can see what **ScanCode** and what associated **Android key code** is generated by each key pressed.
  
-Using the **[[https://play.google.com/store/apps/details?id=com.flossga.android.whichbutton|Key Tester]]** Android app, you can check what **Android key code is received by the app** when you press a key. So you can check if the **key layout** (mapping from //ScanCode// to //Android key code//) is applied as expected.+Using the **[[https://play.google.com/store/apps/details?id=com.flossga.android.whichbutton|Key Tester]]** Android app, you can check what **Android key code is received by the app** when you press a key. So you can check if the **key layout** (mapping from //ScanCode// to //Android KeyCode//) is applied as expected.
  
 Using the **[[https://play.google.com/store/apps/details?id=ru.elron.gamepadtester|Gamepad tester]]** Android app, you can see what **joystick axis** are associated with a gamepad, and the analogic values reported for each **joystick position**. Using the **[[https://play.google.com/store/apps/details?id=ru.elron.gamepadtester|Gamepad tester]]** Android app, you can see what **joystick axis** are associated with a gamepad, and the analogic values reported for each **joystick position**.
 +
 +===== Other remote controllers =====
 +
 +  * **[[https://daytona-global.com/products/?page=Products_Product&mfrID=13&categID=28&subcategID=80&productID=87352|Daytona Smartphone controller]]** - Sent keypresses to the Android device: Enter, Power, Escape, Home, Joystick.
 +  * **[[https://carpe-iter.com/carpe-iter-control/|Carpe Iter Control]]** - Seven programmable keys, with two functions each.
  
 ===== Web References ===== ===== Web References =====