bt_spp_acceptor demo esp32 bluetooth reception time is too long

cckaben
Posts: 2
Joined: Wed Jul 25, 2018 1:26 am

bt_spp_acceptor demo esp32 bluetooth reception time is too long

Postby cckaben » Wed Jul 25, 2018 3:04 am

When I use the mobile app to send data to ESP32, I found that ESP32 Bluetooth will receive the first frame of data for a long time, about 400ms, esp32 is the classic Bluetooth mode, using bt_spp_acceptor demo.

The specific description is as follows:
1. I send 1 byte of data to ESP32 through the serial port of the PC. ESP32 sends it to the mobile app via Bluetooth. The mobile app immediately returns the received data. The time for receiving and returning the app is very short and can be ignored.
2. Test the time of ESP32 Bluetooth from sending to receiving data, the first frame time is about 400ms, and the time of the 2nd, 3rd... frame is about 30ms.
3. If the Bluetooth idle time is more than 5 seconds, there will be a problem that the data reception time is too long.

I want to know why this happens and how to solve it. I checked a lot of manuals and code and I didn't find the problem.
This delay problem has been bothering me for a long time.

Code: Select all

/*
   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/

#include <stdint.h>
#include "string.h"
#include <stdbool.h>
#include <stdio.h>
#include "nvs.h"
#include "nvs_flash.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "freertos/queue.h"
#include "esp_log.h"
#include "esp_bt.h"
#include "esp_bt_main.h"
#include "esp_gap_bt_api.h"
#include "esp_bt_device.h"
#include "esp_spp_api.h"

#include "driver/uart.h"
#include "soc/uart_struct.h"
//#include "string.h"

#include "time.h"
#include "sys/time.h"
#include "driver/gpio.h"

#include "rom/cache.h"
#include "soc/rtc_cntl_reg.h"
#include "driver/spi_slave.h"
#include "esp_spi_flash.h"
#include "esp32_spi.h"
#define SPP_TAG "SPP_ACCEPTOR_DEMO"
#define SPP_SERVER_NAME "SPP_SERVER"
#define EXCAMPLE_DEVICE_NAME "JMD_OBDIIX"
#define SPP_SHOW_DATA 0
#define SPP_SHOW_SPEED 1
#define SPP_SHOW_MODE SPP_SHOW_DATA    /*Choose show mode: show data or speed*/

static const int RX_BUF_SIZE = 1024;
//UART TO FPGA
#define TXD_PIN (GPIO_NUM_17)
#define RXD_PIN (GPIO_NUM_16)


static const esp_spp_mode_t esp_spp_mode = ESP_SPP_MODE_CB;

//static struct timeval time_new, time_old;
//static long data_num = 0;

static const esp_spp_sec_t sec_mask = ESP_SPP_SEC_NONE;
static const esp_spp_role_t role_slave = ESP_SPP_ROLE_SLAVE;


//static void print_speed(void)
//{
//    float time_old_s = time_old.tv_sec + time_old.tv_usec / 1000000.0;
//    float time_new_s = time_new.tv_sec + time_new.tv_usec / 1000000.0;
//    float time_interval = time_new_s - time_old_s;
//    float speed = data_num * 8 / time_interval / 1000.0;
//    ESP_LOGI(SPP_TAG, "speed(%fs ~ %fs): %f kbit/s" , time_old_s, time_new_s, speed);
//    data_num = 0;
//    time_old.tv_sec = time_new.tv_sec;
//    time_old.tv_usec = time_new.tv_usec;
//}

int sendData(const char* logName, const char* data)
{
    const int len = strlen(data);
    const int txBytes = uart_write_bytes(UART_NUM_1, data, len);
    ESP_LOGI(logName, "Wrote %d bytes", txBytes);
    return txBytes;
}

//uint8_t* datarecv;
//int recvBytes = 0;
//clock_t start,finish;
//double duration;

static void rx_task()
{
    static const char *RX_TASK_TAG = "RX_TASK";
    esp_log_level_set(RX_TASK_TAG, ESP_LOG_INFO);
    uint8_t* data = (uint8_t*) malloc(RX_BUF_SIZE+1);

    while (1) {
//    	clock_t start,finish;
//    	double duration;
//    	start = clock();
        const int rxBytes = uart_read_bytes(UART_NUM_1, data, RX_BUF_SIZE, 25/ portTICK_RATE_MS);

        if (rxBytes > 0) {
            data[rxBytes] = 0;
//            ESP_LOGI(RX_TASK_TAG, "Read %d bytes: '%s'", rxBytes, data);
//            ESP_LOG_BUFFER_HEXDUMP(RX_TASK_TAG, data, rxBytes, ESP_LOG_INFO);
//            datarecv = data;
//            recvBytes = rxBytes;
            esp_spp_write(129, rxBytes, data);
        }
//        finish =clock();
//        duration = (double)(finish - start)/CLOCKS_PER_SEC;
//        printf("t0 is:%f\r\n",duration);
    }
    free(data);
}
#define SPP_DATA_LEN ESP_SPP_MAX_MTU
char bt_data[129];
static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
{
    static const char *TX_TASK_TAG = "TX_TASK";
    esp_log_level_set(TX_TASK_TAG, ESP_LOG_INFO);

//    clock_t start1,finish1;
//    double duration1;

    switch (event) {
    case ESP_SPP_INIT_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_INIT_EVT");
        esp_bt_dev_set_device_name(EXCAMPLE_DEVICE_NAME);
        esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE);
        esp_spp_start_srv(sec_mask,role_slave, 0, SPP_SERVER_NAME);
        gpio_pad_select_gpio(GPIO_NUM_27);
        gpio_set_direction(GPIO_NUM_27, GPIO_MODE_OUTPUT);
        gpio_set_level(GPIO_NUM_27, 0);
        break;
    case ESP_SPP_DISCOVERY_COMP_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_DISCOVERY_COMP_EVT");
        break;
    case ESP_SPP_OPEN_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_OPEN_EVT");
//        esp_spp_write(param->srv_open.handle, SPP_DATA_LEN, spp_data);
//        gettimeofday(&time_old, NULL);
        break;
    case ESP_SPP_CLOSE_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_CLOSE_EVT");
        break;
    case ESP_SPP_START_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_START_EVT");
        break;
    case ESP_SPP_CL_INIT_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_CL_INIT_EVT");
        break;
    case ESP_SPP_DATA_IND_EVT:
//#if (SPP_SHOW_MODE == SPP_SHOW_DATA)
    	//BT receive data
//        start1 = clock();
        ESP_LOGI(SPP_TAG, "ESP_SPP_DATA_IND_EVT len=%d handle=%d",
                 param->data_ind.len, param->data_ind.handle);
//        esp_log_buffer_hex("",param->data_ind.data,param->data_ind.len);
        //send BT data to STM32
//        memcpy(bt_data,param->data_ind.data,param->data_ind.len);

//        if(bt_data[0] == 0xA5)
//        {
//            xTaskCreate(spi_task, "spi_rx_task", 4096, NULL, configMAX_PRIORITIES, NULL);
//        }else
//        {
        //send BT data to FPGA
//        finish =clock();
//        duration = (double)(finish - start)/CLOCKS_PER_SEC;
//        printf("t0 is:%f\r\n",duration);
//            const int txBytes = uart_write_bytes(UART_NUM_1, (char *)param->data_ind.data, param->data_ind.len);
          uart_write_bytes(UART_NUM_1, (char *)param->data_ind.data, param->data_ind.len);

//            ESP_LOGI(TX_TASK_TAG, "Wrote %d bytes comand %s", txBytes,(char *)param->data_ind.data);
//            finish1 = clock();
//            duration1 = (double)(finish1 - start1)/CLOCKS_PER_SEC;
//            printf("t1 is:%f\r\n",duration1);
            gpio_pad_select_gpio(GPIO_NUM_26);
            gpio_set_direction(GPIO_NUM_26, GPIO_MODE_OUTPUT);
            gpio_set_level(GPIO_NUM_26, 0);
//        }


//        sendData(TX_TASK_TAG, (char *)param->data_ind.data);
//        esp_spp_write(param->cong.handle, strlen((char *)spp_data), spp_data);
//        printf("recvBytes:%d,datarecv:%s",recvBytes,datarecv);
//        printf("recvBytes:%d\r\n",param->cong.handle);

//#else
//        gettimeofday(&time_new, NULL);
//        data_num += param->data_ind.len;
//        if (time_new.tv_sec - time_old.tv_sec >= 3) {
//            print_speed();
//        }
//#endif
        break;
    case ESP_SPP_CONG_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_CONG_EVT");
        break;
    case ESP_SPP_WRITE_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_WRITE_EVT len=%d cong=%d", param->write.len , param->write.handle);
//        esp_log_buffer_hex("",datarecv,recvBytes);
        break;
    case ESP_SPP_SRV_OPEN_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_SRV_OPEN_EVT");
//        gettimeofday(&time_old, NULL);
        break;
    default:
        break;
    }
}
////////////////////spi_task////////////////
//void spi_task(void){
////    if(bt_data[0] == 0xA5){
//    esp_err_t ret;
//    static const char *RX_TASK_TAG = "RX_TASK";
//    char sendbuf[129]="";
//    char recvbuf[129]="";
//    memset(recvbuf, 0, 33);
//    spi_slave_transaction_t t;
//    memset(&t, 0, sizeof(t));
//
//    while(1) {
//            //Clear receive buffer, set send buffer to something sane
//            memset(recvbuf, 0, 129);
//    //        sprintf(sendbuf, "This is the receiver, sending data for transmission number %04d.", n);
//            memcpy(sendbuf,bt_data,129);
//
////            sendbuf=bt_data;
//            //Set up a transaction of 128 bytes to send/receive
//            t.length=128*8;
//            t.tx_buffer=sendbuf;
//            t.rx_buffer=recvbuf;
//            /* This call enables the SPI slave interface to send/receive to the sendbuf and recvbuf. The transaction is
//            initialized by the SPI master, however, so it will not actually happen until the master starts a hardware transaction
//            by pulling CS low and pulsing the clock etc. In this specific example, we use the handshake line, pulled up by the
//            .post_setup_cb callback that is called as soon as a transaction is ready, to let the master know it is free to transfer
//            data.
//            */
//            ret=spi_slave_transmit(HSPI_HOST, &t, portMAX_DELAY);
//
//            //spi_slave_transmit does not return until the master has done a transmission, so by here we have sent our data and
//            //received data from the master. Print it.
////            ESP_LOGI(RX_TASK_TAG, "Receive %d bytes: '%s'", strlen(recvbuf), recvbuf);
//            ESP_LOG_BUFFER_HEXDUMP(RX_TASK_TAG, recvbuf, strlen(recvbuf), ESP_LOG_INFO);
//            //send spi data to client
////            if(recvbuf[0]==0xA5){
////            uint8_t* data=(uint8_t)recvbuf;
////            uint8_t buf_temp="2222";
////                esp_spp_write(129, strlen(buf_temp), (uint8_t)buf_temp);
////            }
////        }
//    }
//}
/*****************UART1 INIT**************/
void init_uart() {
    const uart_config_t uart_config = {
        .baud_rate = 115200,
        .data_bits = UART_DATA_8_BITS,
        .parity = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE
    };
    uart_param_config(UART_NUM_1, &uart_config);
    uart_set_pin(UART_NUM_1, TXD_PIN, RXD_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
    // We won't use a buffer for sending data.
    uart_driver_install(UART_NUM_1, RX_BUF_SIZE, 8192, 10, NULL, 0);
}

void app_main()
{
    esp_err_t ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES) {
        ESP_ERROR_CHECK(nvs_flash_erase());
        ret = nvs_flash_init();
    }
    ESP_ERROR_CHECK( ret );

    init_uart();// init uart1
    spi_init();
    xTaskCreate(rx_task, "uart_rx_task", 2048, NULL, configMAX_PRIORITIES, NULL);

    esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
    if ((ret = esp_bt_controller_init(&bt_cfg)) != ESP_OK) {
        ESP_LOGE(SPP_TAG, "%s initialize controller failed: %s\n", __func__, esp_err_to_name(ret));
        return;
    }

    if ((ret = esp_bt_controller_enable(ESP_BT_MODE_CLASSIC_BT)) != ESP_OK) {
        ESP_LOGE(SPP_TAG, "%s enable controller failed: %s\n", __func__, esp_err_to_name(ret));
        return;
    }

    if ((ret = esp_bluedroid_init()) != ESP_OK) {
        ESP_LOGE(SPP_TAG, "%s initialize bluedroid failed: %s\n", __func__, esp_err_to_name(ret));
        return;
    }

    if ((ret = esp_bluedroid_enable()) != ESP_OK) {
        ESP_LOGE(SPP_TAG, "%s enable bluedroid failed: %s\n", __func__, esp_err_to_name(ret));
        return;
    }

    if ((ret = esp_spp_register_callback(esp_spp_cb)) != ESP_OK) {
        ESP_LOGE(SPP_TAG, "%s spp register failed: %s\n", __func__, esp_err_to_name(ret));
        return;
    }

    if ((ret = esp_spp_init(esp_spp_mode)) != ESP_OK) {
        ESP_LOGE(SPP_TAG, "%s spp init failed: %s\n", __func__, esp_err_to_name(ret));
        return;
    }

}


cckaben
Posts: 2
Joined: Wed Jul 25, 2018 1:26 am

Re: bt_spp_acceptor demo esp32 bluetooth reception time is too long

Postby cckaben » Fri Jul 27, 2018 3:09 am

This problem seems to be very low-level, but it is true. Hasn't anyone tested this time?

Who is online

Users browsing this forum: Bing [Bot] and 85 guests