ESP32 (31) – BLE, GAP

In my previous tutorials you learned how to use the wifi interface of the esp32 chip. Starting from this post, I’m going to explain you the second wireless technology the esp32 chip supports: bluetooth.

In particular, my tutorial will be about Bluetooth Low Energy (BLE), sometimes called also Bluetooth 4.0 or Bluetooth Smart:

ble-001

Bluetooth Low Energy

BLE is a technology to build personal wireless area networks (WPAN); that is it allows to put in communication different devices (computers, smartphones, smartwatches…) “close” to each other (a theoretical maximum distance of 100m). As the name suggests, version 4.0 of the Bluetooth standard was designed to reduce the power consumption of the devices connected to the network.

Devices are divided into two families:

  • central
  • peripheral

the first ones (central) are devices like PCs, tablets or smartphones with good processing power and memory. The second ones (peripheral) are instead sensors, tags… with less hardware resources and power. A central device can be connected to more peripheral devices at the same time, while it’s not true the opposite:

ble-002

BLE devices periodically report their presence by transmitting advertising packets. The advertising packet can contain up to 31 bytes of data and the transmission frequency can be chosen by the single device: reducing this frequency can indeed reduce energy consumption.

If a BLE device, after having received an avertising package, wants to obtain more information from the device that transmitted it, it can request a second packet of information (always for a maximum of 31 bytes), the scan response packet. The transmission of this second data package is optional:

ble-003

A BLE device can take advantage of advertising packages to send data in broadcast mode. In this case, this device is called a broadcaster, while the devices that receive the data are called observers.

What explained above is defined within a BLE specification called Generic Access Profile (GAP).

esp32

In this first tutorial you’ll learn how to develop a program that will periodically scan the air looking for BLE devices, that is a program which receives advertising packets and displays the data received in the serial console.

Before compiling a program which uses the Bluetooth controller, make sure (using menuconfig) that the controller is enabled (Component config -> Bluetooth):

ble-004

Start your program with the required header files:

#include "esp_bt.h"
#include "esp_bt_main.h"
#include "esp_gap_ble_api.h"

You also need to initialize the NVS partition, used by the Bluetooth driver:

ESP_ERROR_CHECK(nvs_flash_init());

the Bluetooth controller of the esp32 chip supports both the classic and the low energy mode. If one of this two modes is not required in your program, you can release the memory the framework normally allocates to manage it using the esp_bt_controller_mem_release() command. In this example you’re not going to use the classic mode, so:

ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT));

Now you can configure (using the default settings) the controller in BLE mode:

esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
esp_bt_controller_init(&bt_cfg);
esp_bt_controller_enable(ESP_BT_MODE_BLE);

The esp-idf framework esp-idf includes the Bluedroid bluetooth stack. This library was developed by Broadcom and used by Android since version 4.2 Bluedroid is initialized and enabled with the following commands:

esp_bluedroid_init();
esp_bluedroid_enable();

Now you’re ready to start scanning…

GAP, events

In a similar way to what you learned about the wifi driver, the bluetooth driver also runs in a thread separate from our program and communicates with it via events. In order to receive such events, you have to implement a callback function. Whenever the bluetooth driver has to notify an event, it will call that function.

The prototype of the callback function is:

static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param);

You tell the driver which callback function has to use with the esp_ble_gap_register_callback() method:

ESP_ERROR_CHECK(esp_ble_gap_register_callback(esp_gap_cb));

The Bluetooth driver handles several events, there are the ones related to the scan process:

ble-005

Before being able to start the scan process, you have to configure the scan parameters. The configuration is performed using the esp_ble_scan_params_t struct. It’s very important that the variable with the scan parameters is available during all the scan process; it’s therefore necessary to define it globally:

static esp_ble_scan_params_t ble_scan_params = {
  .scan_type              = BLE_SCAN_TYPE_ACTIVE,
  .own_addr_type          = BLE_ADDR_TYPE_PUBLIC,
  .scan_filter_policy     = BLE_SCAN_FILTER_ALLOW_ALL,
  .scan_interval          = 0x50,
  .scan_window            = 0x30
};

With the esp_ble_gap_set_scan_params() method you configure the scan process passing the struct defined above to the driver:

esp_ble_gap_set_scan_params(&ble_scan_params);

When the driver has finished the configuration, it calls the callback function with the event ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT. Depending on the event raised, the callback function also receives some parameters. The framework’s Programming Guide explains – for each event – the related parameters. For this event, it’s available the variable scan_param_cmpl that contains only the status parameter.

In the callback function you can use the switch statement to identify each event:

switch (event) {
  case ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT:
  [...]
  break;

and check if the configuration was successful with:

if(param->scan_param_cmpl.status == ESP_BT_STATUS_SUCCESS)

If so, you can start the scan process:

esp_ble_gap_start_scanning(10);

The parameter is the scan duration (in seconds).

Once the scan process has started, the driver raises the ESP_GAP_BLE_SCAN_START_COMPLETE_EVT event. For this event too it’s possible to verify the correct execution by reading the status parameter (pay attention: the name of the variable which contains the parameter changes!):

case ESP_GAP_BLE_SCAN_START_COMPLETE_EVT:
  if(param->scan_start_cmpl.status == ESP_BT_STATUS_SUCCESS)
    printf("Scan started\n\n");
  else 
    printf("Unable to start scan process");
  break;

GAP, scan process

During the scan process, for each advertising packet the chip receives the event ESP_GAP_BLE_SCAN_RESULT_EVT is raised.

This event contains some subevents. You can identify which subevent was raised reading the scan_rst.search_evt parameters. Two subevents are in particular interesting:

ble-006

the first tells you that a device was detected, while the second one that the scan process completed.

For each detected device, various information is available. For now let’s print its address in the console:

case ESP_GAP_BLE_SCAN_RESULT_EVT:
  if(param->scan_rst.search_evt == ESP_GAP_SEARCH_INQ_RES_EVT) {
    printf("Device found: ADDR=");
    for(int i = 0; i < ESP_BD_ADDR_LEN; i++) {
      printf("%02X", param->scan_rst.bda[i]);
      if(i != ESP_BD_ADDR_LEN -1) printf(":");
    }

The address is an uint8_t array, whose size is defined by the ESP_BD_ADDR_LEN constant. The address is normally displayed in hex form, with the bytes separated by :

ble-007

Device list management

As explained above, the ESP_GAP_BLE_SCAN_RESULT_EVT event is raised everytime a device sends an advertising packet. This means that a single device will be detected multiple times during the scan process.

It’s therefore necessary to maintain a list of the known devices. In my Github repository you can find a test program that scans the network and prints all the detected devices.

You can verify if it works correctly comparing what the program detects with the BLE devices listed by a smartphone… for Android for example you can use the very good nRF Connect application by Nordic.

Here’s what my program detected:

ble-008

and here’s the nRF Connect’s screenshot:

ble-009

 

BLE with Bluno Beetle

Some time ago my friend Mauro Alfieri showed me an interesting development board produced by DFRobot and called Bluno Beetle (now Beetle Ble). It seemed the perfect board to start “playing” with the Bluetooth Low Energy (BLE) technology; therefore I ordered  one board directly from the DFRobot store.

I expected to receive the usual anonymous parcel with the board inside an antistatic plastic bag; DFRobot instead sends its products in an elegant cardboard box, protecting them with foam:

bluno-011 bluno-012

Bluno Beetle is really small and therefore perfect for wearable projects:

bluno-013 bluno-014

But what is it? Simplifying is a board, Arduino Uno compatible (it hosts the ATmega328P microcontroller) to which has been added the CC2540 chip from Texas Instruments to act as USB and BLE controller. The two chips communicate via a serial interface:

bluno-001

The CC2540 chip is actually a real microcontroller that runs a firmware developed by DFRobot. This firmware can be configured using AT commands. Normally the firmware runs in transparent mode, that is it acts as a “bridge” between the USB/BLE interfaces and the ATmega microcontroller. If you then connect the Bluno to your PC and activate the serial monitor, each character you type is forwarded to the ATmega and viceversa.

To send AT commands, first you have to enter the AT mode of the firmware, sending the + character 3 times (without appending a line ending). The firmware confirms the new mode with the sentence “Enter AT Mode”:

bluno-006

Now you can send the commands, appending the Windows line terminator (CRLF). For example to display the firmware version:

bluno-007

To exit the AT mode and go back to transparent mode, you have to send the AT+EXIT command.

Drivers

It may happen that – if it’s the first time you connect the Bluno Beetle to your Windows PC – it is not correctly recognized:

bluno-003

The correct drivers are shipped with the Arduino IDE. You only need to do a manual installation specifying the path where you installed the IDE:

bluno-004

Windows will identify the new device as an Arduino Uno:

bluno-005

Arduino

As explained above, if the firmware running on the CC2540 chip is in transparent mode, using the USB connection you can talk directly to the ATmega328P microcontroller. This means that you can program the microcontroller using the Arduino IDE without any problems… just choose Arduino Uno as board and select the correct serial port:

bluno-008

BLE and transparent mode

In transparent mode Bluno transmits via BLE each byte it receives from Arduino (the ATmega microcontroller) and – viceversa – it sends to Arduino each byte it receives from BLE.

In this first post let’s explore the demo application DFRobot provides; in a future post I’ll explain how to develop your application to interact with Bluno Beetle via BLE.

If you have an Android smartphone, you can directly install the apk file for the application named BlunoBasicDemo (application of which the source code is also available). In the same Github repository you can also find the source code of the iOS application, you have to compile by yourself.

Compile and upload the following sketch on the board:

unsigned long previous_time = 0;
 
void setup() {
  Serial.begin(115200);
}
 
void loop() {
 
  if (Serial.available() > 0) {
    int incomingByte = Serial.read();
    Serial.print("New byte received: 0x");
    Serial.println(incomingByte, HEX);
  }
  unsigned long actual_time = millis();
  if(actual_time - previous_time > 10000) {
    Serial.println("Hello world!");
    previous_time = actual_time;
  }
}

The sketch reads the incoming bytes (coming from the app) and sends back to the app their hexadecimal value. Every 10 seconds moreover the sketch sends to the app the text Hello world!.

Launch the app. After having clicked on the Scan button, you can choose your Bluno board from the list of detected devices:

bluno-009

Every 10 seconds you should see a new HelloWorld! string appear. You can try to send a character (for example the letter “a”); you’ll receive an answer from Arduino (0x61 is indeed the hex code – in the ASCII table – for the letter “a”):

bluno-010

HID mode

Bluno also supports the HID (Human Interface Device) mode. When running in this mode, Bluno simulates an input peripheral (keyboard, mouse…) connected via BLE.

The AT command that enables this mode is:

  • AT+FSM=FSM_HID_USB_COM_BLE_AT

After having enabled the HID mode, you can send one or more “keys” with:

  • AT+KEY=

you can send up to 3 different keys at a time, concatenating their codes with the + character. The codes to be used, according to the type (page) of the HID device, are listed in the USB specification.

The AT+KEY command notifies the pressure of a key on the keyboard.  It is therefore necessary, after a few moments, to send the AT+KEY=0 command to indicate that the key has been released; otherwise on the PC associated with Bluno you’ll see the character appear repeatedly!

Debug mode

Using two different AT commands you can enable the debug mode of the firmware. This mode allows to receive – via the USB connection – a copy of all the data sent and received through the BLE connection.

The two commands are:

  • AT+BLUNODEBUG=ON (copies the messages sent by the ATmega)
  • AT+USBDEBUG=ON (copies the messages received from BLE)

bluno-002

By default the first debug mode is active, while the second is disabled. You can verify it if you upload the sketch listed above: in the serial monitor you’ll see the Hello World! sentences but not the characters sent by the app.

Motorized Camera Dolly Rolls With the Changes

Over the last semester, Cornell student [Ope Oladipo] had the chance to combine two of his passions: engineering and photography. He and teammates [Sacheth Hegde] and [Jason Zhang] used their time in [Bruce Land]’s class to build a motorized camera dolly for shooting time-lapse sequences.

The camera, in this case the one from an iPhone 6, is mounted to an off-the-shelf robot chassis that tools around on a pair of DC motors. The camera mount uses a stepper motor to get just the right shot. A PIC32 on board the ‘bot takes Bluetooth commands from an iOS app that the team built. The dolly works two ways: it can be controlled manually in free mode, or it can follow a predetermined path at a set speed for a specified time in programmed mode.

Our favorite part of the build? The camera’s view is fed to a smart watch where [Ope] and his team can take still pictures using the watch-side interface. Check it out after the break, and stick around for a short time-lapse demo. We’ve featured a couple of dolly builds over the years. Here’s a more traditional dolly that rides a pair of malleable tubes.

Time-lapse example

Thanks for the tip, [Bruce Land]!


Filed under: digital cameras hacks, Microcontrollers

Raspberry Pi Home Automation for the Holidays

When you want to play around with a new technology, do you jump straight to production machinery? Nope. Nothing beats a simplified model as proof of concept. And the only thing better than a good proof of concept is an amusing proof of concept. In that spirit [Eric Tsai], alias [electronichamsters], built the world’s most complicated electronic gingerbread house this Christmas, because a home-automated gingerbread house is still simpler than a home-automated home.

fya59blixaq00y3-largeYeah, there are blinky lights and it’s all controlled by his smartphone. That’s just the basics. The crux of the demo, however, is the Bluetooth-to-MQTT gateway that he built along the way. A Raspberry Pi with a BTLE radio receives local data from BTLE sensors and pushes them off to an MQTT server, where they can in principle be read from anywhere in the world. If you’ve tried to network battery-powered ESP8266 nodes, you know that battery life is the Achilles heel. Swapping over to BTLE for the radio layer makes a lot of sense.

If you’re thinking that you’ve seen this before, maybe you’re thinking of [electronichamsters]’s previous feat of home-automation and cardboard, which is also great fun. If a web search with the keywords “IoT” and “hamsters” is what brought you here: Hackaday aims to please.


Filed under: Holiday Hacks, home hacks, Raspberry Pi

33C3: Breaking IoT Locks

Fast-forward to the end of the talk, and you’ll hear someone in the audience ask [Ray] “Are there any Bluetooth locks that you can recommend?” and he gets to answer “nope, not really.” (If this counts as a spoiler for a talk about the security of three IoT locks at a hacker conference, you need to get out more.)

btle_lockUnlocking a padlock with your cellphone isn’t as crazy as it sounds. The promise of Internet-enabled locks is that they can allow people one-time use or limited access to physical spaces, as easily as sending them an e-mail. Unfortunately, it also opens up additional attack surfaces. Lock making goes from being a skill that involves clever mechanical design and metallurgy, to encryption and secure protocols.

master_jtagIn this fun talk, [Ray] looks at three “IoT” locks. One, he throws out on mechanical grounds once he’s gotten it open — it’s a $100 lock that’s as easily shimmable as that $4 padlock on your gym locker. The other, a Master lock, has a new version of a 2012 vulnerability that [Ray] pointed out to Master: if you move a magnet around the outside the lock, it actuates the motor within, unlocking it. The third, made by Kickstarter company Noke, was at least physically secure, but fell prey to an insecure key exchange protocol.

Along the way, you’ll get some advice on how to quickly and easily audit your own IoT devices. That’s worth the price of admission even if you like your keys made out of metal instead of bits. And one of the more refreshing points, given the hype of some IoT security talks these days, was the nuanced approach that [Ray] took toward what counts as a security problem because it’s exploitable by someone else, rather than vectors that are only “exploitable” by the device’s owner. We like to think of those as customization options.


Filed under: cons

Bluetooth Speaker With Neopixel Visual Display!

Finding a product that is everything you want isn’t always possible. Making your own that checks off all those boxes can be. [Peter Clough] took the latter route and built a small Bluetooth speaker with an LED visualization display that he calls Magic Box.

A beefy 20W, 4Ohm speaker was screwed to the lid of a wooden box converted to the purpose. [Clough] cut a clear plastic sheet to the dimensions of the box, notching it 2cm from the edge to glue what would become the sound reactive neopixel strip into place — made possible by an electret microphone amplifier. There ended up being plenty of room inside the speaker box to cram an Arduino Pro Mini 3.3V, the RN-52 Bluetooth receiver, and the rest of the components, with an aux cable running out the base of the speaker. As a neat touch, neodymium magnets hold the lid closed.

Magic Box Bluetooth Speaker ComponentsWe gotta say, a custom speaker with LED visualization makes for a tidy little package — aside from the satisfaction that comes from building it yourself.

Depending on your particular situation, you may even opt to design a speaker that attaches to a magnet implanted in your head.

[via /r/DIY]


Filed under: Arduino Hacks, hardware, led hacks, musical hacks

Bluetooth Turns 5

Last week, the latest and greatest member of the Bluetooth family of wireless specifications was announced to the world: Bluetooth 5! What main changes are in store? Read the FAQ (PDF), or dig into the full spec (bigger PDF) at 2,800 pages.

Their big-print selling points include “up to 4x the range, 2x the speed, and 8x the broadcasting message capacity” to power the Internet of Things. Etcetera. [Akiba] pointed out via Twitter that they get the fourfold increase in range by adding an extra zero to the “Maximum Output Power” spec, going from 10 mW maximum power to 100 mW. That would do it.

In less snarky news, they’re also allowing for a lower-bitrate mode that will also increase range without simply boosting the power. The spec is actually being changed to let the user work out their optimal blend of power, range, and bitrate. We’re down with that. But you’re not getting 4x the range and 2x the speed without paying the bandwidth piper. That’s just physics.

If you use the beacon mode in Bluetooth Low Energy (BLE), you’ll be happy to hear that they’re lengthening the beacon packet from 31 bytes to 255, so you can send a bunch more data without consuming too much power. That’s the “8x”. Bluetooth 5.0 is also backwards compatible with Bluetooth 4.2, so you don’t have to redo anything if you don’t want to take advantage of the newer features. Your current BLE beacons will keep working.

Finally, there’s some contention-detection and other bandwidth optimizing going on, which is welcome in our crowded 2.4 GHz office spectrum. Our guess is that’s where the “2x speed” is largely coming from, but there are about 2,750 pages that we haven’t read yet, so if you’re digging into the spec, let us know what you find in the comments.

Thanks to [Akiba] for tipping us off to this via Twitter. Go check out his great talk on getting hacker stuff in Shenzhen that was presented at the SuperCon.


Filed under: news, wireless hacks

Game Controller Cuts the Rug

There’s an iconic scene from the movie Big where [Tom Hanks] and [Robert Loggia] play an enormous piano by dancing around on the floor-mounted keys. That was the first thing we thought of when we saw [jegatheesan.soundarapandian’s] PC joystick rug. His drum playing (see the video below) wasn’t as melodious as [Hanks] and [Loggia] but then again they probably had a musical director.

At the heart of the project is, of course, an Arduino. An HC-05 provides a Bluetooth connection back to the PC. We thought perhaps an Arduino with USB input capability like the Leonardo might be in use, but instead, [jegatheesan] has a custom Visual Basic program on the PC that uses SendKeys to do the dirty work.

The switches are more interesting made with old CDs, foil, and sponges. The sponge holds the CDs apart until you step on them and the foil makes the CDs conductive. He uses a lot of Fevicol in the project–as far as we can tell, that’s just an Indian brand of PVA glue, so Elmer’s or any other white glue should do just as well.

The glue also handles the fabric parts. When a project says “no sewing” we realize how some people feel about soldering. The CD/foil/sponge switches might be useful in other contexts. We’d be interested in how the sponges wear with prolonged use.

We’ve seen other giant controllers before. Of course, if you really want a big controller, you can’t beat a Nissan (the link is dead, but the video will give ou the idea).


Filed under: Arduino Hacks

Make Your Eyes Louder With Bluetooth Speaker Goggles

Your eyes are cool, but they aren’t very loud. You can remedy that with this build from [Sam Freeman]: a pair of Bluetooth speaker goggles. Combine a pair of old welders goggles with a Bluetooth receiver, a small amp and a couple of cheap speaker drivers and you’re well on your way to securing your own jet set radio future.

[Sam] found a set of speaker drivers that were the same size as the lenses of the goggles, as if they were designed for each other. They don’t do much for your vision, but they definitely look cool. [Sam] found that he could run the speakers for an hour or so from a small Lithium Ion battery that’s hidden inside the goggles, along with a large lever switch for that throwback electronics feel. The total cost of this build is a reasonably-low at $40, or less if you use bits from your junk pile.

The real trick is watching them in action and deciding if there’s any motion happening. Don’t get us wrong, they look spectacular but don’t have the visual feedback component of, say, the bass cannon. Look for yourself in the clip below. We might add a pair of googly eyes on the speakers that dance as they move, but that would get away from the more serious Robopunk look that [Sam] is going for. What would you add to build up the aesthetic of these already iconic goggles?


Filed under: digital audio hacks, wearable hacks

Retrofitting Smoke Alarms With Bluetooth

Everybody should have a few smoke alarms in their house, and everyone should go check the battery in their smoke alarm right now. That said, there are a few downsides to the traditional smoke alarm. They only work where you can hear them, and this problem has been solved over and over again by security companies and Internet of Things things.

Instead of investing in smart smoke alarms, [Johan] decided to build his own IoT smoke alarm. It’s dead simple, costs less than whatever wonder gizmo you can buy at a home improvement store, and reuses your old smoke alarm. In short, it’s everything you need to build an Internet-connected smoke alarm.

Smoke alarms, or at least ionization-based alarms with a tiny amount of radioactive americium, are very simple devices. Inside the alarm, there’s a metal can – an ionization chamber – with two metal plates. When smoke enters this chamber, a few transistors sound the alarm. If you’ve ever taken one apart, you can probably rebuild the circuit from memory.

Because these alarms are so simple, it’s possible to hack in some extra electronics into a design that hasn’t changed in fifty years. For [Johan]’s project, he’s doing just that, tapping into one of the leads on the ionization chamber, measuring the current through the buzzer, and adding a microcontroller with Bluetooth connectivity.

For the microcontroller and wireless solution, [Johan] has settled on TI’s CC2650 LaunchPad. It’s low power, relatively cheap, allows for over the air updates, and has a 12-bit ADC. Once this tiny module is complete, it can be deadbugged into a smoke alarm with relative ease. Any old phone can be used as a bridge between the alarm network and the Internet.

The idea of connecting a smoke alarm to the Internet is nothing new. Security companies have been doing this for years, and there are dozens of these devices available at Lowes or Home Depot. The idea of retrofitting smarts into a smoke alarm is new to us, and makes a lot of sense: smoke detectors are reliable, cheap, and simple. Why not reuse what’s easy and build out from there?


Filed under: home hacks, Microcontrollers