資料介紹
描述
項目描述
項目由兩臺設備組成,其中一臺是控制設備(本例中是手機),另一臺是遠程可穿戴設備。遠程設備有 LED 指示它何時超出范圍。控制設備打開連接,并定期發送測量RSSI的數據包。
入門
項目所需的硬件是 Nordic Semiconductors 藍牙開發套件之一。以下所有步驟均在 nRF5340-DK 上完成。
在開始之前,最好遵循設置軟件環境的指南。
代碼是在 nRF Connect SDK v1.5.0 上開發的,帶有修補的 zephyr。該補丁是添加對 LCD 顯示的支持所必需的,可在NordicPlayground github repo中找到。可能較新版本的 SDK 已經支持板dts 文件中的 Arduino 標頭定義。
首先,我們將通過簡單的步驟讓代碼運行,然后我們將深入了解 SDK 細節。
編程 nRF5340-DK
- 從 Nordic示例應用補丁- 克隆項目,然后按照說明應用補丁
- 從 Github 克隆虛擬皮帶項目
- 將項目導入 SEGGER Embedded Studio
- 連接 nRF5340-DK
- 將紅色 LED 連接到引腳 P0.30,將綠色 LED 連接到引腳 P0.31
- 連接 Adafruit 2.8" LCD 顯示屏
- 從“構建”菜單中選擇“構建并運行”。
顯示屏應顯示 RSSI 標簽和 RSSI 圖形背景。
出于測試目的,LED 可以通過相當大的 (>= 10k ohm) 限流電阻器直接連接到端口輸出。
從安卓手機控制
- 打開MIT App Inventor頁面
- 下載并安裝最新的BluetoothLE 擴展。
- 從項目存儲庫導入 virtual-leash/app-inventor/control-application.aia
- 編譯 apk,或從 Play 商店安裝“MIT AI2 Companion”
- 在手機上下載并運行應用程序
- 按“掃描設備”
- 選擇“Otown”設備——這就是 DK 通過藍牙做廣告的方式
- 按“附加”
- 綠色 LED 應開始每秒閃爍一次
實施細節
在接下來的章節中,我們嘗試添加盡可能多的信息,以幫助其他人了解一切在幕后是如何運作的。了解北歐設備的開發、使用 Zephyr OS 和使用藍牙本身是一段相當長的旅程。
為了更容易理解,我們首先展示了工作代碼的描述,然后有一些或多或少成功的步驟引導我們找到了這個特定的解決方案。整體學習部分需要幾個星期的下班后實驗才能開始。
配置項目、了解設備樹文件、覆蓋文件、了解藍牙參數等方面的學習曲線非常陡峭。我們不打算在此處提供有關這些主題的完整教程。
SDK 附帶的 Nordic 示例大多是開箱即用的。這是一個令人鼓舞的開始,但后來被 Arduino 寵壞了,我們認為復制粘貼代碼足以將部分示例添加到我們的代碼中。這是第一個讓我們損失 2-3 周的錯誤。僅復制源代碼是不夠的,還有項目配置文件,并且通常需要在示例代碼之上進行大量自定義。
最終代碼是使用常規連接開發的,DK 作為“外圍”設備,電話作為“中央”設備。回想起來,我們可能會使用 BluetoothLE 的 Broadcaster-Observer 角色,因為快速原型平臺(應用程序發明者、flutter)對無連接數據傳輸的支持很差或不支持。
nRF5340-DK 上的藍牙配置詳細信息
第一個也是最困難的部分是找到正確的配置設置。設置我們最終啟用藍牙外圍設備:
# Incresed stack due to settings API usage
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048
CONFIG_BT=y
CONFIG_BT_DEBUG_LOG=y
CONFIG_BT_SMP=y
CONFIG_BT_SIGNING=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_DIS=y
CONFIG_BT_ATT_PREPARE_COUNT=5
CONFIG_BT_PRIVACY=y
CONFIG_BT_DEVICE_NAME="Otown"
CONFIG_BT_DEVICE_APPEARANCE=833
配置保存在prj.conf
. 這是迄今為止最神秘的部分,并且在剛開始使用 Zephyr 時文檔記錄很少。對我們有用的是從示例、文檔和 Zephyr 源代碼中復制的配置組合。
之后啟用和啟動藍牙非常簡單,并且在所有示例中看起來基本相同。所有的魔法都發生在從配置設置自動生成的代碼中。
int err = bt_enable(NULL);
if (err) {
LOG_ERR("Bluetooth init failed (err %d)\n", err);
return;
}
任何面向連接的藍牙鏈接的第一部分都是設置廣告細節。為此,Zephyr 中有一些非常復雜的宏。這是一個對我們有用的結構:
//Unique Universal ID of service
#define OTOWN_UUID BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0x39342d62, 0x3932, 0x662d, 0x6538, 0x313134343332))
// Advertising details for just one service, and generally discoverable peripheral
static const struct bt_data advertising_data[] = {
BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
BT_DATA_BYTES(BT_DATA_UUID128_ALL, BT_UUID_128_ENCODE(0x39342d62, 0x3932, 0x662d, 0x6538, 0x313134343332)),
};
// Bluetooth connect and disconnect callbacks
static struct bt_conn_cb conn_callbacks = {
.connected = connected,
.disconnected = disconnected,
};
...
// register connect and disonnect callbacks
bt_conn_cb_register(&conn_callbacks);
// Pass structure to bt_le_adv_start method
err = bt_le_adv_start(BT_LE_ADV_CONN_NAME, advertising_data, ARRAY_SIZE(advertising_data), NULL, 0);
我們使用從許多在線生成器之一生成的 UUID。對于自定義通信通道,它們基本上可以是連接雙方都知道的隨機值。
在最基本的層面上,藍牙由服務組成,這些服務進一步分解為可以讀取或寫入的特性。
每個對象都有很多配置參數。在我們的項目中,我們使用了具有 2 個特征的單個服務。一種具有讀/寫方法,另一種是只寫。為簡單起見,訪問特征沒有加密或任何特殊配對要求。
#define REMOTE_RSSI_CHARACTERISTIC_UUID BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0x63342d31, 0x3836, 0x372d, 0x3166, 0x306331633562))
#define DETACH_CHARACTERISTIC_UUID BT_UUID_DECLARE_128(BT_UUID_128_ENCODE(0x1e086d95, 0x7faa, 0x4993, 0x984e, 0xcf234cec373b))
/* Primary Service Declaration */
BT_GATT_SERVICE_DEFINE(otown_svc, //create a struct with _name
BT_GATT_PRIMARY_SERVICE(OTOWN_UUID), //Main UUID
BT_GATT_CHARACTERISTIC(REMOTE_RSSI_CHARACTERISTIC_UUID,
BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE, // Properties
BT_GATT_PERM_READ | BT_GATT_PERM_WRITE, // permissions read/write no security
read_otown, write_otown, otown_value), // Callback functions and value
BT_GATT_CHARACTERISTIC(DETACH_CHARACTERISTIC_UUID,
BT_GATT_CHRC_WRITE, // Properties
BT_GATT_PERM_WRITE, // permissions write no security
NULL, write_detach, detach_request), //Callback functions and value
BT_GATT_CCC(vnd_ccc_cfg_changed, //Client Configuration Configuration
BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT),
);
處理這些特征的整個代碼是自動生成的。
寫入和讀取特性通過回調函數發生。在這些回調中不要使用太多時間是非常重要的。在回調中更新 LCD 顯示會在幾秒鐘后導致連接不穩定。日志輸出似乎是可以容忍的。
寫入時,數據片段必須存儲在緩沖區中:
//Callback function of write command
static ssize_t write_otown(struct bt_conn *conn, const struct bt_gatt_attr *attr,
const void *buf, uint16_t len, uint16_t offset,
uint8_t flags) {
uint8_t *value = attr->user_data;
if (offset + len > sizeof(otown_value)) {
return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
}
memcpy(value + offset, buf, len);
然后可以解析接收到的字符串并將其傳遞給主應用程序。在這種情況下,使用了 Zephyr 消息隊列。
int value_int = atoi(value);
k_msgq_put(&rssi_queue, &value_int, K_NO_WAIT);
return len;
}
消息隊列是固定大小的循環緩沖區,提供應用程序線程之間的通信方式。這是一個簡單的例子:
// Queue for passing received RSSI values to main thread (4 elements)
K_MSGQ_DEFINE(rssi_queue, sizeof(int), 4, 4);
...
// write callback on Bluetooth thread
k_msgq_put(&rssi_queue, &value_int, K_NO_WAIT);
...
// main thread - get value from queue, and display on LCD
int rssi;
if(k_msgq_get(&rssi_queue, &rssi, K_NO_WAIT) == 0) {
LOG_INF("RSSI = %d", rssi);
gui_add_point_to_chart(rssi);
}
只是改變狀態的更簡單的方法不需要使用隊列。這是分離特征的寫回調代碼
#define DETACH_COMMAND "detach"
static ssize_t write_detach(...) {
...
// compare received string against predefined command
if(strncmp(value, DETACH_COMMAND, strlen(DETACH_COMMAND)) == 0) {
...
detached_safely = true;
}
return len;
}
最后斷開回調負責檢查電話是否“安全”斷開連接
static void disconnected(...) {
...
// turn on red leds if remote device did not detach safely before disconnecting
if(!detached_safely) {
gpio_set_red(true);
}
}
使用 GPIO
必須在項目配置文件中啟用第一個 GPIO 庫
CONFIG_GPIO=y
使用 GPIO 通常需要在電路板覆蓋文件中定義端口,但是有一個可用于原型設計的快捷方式
#define RED_LED_PIN 30
// "guess" that port 0 is named GPIO_0 on nRF boards
gpio = device_get_binding("GPIO_0");
if (gpio == NULL) {
printk("error getting GPIO_0 device\n");
return;
}
// configure pin 30 as an output
ret = gpio_pin_configure(gpio, RED_LED_PIN, GPIO_OUTPUT);
...
// set output
gpio_pin_set(gpio, RED_LED_PIN, true);
使用液晶顯示器
lvgl 庫支持 Adafruit 2.8" LCD 顯示器(在適當的板配置后)。盡管在我們的項目中不是絕對必要的,但它很有趣,并提供了很好的調試機會。
在編寫這個項目時,有用于屏幕布局的 GUI 設計器的概念證明,但是代碼生成器還沒有準備好,可用的 GUI 組件很少。我們使用的代碼大部分是從 NordicPlayground 上的 Nordic 示例中復制而來的。
圖形組件的文檔不是很好,經常需要查看源代碼。除此之外,有時設置組件屬性的順序很重要。在正面的觸摸屏上,顯示與 Nordic 和 Zephyr 示例代碼沒有問題。
我們必須在項目文件中設置一些配置選項以啟用 LVGL 支持
# LVGL DISPLAY
CONFIG_HEAP_MEM_POOL_SIZE=16384
CONFIG_MAIN_STACK_SIZE=4096
CONFIG_DISPLAY=y
CONFIG_DISPLAY_LOG_LEVEL_ERR=y
CONFIG_LVGL=y
CONFIG_LVGL_ANTIALIAS=y
CONFIG_LVGL_USE_LABEL=y
CONFIG_LVGL_USE_CONT=y
CONFIG_LVGL_USE_BTN=y
CONFIG_LVGL_USE_CHECKBOX=y
CONFIG_LVGL_USE_IMG=y
CONFIG_LVGL_USE_THEME_MATERIAL=y
CONFIG_LVGL_USE_ANIMATION=y
CONFIG_LVGL_USE_SHADOW=y
CONFIG_LVGL_USE_CHART=y
CONFIG_LVGL_CHART_AXIS_TICK_LABEL_MAX_LEN=256
CONFIG_NEWLIB_LIBC=y
具體顯示必須在CMakeLists.txt中選擇
set(SHIELD adafruit_2_8_tft_touch_v2)
所有組件配置代碼,包括 GUI 組件的一些實驗都可以在gui.c
手機藍牙應用(MIT App Inventor)
手機應用程序非常簡單,功能僅限于掃描附近的藍牙設備,然后在附加到設備后發送帶有數據的字符串。
定期測量連接設備的 RSSI 并將其寫入“RSSI”特性。這解決了 nRF SDK 上的問題,即一旦連接到中央設備,就無法在外圍設備上讀取 RSSI。
按下分離按鈕將向“分離”特性發送“分離”命令。
一點歷史:項目的考慮因素
對于手機應用程序,我們最初計劃使用 Flutter,因為它具有原生的跨平臺支持,但是,缺乏適當的 ble 庫導致我們在更簡單的東西上進行原型設計。起初,我們想使用 App Inventor 快速制作原型用于測試目的,雖然它一開始看起來很幼稚且不通用,但諷刺的是,它支持的 BLE 功能比任何可用的 Flutter BLE 庫都多(例如從一個已經連接的設備),所以我們決定使用它。
另一個挫折是嘗試從連接的設備獲取 nRF SDK 中的 RSSI。RSSI 在掃描階段很容易獲得,但是在建立連接后無法獲取。在對網絡處理器代碼和 HCI 接口進行修改時,我們陷入了死胡同。我們嘗試使用 hci_pwr_ctrl 示例,其中藍牙控制器(在 DK 情況下為網絡核心)將 RSSI 值隧道傳輸到第二個核心上的應用程序線程。不幸的是,我們沒有讓這個示例工作,因為 nRF 的 Zephyr SDK 中顯然存在一個已知錯誤。對于初學者來說也太高級了。
最初,我們想使用 nRF5340-DK 作為中央設備,以及簡單的鑰匙查找器藍牙信標
我們找不到一個好的參數組合來保持與信標的連接。我們嘗試了多個安全/配對參數,但在短暫的協商階段后連接幾乎立即斷開。錯誤代碼不是很有幫助,因此路徑被刪除了。
BluetoothLE 無連接廣播者-觀察者角色非常有前途。我們基于 Zephyr 示例在 nRF5340-DK 和 nRF52840 加密狗之間進行了簡單的廣告設置,但是我們無法輕松傳輸任何有意義的數據。所有修改都導致代碼失敗。可能擁有 2 個完整的開發套件會更容易。手機應用程序原型設計框架中缺乏對這些角色的支持也導致了這條路的放棄。
一旦我們找到一些時間對其進行重新測試和清理,其中一些實驗的代碼將在 GitHub 存儲庫中提供。
提示與技巧
在學習 Zephyr 時,我們為 MAX6675 熱電偶 ADC 開發了一個簡單的 SPI 驅動程序。它作為 Zephyr 2.4.99 的補丁提供(隨 nRF SDK 1.5.0 提供)。
從 Play 商店獲取nRF Connect應用程序非常有幫助。它非常適合獲取有關外圍設備的詳細信息。非常穩定且功能豐富的藍牙連接調試。然而,我們無法確定是否可以將其用作 Brodcaster 或 Observer。
在帶有外部 TTL 到 USB 轉換器的 nRF52840 加密狗上獲得調試接口取得了一些成功。
默認情況下調試輸出被禁用。要將其重定向到串行端口(默認情況下,引腳 0.20 上的 TX,引腳 0.24 上的 RX)在項目配置中啟用 SERIAL 和 UART_CONSOLE。
配置用于調試的 USB 接口最初看起來很簡單,但最終它只適用于 Zephyr USB 日志記錄示例。當配置和代碼被復制粘貼到我們的應用程序時,它在第一個日志記錄宏上失敗了。
這是一些我不記得它來自哪里的隨機注釋,但是在從 Zephyr 為 nRF52840 加密狗構建藍牙示例時它非常重要:
啟用 FLASH 設置。要控制藍牙設備名稱,請啟用設置和 NVS。然后可以更改設備名稱。
在 AppInventor 方面:確保您沒有使用 2019 年以來過時的 BLE 插件,較新的 android 設備無法在其上運行,因為操作系統受到更多限制,但它已通過 2020 年 12 月插件修復。
有時應用程序會弄亂手機上的藍牙子系統,顯示一堆錯誤。關閉應用程序和禁用->啟用周期有助于讓事情重回正軌。
原型圖片
?
- CS5340 ADC立體聲模數轉換器
- 使用nRF5340 DK進行DSP處理的震顫健康分析
- nRF5340模塊開源分享
- 基于nRF5340開發套件的開源可穿戴式下臂支架
- nrf5340 LCD和flash 共用Qspi 息屏導致flash讀寫問題
- 教你快速維修皮帶滾筒軸磨損 0次下載
- 基于NRF24LU1P-F32Q32-DK射頻收發器的
- 基于NRF8001-DK無線系統的
- AD5340評估軟件
- 2.4GHz收發器芯片NRF24L01+數據手冊 0次下載
- 圖片:AS73210-AS89010-AB4 SET DK_IM000289_1-00.jpg
- AD5340 Evaluation Software
- 基于nRF51-DK無線連結的參考設計
- 基于nRF52-DK無線連結的參考設計
- nRF51 DK板載的開發指導手冊免費下載 0次下載
- 變頻器在洗煤廠皮帶機上的應用 858次閱讀
- Azure Percept DK的硬件介紹與設置使用 1149次閱讀
- Azure Kinect Senser DK套件簡介 3845次閱讀
- 皮帶輸送機運輸系統的工作原理及其故障維修 1.7w次閱讀
- DK912芯片功能及基本參數_DK912芯片應用電路 9.4w次閱讀
- nRF5系列首個高端多協議SOC nRF5340TM,滿足尖端可穿戴設備的需求 8320次閱讀
- 微雪電子藍牙5.0 藍牙Mesh NRF52840簡介 5126次閱讀
- 微雪電子NRF24L01 RF Board 2.4G無線模塊簡介 3075次閱讀
- 皮帶秤測速傳感器的常見故障 7127次閱讀
- 講述Nordic nRF5 SDK的主要調試手段,以幫助大家快速定位問題 1.2w次閱讀
- 淺談皮帶機減速機漏油的7種情況 2208次閱讀
- nrf24l01無線模塊傳輸距離分析 3.5w次閱讀
- nrf24l01收發程序詳解 3w次閱讀
- nRF905工作原理_nRF905基本特點 1.1w次閱讀
- nrf905引腳圖及引腳說明_nrf905主要參數 1.1w次閱讀
下載排行
本周
- 1山景DSP芯片AP8248A2數據手冊
- 1.06 MB | 532次下載 | 免費
- 2RK3399完整板原理圖(支持平板,盒子VR)
- 3.28 MB | 339次下載 | 免費
- 3TC358743XBG評估板參考手冊
- 1.36 MB | 330次下載 | 免費
- 4DFM軟件使用教程
- 0.84 MB | 295次下載 | 免費
- 5元宇宙深度解析—未來的未來-風口還是泡沫
- 6.40 MB | 227次下載 | 免費
- 6迪文DGUS開發指南
- 31.67 MB | 194次下載 | 免費
- 7元宇宙底層硬件系列報告
- 13.42 MB | 182次下載 | 免費
- 8FP5207XR-G1中文應用手冊
- 1.09 MB | 178次下載 | 免費
本月
- 1OrCAD10.5下載OrCAD10.5中文版軟件
- 0.00 MB | 234315次下載 | 免費
- 2555集成電路應用800例(新編版)
- 0.00 MB | 33566次下載 | 免費
- 3接口電路圖大全
- 未知 | 30323次下載 | 免費
- 4開關電源設計實例指南
- 未知 | 21549次下載 | 免費
- 5電氣工程師手冊免費下載(新編第二版pdf電子書)
- 0.00 MB | 15349次下載 | 免費
- 6數字電路基礎pdf(下載)
- 未知 | 13750次下載 | 免費
- 7電子制作實例集錦 下載
- 未知 | 8113次下載 | 免費
- 8《LED驅動電路設計》 溫德爾著
- 0.00 MB | 6656次下載 | 免費
總榜
- 1matlab軟件下載入口
- 未知 | 935054次下載 | 免費
- 2protel99se軟件下載(可英文版轉中文版)
- 78.1 MB | 537798次下載 | 免費
- 3MATLAB 7.1 下載 (含軟件介紹)
- 未知 | 420027次下載 | 免費
- 4OrCAD10.5下載OrCAD10.5中文版軟件
- 0.00 MB | 234315次下載 | 免費
- 5Altium DXP2002下載入口
- 未知 | 233046次下載 | 免費
- 6電路仿真軟件multisim 10.0免費下載
- 340992 | 191187次下載 | 免費
- 7十天學會AVR單片機與C語言視頻教程 下載
- 158M | 183279次下載 | 免費
- 8proe5.0野火版下載(中文版免費下載)
- 未知 | 138040次下載 | 免費
評論
查看更多