Will show you how to use BLE communication in ESP32 Controllers.

Things used in this project

Hardware components
M5StickC ESP32-PICO Mini IoT Development BoardM5Stack M5StickC ESP32-PICO Mini IoT Development BoardM5Stack – M5Stamp PICO×1
Arduino 101Arduino 101×1
Software apps and online services
Arduino IDEArduino IDE


Hey, what’s up, Guys! Pradeep here

In this tutorial, I’m going to show you how to trigger actions with Bluetooth using M5Stamp PICO and M5Stick C which are very cheap and High efficient ESP32 Controllers.

Components Required:

What are M5Stick and M5Stamp?

M5Stack is a technology company that designs and manufactures anopen-source development toolkit, including hardware, programming platform, and IoT solutions. It was founded by Jimmy Lai in 2017 and isbased in Shenzhen, China.

M5Stack created the M5Stick and M5Stamps, which are both based on the ESP32 controller. The M5Stick C features an embedded TFT display and battery, while the M5Stamp has a small footprint and can be used in a variety of IoT products.

M5StickC is a mini M5Stack, powered by ESP32. It is a portable, easy-to-use, open-source, IoT development board. It is an ESP32 development board with 0.96 inch TFT color screen (80 * 160 resolution), Red LED, button, Microphone, IR transmitter, 6-axis IMU (SH200Q), and 80 mAH battery. The ESP32 module ESP32-Pico in M5StickC also has a built-in 4MB flash. If the M5StickC is equipped with a watch base and watch belt, you can wear it on your wrist.

It is built in a continually growing hardware and software ecosystem. It has a lot of compatible modules and units, as well as the open-source code & engineering communities that will help you maximize your benefits in every step of the developing process.

Power switch operation:

Power on: Press the power button for 2 seconds

Power off: Press the power button for 6 seconds

The input range of VBUS_VIN and VBUS_USB is limited to 4.8-5.5V, and the internal battery will be charged through AXP192 power management when VBUS is powered.

STAMP-PICO features an ultra-compact design with two low-power Xtensa® 32-bit LX6 microprocessors at 240MHz on a PCB as tiny and delicate as a postage stamp. low power consumption. It is ideal for any space-constrained or battery-powered devices such as wearables, medical devices, sensors, and other IoT devices.

1, MULTIFORM: 5 options of installation, means endless possibilities! (SMT, DIP, flywire, grove interface), with a high-temperature resistant plastic shell, 3D antenna and components can be better protected.

2, LOW-CODE DEVELOPMENT: STAMP-PICO supports UIFlow graphical programming platform, scripting-free, cloud push; and fully compatible with Arduino, MicroPython, ESP32-IDF, and other mainstream development platforms to quickly build various applications.

3, HIGH INTEGRATION: STAMP-PICO contains a 5V->3.3V DC/DC port, GPIOx12, programmable RGB light x1, button x1, and finely tuned RF circuit, providing stable and reliable wireless communication.

4, STRONG EXPANDABILITY: Easy access to M5Stack’s hardware and software ecology system: a wealth of sensors, actuators, functional modules, and accessories to choose from, and Extremely fast adaptation.

Set up M5Stamp and M5Stick with Arduino IDE by following these instructions.


Flow :

M5Stick C will act as a BLE transmitter, while M5Stamp PICO will act as a BLE receiver. When Button A on the M5Stick is pressed, the M5Stamp’s LED turns green.

Coding for Transmitter:

#include <M5StickC.h>
#include "BLEDevice.h"
#include "BLEUtils.h"
#include "BLEServer.h"
#include "BLEBeacon.h"

BLEAdvertising *pAdvertising; // BLE Advertisement type
struct timeval now;
#define GPIO_DEEP_SLEEP_DURATION 1 // sleep x seconds and then wake up
RTC_DATA_ATTR static time_t last; // remember last boot in RTC Memory
RTC_DATA_ATTR static uint32_t bootcount; // remember number of boots in RTC Memory
#define BEACON_UUID "87b99b2c-90fd-11e9-bc42-526af7764f64" // UUID 1 128-Bit (may use linux tool uuidgen or random numbers via https://www.uuidgenerator.net/)
void setBeacon()

BLEBeacon oBeacon = BLEBeacon();
oBeacon.setMajor((bootcount & 0xFFFF0000) >> 16);
oBeacon.setMinor(bootcount & 0xFFFF);
BLEAdvertisementData oAdvertisementData = BLEAdvertisementData();
BLEAdvertisementData oScanResponseData = BLEAdvertisementData();

oAdvertisementData.setFlags(0x04); // BR_EDR_NOT_SUPPORTED 0x04

std::string strServiceData = "";

strServiceData += (char)26; // Len
strServiceData += (char)0xFF; // Type
strServiceData += oBeacon.getData();


void setup() {
M5.Lcd.setTextColor(YELLOW); //Set the font color to yellow. 设置字体颜色为黄色
M5.Lcd.setCursor(3, 10);

void loop() {

M5.Lcd.setCursor(3, 10);
if (M5.BtnA.wasReleased()) {
Serial.println("Trigger mode");
// Create the BLE Device
BLEDevice::init("BLE Receiver 01");
// Create the BLE Server
BLEServer *pServer = BLEDevice::createServer(); // <-- no longer required to instantiate BLEServer, less flash and ram usage
pAdvertising = BLEDevice::getAdvertising();
// Start advertising
Serial.println("Advertizing started...");
M5.Lcd.setCursor(3, 10);

Upload the above code to your M5Stick C Controller.

Coding for Receiver:

#include "Arduino.h"
#include <FastLED.h>
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>

// How many leds in your strip?
#define NUM_LEDS 1
#define DATA_PIN 27

// Define the array of leds

String knownBLEAddresses[] = {"24:a1:60:53:06:3e"};
int RSSI_THRESHOLD = -100;
bool device_found;
int scanTime = 1; //In seconds
BLEScan* pBLEScan;
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice advertisedDevice) {
for (int i = 0; i < (sizeof(knownBLEAddresses) / sizeof(knownBLEAddresses[0])); i++)
if (strcmp(advertisedDevice.getAddress().toString().c_str(), knownBLEAddresses[i].c_str()) == 0)
device_found = true;
device_found = false;
Serial.printf("Advertised Device: %s \n", advertisedDevice.toString().c_str());
void setup() {
Serial.begin(115200); //Enable UART on ESP32
FastLED.addLeds<SK6812, DATA_PIN, RGB>(leds, NUM_LEDS); // GRB ordering is typical
Serial.println("Scanning..."); // Print Scanning
pBLEScan = BLEDevice::getScan(); //create new scan
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks()); //Init Callback Function
pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster
pBLEScan->setInterval(100); // set Scan interval
pBLEScan->setWindow(99); // less or equal setInterval value
void loop()
BLEScanResults foundDevices = pBLEScan->start(scanTime, false);

for (int i = 0; i < foundDevices.getCount(); i++)
BLEAdvertisedDevice device = foundDevices.getDevice(i);
int rssi = device.getRSSI();
Serial.print("RSSI: ");
if (rssi > RSSI_THRESHOLD && device_found == true)
leds[0] = 0xf00000;

// Now turn the LED off, then pause
leds[0] = 0x00f000;
pBLEScan->clearResults(); // delete results fromBLEScan buffer to release memory

In the above code, you have to change the BLE Address of your M5Stick C.

Here I have added my M5Stick C’s BLE Address. Change this according to yours.


Once the Transmitter and Receiver codes have been uploaded to the M5Stick and M5Stamp, connect the M5Stamp to your PC and open the serial monitor, then click the button A on the M5Stick C, which will display Triggered on the TFT Display.

Check the Serial Monitor Results whenever you see a triggered message in your M5Stick C.

The name of the ESP Transmitter, RSSI, and Triggered Message will be displayed on the serial monitor. The Green led on the M5Stamp will blink.

The Green led will blink every time the button is pressed.


Github repository for the project

Repo not found. Make sure the repo is public!