Configuring iBeacons

iBeacons are a great way to locate you within your apartment without draining the battery too much. An iBeacon is basically a Bluetooth-Low-Energy device that just broadcasts an identifier in periodic intervals. iOS and Android devices that receive these broadcasts can identify the iBeacon and even calculate the distance to it.

For in-door navigation, the cheapest iBeacons works best as their range is limited. This makes it easier to locate you without using complex triangulation algorithms. When you move, you will just leave a cell when you are too far away for the iBeacon.

As most existing iBeacons use a Texas instruments chipset they are not extremely cheap. Even when ordering directly from China, it is hard to find them for less than $10. One iBeacon that is relatively cheap is the Ghostyu. It consists of a small PCB and a relatively large battery on the back.


Using a single piece of these is simple. You can just use them as they come. If there are neighbours or people on your way to work that use the same beacon, you might run into trouble as the basic configuration is the same for all of these devices. The basic configuration is:

UUID: E2C56DB5-DFFB-48D2-B060-D0F5A71096E0
Major: 0
Minor: 0

All 3 IDs can be used, but the UUID is always being used (you can ignore major and minor).

Therefore I recommend not only to set major and minor to different values than the default, but also UUID. The UUID is an 128-bit ID, you can just randomly select one without having to fear that somebody else in the world will use this. The easiest way is using an online UUID generator.

But how do you change the UUID? For the Ghostyu, there is an iOS app called LightBeacon. Unfortunately it is completely in Chinese. However, clicking around a bit should bring you to the following configuration dialog:


Here, you can not only define UUID, major and minor ID, but also the advertising interval. This can have a major impact on the battery life. If you want to use iBeacons to turn the light on when you enter a room, 0.5s might still be ok. If you just want to track you and turn the light off when you left the room for some time, even the longest interval of 4 seconds is more than enough. In many use cases, 4 seconds will work fine and result in a longer battery life.  Now just store the value to the iBeacon. It will reboot and advertise the new UUID, major and minor.

Battery powered ESP8266 sensor

The ESP8266 is a powerful and inexpensive device. There is almost no need anymore to use proprietary RF protocols like the nRF24 chip that was popular some years ago. However, there is one major problem when using WLAN: power consumption.

When connected to a WLAN, the ESP8266 consumes at least 80mA – sometimes even more. If you use 3 2400mAh that means, they will be empty in a bit more than a day. This doesn’t sound like a good deal.

Luckily, for sensor applications, you don’t have to be connected to the LAN the whole time. You don’t even have to have the ESP itself running. To save as much power as possible, you have to do the following:

  1. Collect your data. If this takes time, do it before connecting to WLAN. If it takes just a few millesconds, it doesn’t matter much.
  2. Connect to WLAN.
  3. Send data.
  4. Go to deep sleep mode. You use the ESP.deepSleep() method for this.

You have to look at a few things when using the ESP.deepSleep() method:

  1. To wake up after sleeping, GPIO16 of the ESP8266 has to be connected to RESET. Otherwise the device won’t wake up again.
  2. The delay parameter is defined in microseconds (not seconds or milliseconds). If it looks like your device isn’t sleeping at all, you might have used a value that is too small (you won’t even notice if the device sleeps for 3600 microseconds)
  3. There is a second parameter that can have the values WAKE_RF_DEFAULT, WAKE_RFCAL,WAKE_NO_RFCAL, WAKE_RF_DISABLED. The WAKE_RF_DISABLED looks good, but beware to use it. Using this does not mean that the RF subsystem is disabled during sleep (it always is), but that it is disabled when waking up again. Your ESP8266 won’t be able to do any network communication anymore.

A few other tips to save energy:

  1. Do not turn on LEDs for a longer time. Flashing them a few milliseconds is usually a good visual feedback and will consume only a tiny bit of energy.
  2. If you need to have LEDs on for a longer time, dimm them. analogWrite is your friend for this.

Check out this sample code. It uses WiFiManager which helps to connect to configure your WLAN SSID/password and even the name/IP address of the MQTT broker.

#include         // Generic ESP8266 WiFi routines
#include        // MQTT client
#include           // Local DNS Server used for redirecting all requests to the configuration portal
#include    // Local WebServer used to serve the configuration portal
#include         // WiFi Configuration Magic

const char* mqtt_server = "";
const char* mqtt_channel_up = "active";
const char* mqtt_channel_data = "sensor/%d/adc";

const int pin_red = 15;
const int pin_green = 12;
const int pin_blue = 13;
const int pin_button = 4;
const int analog_ldr = 0;

const int sleepSeconds = 60 * 15;

WiFiManager wifiManager;
WiFiClient espClient;
PubSubClient client(espClient);

void send_sensor_data(void) {
  Serial.println("Sending sensor data\n");
  int data = analogRead(A0);
  char s_channel[50];
  char s_id[10];
  char s_data[10];
  sprintf(s_channel, mqtt_channel_data, ESP.getChipId());
  sprintf(s_id, "%d", ESP.getChipId());
  sprintf(s_data, "%d", data);

  digitalWrite(pin_blue, HIGH);
  digitalWrite(pin_blue, LOW);
  if (! client.connected()) {
    Serial.println("Could not connect to MQTT broker, doing nothing");
  } else {
    digitalWrite(pin_green, HIGH);
    client.publish(mqtt_channel_up, s_id); // show that this device is up
    client.publish(s_channel, s_data); // send sensor data
    digitalWrite(pin_green, LOW);

void setup() {
  delay(500); // This makes it easier to upload new firmware and/or press the "clean" button

  pinMode(pin_red, OUTPUT);
  pinMode(pin_green, OUTPUT);
  pinMode(pin_blue, OUTPUT);

  digitalWrite(pin_red, HIGH);

  // Setup Serial interface for debugging

  //  Bring up WLAN
  WiFiManager wifiManager;

  //sets timeout until configuration portal gets turned off
  //useful to make it all retry or go to sleep
  //in seconds

  WiFiManagerParameter custom_mqtt_server("server", "mqtt server", mqtt_server, 40);

  if (digitalRead(pin_button) == 0) {
    // reset settings

  //fetches ssid and pass and tries to connect
  //if it does not connect it starts an access point with the specified name
  //here  "AutoConnectAP"
  //and goes into a blocking loop awaiting configuration
  if (!wifiManager.autoConnect()) {
    Serial.println("failed to connect and hit timeout");
    // do nothing: deep sleep, but longer than usual. Something might be wrong and
    // we should save power
    ESP.deepSleep(sleepSeconds * 10 * 1000000, WAKE_RF_DISABLED);

  mqtt_server = custom_mqtt_server.getValue();

  Serial.println("WiFi connected");
  Serial.println("IP address: ");

  // Setup MQTT client
  client.setServer(mqtt_server, 1883);

  digitalWrite(pin_red, LOW);

void loop(void) {
  Serial.printf("Sleeping deep for %i seconds...", sleepSeconds);
  ESP.deepSleep(sleepSeconds * 1000000);

Innovation begins at home

Andy Stanford-Clark, IBM Distinguished Engineer for the Internet of Things, will explain how his hobby of home automation and his passion for energy saving converges with the Internet of Things.
This has led to projects that have helped alleviate energy poverty in social housing, and are helping commuters from the Isle of Wight check if the ferries are running on time.
Andy will explain that “it’s all about the data” and how these solutions are built from instrumented, interconnected, intelligent devices. He will illustrate his talk with examples from his home, including his twittering mouse traps!

Click on the image to view the video on Vimeo.

Screenshot 2016-05-17 09.22.36