Mapping Caps-Lock Key to Control Key

I used to use Happy Hacking Keyboard. Its control key is located where usual keyboard has caps-lock key. (see below picture). So, for me it’s natural that control key is there, below the tab key and above the shift key.

This post shows steps to reassign the caps-lock key to control key on ordinary keyboard, on Windows, Mac OS X, and Linux.

 

Contents
1. Windows
2. Mac OS X
3. Linux
4. Reference

 

1. Windows
I tested with Windows 10 laptop. According to [1], this also works for Windows 7, 8 and Vista.

1-1. Download and install SharpKeys from here.

1-2. Launch SharpKeys and click on “Add” button.

1-3. In “Edit Key Mapping” window, select “Caps Lock” as “From key”, and “Left Ctrl” as “To key”, then click on “OK”.

1-4. Click on “Write to Registry”.

1-5. Restart PC for the changes to take effect.

 

 

2. Mac OS X
2-1. Open “System Preferences”.

2-2. Select “Keyboard”.

2-3. Click on “Modifier Keys…” button.

2-4. Select “Control” from pull-down menu for Caps Lock Key, then click on “OK”.

 

 

3. Linux
I tested this with Ubuntu 16.04.

3-1. Open keyboard config file.

sudo nano /etc/default/keyboard

3-2. Search a line starts with “XKBOPTIONS” and edit as below:

XKBOPTIONS=ctrl:nocaps

3-3. Restart PC for the changes to take effect.

sudo reboot

 

 

4. References
[1] Map Any Key to Any Key on Windows 10, 8, 7, or Vista – How-To Geek
[2] macOS Sierra: Change modifier keys – Apple Support
[3] Change caps-lock to control in virtual console on Ubuntu 17 – ask ubuntu

 

 

Creating AltBeacon with Raspberry Pi using BlueZ Example Code


Update (Jul 9, 2019):
Step 1 is no longer required since Raspbian Buster (2019-06-20). Please check the updated steps in here.


 

A previous post showed the steps to make an iBeacon transmitter with Raspberry Pi using BlueZ example code (i.e. “example-advertisement). This post shows the steps for AltBeacon [1] in the same manner.

 

Here are the contents of this post.

Contents
– Prerequisites
– Steps
1. Enable experimental flag
2. Download BlueZ
3. Modify BLE Advertisement Example Code
4. Test
– Summary
– Reference

 

Prerequisites
Here are some prerequisites before start.

  • Raspberry Pi 3 B+ or Raspberry Pi Zero W
    Or any other model with Bluetooth adapter (e.g. Plugable BLE Adapter, Panda Bluetooth 4.0 Adapter)
  • Raspbian Stretch (March 2018)
    I would suggest to use Desktop version of Stretch because I got “DBus.Error.AccessDenied” for some reason when I ran “example-advertisement” on Raspbian Lite. It seems it’s similar to this but couldn’t figure out the cause/workaround.
  • Internet access
    It’s required to download BlueZ example code. Here is a Wi-Fi Setup steps. If you already have the code, you can work offline.

 

Steps
1. Enable experimental flag
Skip to Step 2 if you are using BlueZ 5.48 or higher. (update BlueZ to 5.48)

$ bluetoothd -v
5.48

If not, follow the steps below.

Bluetooth service needs to be executed with experimental flag since ‘LEAdvertisingManager1’ interface is an experimental feature until BlueZ 5.48 release.

1-1. Open the configuration file for Bluetooth service.

sudo nano /lib/systemd/system/bluetooth.service

1-2. Find a line starting with “ExecStart” and add “–experimental” at the end of the line. After modification, the line should look like this:

ExecStart=/usr/libexec/bluetooth/bluetoothd --experimental

1-3. Reload the configuration file and restart Bluetooth service.

sudo systemctl daemon-reload 
sudo systemctl restart bluetooth.service

1-4. Check the status of Bluetooth service. [Optional]

systemctl status bluetooth.service

You should see the experimental flag. (Line 9 in the example below)

pi@raspberrypi:~ $ systemctl status bluetooth.service 
● bluetooth.service - Bluetooth service
   Loaded: loaded (/lib/systemd/system/bluetooth.service; enabled; vendor preset: enabled)
   Active: active (running) since Wed 2018-02-21 14:31:19 UTC; 4s ago
     Docs: man:bluetoothd(8)
 Main PID: 1122 (bluetoothd)
   Status: "Running"
   CGroup: /system.slice/bluetooth.service
           └─1122 /usr/lib/bluetooth/bluetoothd --experimental

 

2. Download BlueZ
2-1. Download BlueZ source code.

wget www.kernel.org/pub/linux/bluetooth/bluez-5.43.tar.xz

2-2. Extract the archive file.

tar xvf bluez-5.43.tar.xz

2-3. Run the sample code and make sure that it works. [Optional]

./bluez-5.43/test/example-advertisement

Output should be like this:

$ ./bluez-5.43/test/example-advertisement
GetAll
returning props
Advertisement registered

* Press Ctrl + C to stop the script.

 

3. Modify BLE Advertisement Example Code
3-1. Copy the example code.

cp ./bluez-5.43/test/example-advertisement ./example-altbeacon

3-2. Open the file and look for TestAdvertisement class.

3-3. Replace ‘__init__’ method:

    def __init__(self, bus, index):
        Advertisement.__init__(self, bus, index, 'peripheral')
        self.add_service_uuid('180D')
        self.add_service_uuid('180F')
        self.add_manufacturer_data(0xffff, [0x00, 0x01, 0x02, 0x03, 0x04])
        self.add_service_data('9999', [0x00, 0x01, 0x02, 0x03, 0x04])
        self.include_tx_power = True

with:

    def __init__(self, bus, index):
        company_id =  0x0118
        type =       [0xBE, 0xAC]
        id1 =        [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
                      0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16]
        id2 =        [0x11, 0x22]
        id3 =        [0x33, 0x44]
        rssi_at_1m = [0xB3]
        feature  =   [0x00]
        Advertisement.__init__(self, bus, index, 'peripheral')
        self.add_manufacturer_data(company_id, type + id1 + id2 + id3 + rssi_at_1m + feature)

 

4. Test
4-1. Run the code. The console output should be same as Step 2-3.

./example-altbeacon

4-2. Find your Raspberry Pi using a beacon scanner app. If everything goes well, the Raspberry Pi should be broadcasting AltBeacon message and it can be detected by app. Below are examples of apps.

‘nRF Connect’ for Android

 

‘Locate Beacon’ for iPhone

 

Summary
AltBeacon is an open source version of Apple’s iBeacon. It has the same functionality as iBeacon, and the two have similar data structure as below.

*2 : Bluetooth 4.0 Core Specification, Volume 3, Part C, Appendix C, 18.1 Flags
*4 Manufacture dependent value
*5 Application dependent value
*6 Device dependent value

 

References
[1] AltBeacon

 

 

Creating iBeacon with Raspberry Pi using BlueZ Example Code


Update (Jul 9, 2019):
Step 1 is no longer required since Raspbian Buster (2019-06-20). Please check the updated steps in here.


 

This post shows steps to create an iBeacon with Raspberry Pi, by modifying BlueZ BLE Advertisement example code (i.e. “example-advertisement).

Note:
Even though it uses Bluetooth Low Energy standard, iBeacon is Apple’s proprietary protocol and making/deploying iBeacon devices requires the license from Apple [1]. The scope of this post is limited to getting familiar with BlueZ advertising example code and iBeacon format for experimental purpose.

Here are the contents of this post.

Contents
– Prerequisites
– Steps
1. Enable experimental flag
2. Download BlueZ
3. Modify BLE Advertisement Example Code
4. Test
– Summary
– Reference

 

Prerequisites
Here are some prerequisites before start.

  • Raspberry Pi 3 B+ or Raspberry Pi Zero W
    Or any other model with Bluetooth adapter (e.g. Plugable BLE Adapter, Panda Bluetooth 4.0 Adapter)
  • Raspbian Stretch (Nov 2017)
    I would suggest to use Desktop because I got “DBus.Error.AccessDenied” for some reason when I ran “example-advertisement” on Raspbian Lite. It seems it’s similar to this but couldn’t figure out the cause/workaround.
  • Internet access
    It’s required to download BlueZ example code. Here is a Wi-Fi Setup steps. If you already have the code, you can work offline.

 

Steps
1. Enable experimental flag
Bluetooth service needs to be executed with experimental flag since ‘LEAdvertisingManager1’ interface, which is used in the example code, is experimental feature in BlueZ 5.43 (pre-installed in Stretch Nov 2017). In case you’ve updated BlueZ to 5.48 or higher, skip Step 1 since the interface have been marked as stable since 5.48. [2]

1-1. Open the configuration file for Bluetooth service.

sudo nano /lib/systemd/system/bluetooth.service

1-2. Find a line starting with “ExecStart” and add “–experimental” at the end of the line. After modification, the line should look like this:

ExecStart=/usr/libexec/bluetooth/bluetoothd --experimental

1-3. Reboot the board to restart Bluetooth service.

sudo reboot

1-4. Check the status of Bluetooth service. [Optional]

systemctl status bluetooth.service

You should see the experimental flag. (Line 9 in the example below)

pi@raspberrypi:~ $ systemctl status bluetooth.service 
● bluetooth.service - Bluetooth service
   Loaded: loaded (/lib/systemd/system/bluetooth.service; enabled; vendor preset: enabled)
   Active: active (running) since Wed 2018-02-21 14:31:19 UTC; 4s ago
     Docs: man:bluetoothd(8)
 Main PID: 1122 (bluetoothd)
   Status: "Running"
   CGroup: /system.slice/bluetooth.service
           └─1122 /usr/lib/bluetooth/bluetoothd --experimental

 

2. Download BlueZ
2-1. Download BlueZ source code.

wget www.kernel.org/pub/linux/bluetooth/bluez-5.43.tar.xz

2-2. Extract the archive file.

tar xvf bluez-5.43.tar.xz

2-3. Make sure that the sample code works. [Optional]

./bluez-5.43/test/example-advertisement

Output should be like this:

$ ./bluez-5.43/test/example-advertisement
GetAll
returning props
Advertisement registered

 

3. Modify BLE Advertisement Example Code
3-1. Copy the example code.

cp ./bluez-5.43/test/example-advertisement ./example-ibeacon

3-2. Open the file and look for TestAdvertisement class.

3-3. Replace ‘__init__’ method:

    def __init__(self, bus, index):
        Advertisement.__init__(self, bus, index, 'peripheral')
        self.add_service_uuid('180D')
        self.add_service_uuid('180F')
        self.add_manufacturer_data(0xffff, [0x00, 0x01, 0x02, 0x03, 0x04])
        self.add_service_data('9999', [0x00, 0x01, 0x02, 0x03, 0x04])
        self.include_tx_power = True

with:

    def __init__(self, bus, index):
        company_id =   0x004C
        beacon_type = [0x02, 0x15]
        uuid =        [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 
                       0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16]
        major =       [0x11, 0x22]
        minor =       [0x33, 0x44]
        tx_power =    [0xB3]
        Advertisement.__init__(self, bus, index, 'peripheral')
        self.add_manufacturer_data(company_id, beacon_type + uuid + major + minor + tx_power)

 

4. Test
4-1. Run the code. The console output should be same as Step 2-3.

./example-ibeacon

4-2. Find your ibeacon running on Raspberry Pi using a beacon scanner app (e.g. nRF Connect).

 

Summary
If everything goes well, the Raspberry Pi should be broadcasting iBeacon message and you can find it with a scanner app. Some of the iBeacon data can be configured on Step 3-3 for your application. Here is a brief explanation of those data.

  • ‘company_id’
    Company Identifiers are defined by Bluetooth SIG [3]. For iBeacon, it must be Apple’s ID (i.e. 0x004C).
  • ‘beacon_type’
    It must be ‘0x0215’ which means Proximity Beacon.
  • ‘uuid’
    Proximity UUID is an application unique ID.
  • major‘ and ‘minor
    Major Number and Minor Number are application dependent values which can be used to identify more precise location, etc.
  • ‘tx_power’
    Tx Power is a device dependent value. It must be calibrated for each device when it’s deployed.

 

References
[1] iBeacon – Apple Developer
[2] BlueZ Release Notes
[3] Company Identifiers – Bluetooth SIG

 

 

Setting Up UART Serial Communication between Raspberry Pis


This post shows how to setup serial communication between two Raspberry Pi boards.

Here is the list of contents of this post.

Contents

 

Prerequisites

 

Steps
1. Wiring
Connect jumper wires between two Raspberry Pi boards. Check this useful site for pinout (GND, Tx, and Rx).

Note: Rx pin on one Raspberry Pi should be connected to Tx pin on the other Raspberry Pi.

 

Note: Step 2 to Step 4 need to be done on both Raspberry Pis. 

2. Enabling UART
2-1. Open “/boot/config.txt”.

sudo nano /boot/config.txt

2-2. Add the lines below at the end of the file.

# Enable UART
enable_uart=1

 

3. Disabling console service
3-1. Disable serial-getty service.

sudo systemctl disable serial-getty@ttyS0.service
3-2. Open “/boot/cmdline.txt”.
sudo nano /boot/cmdline.txt

3-3. Remove “console=serial0,115200”, then save the file.

3-4. Reboot.
sudo reboot

 

4. Setting up terminal emulator
To send and receive data, I’ll use minicom, a text-based terminal emulator.

4-1. Install minicom.

sudo apt-get install minicom -y

4-2. Type below to launch minicom and connect to UART.

minicom -b 115200 -o -D /dev/ttyS0

4-3. Press Ctrl-A then E to enable local echo. You should see “Local echo ON” message at the bottom of the screen.

4-4. Press Ctrl-A then A to enable linefeed. You should see “Add linefeed ON” message at the bottom of the screen.

 

5. Verify
5-1. Type something in minicom on one Raspberry Pi. You should be able to see the text on the other Raspberry Pi.

5-2. Type something back on the other Raspberry Pi.

 

Note: You can exit minicom by pressing Ctrl-A, and X, then select “Yes”.

 

 

Updating BlueZ on Raspberry Pi (5.43 to 5.48)


Update (Jul 9, 2019):
Now, Raspbian Buster, released on 6/20/2019, has bluez 5.50 by default!


Update (March 3, 2019):
Please see this post to update BlueZ to 5.50.


 

This post shows how to update BlueZ from 5.43 (the default version comes with Raspbian Stretch November 2017 version) to 5.48 (the latest as of 2/14/2018) on Raspberry Pi.
According to the release notes [1], many issues (especially GATT related issues) have been fixed and also, Advertising Manager API, which was previously marked as experimental, is now stable in 5.48.

Here is the list of contents of this post.

– Assumptions
– Steps
1. Check Current BlueZ Version
2. Install Dependencies
3. Install Latest BlueZ
4. Verify Update
– Reference

 

Assumptions
In this post, I assume that you already have Raspberry Pi 3 B+ or Raspberry Pi Zero W running Raspbian Stretch November 2017 version.

 

Steps
1. Check Current BlueZ Version
1-1. Before starting, let’s check the current BlueZ version.

bluetoothctl -v

In case you are using Raspbian Stretch (November 2017 version), the BlueZ version should be 5.43.

$ bluetoothctl -v
5.43

 

2. Install Dependencies
2-1. Update the package list.

sudo apt-get update

2-1. Install the dependencies.

sudo apt-get install libdbus-1-dev libglib2.0-dev libudev-dev libical-dev libreadline-dev -y

 

3. Install Latest BlueZ
3-1. Download the latest version of BlueZ source code.

wget www.kernel.org/pub/linux/bluetooth/bluez-5.48.tar.xz

3-2. Uncompress the downloaded file.

tar xvf bluez-5.48.tar.xz && cd bluez-5.48

3-3. Configure.

./configure --prefix=/usr --mandir=/usr/share/man --sysconfdir=/etc --localstatedir=/var --enable-experimental 

3-4. Compile the source code.

make -j4

3-5. Install.

sudo make install

3-6. Reboot Raspberry Pi 3.

sudo reboot

 

4. Verify Update
4-1. Verify the BlueZ version by issuing the command below.

bluetoothctl -v

The result should be like this:

$ bluetoothctl -v
bluetoothctl: 5.48

 

References
[1] BlueZ Release Notes
[2] Installing Bluez 5.44 onto Raspbian? – Raspberry Pi Stack Exchange