In this blog post I will show you how to configure the RN4020 module from Microchip as an Eddystone Bluetooth beacon, using one BLE2 click and one USB-UART click board from MikroElektronika. Of course, this tutorial applies to any other RN4020 breakout boards and can be used with almost any FTDI-based USB-UART which provides RTS and CTS data pins.
As a prerequisite, the RN4020 module must be updated to the latest firmware version BTLE v1.33.4 BEC. If your RN4020 module comes with an older firmware version you have to upgrade it first — see also the RN4020 firmware upgrade tutorial for instructions.
Before we go to the RN4020 configuration, a few words about Bluetooth beacon technologies…
First of all, what the heck is a Bluetooth beacon? Well, it’s a small device that exist for the sole purpose to broadcast information to nearby smart devices that are listening for those advertisement packets. So, to use a beacon one must have a smart device with Bluetooth enabled, and depending on the beacon type you might need a dedicated app that listens to those broadcasted packets and performs different actions.
The most obvious use is as a shopping aid, broadcasting special offers, etc. Museums can use beacons to act like a virtual guide, allowing for a dedicated app to display personalized information. Packets broadcasted by beacons can be used to provide accurate location. And those are only a few possible applications of the Bluetooth beacon…
One must observe that actually the beacon itself is a “dumb device” — it does only broadcast messages, the rest is done by the application installed on the smart device. The beacon does not track you. It simply can’t, as it’s a broadcast-only device. If there’s any user tracking, that is done within the application on the smart device.
By now three major beacon technologies are on the market: iBeacon, AltBeacon and Eddystone.
iBeacon is a technology developed by Apple in 2013. An advertised packet consists on a standard iBeacon prefix, 16-byte UUID, followed by a 2-byte major and 2-byte minor. Although any beacon can be regarded as an Ibeacon if it broadcasts according to the Apple standard, the use of iBeacons is limited by the strict Apple licensing policies.
AltBeacon is a standard developed by Radius networks as an open and inter-operable specification for proximity beacons.
Eddystone beacon technology was developed by Google in 2015 and brings some nice enhancements over the AltBeacon standard. Eddystone beacons can be detected by both Android and iOS devices. Eddystone is an open standard, the specifications being available on https://github.com/google/eddystone. In many ways the Eddystome beacons can be regarded as the foundation of the physical web, which aims to be an “open approach to enable quick and seamless interactions with physical objects and locations”.
An interesting aspect of the Eddystone beacons is that it provides several different advertising frames:
- Eddystone-UID: A unique, static ID with a 10-byte Namespace component and a 6-byte Instance component.
- Eddystone-EID: A time-varying beacon frame that can be resolved to a stable identifier by a linked resolver.
- Eddystone-URL: A compressed URL that, once parsed and decompressed, is directly usable by the client.
- Eddystone-TLM: Beacon status data that is useful for beacon fleet maintenance, and powers Google Proximity Beacon API’s diagnostics endpoint. TLM frames are usually interleaved with an identifying frame such as Eddystone-UID or Eddystone-EID.
From a maker’s point of view, one of the most interesting aspects of the Eddystone beacon technology is the ability to broadcast URL information. Thus, many smart devices that run Google Chrome with physical web enabled can receive the URL information, without the need of a dedicated app.
With Eddystone I can simply place one beacon outside my maker space, advertising it to anyone in the close proximity. All I have to do is broadcast a short URL to my blog page. Simple as that. And you will see that it’s so easy to implement such a beacon, and it uses only one RN4020 and a pair of AA batteries.
Going for a such simple approach means that some sacrifices must be done — the beacon I propose today broadcasts only URL frames. No TLM (telemetry) frames are broadcasted, so you can’t check the beacon status from a distance. Also no UID frames, as those are usable only with a dedicated app, and writing apps for iOS and Android is beyond the purpose of this blog.
An Eddystone URL frame
Supposing I wish to broadcast the URL of this tutorial. The Eddystone packet is quite short, so the full name of the page will not fit into it. Thus, I have to use some URL shortening service. This tutorial uses the short URL https://bit.ly/mybcn, which can be used to redirect usets to this page, for example. It also provides some analytics, so I will know how many people have visited this page coming from my beacon.
To advertise an URL one must create an URL frame according to the Eddystone specifications:
Byte offset Field Description Frame type Must be 0x10 for URL frame 1 TX power Calibrated TX power at 0m 2 URL scheme Encoded Scheme Prefix 3+ Encodd URL 0–17 bytes
A precise value of TX power at 0m is hard to determine. Instead I performed several measurements at a distance of 1m, computed the average value then added 41dBm to that. 41dBm is the signal loss that occurs over 1 meter. Measurements were performed using nRF Master Control all on a Lenovo TAB 2, with Android 5.0.1. I found that the TX power at 0m is -14 dbm, which as a signed HEX is 0xF2.
URL prefix scheme is a way to shorten the http… part of the URL. Possible values are:
| Decimal | Hex | Expansion |
| | 0x00 | http://www. |
| 1 | 0x01 | https://www. |
| 2 | 0x02 | http:// |
| 3 | 0x03 | https:// |
So in the case of the shortlink above, the https:// part becomes just 0x03. One single byte. The rest of the address is encoded in ASCII. The full frame, according to https://github.com/google/eddystone/blob/master/protocol-specification.md should be:
0x03, // Length of Service List
0x03, // Param: Service List
0xAA, 0xFE, // Eddystone ID
0x12, // Length of Service Data (0x12 = 18 bytes)
0x16, // Service Data (1 byte)
0xAA 0xFE // Eddystone ID (2 bytes)
0x10 // Frame type: URL (1 byte)
0xF2 // Power (1 byte)
0x03 // https:// (1 byte)
0x62 // b (12 bytes)
0x69 // i
0x74 // t
0x2E // .
0x6C // l
0x79 // y
0x2F // /
0x6D // m
0x79 // y
0x62 // b
0x63 // c
0x6E // n (total is 18 bytes)
The whole encoded URL frame is: 0303AAFE1216AAFE10F2036269742E6C792F6D7962636E
Quite complicated, huh? Well, this whole encoding process will probably run for one time only. besides, there are some tools that help, such is the Eddystone URL generator by Martin Kompf, and the ASCII-to-HEX converter.
RN4020: Eddystone Bluetooth beacon
To use the RN4020 as an Eddystone beacon one must use the custom advertisement features, which are available only in version 1.33.4 BEC. If I choose to broadcast only the URL frame that I can use the scripting features of the RN2040 and I can use this little BLE module in standalone mode, without a microcontroller to drive it.
To program the script I will use the same connection as in the firmware update tutorial, with an USB-UART click providing RX, TX lines and power, and SWAKE pin connected to Vcc. I will use TerraTerm to run the following commands:
# Clear previous Eddystone frame
# Add Eddystone service to a new frame
# Add URL information to the frame
# Start advertising
# End with ESC (works fine with ESC key in TerraTerm)
Then I configure the script to run at power on:
SR,01001000 // Run script after power on
R,1 // Reboot
The + command turn on echo, so I can see on the terminal the command I have sent.
WC clears any previous script.
WW allows for a script to be entered.
The script is set to start at power on (@PW_ON event). It first performs a NZ command, which clears any previous advertising payload. Then I start building a new advertising frame by using NB to append information. In my case I fist append 03AAFE which is the Eddystone service, then I append the frame content, respectively 16AAFE10F2036269742E6C792F6D7962636E. The A command starts advertising in default mode, at 100ms intervals. Pressing ESC key on the PC exits the scripting mode.
If you wish you can run LW command to verify the content of the script. The script can be manually startedd with WR, and can be stopped with WP.
SR,01001000 sets the script to be run at startup, with serial output enabled. R,1 reboots and save the settings. At this moment the USB-UART is not needed anymore, and the beacon can run by itself on battery power.
And here are some screen captures from Android and iOS devices:
Given the default advertising period of 100ms, with the above connections the current consumption of this particular BLE2 click module is approximately 3.4mA with the blue WAKE LED on, and 2.4mA with the WAKE LED removed.
With SWAKE pin set to low the current consumption is 41μA, but in this mode UART is limited to 2400 baud. Thus, I can run on a pair of AA alkaline batteries for more than 5 years, or on a CR2032 battery for about six months (estimated using http://oregonembedded.com/batterycalc.htm).
Originally published at https://electronza.com on May 25, 2016. Moved to Medium on April 24, 2020.