之前接到一個案子忙了好大一會,最近稍微比較有空才可以整理。
整體需求算是大架構但整體算簡單。
客戶想要將他們既有的機械式產品提升到物聯網世代,加入藍芽的模組,讓終端使用者可以透過無線的方式去監測及操作產品。
聽到產品後,發現這案最需要注意的是需要整合藍芽模組框架的處理及程式化客戶既有機械式行為。
著手開始後產品規劃後,由於客戶的時脈連millisecond的等級都不到,最後決議在藍芽模組的OS架構底下,再去開一個Thread 來Handle Task Queue, 將所有的機械式行為變成interrupt 來處理。
最後綜合考量下選擇了Infineon的CYBT-413055這顆晶片來去做開發。
以下為案子紀錄與心得
案子遇到幾個大問題:
1. 客戶產品的馬達需要運轉後,需要即時煞停。
一開始與客戶了解機械原理時,客戶並沒有提出這項需求。在做出POC版的後,發現產品的動作並非正常。後來才了解產品需要及時煞停的服務。所以在馬達控制的控制信號中,多了另一個Pmos來控制煞車訊號。
1-1. 當客戶發現到煞車問題後,隨即提出是否可以透過藍芽來更改煞車力道
這問題有點抽象,原本想將馬達煞車改成ABS那種點煞訊號,發現周邊元件壽命會降低。所以只好更改馬達斷電 <-> 馬達煞車 這段時間差來造成煞車力道的模擬。
但這問題發現如果將斷電後隨即煞車會造成N & Pmos同時通路 進而導致整個板子短路。
最後透過Scope去了解整體訊號的最短時機大約為2ms,所以將保險時間拉至3ms

2. Limit Switch 雜訊太多
使用四隻腳的Swtich(ESE31R) 才可以固定在板子上。但每當動作時,SoC誤動作的機率很大。接了示波器才發現訊號很雜。研究了很久,發現Swtich 腳位定義為三隻腳接地,剩下一隻接到訊號接收端。但Layout並未將全部的GND接地,反而只接一隻腳。全接地後訊號極為正常。
3.OTA功能(over the air)
隨著客戶胃口越來越大,客戶希望隨時推播最新的Firmware給專端使用者。所以只好把OTA的功能一併時現在韌體內。因為一開始的專案並沒有include OTA的功能。所以要從Sample code porting到專案才發現不是一件很簡單的事情。
首先要先將build出來的binary檔案設定為OTA可使用的binary檔案,要做到這件事情需要在Makefile裏面新增新的config
OTA_FW_UPGRADE?=1
由於SDK已經有OTA的模組了,所以要將整個OTA的marco實現在專案內。
在主要handle ble service的檔案內新增
#include "wiced_bt_ota_firmware_upgrade.h" //header file
#ifdef FW_OTASERVER_ADVERT
#define HANDLE_OTA_FW_UPGRADE_GATT_SERVICE 1
#define HANDLE_OTA_FW_UPGRADE_GAP_SERVICE 2
#define HANDLE_OTA_FW_UPGRADE_CHAR_DEV_NAME 3
#define HANDLE_OTA_FW_UPGRADE_CHAR_DEV_NAME_VAL 4
#define HANDLE_OTA_FW_UPGRADE_CHAR_DEV_APPEARANCE 5
#define HANDLE_OTA_FW_UPGRADE_CHAR_DEV_APPEARANCE_VAL 6
#endif
同時要將OTA的藍芽service給開啟才可以透過藍芽傳送資料。
PRIMARY_SERVICE_UUID128(HANDLE_OTA_FW_UPGRADE_SERVICE, UUID_OTA_FW_UPGRADE_SERVICE),
CHARACTERISTIC_UUID128_WRITABLE(HANDLE_OTA_FW_UPGRADE_CHARACTERISTIC_CONTROL_POINT, HANDLE_OTA_FW_UPGRADE_CONTROL_POINT,
UUID_OTA_FW_UPGRADE_CHARACTERISTIC_CONTROL_POINT, LEGATTDB_CHAR_PROP_WRITE | LEGATTDB_CHAR_PROP_NOTIFY | LEGATTDB_CHAR_PROP_INDICATE,
LEGATTDB_PERM_VARIABLE_LENGTH | LEGATTDB_PERM_WRITE_REQ /*| LEGATTDB_PERM_AUTH_WRITABLE*/),
// Declare client characteristic configuration descriptor
// Value of the descriptor can be modified by the client
// Value modified shall be retained during connection and across connection
// for bonded devices. Setting value to 1 tells this application to send notification
// when value of the characteristic changes. Value 2 is to allow indications.
CHAR_DESCRIPTOR_UUID16_WRITABLE(HANDLE_OTA_FW_UPGRADE_CLIENT_CONFIGURATION_DESCRIPTOR, UUID_DESCRIPTOR_CLIENT_CHARACTERISTIC_CONFIGURATION,
LEGATTDB_PERM_READABLE | LEGATTDB_PERM_WRITE_REQ /*| LEGATTDB_PERM_AUTH_WRITABLE */),
// Handle 0xff07: characteristic WS Data, handle 0xff08 characteristic value. This
// characteristic is used to send next portion of the FW Similar to the control point
CHARACTERISTIC_UUID128_WRITABLE(HANDLE_OTA_FW_UPGRADE_CHARACTERISTIC_DATA, HANDLE_OTA_FW_UPGRADE_DATA,
UUID_OTA_FW_UPGRADE_CHARACTERISTIC_DATA, LEGATTDB_CHAR_PROP_WRITE,
LEGATTDB_PERM_VARIABLE_LENGTH | LEGATTDB_PERM_WRITE_REQ | LEGATTDB_PERM_RELIABLE_WRITE),
同時在一開始init BLE時要啟用相關的設定
wiced_ota_fw_upgrade_connection_status_event(p_conn_status);
UNUSED_VARIABLE(status);
由於OTA的servies 定義是在比較後面的,跟專案本來自定義的ID差很多,所以直接判斷如果request的ID是在後面的,直接丟給OTA module 去處理。
if (p_data->handle > HANDLE_OTA_FW_UPGRADE_SERVICE)
{
return wiced_ota_fw_upgrade_write_handler(conn_id, p_data);
}
這樣Bluetooth 會直接判斷如果是OTA的話是否成功。
做到這邊Firmware的OTA功能就算是告個段落了。在Bluetooth peripheral side只要使用SDK的OTA module 即可更新Firmware.
4. Bluetooth Mac Address不一致
由於每次build出來都是直接燒錄進去,偶然發現如果燒錄到不同的晶片會發生位置是一樣的,這樣在其他藍芽裝置在discover的時候會無法分辨兩個裝置。進一步才發現是bluetooth的Address都是一樣的。
要解決這個問題就要將每次build出來的位置為不一樣,翻了一下SDK手冊有一個很便利的地方,之需要將MakeFile內部新增config即可。
BT_DEVICE_ADDRESS?=random
未完待續…
搶先發佈留言