Introduction: Presence Sensor

Wearables are usually BLE enabled devices. It is common for them to periodically advertise some data along its MAC address. We use an ESP to scan these data and trigger an event through internet when it finds a specific MAC address.

This particular implementation is for a single user on a smart plug connected to a lamp. But it also can be used with a set of registered devices with any kind of IOT enabled devices.


  1. ESP32
  2. (optional) TECKIN WiFi Wall Plug S10
  3. BLE enabled device of any sort

Step 1: Define Your Scenario

For the trigger, you could use most of the modern wearables. This can be an Apple Watch, a mi fit band, a phone or even your own DIY wearable based on an ESP32.

Probably one of the most important steps. You have to think ahead in 3 things:

1. Which wearable or device is going to be the trigger of the proximity sensor.

2. What is going to trigger the sensor (this is done through IFTTT).

3. When the sensor is going to trigger

For this example, I will be using my Apple Watch to trigger a smart plug to turn on a lamp when I sit at my desk.

In this tutorial we will be looking at a smart plug by TECKIN. You can find it at amazon at a good price. It is also compatible with Alexa and google Home. Great value!

Step 2: (Intro) Set Trigger - Multiple Users

If you want to configure so that it works any person with a BLE enabled device close enough to your sensor, then skip the next step. This is pretty useful, is the setting I personally use. Keep in mind this sensor can be easily hacked or exploited to trigger so I wouldn't trust much from a security stand pint; just for a practical one (ie, I don't want it to be triggered by my PC since it will be always next to the sensor).

Step 3: (Intro) Set Trigger - Limited Users

This step varies greatly on your setup. To limit which devices can trigger the sensor you have many routes to limit:

- BLE MAC address (equivalent to the IP address on a wifi network. The reason it does not guarantees security since is not the real MAC address of the module. On iOS devices it changes every time you restart the bluetooth, not so fun)

- Manufacturer Code (better option, but no way to limit specific devices from the same manufacturer/model)

- Name, Service UIDD (rare but the best option, mostly DIY wearables or maybe an android app)

Some Notes:

1. If it is an iOS device:

- You have some important pros and cons. Pro, they transmit the power level at which it is advertising data. That is helpful at the calibration stage, you will find that using an Apple Watch is helpful since it broadcasts at 24db, iPhones and most devices transmit at 12db.

CON, you will have to find workarounds. The advertised MAC address (the main method of identification) changes each time the bluetooth signal is restarted, meaning you will have to upload the code each time... not fun. You can use the manufacturer data which may vary between models. This means that you can limit so that it senses "all iPhone 8".

2. If it is an Android device:

- I personally don't have an android device. But there are probably many applications that can fix the MAC address or even add a personalized name(if that is the way you want to go). On iOS devices there is an app "nrf connect" that can do this. But is not persistent, meaning if you lock the screen or switch apps.. the configuration goes off in a couple of seconds.

3. Another ESP32. (your best bet)

- A simple code like this can be implemented in a device like this one; an esp32 powered smart band. The code is actually an example from the ESP BLE library BLE_IBeacon.ino. I haven't test it to much since my smart band is on shipping, probably will post updates soon.

Step 4: (Setup) - IFTTT

Ok, so at this stage you should probably taken all the desicions of your workflow. You have your triggering device, you have a place to put the ESP with a wireless connection to the internet and you have an action in mind that IFTTT can automate.

IFTTT is powerful; whether it's just to send a simple notification to your device, you want a tweet to be sent or turn on a lightbulb with a smart plug. In this tutorial we will implement the last one with TECKIN smart plugs compatible with IFTTT. Either way, download the IFTTT app or go to the web and create an account.

That is it for now!

If you just want to send a notification or something else than the Smart Life plug you can skip the next step.

Step 5: (Setup) IOT Device *optional*

Download "Smart Life" app from the PlayStore (android) or AppStore (iOS). Instructions are pretty much straight forward, although the process is a little bit tricky. I found out at the stage of scanning (when the blue button was blinking) it stopped at some point, then I manually pressed it to turn on and off a couple of times. That helped me. Anyways; the setup of this plug is nothing different with our application so if you already own one and have it connected to your app you should be ready to go.

TAKE NOTE: You need to be able to turn the switch on and off from the app before you move on from this step. That will mean you have configured correctly the smart plug.

The IFTTT app should synchronize with the "Smart Life" app seamlessly, probably prompting an authentication while creating an event at the next step.

Step 6: (Setup) IFTTT Webhook Api *Experienced Users*

If you have not used before the IFTTT app and are not that comfortable with some technical terms skip this step for the Detailed Guide (with photos) at the next step.

1. Create a new event.

2. Set "this" to be a webhook api. Write down the name you set to the event.

3. Set "that" to your desired behavior. For the smart plug search smart life and select 'turn on'.

4. Select your smart plug and press finish.

5. At the home screen look for 'webhooks' card. After you pressed it, press "get more" at the bottom.

6. Press documentation. This will show you your api key along with an URL builder&tester.

7. Use de URL builder with the name you wrote at #2. Copy that and write down.

8. Repeat if you want a behavior to be triggered when the presence sensor is no longer active. In our case repeat #3 but select 'turn off'. Also, at #2 the name should also be different this time around.

If you are done skip the next step.

Step 7: (Setup) IFTTT Webhook Api *For Beginners With Photos*

Detailed Guide *the photo guide should be similar with android and on web*

IFTTT is a simple workflow, if "this happens" then "that happens". You must create a new one,

1. on the app press "get more" and a list will show.

2. Right below the search bar a says "make your own applets from scratch", press the Plus sign.

3. Press "this" plus sign

In our case "this" is going to be an api call through the internet. An api call is a consult to a URL, kind of like when you type a google search and the url is long string of characters). To create the api: (after pressing "this")

4. Search "webhooks"

5. Select the only option

6. Name your event (in this example we will use "Sit"). Write down this name, very important.

7. Press Create Trigger

Ok! we are closer, Now to the "that" part. For this tutorial we will set "that" to turn on the Smart plug. But you can choose anything from IFTTT. A good way of testing the setup is to select "notifications" which will send a notification to your phone each time the sensor triggers (or the api is called, even from a web browser: useful for testing!)

8. Press "that" plus sign

9. Search "Smart Life" (or "notifications")

10. Press 'turn on' (you will need to repeat this steps to create another event to turn off for when you leave)

11. If you have both apps and the plug correctly configured, you should see your plug at the drop down 'which device/group.

12. Select Create Action and then finish.

Now you should see the event is connected. Now we need to get the api URL. For this:

13. Go to the IFTTT Homescreen

14. Find Webhooks card

15. Select "Get More"

16. Tap at the Documentation button. You should see a web page with your key.

17. At the placeholders "{event}" fill in the name of your event (remember Point 6)

18. Go to the bottom of the page and tap "Test It"

What you should probably see is a green banner "event has been triggered" and you should see if it worked or not. In our case the plug should turn on. Or you should see a notification if you decided to go that path. It may take a little while, but no more than a minute to see if you made it. Remember it is probably case sensitive.

19. Finally. Copy the url where you replaced the name of your event (at 17) and save it somewhere safe. You will need this soon.

20. Repeat 1-12. At 6 we will use "Stand" this time around. At 10 select 'turn off' instead.

21. Repeat 13-18 if you want, but you can get away with the url you copied at 19, but now change the place where you wrote "Sit" and replace with "Stand". You can test this on a web browser. It should say 'Congratulations! You've fired the Stand event'. Then the plug should have turned off.

Step 8: (Code) Programing the ESP32

You can skip this step if you feel comfortable uploading sketches from the Arduino IDE to your ESP32 Board. Only remember to set a partition of 2mb for the app at least since the sketch weights a little more than 1.2mb usual limit.

There are many great tutorials out there, here are some of which I recommend:

But still, so you are not so lost I will breakdown few important key points.

- ESP32 is not an Arduino board yet it still can be programmed by the Arduino IDE. With simple Arduino code. But, you will still need to configure the IDE to work with the ESP32.

- You will need to install some libraries through the 'Additional boards manager' at preferences. This is the URL you should paste:

- (optional, may help)At Tools->Manage Libraries... -> (find esp BLE library)

- at Tools, you should now have a long list of ESP devices, I recommend ESP32 dev module

- (IMPORTANT) Select (no Ota 2mb app/2mb spifs) at partition manager. This step is important since the app becomes quite heavy as a product of using both wifi/http connections as well as a BLE scanner.

If you done everything right you should be able to program the ESP32. Now the process of doing so is similar to the arduino in some boards. Plug it in, select the matching board, the USB port and you are done. But, in many other cases you will have to proceed with

Step 9: (Code) Upload the Code to the ESP32

Ok, if you are here, that means you have successfully uploaded a sketch to the ESP32 board, preferably the blink.ino sketch.

Now, here is the main code attached, you can also find it at the GitHub repo. You have to replace the following:

SSID - Your wifi Name

PSK - Your wifi Password

sit - The URL with "Sit" from the IFTTT api you wrote earlier

stand - The URL with "Stand" From the IFTTT api you wrote earlier

Now get your trigger device close to the board and then upload the code. Then open the Serial Monitor (baud 115200) after successfully loaded the code.

If you plan to use this with any kind of BLE enabled device skip the next step.

NOTE: if you get memory error messages its because default settings only leave 1mB of memory (out of the 4mB present) for the ESP raw code. It leaves a portion for couple of things as an option to program over the air. I usually do the following:

- at Tools, you should now have a long list of ESP devices, I recommend ESP32 dev module
-Select 'no Ota 2mb app/2mb spifs' at partition manager.

This gives me double memory space, needed for this application.

Step 10: (Code) Upload the Code to the ESP32 *optional*

Here is the tricky part mentioned at the "Set the trigger" Step. The monitor will output the MAC address (should look like ##:##:##:##:## where # is either a number or a letter from a to f), The manufacturer Code and the RSSI (a negative number). Here you have to play around a little to find which is your device. I usually put it next to the board so I can clearly see which is the smallest number. I uncheck the 'autoscroll' box so I can copy the values.

  • If it is the Mac Address fill 'myDevice' with it. Then uncomment line #96 and comment line #95
  • If it is the Name fill 'myDevice' with it. Then uncomment line #97 and comment line #95
  • If it is the MaufactureData you are out of luck for now, I am still developing that part.

For adding support for may devices you should be able to copy the conditianal statement either at #96 or #97 and place them next to each other in this syntax:

if( (condition1) || (condition2) || (condition3) ){

Add more variables (myDevice1,myDevice2,myDevice3) accordingly.

Step 11: Place the ESP and Calibrate

This is the most important part of the setup. Carefully going through this process will be de difference in it working like magic or just giving you strong headaches.

At this point the code you uploaded is working with the parameters I have personally tested and use daily with my phone on my desk; it doesn't mean it will work for you too. So you need to do the calibration yourself.

1. Place the ESP32 Board at its final FIXED location. If you move for some reason the position of your ESP32, you should probably do this again. This will ensure you a good experience overall.

1. (extra) keep in mind you will need to be able to connect to your pc while doing this. If you can't because you are on a desktop you will have to do trial and error keeping in mind that every trial must be near identical in positioning, trigger device and other factors that may come in to count.

2. Open Serial Monitor with the code running.

The code by default will post through the Serial Monitor the RSSI (Received signal strength indication) of each found bluetooth device (or just the device(s) matching your parameters). Play around a little with your main device of action (triggering device). You have to determine what are the thresholds you want to use. Carefully adjusting this configuration will

3. When you determine the thresholds replace them here:

  • near_thrsh
  • far_thrsh

4. Re upload the code, test and repeat until you find optimal performance.

Few things to consider:

1. You want about 20db of difference between the thresholds. If near_thrsh is set to 50 then it is desired that far_thrsh is 70 or more. If the difference is too short, then you might find some distances or places where the board is triggering on and off non stop. Increassing this difference will ensure you avoid this undesirable behavior. I found personally that 20db of margin is good enough.

2. At calibration test real life scenarios as much as posible, this will help determine the best performance.

3. Study the class at line 82 of the code; here is where all the logic is done. The code is well commented though. Feel free to ask at the GitHub!

Step 12: Congrats! You Are Done!

Let me know down in the comments of any suggestions or if you are experiencing problems. Remember to check the GitHub if your issue has already been solved!

Wearables Contest

Participated in the
Wearables Contest