)
第一次拿到Arduino Primo的時候我其實是有點懵的。這塊板子長得不像我當時熟悉的任何一款Arduino沒有DIP封裝的ATmega芯片沒有Uno那種標準的Shield排針布局中間那顆主控IC赫然印著Nordic Semiconductor的標志——nRF52832。如果你只看名字以為Primo只是“又一個Arduino開發(fā)板”那你大概率會低估它但如果你看懂了“Features Nordic Semiconductor SoC”這行字背后的分量你會發(fā)現(xiàn)這其實是Arduino家族里一塊非常特殊、也非常值得玩的開山板。這篇文章不打算照抄數(shù)據(jù)手冊我盡量以一個實際開發(fā)者的視角把這幾個問題講透為什么Arduino會在Primo上用Nordic的SoC而不是繼續(xù)用AVR或轉投ESPnRF52832這顆SoC到底給Arduino生態(tài)帶來了哪些不一樣的能力作為普通玩家或工程師怎么把它跑起來、用它做點真正適合的項目以及當你不再滿足于Arduino語法、想往底層走的時候Primo又能把你帶到哪里。很多人知道Arduino.Uno、Nano、ESP32但一提到Primo就會覺得陌生這很正常。這塊板子當年沒有大火官方也早已停產(chǎn)但它在Arduino探索低功耗藍牙和SoC方向上的意義比它本身的銷量重要得多。1. Primo的定位Arduino家族里的多協(xié)議無線試驗田1.1 從Uno到PrimoArduino對無線平臺的一次押注早期的Arduino生態(tài)里無線方案一直是“外掛式”的。Uno要聯(lián)網(wǎng)插一塊ESP8266或者ENC28J60擴展板要藍牙再插一塊HC-05藍牙模塊。這種方法對學習來說很友好因為每一層都是獨立的出了問題也好排查。但對產(chǎn)品原型來說就很痛苦——飛線、供電、電平匹配、協(xié)議轉換任何一個環(huán)節(jié)都可能成為不穩(wěn)定因素的來源。Arduino后來其實嘗試過幾條不同的無線路線有基于WiFi的Uno WiFi、MKR系列也有和Nordic合作的Primo。Primo比較特別的地方在于它沒有沿用“MCU無線模塊”的組合而是直接用一顆nRF52832 SoC做主控。也就是說BLE、NFC這些無線能力不是外設而是這顆芯片原生的一部分。這塊板子在當時算是一次相當激進的押注因為這意味著開發(fā)者不能再像以前那樣“MCU歸MCU、藍牙歸藍牙”地分開處理而是必須在同一顆芯片上同時管理應用邏輯和射頻協(xié)議棧。我認識的一些老玩家當年并不太適應這個變化覺得“Arduino不是這樣子用的”。但從今天看Primo代表的這個方向恰恰是后面幾年物聯(lián)網(wǎng)開發(fā)板的主流一顆SoC集成算力、無線和豐富外設然后用簡潔的上層框架把它包裝起來。ESP32的爆火也驗證了同一條路線。只是Primo來得太早生態(tài)還沒鋪開才顯得有點生不逢時。1.2 為什么是Nordic而不是TI、Dialog或ESP這個問題我覺得挺值得展開。Arduino選Nordic不是隨便抽簽決定的。在低功耗藍牙這個細分領域Nordic的nRF51系列早就被大量運動手環(huán)、心率帶、beacon和醫(yī)療配件采用它的SoftDevice協(xié)議棧在BLE開發(fā)圈子里口碑一直不差。相比TI的CC254x那套復雜的協(xié)議棧和Dialog更加封閉的開發(fā)方式Nordic在“給嵌入式開發(fā)者留出足夠自由度”和“把BLE協(xié)議棧做穩(wěn)定”之間取得了相當好的平衡。當時選nRF52832還有一層現(xiàn)實考量它已經(jīng)是Cortex-M4F內核64MHz主頻512KB Flash和64KB RAM性能比傳統(tǒng)8位AVR高了好幾個量級同時也比同期的CC2640在RAM和Flash上更慷慨一點。這意味著Arduino的運行時、BLE協(xié)議棧和用戶代碼可以同時裝進這顆芯片而不至于天天為內存發(fā)愁。所以Primo選擇nRF52832本質上是相中了“無線能力 通用計算能力 低功耗”這三者不可兼得時Nordic給出的一個足夠均衡的答案。當然你可能會問為什么不用ESP32這里有個時間線問題。Primo發(fā)布的時代ESP32才剛剛嶄露頭角而且ESP32的功耗模型和BLE實現(xiàn)偏重并不適合“紐扣電池跑幾個月”這類場景。Primo瞄準的是可穿戴、傳感器節(jié)點、Beacon這類低功耗BLE應用而不是需要Wi-Fi和高算力的AIoT場景。兩者的路線差異從第一天就是明確的。1.3 熱詞背后的共同關切SoC啟動、協(xié)議棧與射頻電源我注意到一些開發(fā)者搜索這類板子時常會帶著“SoC芯片啟動”“RF SoC ADC電源紋波”“無人機遙控器MCU和SoC通道數(shù)”這類問題。這些熱詞看起來雜亂其實指向同一個困惑當開發(fā)對象從普通MCU變成一顆RF SoC后很多過去的經(jīng)驗都失效了。最典型的就是啟動流程。AVR單片機基本就是上電、從0x0000開始執(zhí)行邏輯簡單到可以用幾句話說清。而nRF52832這類SoC要處理的是電源域的上電時序、外部或內部晶振起振、SoftDevice協(xié)議棧的初始化、應用代碼從指定Flash地址進入。你在Arduino里寫的setup()只是這套流程跑完后交到你手里的那一刻。理解了這層再看“SoC啟動”這個詞就不會覺得玄乎了。射頻電源紋波也是RF SoC特有的坑。BLE在廣播和連接事件里會瞬間拉高電流如果電源路徑設計不好VDD上的紋波會直接影響ADC采樣精度甚至導致射頻指標劣化。很多初學者用Primo讀電池電壓發(fā)現(xiàn)數(shù)值跳得厲害問題往往不是代碼而是采樣時機和電源去耦沒處理好。這些內容我放到后面第5章細說。現(xiàn)在先把Primo這顆主控本身的能力弄清楚。2. nRF52832拆解一顆Cortex-M4F SoC能為Arduino帶來什么2.1 關鍵規(guī)格速覽不是“性能強”而是“性能剛好”很多人看芯片參數(shù)喜歡用“強不強”來評價。但nRF52832給我的感受是“剛剛好”。它沒有把性能堆到夸張的程度而是在一個合理的功耗預算下提供了足夠做產(chǎn)品原型的算力和外設。這里整理了一份從Arduino開發(fā)視角看的規(guī)格表項目nRF52832規(guī)格對Arduino開發(fā)者的實際意義內核ARM Cortex-M4F最高64MHz支持FPU和DSP指令跑浮點運算、傳感器融合比AVR舒服很多存儲512KB Flash64KB RAM可以塞進BLE協(xié)議棧加相對復雜的應用代碼無線BLE 5.02M PHY、ANT、私有2.4GHzPrimo的BLE能力來自這里支持2Mbps高速模式NFCNFC-A標簽手機靠近即可觸發(fā)配對或讀取信息ADC12位逐次逼近型ADC比Uno的10位精度高但要注意參考電壓和采樣時機通用外設SPI、TWI(I2C)、UART、PDM、I2S、PWM、QDEC能接音頻麥克風、驅動RGB燈、接編碼器等低功耗System OFF約0.3uASystem ONRT C約1.9uA典型值電池供電項目的功耗預算可以做到很低GPIO最多32個相對Mega少很多但做無線傳感器節(jié)點足夠了我說“性能剛好”是因為Primo不等于讓你拿它去跑復雜的圖像處理或本地AI推理。它真正的舒適區(qū)是“低功耗無線節(jié)點 中等復雜度本地邏輯”。你可以在它上面跑一個完整的BLE數(shù)據(jù)采集程序同時做傳感器讀取、數(shù)據(jù)處理和協(xié)議打包這在8位AVR上是相當吃力的而在nRF52832上則游刃有余。2.2 SoftDevice協(xié)議棧Arduino代碼塊如何與BLE共存如果你之前只寫過Arduino的串口收發(fā)和引腳控制第一次接觸“SoftDevice”這個詞可能會有點發(fā)怵。你可以把SoftDevice理解成Nordic提供的一個“預編譯藍牙協(xié)議棧”它燒錄在Flash的低地址段以S132這類版本號區(qū)分。你的應用代碼運行在它之上的地址空間通過API調用來收發(fā)BLE事件。在Arduino環(huán)境里這套機制被封裝得比較干凈。ArduinoBLE庫在BLE.begin()時會幫你去和底層協(xié)議棧握手之后的廣播、連接、特征讀寫看起來就和普通庫函數(shù)差不多。但實際工作中你需要意識到一個問題所以你的代碼并不是獨占整顆芯片的。SoftDevice占據(jù)的Flash和RAM不能被你亂寫同時一些外設和中斷協(xié)議棧也在使用。好在Arduino核心在編譯時已經(jīng)通過鏈接腳本處理了地址偏移普通用戶平時不太需要手動改但當你看到編譯日志里“Flash used”的數(shù)字比預期高很多時不用驚訝——一部分空間確實被無線協(xié)議棧“房租”占掉了。我見過一些開發(fā)者想繞過SoftDevice直接把nRF52832當純MCU用把全部Flash都留給自己。這在技術上可行但你丟掉了這顆芯片最值錢的BLE能力。Arduino Primo的價值恰恰在于它幫你把這些復雜封裝好了你可以先用簡單API體驗BLE再逐步理解底層。2.3 短板盤點Wi-Fi缺失、ADC精度、官方支持生命周期任何板子都不是萬能的Primo的短板也很明顯。最直接的就是沒有Wi-Fi。如果你的項目需要聯(lián)網(wǎng)上傳數(shù)據(jù)、走MQTT或者做Web配置界面Primo單靠BLE做不到必須再外掛Wi-Fi模塊或選其他板子。這也是它后來被很多玩家放棄的核心原因之一BLE雖然低功耗但在“什么都能干”的物聯(lián)網(wǎng)場景里開發(fā)者還是會優(yōu)先選帶Wi-Fi的ESP32。第二個短板和ADC精度有關。nRF52832的ADC是12位的紙面精度比Uno高但實際表現(xiàn)高度依賴電源質量和參考電壓。如果你用電池供電在BLE廣播瞬間去讀ADC數(shù)據(jù)會出現(xiàn)明顯波動。這不是芯片壞了而是電源紋波和采樣時序的典型問題。項目中給傳感器和ADC供電做好去耦或者避開射頻事件再去采樣是必須要考慮的事。第三個短板是官方支持的生命周期。Arduino Primo已經(jīng)停產(chǎn)Nordic的一線產(chǎn)品重心也轉到了nRF52840和nRF5340上。這意味著你在新版本IDE里偶爾會遇到板卡包兼容問題社區(qū)討論也相對少。如果你是需要長期穩(wěn)定供應鏈做產(chǎn)品的人我建議直接考慮官方仍在支持的nRF52840開發(fā)板但如果你是學習、折騰、研究SoC內部機制Primo的二手價格反而成了優(yōu)勢。3. 上手實操IDE配置、板卡安裝、點燈與BLE廣播3.1 板卡包安裝從在線安裝到離線遷移Primo雖然停產(chǎn)了但Arduino IDE的板卡管理里還是能裝到官方支持包的。常規(guī)做法是打開IDE的“開發(fā)板管理器”搜索“Primo”或“Nordic”相關關鍵詞找到Arduino官方維護的板卡包安裝。安裝完成后在開發(fā)板列表里選擇Arduino Primo就能開始編譯上傳了。這里有個實操細節(jié)。Arduino IDE 2.x默認會把板卡包、編譯器、工具鏈全部放在用戶目錄下的Arduino15文件夾時間一長能占到好幾個GB。C盤空間緊張的朋友建議提前在IDE設置里把數(shù)據(jù)目錄指到其他盤避免以后遷移麻煩。如果你需要在沒有網(wǎng)絡的機器上開發(fā)也可以把已下載好的Arduino15里對應的包目錄直接拷貝到新機器同一位置這其實就是很常用的“離線安裝包”思路。我自己的習慣是裝好一套順手環(huán)境后把這個目錄壓縮備份換電腦時直接解壓省去重新下載一堆工具的等待時間。安裝之后不妨先編譯一個空項目確認工具鏈和板卡包都正常工作。如果編譯時報找不到頭文件、找不到工具鏈多半是板卡包沒裝完整別急著懷疑代碼先把包卸載重裝一遍多數(shù)問題都能解決。3.2 引腳映射、點燈與芯片信息讀取Primo的引腳排布和Uno、Mega不一樣它也不再兼容傳統(tǒng)Shield。所以你拿到板子后第一件事應該是去看官方引腳圖弄清楚哪些引腳連接了板載的NFC天線、IMU、麥克風、RGB LED和按鍵。這些板載器件已經(jīng)占用了不少GPIO如果你把它們也當成普通引腳用很可能出現(xiàn)莫名其妙的外部干擾。點燈向來是嵌入式世界的Hello World。和Uno不同Primo等板載包的LED_BUILTIN定義未必和你的預期一致所以我在代碼里通常會自己定義一個測試引腳方便按原理圖調整// 如果板載包沒有定義LED_BUILTIN請根據(jù)Primo原理圖修改引腳號 #define TEST_LED 2 void setup() { Serial.begin(9600); pinMode(TEST_LED, OUTPUT); // 打印芯片唯一ID確認SoC正常工作 Serial.print(DEVICEID: ); Serial.println(NRF_FICR-DEVICEID[0], HEX); } void loop() { digitalWrite(TEST_LED, HIGH); delay(500); digitalWrite(TEST_LED, LOW); delay(500); }直接訪問NRF_FICR寄存器是nRF52系列特有的方式你可以用它讀出這顆芯片的出廠唯一ID。如果串口能打印出一串十六進制數(shù)說明SoC已經(jīng)正常啟動USB轉串口通信也沒有問題。對剛到手的板子來說這一步的花費時間很少但能幫你把“板子能不能跑”這個問題一次性排除掉。3.3 第一個BLE廣播程序用ArduinoBLE庫跑通點完燈Primo真正的高光時刻來了跑一個BLE廣播程序。Arduino官方提供了一套跨平臺的ArduinoBLE庫對Primo這類nRF52板卡支持得比較完整。下面是一個很簡潔的外設示例廣播出一個服務并允許手機連接后讀取一個持續(xù)變化的特征值#include ArduinoBLE.h BLEService testService(180C); BLEUnsignedCharCharacteristic tickChar(2A56, BLERead | BLENotify); void setup() { Serial.begin(9600); while (!Serial); if (!BLE.begin()) { Serial.println(BLE init failed); while (1); } BLE.setLocalName(PrimoBLE); BLE.setAdvertisedService(testService); testService.addCharacteristic(tickChar); BLE.addService(testService); BLE.advertise(); Serial.println(BLE advertising...); } void loop() { BLEDevice central BLE.central(); if (central) { Serial.print(connected: ); Serial.println(central.address()); while (central.connected()) { tickChar.writeValue((uint8_t)(millis() / 1000)); delay(100); } } }這段代碼跑通后你打開手機的BLE調試助手或者nRF Connect就能看到一個名叫“PrimoBLE”的設備連接后能讀到那個每秒變化的數(shù)字。從Arduino玩家的角度看這就是“一行代碼讓單片機變成藍牙外設”的體驗從SoC的角度看這個過程背后是SoftDevice對廣播、連接、通知等一堆協(xié)議事件的調度。我建議你把手機上的nRF Connect打開多觀察一下廣播包里有哪些字段看看連接后的MTU大小、連接間隔這些參數(shù)。因為今后你做實際項目時這些參數(shù)會直接影響功耗、吞吐量和兼容性。3.4 上傳失敗與串口異常的常見排錯Primo使用板載調試器實現(xiàn)燒錄所以你要把數(shù)據(jù)線插到板子的USB口而不是外接一個USB轉TTL模塊。很多新手在這里栽過跟頭以為和Uno一樣找個USB轉串口就能燒結果怎么都連不上。實際開發(fā)中我遇到的上傳失敗大概可以歸成三類串口被IDE的串口監(jiān)視器占著上傳時就會報端口被占用。解決方法是先關掉串口監(jiān)視器再燒。數(shù)據(jù)線質量太差只供電沒數(shù)據(jù)或者接觸不良。換根短一點、質量好的線很多詭異問題直接消失。板卡包和IDE版本不完全兼容。Arduino IDE 2.x對老開發(fā)板的支持偶爾有坑我遇到這種情況會先用1.8.x驗證一下確認是IDE還是板子的問題再決定要不要換回舊版IDE。另外如果你在Windows下發(fā)現(xiàn)設備管理器里沒有正常識別出板載調試器大概率是驅動沒有正確安裝。重新安裝板卡包時注意選完整安裝通常會把需要的驅動一起帶上。整個過程其實不算復雜只要能冷靜地把問題拆成“板子、線、IDE、驅動”四個環(huán)節(jié)逐個排除就行了。4. 項目選型舵機、小車、可穿戴哪些場景真正適合Primo4.1 舵機和電機控制PPI驅動的PWM體驗Arduino玩家最常見的“整活”項目就是控制舵機、驅動小車。那Primo適不適合干這些活呢答案是可以而且有些地方比Uno體驗更好。nRF52832的PWM外設不是靠CPU反復翻轉引腳來實現(xiàn)的而是通過可編程外設互聯(lián)PPI和定時器協(xié)同工作。意思是PWM波形一旦配置好后續(xù)輸出由硬件自己完成CPU可以騰出來處理藍牙協(xié)議棧或者其他邏輯。你寫一個舵機控制程序讓它一邊通過BLE接收指令一邊輸出PWM波形在Uno上可能會遇到定時器不夠用、中斷沖突這些問題在Primo上則流暢很多。我來舉個實際場景。你要做一個手機BLE遙控的小車Uno的方案是“Uno 藍牙串口模塊 電機驅動板”接線復雜不說藍牙串口透傳的可靠性和實時性也一般。換成Primo的話手機直接連Primo的BLE電機控制指令通過特征值下發(fā)PWM由硬件生成這套鏈路從底層就比“串口透傳”穩(wěn)定。唯一要適應的是Primo的GPIO數(shù)量有限做四驅小車或者帶機械臂的復雜小車時引腳要精打細算。如果你拿它去跑GRBL或者CNC控制這類項目我就不太推薦了。GRBL這類固件高度依賴AVR的定時器架構和訪問時序移植到nRF52832上需要改的東西太多不如直接用Uno或者ESP32方案來得省心。Arduino語法兼容不等于外設行為兼容這是我在Primo上吃過幾次虧之后最深的體會。4.2 電池供電傳感器與可穿戴應用Primo真正的主場其實是電池供電的低功耗無線傳感設備和可穿戴原型。板載的6軸IMU和數(shù)字麥克風讓它非常適合做手勢識別、動作監(jiān)測、語音喚醒這類原型NFC功能又能讓手機靠近板子時快速讀取設備信息或者觸發(fā)配對。舉個例子你可以用它做一個簡易的“老人跌倒報警”原型IMU檢測到劇烈加速度變化通過BLE向手機發(fā)送告警平時芯片進入低功耗模式只有事件發(fā)生時才會被喚醒。整個系統(tǒng)用一塊鋰電池就能跑很久這是Uno這種8位開發(fā)板很難做到的。很多人以為低功耗就是“芯片選對了就行”其實代碼方式影響也很大。在Arduino環(huán)境里如果你只是讓loop()空轉nRF52832的功耗并不會自動降到很低。要讓塊Primo在電池供電下發(fā)揮SoC的優(yōu)勢你得主動利用事件等待機制在沒事做的時候讓CPU停下來等待喚醒事件而不是空跑循環(huán)。這話題我在第5章細講。4.3 Primo、ESP32、STM32怎么選身邊朋友經(jīng)常問我類似的問題“我想做無線項目到底買Primo、ESP32還是STM32”我給出的判斷方式其實很直接先看你的無線需求再看功耗和開發(fā)效率。維度Arduino Primo (nRF52832)ESP32STM32 外接無線模塊無線能力原生BLE NFC低功耗優(yōu)化好Wi-Fi BLE能力全面取決于外接模塊通常需要自己處理協(xié)議功耗極低適合電池供電較高Wi-Fi常開會明顯耗電取決于模塊選擇和低功耗設計算力中等適合傳感器節(jié)點較強可做語音、圖像等較重負載根據(jù)具體型號差異很大生態(tài)Arduino核心較成熟但板子停產(chǎn)社區(qū)極其活躍教程多STM32Cube生態(tài)強大入門門檻稍高適合場景可穿戴、Beacon、BLE遙控器、傳感器節(jié)點需要聯(lián)網(wǎng)、需要本地處理能力的物聯(lián)網(wǎng)節(jié)點純MCU業(yè)務或需要嚴格RTOS控制的場景如果你的項目一定要聯(lián)網(wǎng)、要跑MQTT、要做Web配網(wǎng)ESP32是更省事的選擇如果你主要是處理本地控制邏輯不要求低功耗STM32的生態(tài)也很成熟但如果你做的是一塊“必須用紐扣電池跑幾個月”的BLE設備Primo這顆nRF52832的路線依然是值得認真考慮的。我也見過有人拿Primo去做帶屏的BLE遙控器比如控制無人機云臺或者航模通道。這里要注意帶寬和通道數(shù)的問題。BLE的連接間隔和單次傳輸數(shù)據(jù)量是有限的你不可能像PPM或者SBUS那樣在一個通道里高頻塞進大量通道數(shù)據(jù)。像無人機遙控器這種場景MCU負責采集所有搖桿通道SoC負責以合理的數(shù)據(jù)包結構通過BLE發(fā)送出去接收端再做映射。控制8個通道、用10ms/20ms的連接間隔在nRF52832上完全可行但數(shù)據(jù)包設計要足夠緊湊。5. 從Arduino走向底層低功耗、射頻布局與Nordic SDK5.1 低功耗從__WFE()到System OFF想要發(fā)揮Primo的低功耗優(yōu)勢Arduino默認的loop()輪詢模式是不夠的。最簡單有效的改動是在沒事做的時候讓CPU進入WFEWait For Event狀態(tài)void loop() { // 沒有事件需要處理時讓CPU停下來等待喚醒 delay(10); __WFE(); // 喚醒后的業(yè)務邏輯 }__WFE()是Cortex-M內核的一條指令意思是“停止執(zhí)行直到有事件發(fā)生”。在Arduino環(huán)境里定時器中斷、GPIO中斷、BLE協(xié)議棧事件都可以把它喚醒。這樣CPU不用在空循環(huán)里白白耗電雖然省下的功耗不如完整休眠模式多但已經(jīng)是一個很明顯的改善。再往下一步就是用NRF_POWER-SYSTEMOFF進入System OFF。這個模式下芯片幾乎完全斷電電流能降到微安級別只能用復位或者特定的DETECT引腳喚醒。要注意的是System OFF之后你的程序相當于關機重啟所以只能用在“按一下按鍵喚醒并上報一次數(shù)據(jù)”這種場景。這里稍微走神就可能把設備“鎖死”所以我建議新手先把__WFE()和delay()配合玩明白再考慮System OFF。在Arduino層面做低功耗優(yōu)化本質上是在和整個運行時環(huán)境博弈。你要理解庫里哪些操作會阻止CPU休眠比如delay()常用的忙等待實現(xiàn)就會讓CPU空轉換成定時器喚醒的方式會好很多。這塊內容沒有統(tǒng)一的銀彈只能在具體項目里逐個排查。5.2 RF SoC硬件設計里的三個坑天線凈空、晶振、ADC電源紋波如果你不只是用官方Primo板還想基于nRF52832自己畫板子那這三個坑幾乎是必踩的提前繞開能省很多時間。第一天線凈空。BLE天線周圍不能鋪地銅不能放金屬件天線下方PCB要開凈空區(qū)。天線匹配網(wǎng)絡要參考Nordic參考設計不要自己隨便估幾個電容電感就上。很多人以為“天線能收就行了”結果測出來的發(fā)射功率和靈敏度差一大截還查不出原因。第二晶振的選擇。nRF52832需要一顆32.768kHz的慢速晶振給射頻協(xié)議棧維持定時這和普通MCU“隨便焊個晶振能跑就行”完全不同。慢速晶振的負載電容和等效串聯(lián)電阻都要符合芯片手冊要求否則藍牙連接就會不穩(wěn)定甚至廣播都發(fā)不出去。我見過一塊板子打印日志一切正常但BLE連上就掉線最后查出來就是晶振不起振導致協(xié)議棧時鐘紊亂。第三ADC電源紋波。前面提到的RC SoC ADC受電源紋波影響大在做電池電壓采樣時尤其明顯。電池供電時BLE廣播瞬間電流可能沖到十幾毫安甚至更高電源路徑上的壓降和紋波都會被ADC讀出來。我的經(jīng)驗是電池電壓采樣不要放在廣播事件前后可以通過定時器錯開采樣時間同時電源輸入端加一個10uF陶瓷電容和一個小阻值RC濾波ADC結果會平穩(wěn)很多。這個經(jīng)驗適用于任何帶有射頻SoC的板子不只是Primo。5.3 把Primo當跳板轉向nRF5 SDK和ZephyrArduino Primo對很多人來說只是入門的一塊開發(fā)板但它的真正價值是可以作為你深入低功耗藍牙SoC開發(fā)的跳板。等你用ArduinoBLE庫跑通了廣播、連接、讀寫特征值之后你會發(fā)現(xiàn)一個很自然的問題這些API到底是怎么工作的BLE事件是怎么被分發(fā)的SoftDevice和應用代碼怎么共存這時候你就可以嘗試打開Nordic官方的nRF5 SDK在nRF52832上直接編寫基于SoftDevice的BLE程序。你會發(fā)現(xiàn)Arduino核心替你隱藏了很多東西從sd_ble_gap_advertising_start()到app_timer從ble_gatts服務定義到連接參數(shù)更新每一步都需要你顯式地理解協(xié)議棧的行為。這個過程確實比Arduino繁瑣但對一次真正搞懂BLE應用開發(fā)來說非常值得。另一個路線是Zephyr RTOS。Nordic現(xiàn)在對Zephyr的支持力度很大nRF52832在Zephyr里也有完整支持。Zephyr的藍牙協(xié)議棧用起來和Nordic SoftDevice的方式不太一樣抽象層次更高一些。如果你之前的嵌入式開發(fā)經(jīng)歷是“非RTOS即裸機”Zephyr會花一些時間適應但學會了之后你再做多任務藍牙應用時思路會清晰很多。我自己從Arduino轉到nRF5 SDK時最大的障礙不是API多而是心態(tài)上要從“調用庫函數(shù)”切換到“理解事件驅動的狀態(tài)機”。5.4 最后一個小技巧用NFC標簽快速進入BLE配網(wǎng)Primo板載的nRF52832支持NFC-A標簽功能這算是一個很有用但容易被忽略的點。很多BLE設備第一次配對時需要手動打開手機App去掃描過程比較繁瑣但有了NFC手機靠近板子的NFC天線區(qū)域就能直接觸發(fā)打開App或者讀取設備信息從而快速進入配對流程。在Arduino環(huán)境中NFC功能沒有像BLE那么完整的封裝通常需要配置NFC tag的NDEF數(shù)據(jù)。比較常見的一個用法是把NFC標簽里寫入一個URL比如https://example.com/start