ESP32:藍芽BLE控制M3508電機

胡小安發表於2022-02-03

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


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

ESP32:藍芽BLE控制M3508電機

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

作者:胡小安

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

相關文章