// 与pad之间进行数据通信,具有蓝牙、wifi两种方式 #include #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_log.h" #include "inc/communication_pad.h" #include "inc/wifi_softap.h" #include "inc/tcp_server.h" #include "inc/ble_gatts_server.h" #include "../stm32/ModbusS.h" #include "../stm32/config.h" static const char *TAG = "communication_pad"; padDataCtrl_t pad_notify_data; struct measureData measure_data; int register_pad_data(padDataCtrl_t *data_ctrl, uint8_t tag, uint8_t *data, int len, padUpdataFun updata_fun) { if (data_ctrl->cnt >= MAX_NOTIFY_DATA) { ESP_LOGI(TAG, "register_pad_data failed, data_ctrl is full"); return -1; } data_ctrl->datas[data_ctrl->cnt].tag = tag; data_ctrl->datas[data_ctrl->cnt].data = data; data_ctrl->datas[data_ctrl->cnt].len = len; data_ctrl->datas[data_ctrl->cnt].updata_fun = updata_fun; data_ctrl->cnt++; return 0; } extern flow_t *pflow; extern depth_t *depth_data; static void measure_data_updata(void) { measure_data.speed = depth_data->speed; measure_data.time = depth_data->one_pile_work_time; measure_data.depth = depth_data->depth; measure_data.pile_id = gWordVar[LAST_PILE_ID_ADDR]; measure_data.flow1 = pflow[0].flow; measure_data.flow_10cm1 = depth_data->depth_flow[0]; measure_data.flow_total1 = pflow[0].total_flow; measure_data.flow2 = pflow[1].flow; measure_data.flow_10cm2 = depth_data->depth_flow[1]; measure_data.flow_total2 = pflow[1].total_flow; measure_data.current[0] = gWordVar[AC_CURRENT_REG_ADDR + 0]; measure_data.current[1] = gWordVar[AC_CURRENT_REG_ADDR + 1]; measure_data.current[2] = gWordVar[AC_CURRENT_REG_ADDR + 2]; } // 上报data_ctrl中的数据 static void pad_notify_data_fun(const padDataCtrl_t *data_ctrl) { uint8_t data[1024]; // 这里的大小并没有控制 int data_len =0; // data[0] = NOTIFY_TAG; // data_len = 1; for (int i = 0; i < data_ctrl->cnt; i++) { if (data_ctrl->datas[i].updata_fun) data_ctrl->datas[i].updata_fun(); // 更新数据 data[data_len++] = data_ctrl->datas[i].tag; data[data_len++] = data_ctrl->datas[i].len; memcpy(data + data_len, data_ctrl->datas[i].data, data_ctrl->datas[i].len); data_len += data_ctrl->datas[i].len; } // 调用蓝牙和wifi的notify函数 tcp_server_notify(data, data_len); ble_server_notify(data, data_len); } static void pad_notify_task(void *pvParameters) { ESP_LOGI(TAG, "pad_notify_task"); while (1) { pad_notify_data_fun(&pad_notify_data); vTaskDelay(pdMS_TO_TICKS(100)); } vTaskDelete(NULL); } // 通信初始化 void pad_communication_init(void) { wifi_init_softap(); tcp_server_init(); ble_gatts_server_init(); register_pad_data(&pad_notify_data, 0xA1, &measure_data, sizeof(measure_data), measure_data_updata); register_pad_data(&pad_notify_data, 0xA2, &gWordVar[REG_GPS_MESSAGE], sizeof(gps_message_t), NULL); // 透传不用更新数据 xTaskCreate(pad_notify_task, "pad_notify_task", 4096, NULL, 8, NULL); } /* * 协议说明: * 功能码1byte + ... * 0XF0:写寄存器 2byte寄存器地址 + 1byte数据长度(字节为单位) + 数据 小端 * 0XF1:读寄存器 2byte寄存器地址 + 1byte数据长度(字节为单位) * 0XF2:开notify * 0XF3:关notify * 如果是读寄存器功能,则从参数返回读取结果数组,否则返回NULL,注意,返回的指针需要手动free */ void pad_deal_recived_data(uint8_t *data, int len, int *enable_notify, uint8_t **retbuf, int *retlen) { ESP_LOGI(TAG, "pad_deal_recived_data"); *retbuf = NULL; *retlen = 0; if (len >= 4 && data[0] == 0xF0) /* 写gWordVar寄存器 */ { uint16_t addr = data[1] + (data[2] << 8); uint16_t addr_ = addr; uint8_t cnt = data[3]; if (cnt > len - 4) { ESP_LOGI(TAG, "write format is fault, cnt > len - 4"); return; } ESP_LOGI(TAG, "write addr:%d cnt:%d", addr, cnt); uint8_t i; for (i = 0 + 4; i < cnt + 4; i+=2) /* 发送的数据要求两字节对齐 */ { gWordVar[addr++] = data[i] + (data[i + 1] << 8); ESP_LOGI(TAG, "gwordvar[%d]:0x%x", addr-1, gWordVar[addr-1]); } ModBusWordWriteHook(addr_, cnt); } else if (len >= 4 && data[0] == 0xF1) /* 读gWordVar,返回*/ { uint16_t addr = data[1] + (data[2] << 8); uint8_t cnt = data[3]; ESP_LOGI(TAG, "read addr:%d cnt:%d", addr, cnt); *retbuf = (uint8_t *)malloc(cnt + 4); (*retbuf)[0] = data[0]; (*retbuf)[1] = data[1]; (*retbuf)[2] = data[2]; (*retbuf)[3] = data[3]; memcpy((*retbuf) + 4, (uint8_t *)(gWordVar + addr), cnt); *retlen = cnt + 4; } else if (len == 1 && data[0] == 0xF2) /* 开启notify */ { ESP_LOGI(TAG, "enable notify"); *enable_notify = 1; } else if (len == 1 && data[0] == 0xF2) /* 关闭notify */ { ESP_LOGI(TAG, "disable notify"); *enable_notify = 0; } else ESP_LOGI(TAG, "format err!"); }