Need to use esp_spp_write in succession and at a very fast rate , I have read up about it
"This function is used to write data, only for ESP_SPP_MODE_CB. When this function need to be called repeatedly, it is strongly recommended to call this function again after the previous event ESP_SPP_WRITE_EVT is received and the parameter ‘cong’ is equal to false. If the previous event ESP_SPP_WRITE_EVT with parameter ‘cong’ is equal to true, the function can only be called again when the event ESP_SPP_CONG_EVT with parameter ‘cong’ equal to false is received. This function must be called after an connection between initiator and acceptor has been established."
but am unable to understand .plz help.
ESP BT SPP
-
- Posts: 1708
- Joined: Mon Oct 17, 2022 7:38 pm
- Location: Europe, Germany
Re: ESP BT SPP
What is it you don't understand?
It's actually pretty simple:
You start sending data by first calling esp_spp_write for some chunk of data; limit the size of the chunk to some sensible value, e.g. ESP_SPP_MAX_MTU.
The BT stack responds to your esp_spp_write with an ESP_SPP_WRITE_EVT. When you receive that event, you can immediately send the next chunk of data, but only if that event's "cong" parameter is false. If "cong" is true, you don't send the next chunk immediately but wait for an ESP_SPP_CONG_EVT indicating that "cong" is now false.
Pseudocode:
It's actually pretty simple:
You start sending data by first calling esp_spp_write for some chunk of data; limit the size of the chunk to some sensible value, e.g. ESP_SPP_MAX_MTU.
The BT stack responds to your esp_spp_write with an ESP_SPP_WRITE_EVT. When you receive that event, you can immediately send the next chunk of data, but only if that event's "cong" parameter is false. If "cong" is true, you don't send the next chunk immediately but wait for an ESP_SPP_CONG_EVT indicating that "cong" is now false.
Pseudocode:
Code: Select all
if ((event == ESP_SPP_WRITE_EVT && event.cong == false) || (event == ESP_SPP_CONG_EVENT && event.cong == false)) {
esp_spp_write(nextChunkOfData);
}
Re: ESP BT SPP
Hi thank you for your explanation, I have a sample that I am using for 2 way communications. I want to use the write function multiple times in succession in very fast rate. I am having difficulty in understanding that where and how to use this function to send data received through uart.
This is the code
#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 "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 "time.h"
#include "sys/time.h"
#define SPP_TAG "SPP_ACCEPTOR_DEMO"
#define SPP_SERVER_NAME "SPP_SERVER"
#define EXCAMPLE_DEVICE_NAME "ESP_SPP_ACCEPTOR"
#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 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;
}
static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
{
char buf[1024];
char spp_data[256];
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_CONNECTABLE,ESP_BT_GENERAL_DISCOVERABLE);
esp_spp_start_srv(sec_mask,role_slave, 0, SPP_SERVER_NAME);
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");
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)
ESP_LOGI(SPP_TAG, "ESP_SPP_DATA_IND_EVT len=%d handle=%d",
param->data_ind.len, param->data_ind.handle);
if (param->data_ind.len < 1023) {
snprintf(buf, (size_t)param->data_ind.len, (char *)param->data_ind.data);
printf("%s\n", buf);
sprintf(spp_data, "Receined characters: %d\n", param->data_ind.len);
esp_spp_write(param->write.handle, strlen(spp_data), (uint8_t *)spp_data);
}
else {
esp_log_buffer_hex("",param->data_ind.data,param->data_ind.len);
}
#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");
break;
case ESP_SPP_SRV_OPEN_EVT:
ESP_LOGI(SPP_TAG, "ESP_SPP_SRV_OPEN_EVT");
gettimeofday(&time_old, NULL);
break;
default:
break;
}
}
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 );
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
if (esp_bt_controller_init(&bt_cfg) != ESP_OK) {
ESP_LOGE(SPP_TAG, "%s initialize controller failed\n", __func__);
return;
}
if (esp_bt_controller_enable(ESP_BT_MODE_CLASSIC_BT) != ESP_OK) {
ESP_LOGE(SPP_TAG, "%s enable controller failed\n", __func__);
return;
}
if (esp_bluedroid_init() != ESP_OK) {
ESP_LOGE(SPP_TAG, "%s initialize bluedroid failed\n", __func__);
return;
}
if (esp_bluedroid_enable() != ESP_OK) {
ESP_LOGE(SPP_TAG, "%s enable bluedroid failed\n", __func__);
return;
}
if (esp_spp_register_callback(esp_spp_cb) != ESP_OK) {
ESP_LOGE(SPP_TAG, "%s spp register failed\n", __func__);
return;
}
if (esp_spp_init(esp_spp_mode) != ESP_OK) {
ESP_LOGE(SPP_TAG, "%s spp init failed\n", __func__);
return;
}
}
This is the code
#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 "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 "time.h"
#include "sys/time.h"
#define SPP_TAG "SPP_ACCEPTOR_DEMO"
#define SPP_SERVER_NAME "SPP_SERVER"
#define EXCAMPLE_DEVICE_NAME "ESP_SPP_ACCEPTOR"
#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 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;
}
static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
{
char buf[1024];
char spp_data[256];
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_CONNECTABLE,ESP_BT_GENERAL_DISCOVERABLE);
esp_spp_start_srv(sec_mask,role_slave, 0, SPP_SERVER_NAME);
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");
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)
ESP_LOGI(SPP_TAG, "ESP_SPP_DATA_IND_EVT len=%d handle=%d",
param->data_ind.len, param->data_ind.handle);
if (param->data_ind.len < 1023) {
snprintf(buf, (size_t)param->data_ind.len, (char *)param->data_ind.data);
printf("%s\n", buf);
sprintf(spp_data, "Receined characters: %d\n", param->data_ind.len);
esp_spp_write(param->write.handle, strlen(spp_data), (uint8_t *)spp_data);
}
else {
esp_log_buffer_hex("",param->data_ind.data,param->data_ind.len);
}
#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");
break;
case ESP_SPP_SRV_OPEN_EVT:
ESP_LOGI(SPP_TAG, "ESP_SPP_SRV_OPEN_EVT");
gettimeofday(&time_old, NULL);
break;
default:
break;
}
}
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 );
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
if (esp_bt_controller_init(&bt_cfg) != ESP_OK) {
ESP_LOGE(SPP_TAG, "%s initialize controller failed\n", __func__);
return;
}
if (esp_bt_controller_enable(ESP_BT_MODE_CLASSIC_BT) != ESP_OK) {
ESP_LOGE(SPP_TAG, "%s enable controller failed\n", __func__);
return;
}
if (esp_bluedroid_init() != ESP_OK) {
ESP_LOGE(SPP_TAG, "%s initialize bluedroid failed\n", __func__);
return;
}
if (esp_bluedroid_enable() != ESP_OK) {
ESP_LOGE(SPP_TAG, "%s enable bluedroid failed\n", __func__);
return;
}
if (esp_spp_register_callback(esp_spp_cb) != ESP_OK) {
ESP_LOGE(SPP_TAG, "%s spp register failed\n", __func__);
return;
}
if (esp_spp_init(esp_spp_mode) != ESP_OK) {
ESP_LOGE(SPP_TAG, "%s spp init failed\n", __func__);
return;
}
}
Who is online
Users browsing this forum: Baidu [Spider], MicroController and 112 guests