You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
375 lines
14 KiB
375 lines
14 KiB
/*
|
|
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.
|
|
*/
|
|
|
|
/****************************************************************************
|
|
*
|
|
* This demo showcases BLE GATT server. It can send adv data, be connected by client.
|
|
* Run the gatt_client demo, the client demo will automatically connect to the gatt_server demo.
|
|
* Client demo will enable gatt_server's notify after connection. The two devices will then exchange
|
|
* data.
|
|
*
|
|
****************************************************************************/
|
|
#include "motor_drive.h"
|
|
#include "t_bluetooth.h"
|
|
|
|
/***********************************************************************************************************************
|
|
* ****************************************************user_define**************************************************** *
|
|
***********************************************************************************************************************/
|
|
|
|
char bluetooth_rx_buffer[profile_b_buffer_size] = {0};
|
|
|
|
ble_gatts_str_t ble_gatts_a_str = {
|
|
.attr_handle = 0,
|
|
.send_conn_id = 0,
|
|
.send_gatts_if = 0,
|
|
};
|
|
|
|
/***********************************************************************************************************************
|
|
* **********************************************user_function_statement********************************************** *
|
|
***********************************************************************************************************************/
|
|
void bluetooth_gatts_try_process_data();
|
|
void timer_set_pause_and_counter_zero(int group, int timer);
|
|
void port_timer_delay_ms(uint64_t delay);
|
|
bool parse_rxbuffer_and_validation_data(cJSON **json_tmp);
|
|
bool parse_json_to_struct(cJSON *ch);
|
|
void receipt_json_set_position();
|
|
void receipt_json_get_status();
|
|
|
|
bluetooth_processer_t s_bluetooth_processer = {
|
|
.bluetooth_processer_rx_buf = bluetooth_rx_buffer,
|
|
.bluetooth_processer_rx_buf_size = sizeof(bluetooth_rx_buffer),
|
|
.bluetooth_baundrate_one_packet_delay_ms = kbluetooth_baundrate_one_packet_delay_ms,
|
|
.port_delay_ms = port_timer_delay_ms,
|
|
|
|
.bluetooth_rx_buffer_start_receving = false,
|
|
.bluetooth_rx_buffer_processing = false,
|
|
|
|
.order = "order",
|
|
.index = 0,
|
|
.speed_level = 0,
|
|
.position = 0.0,
|
|
.direction = 0,
|
|
.code = 0,
|
|
.info = "noerror",
|
|
.deviceState = "init",
|
|
.deviceException = 0,
|
|
.deviceExceptionInfo = "noexception",
|
|
|
|
.cmd_flag = false,
|
|
.actively_report_flag = false,
|
|
};
|
|
|
|
/***********************************************************************************************************************
|
|
* *******************************************************timer******************************************************* *
|
|
***********************************************************************************************************************/
|
|
// static bool IRAM_ATTR timer_group_isr_callback(void *args)
|
|
// {
|
|
// bluetooth_rx_buffer_start_receving = true;
|
|
// return pdFALSE;
|
|
// }
|
|
|
|
void timer_group_init(int group, int timer, bool auto_reload, int timer_interval, uint32_t timer_unit_time)
|
|
{
|
|
/* Select and initialize basic parameters of the timer */
|
|
timer_config_t config = {
|
|
.divider = 80,
|
|
.counter_dir = TIMER_COUNT_UP,
|
|
.counter_en = TIMER_PAUSE,
|
|
.alarm_en = TIMER_ALARM_EN,
|
|
.auto_reload = auto_reload,
|
|
}; // default clock source is APB
|
|
timer_init(group, timer, &config);
|
|
|
|
/* Timer's counter will initially start from value below.
|
|
Also, if auto_reload is set, this value will be automatically reload on alarm */
|
|
timer_set_counter_value(group, timer, 0); //指定定时器首个计数值为0
|
|
|
|
//检查定时器的当前值,调用函数 timer_get_counter_value() 或 timer_get_counter_time_sec()。
|
|
//可通过调用函数 timer_pause() 随时暂停定时器。要再次启动它,调用函数 timer_start()。
|
|
|
|
/* Configure the alarm value and the interrupt on alarm. */
|
|
timer_set_alarm_value(group, timer, timer_interval * ((80 * timer_unit_time) / 80));
|
|
|
|
timer_enable_intr(group, timer);
|
|
|
|
// timer_isr_callback_add(group, timer, timer_group_isr_callback, NULL, 0);
|
|
|
|
// timer_start(group, timer);
|
|
timer_pause(group, timer);
|
|
}
|
|
|
|
/***********************************************************************************************************************
|
|
* *******************************************************main******************************************************** *
|
|
***********************************************************************************************************************/
|
|
void app_main(void)
|
|
{
|
|
esp_ble_gatts_init(&ble_gatts_a_str, &s_bluetooth_processer);
|
|
// motor_init();
|
|
// motor_encoder_init();
|
|
timer_group_init(TIMER_GROUP_0, TIMER_0, false, timer_group0_interval_num, timer_interval_ms);
|
|
// gatts_profile_a_constructor_s();
|
|
|
|
// uint8_t temp[5] = "hello";
|
|
// esp_gatt_rsp_t rsp;
|
|
// memset(&rsp, 0, sizeof(esp_gatt_rsp_t));
|
|
// rsp.attr_value.len = 4;
|
|
// rsp.attr_value.value[0] = 0x11;
|
|
// rsp.attr_value.value[1] = 0x22;
|
|
// rsp.attr_value.value[2] = 0x33;
|
|
// rsp.attr_value.value[3] = 0x44;
|
|
|
|
while (true)
|
|
{
|
|
// if (ble_gatts_a_str.attr_handle != 0)
|
|
// {
|
|
// rsp.attr_value.handle = ble_gatts_a_str.attr_handle;
|
|
// ESP_LOGI(GATTS_TAG, "%d,%d,%d", ble_gatts_a_str.attr_handle, ble_gatts_a_str.send_conn_id, ble_gatts_a_str.send_gatts_if);
|
|
// esp_ble_gatts_send_indicate(ble_gatts_a_str.send_gatts_if, ble_gatts_a_str.send_conn_id,
|
|
// ble_gatts_a_str.attr_handle, 5, temp, true);
|
|
// esp_ble_gatts_send_response(ble_gatts_a_str.send_gatts_if, ble_gatts_a_str.send_conn_id, 1,
|
|
// ESP_GATT_OK, &rsp);
|
|
// ets_delay_us(1000000);
|
|
// }
|
|
// esp_ble_gatts_set_attr_value(ble_gatts_a_str.constructor_param->read.handle, 5, temp);
|
|
|
|
bluetooth_gatts_try_process_data();
|
|
if (s_bluetooth_processer.actively_report_flag)
|
|
{
|
|
receipt_json_get_status();
|
|
s_bluetooth_processer.actively_report_flag = false;
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/***********************************************************************************************************************
|
|
* *************************************************user_funtion_def************************************************** *
|
|
***********************************************************************************************************************/
|
|
|
|
|
|
void timer_set_pause_and_counter_zero(int group, int timer)
|
|
{
|
|
timer_pause(group, timer);
|
|
timer_set_counter_value(group, timer, 0);
|
|
}
|
|
|
|
bool validation_param(cJSON *object, char *param)
|
|
{
|
|
cJSON *current_element = object->child;
|
|
|
|
while (current_element->string != NULL)
|
|
{
|
|
if (current_element->string == param)
|
|
{
|
|
return true;
|
|
}
|
|
current_element = current_element->next;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void bluetooth_gatts_try_process_data()
|
|
{
|
|
cJSON *json_tmp;
|
|
// cJSON *ch;
|
|
//开始接收
|
|
if (s_bluetooth_processer.bluetooth_rx_buffer_start_receving)
|
|
{
|
|
//开启定时器
|
|
s_bluetooth_processer.port_delay_ms(s_bluetooth_processer.bluetooth_baundrate_one_packet_delay_ms);
|
|
// port_timer_delay_ms(kbluetooth_baundrate_one_packet_delay_ms);
|
|
s_bluetooth_processer.bluetooth_rx_buffer_processing = true;
|
|
|
|
//打印输出
|
|
// ESP_LOGI(GATTS_TAG, "%s", s_bluetooth_processer.bluetooth_processer_rx_buf);
|
|
|
|
//验证解析数据是否正确
|
|
if (parse_rxbuffer_and_validation_data(&json_tmp))
|
|
{
|
|
// JSON解析到结构体,如果order更改表示有指令传输进来,并且更改指令标志位(cmd_flag)为true
|
|
if (parse_json_to_struct(json_tmp->child))
|
|
{
|
|
ESP_LOGI(GATTS_TAG, "order:%s ,index:%d speedLevel:%d position:%f direction:%d",
|
|
s_bluetooth_processer.order, s_bluetooth_processer.index, s_bluetooth_processer.speed_level,
|
|
s_bluetooth_processer.position, s_bluetooth_processer.direction);
|
|
if (strcmp(s_bluetooth_processer.order, set_position) == 0)
|
|
{
|
|
ESP_LOGI(GATTS_TAG, set_position);
|
|
motor_cmd_set_position(s_bluetooth_processer.speed_level, s_bluetooth_processer.position, s_bluetooth_processer.direction);
|
|
receipt_json_set_position();
|
|
}
|
|
if (strcmp(s_bluetooth_processer.order, get_status) == 0)
|
|
{
|
|
ESP_LOGI(GATTS_TAG, get_status);
|
|
receipt_json_get_status();
|
|
}
|
|
// if (strcmp(s_bluetooth_processer.order, "deviceStatusReport") == 0)
|
|
// {
|
|
// ESP_LOGI(GATTS_TAG, "deviceStatusReport");
|
|
// }
|
|
s_bluetooth_processer.actively_report_flag = true;
|
|
}
|
|
}
|
|
|
|
//释放空间
|
|
cJSON_Delete(json_tmp);
|
|
// buffer置0
|
|
buffer_all_init();
|
|
//未在处理数据
|
|
s_bluetooth_processer.cmd_flag = false;
|
|
s_bluetooth_processer.bluetooth_rx_buffer_start_receving = false;
|
|
s_bluetooth_processer.bluetooth_rx_buffer_processing = false;
|
|
}
|
|
}
|
|
|
|
void port_timer_delay_ms(uint64_t delay)
|
|
{
|
|
uint64_t timer_count = 0;
|
|
timer_set_counter_value(TIMER_GROUP_0, TIMER_0, 0);
|
|
timer_start(TIMER_GROUP_0, TIMER_0);
|
|
|
|
while (timer_count < (delay * 1000))
|
|
{
|
|
timer_get_counter_value(TIMER_GROUP_0, TIMER_0, &timer_count);
|
|
}
|
|
|
|
timer_pause(TIMER_GROUP_0, TIMER_0);
|
|
}
|
|
|
|
bool parse_rxbuffer_and_validation_data(cJSON **json_tmp)
|
|
{
|
|
*json_tmp = cJSON_Parse(&bluetooth_rx_buffer[0]);
|
|
if (*json_tmp == NULL)
|
|
{
|
|
ESP_LOGE(GATTS_TAG, "parse rxbuffer nil or redundant symbol ',' ");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool parse_json_to_struct(cJSON *ch)
|
|
{
|
|
uint8_t cmd_length = 0;
|
|
while (ch != NULL)
|
|
{
|
|
// ESP_LOGI(GATTS_TAG, "%s", ch->string);
|
|
if (strcmp(ch->string, "order") == 0)
|
|
{
|
|
s_bluetooth_processer.order = ch->valuestring;
|
|
|
|
if (strcmp(ch->valuestring, set_position) == 0)
|
|
{
|
|
cmd_length = cmd_length_set_position;
|
|
}
|
|
if (strcmp(ch->valuestring, get_status) == 0)
|
|
{
|
|
cmd_length = cmd_length_get_status;
|
|
}
|
|
// if (strcmp(ch->valuestring, "deviceStatusReport") == 0)
|
|
// {
|
|
// cmd_length = cmd_length_device_status_report;
|
|
// }
|
|
cmd_length--;
|
|
}
|
|
if (strcmp(ch->string, "index") == 0)
|
|
{
|
|
s_bluetooth_processer.index = ch->valueint;
|
|
cmd_length--;
|
|
}
|
|
if (strcmp(ch->string, "speedLevel") == 0)
|
|
{
|
|
s_bluetooth_processer.speed_level = ch->valueint;
|
|
cmd_length--;
|
|
}
|
|
if (strcmp(ch->string, "position") == 0)
|
|
{
|
|
s_bluetooth_processer.position = ch->valuedouble;
|
|
cmd_length--;
|
|
}
|
|
if (strcmp(ch->string, "direction") == 0)
|
|
{
|
|
s_bluetooth_processer.direction = ch->valueint;
|
|
cmd_length--;
|
|
}
|
|
ch = ch->next;
|
|
}
|
|
|
|
if (cmd_length == 0)
|
|
{
|
|
s_bluetooth_processer.cmd_flag = true;
|
|
}
|
|
else
|
|
{
|
|
ESP_LOGE(GATTS_TAG, "JSON directive missing or exceeded");
|
|
}
|
|
|
|
return s_bluetooth_processer.cmd_flag;
|
|
}
|
|
|
|
void receipt_json_set_position()
|
|
{
|
|
cJSON *pRoot = cJSON_CreateObject(); //创建一个对象
|
|
if (!pRoot)
|
|
{
|
|
return;
|
|
}
|
|
|
|
cJSON_AddStringToObject(pRoot, "order", "receipt"); //添加一个节点
|
|
cJSON_AddNumberToObject(pRoot, "code", s_bluetooth_processer.code);
|
|
cJSON_AddStringToObject(pRoot, "info", "success");
|
|
cJSON_AddNumberToObject(pRoot, "index", s_bluetooth_processer.index);
|
|
char *szJson = cJSON_Print(pRoot);
|
|
|
|
if (szJson != NULL)
|
|
{
|
|
ESP_LOGI(GATTS_TAG, "%s", szJson);
|
|
|
|
// esp_gatt_rsp_t rsp;
|
|
// memset(&rsp, 0, sizeof(esp_gatt_rsp_t));
|
|
// rsp.attr_value.handle = constructor_param->read.handle;
|
|
// rsp.attr_value.len = 4;
|
|
// rsp.attr_value.value[0] = 0x11;
|
|
// rsp.attr_value.value[1] = 0x22;
|
|
// rsp.attr_value.value[2] = 0x33;
|
|
// rsp.attr_value.value[3] = 0x44;
|
|
|
|
// esp_ble_gatts_send_response(constructor_gatts_if, constructor_param->read.conn_id,
|
|
// constructor_param->read.trans_id, ESP_GATT_OK, &rsp);
|
|
|
|
free(szJson);
|
|
}
|
|
|
|
cJSON_Delete(pRoot);
|
|
}
|
|
|
|
void receipt_json_get_status()
|
|
{
|
|
cJSON *pRoot = cJSON_CreateObject(); //创建一个对象
|
|
if (!pRoot)
|
|
{
|
|
return;
|
|
}
|
|
|
|
cJSON_AddStringToObject(pRoot, "order", "receipt"); //添加一个节点
|
|
cJSON_AddNumberToObject(pRoot, "index", s_bluetooth_processer.index);
|
|
cJSON_AddStringToObject(pRoot, "deviceState", s_bluetooth_processer.deviceState);
|
|
cJSON_AddNumberToObject(pRoot, "deviceException", s_bluetooth_processer.deviceException);
|
|
cJSON_AddStringToObject(pRoot, "deviceExceptionInfo", s_bluetooth_processer.deviceExceptionInfo);
|
|
cJSON_AddNumberToObject(pRoot, "position", s_bluetooth_processer.position);
|
|
|
|
char *szJson = cJSON_Print(pRoot);
|
|
|
|
if (szJson != NULL)
|
|
{
|
|
ESP_LOGI(GATTS_TAG, "%s", szJson);
|
|
free(szJson);
|
|
}
|
|
|
|
cJSON_Delete(pRoot);
|
|
}
|