ESP32:藍牙BLE控制M3508電機


ESP32:藍牙BLE控制M3508電機

過年好啊

先給各位朋友拜個年,祝大家新春快樂,事事順利,身體健康啊!

還是熟悉的3508,內容概述:

  1. ESP32主控
  2. 藍牙BLE通信
  3. 使用實時系統(FreeRTOS)
  4. 使用ESP32的TWAI總線(CAN)

ESP32使用ESP-IDF v4.3開發,倉庫地址放在文末。

目錄

ESP32的TWAI(CAN)

概覽與對比

有人說ESP32沒有CAN總線控制器,其實不然,只不過它被稱作TWAI,two-wire automotive interface。這也是ESP32可以用來控制大疆M3508、M2006等電機的根本原因。由於官方放出的資料很少,所以不被大家所熟知。

ESP32的CAN控制器在功能上比STM32略遜一籌,同時技術披露較少,其硬件設計參數基本都是未知的。但從另一方面說,整體配置使用比STM32更簡單一些的,特別是結合實時系統提供的一些組件,不需要過多的考慮中斷等問題。

最大區別在於,STM32有三組FIFO和靈活分配的filter,ESP32則采用收發buffer,控制器硬件將接受到的消息放入buffer中,軟件驅動再把buffer中的報文處理過后放入queue,用戶應用讀取queue獲取報文,發送同理。

反饋的獲取

ESP32沒有提供中斷回調函數接口。意味着STM32上使用接收中斷來更新電機反饋的方法是行不通的,為保證反饋量的實時性,有以下三種方法可以選擇:

  1. 使用優先級合適的任務進行輪詢
  2. 利用定時器中斷回調進行輪詢
  3. 利用TWAI控制器的alert查詢阻塞讀取

由於我使用的FreeRTOS的tick為10ms,而大疆C620電調的發送速率默認為1KHz,所以我使用了第一個方法來獲取電機反饋數據。創建一個從queue中讀取報文的任務,不斷阻塞查詢queue,計算更新反饋數據。

藍牙BLE

ESP32的最大亮點就是支持WiFi、藍牙協議棧,使用藍牙代替串口的應用場景無需多言。其中低功耗藍牙BLE非常合適少量文本數據的發送。下面簡要介紹幾個藍牙BLE概念。

GAP

GAP定義了設備的廣播行為,例如手機可以掃描到很多藍牙BLE設備便是靠GAP。GAP把設備分成兩種:中心設備(Central)、外圍設備(Peripheral),外圍設備對外不斷廣播,中心設備掃描、接收廣播。發現后進而建立連接,再利用下文的GATT協議進行數據傳輸。

舉例來說,我們的手機往往扮演中心設備的角色,而智能手環、智能家居、藍牙耳機、電動牙刷等設備則是外圍設備。

GATT

利用GAP發現並連接相應設備后,就可以開始傳輸數據了。藍牙BLE的數據傳輸建立在GATT協議上,它定義了BLE設備之間如何傳輸數據。GATT把設備分為Client和Server,其中命令與請求由Client主動發起,Server被動接受。

請注意:GATT的Client、Server身份與GAP的中心、外圍設備沒有任何關系,它們可以任意搭配,甚至可以既是Server又是Client。

參考:Getting Started with Bluetooth Low Energyhttps://www.oreilly.com/library/view/getting-started-with/9781491900550/ch04.html

在本例中,運行着GATT Server的ESP32在建立連接前主動對外廣播,充當外圍設備。手機作為GATT Client,可以主動發起數據傳輸。

下面是典型的GATT Server的數據層級結構圖,服務端上可以同時提供多個Service讓客戶端選擇,每個Service內可以有多個Characteristic,其中就保存着數據的內容和描述。客戶端請求的時候就可以單獨請求某個Service里的某個Characteristic包含的數據。

GATT-Server結構

舉例說明,某款智能手環作為GATT Server,定義了電量和運動兩個Service。電量服務內有一個Characteristic保存着電池電量百分比,手機請求它即可獲得手環電量。運動Service內有步數、消耗卡路里、睡眠時間等Characteristic,手機可以在需要的時候分別請求這些數據。

由於藍牙協議內容較多,這里暫不展開,后面有機會可以進一步深入討論。

ESP32 API

為了使用BLE,首先要把藍牙外設驅動、硬件初始化,按照之前說的,為了建立連接我們要初始化GAP,為了傳輸數據要初始化GATT。具體表現為要為GAP、GATT注冊處理事件的回調函數。

	ret = esp_ble_gatts_register_callback(gatts_event_handler);
	//錯誤處理
    ret = esp_ble_gap_register_callback(gap_event_handler);
	//錯誤處理
    ret = esp_ble_gatts_app_register(PROFILE_A_APP_ID);
	//錯誤處理

這些回調函數使用switch語句判斷由底層驅動傳遞上來的事件編號,並給出處理步驟,我們對其中的讀寫事件處理進行修改,使其符合我們的數據傳輸需求。


結合前面完成的TWAI驅動、移植的PID程序,電機控制程序基本完成。

實際上手

使用微信上的BLE調試小程序或者Nordic Connect軟件都可以,后者較為專業簡潔,但兩者功能上差別不大。

Nordic Connect界面

向圖中的Characteristic發送速度目標值,會觸發ESP_GATTS_WRITE_EVT事件,在處理中加入解析並向發送設備返回一個notify告知寫入成功:

char data[30];
memcpy(data,param->write.value,param->write.len);
data[param->write.len]=0;
moto_pid.target=atof(data);
printf("resetting target:%.2f\n",moto_pid.target);
sprintf(data,"SET TARGET:%.2f",moto_pid.target);
if (a_property & ESP_GATT_CHAR_PROP_BIT_NOTIFY){//發送notice
    esp_ble_gatts_send_indicate(gatts_if, param->write.conn_id,
    gl_profile_tab[PROFILE_A_APP_ID].char_handle,
    strlen(data),(unsigned char *)data, false);}

當按下左邊的獲取按鈕時,會觸發ESP_GATTS_READ_EVT事件,使用response讓Client獲得圖中的速度值:

char spd[20];
sprintf(spd,"speed:%hd",moto_chassis->speed_rpm);
rsp.attr_value.len = strlen(spd);
memcpy(rsp.attr_value.value,spd,rsp.attr_value.len);
esp_ble_gatts_send_response(gatts_if, param->read.conn_id, 
                            param->read.trans_id,
                            ESP_GATT_OK, &rsp);

總結

臨近年關,事也多,心也燥。這次本是簡單的移植,文章卻一直拖到正月初二才寫完。涉及藍牙協議棧的東西不敢多說,還需要多加研究。最后,祝大家新春快樂,工作順利,身體健康!

工程倉庫地址GitHub:https://github.com/HuXioAn/ESP32-M3508-BLE


技術新人,水平有限,文中紕漏請一定指出,如有其他意見也請不吝賜教。更多嵌入式相關內容請移步公眾號,來找我聊聊天吧:

歡迎轉載,轉載請注明作者與原文地址。

作者:胡小安

原文地址:https://www.cnblogs.com/huxiaoan/p/15861624.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM