BLE

ESP32のBLEを使ったサンプルです。BLE専用のライブラリはないため、ATパーサーを使ってBLE通信を行います。ESP32の初期ファームウェアには、以下に示す通りのGATTプロファイルが用意されています。

GATTプロファイル

UUID アクセス・プロパティ サイズ(バイト) Characteristic番号
A002 Read 2 -
C300 Read 1 1
C301 Read 512 2
C302 Write 1 3
C303 Write Without Response 3 4
C304 Write 2 5
C305 Notify 5 6
C306 Indicate 5 7

Example

GR-LYCHEE is a server and smartphone acts as a client. After executing the program, try using the iPhone application Light Blue etc.

#include <Arduino.h>
#include "ESP32.h"

BufferedSerial esp32(P7_1, P0_1, 1024);
ATParser_os esp_parser(esp32);
DigitalOut esp_en(P5_3);
DigitalOut esp_io0(P3_14);
DigitalOut led_green(LED1);
DigitalOut led_yellow(LED2);
DigitalOut led_orange(LED3);
DigitalOut led_red(LED4);
InterruptIn button0(USER_BUTTON0);
InterruptIn button1(USER_BUTTON1);
Semaphore event_sem(0);

const char ble_name[] = "GR-LYCHEE";
bool ble_advertizing;
bool ble_connected;
uint8_t ble_conn_index;
uint8_t ble_srv_index;

bool button0_flag = false;
bool button1_flag = false;
uint8_t ble_notification_on = false;

void esp32_event() {
    event_sem.release();
}

void ble_client_read() {
    uint8_t mac[6] = {0};
    led_yellow = 1;
	esp_parser.recv("%hhd,\"%hhx:%hhx:%hhx:%hhx:%hhx:%hhx\"", &ble_conn_index, &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]);
    printf("%d, mac[%x:%x:%x:%x:%x:%x]\r\n", ble_conn_index, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
    led_yellow = 0;
}

void ble_client_write() {
    uint8_t char_index, desc_index;
    led_orange = 1;
	esp_parser.recv("%hhd,%hhd,%hhd,", &ble_conn_index, &ble_srv_index, &char_index);
    printf("conn=%d srv=%d char=%d\r\n", ble_conn_index, ble_srv_index, char_index);
    char c = esp_parser.getc();
    if( c != ','){
    	desc_index = c;
    	esp_parser.getc(); // to read ',' after desc_index.
        printf("desc=%d\r\n", desc_index);
    }
    uint16_t len;
    esp_parser.recv("%hhd,", &len);
    printf("length=%d\r\n", len);
	for (int i = 0; i < len; i++) {
		uint8_t value = esp_parser.getc();
		printf("%x\r\n", value);
	}
	led_orange = 0;
}

void ble_client_disconn(){
	led_green = 0;
	ble_connected = false;
}

void ble_client_conn(){
    uint8_t mac[6] = {0};
	esp_parser.recv("%hhd,\"%hhx:%hhx:%hhx:%hhx:%hhx:%hhx\"", &ble_conn_index, &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]);
    printf("connected client %d, mac[%x:%x:%x:%x:%x:%x]\r\n", ble_conn_index, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);

    led_green = 1;
    ble_advertizing = false;
    ble_connected = true;
}

void ub0_interrupt(){
	if(button0_flag == false){
		button0_flag = true;
	    event_sem.release();
	}
}

void ub1_interrupt(){
	if(button1_flag == false){
		button1_flag = true;
	    event_sem.release();
	}
}

void setup() {

    printf("Bluetooth sample started\r\n");
    led_green = 0;
    led_yellow = 0;
    led_orange = 0;
    led_red = 0;
    ble_advertizing = false;
    ble_connected = false;
    button0.fall(ub0_interrupt);
    button1.fall(ub1_interrupt);

    // Initializing esp32 access
    esp32.baud(115200);
    esp32.attach(Callback<void()>(esp32_event));
    esp_io0 = 1;
    esp_en = 0;
    Thread::wait(10);
    esp_en = 1;
    esp_parser.setTimeout(1500);
    if (esp_parser.recv("ready")) {
        printf("ESP32 ready\r\n");
    } else {
        printf("ESP32 error\r\n");
        led_red = 1;
        while (1);
    }

    // Initializing esp32 as a server with GATT service
    esp_parser.setTimeout(5000);
    if (esp_parser.send("AT+BLEINIT=2") && esp_parser.recv("OK")
            && esp_parser.send("AT+BLENAME=\"%s\"", ble_name) && esp_parser.recv("OK")
            && esp_parser.send("AT+BLEGATTSSRVCRE") && esp_parser.recv("OK")
            && esp_parser.send("AT+BLEGATTSSRVSTART") && esp_parser.recv("OK")){
        printf("GATT initialized\r\n");
    } else {
        printf("fail to initialize");
        led_red = 1;
        while (1);
    }
    esp_parser.oob("+READ:", ble_client_read);
    esp_parser.oob("+WRITE:", ble_client_write);
    esp_parser.oob("+BLEDISCONN:", ble_client_disconn);
    esp_parser.oob("+BLECONN:", ble_client_conn);

    while (1) {
        if (esp_parser.send("AT+BLEADVSTART") && esp_parser.recv("OK")){
            printf("Advertising started, please connect to any client\r\n");
        } else {
            printf("fail to start advertising");
            led_red = 1;
            while (1);
        }

        ble_advertizing = true;

        uint8_t start, type;
        uint16_t uuid;
        esp_parser.send("AT+BLEGATTSSRV?");
        if(esp_parser.recv("+BLEGATTSSRV:%hhd,%hhd,%hhx,%hhd\r\nOK", &ble_srv_index, &start, &uuid, &type)){
        	printf("srv_index=%d\r\n", ble_srv_index);
        } else {
            printf("fail to get service");
            led_red = 1;
        }

        while (ble_connected || ble_advertizing) {
            event_sem.wait();
            esp_parser.setTimeout(5);
            esp_parser.recv(" ");  //dummy read for parser callback

            if(button0_flag){
            	static uint8_t data = 1; // write data
        		esp_parser.setTimeout(5000);
            	if(esp_parser.send("AT+BLEGATTSSETATTR=%d,1,,1", ble_srv_index) && esp_parser.recv(">")){
            		if(esp_parser.putc(data) && esp_parser.recv("OK")){
                    	printf("success to send\r\n");
            		} else {
                    	printf("fail to send\r\n");
            		}
            	} else {
                    printf("fail to command AT");
            	}
        		esp_parser.flush();
        		button0_flag = false;
                data++;
            }
        }
    }
}

void loop() {

}


Made by Gadget Renesas Project
Contents are CC BY-SA 3.0