基於nRF52832 SoC的RedBear BLE NANO Kit v2物聯網開發板初體驗

IoT大殺器nRF52832

nRF52832

nRF52832 SoC芯片主要參數:
* ARM Cortex-M4,32-bit
* 最大主頻64 MHz
* 內部閃存512kB
* SRAM達到64kB
* 支持Bluetooth 5和NFC
* 支持多種開發環境

相比之下Arduino Uno的ATmega328芯片的主頻才16MHz,Flash 32kB,SRAM 2kB,不帶任何無線功能。對比強烈。

Nordic的官方組件評測可以看:
一款基於Cortex-M4的BLE SoC——Nordic nRF52開發套件評測搜狐科技搜狐網
Arduino也推出了Primo這個板子:
Arduino使用Nordic nRF52832 SoC的Arduino Primo基板-通信/網絡-與非網

RedBear BLE Nano Kit v2

入手的是RedBear推出的超小型開發板。小巧全能就是王道!
這個板子雖然是某香港/深圳公司做的,中文世界的介紹幾乎沒有,RedBear的人看到此文不介意給本人支付廣告費(@HᴗP@)。
BLE Nano v2

nRF52832的特性之外,還有:
* Arduino IDE,Mbed,JavaScript,Nordic nRF52 SDK,Python,Apache Mynewt,FreeRTOS等開發環境
* 板載LED D13
* UART,SPI,I2C
* 最大11個端口,也足夠用了
* VDD除了3.3V,還支持1.8V的輸出
* 可以在1.8V-3.6V工作
* 大小隻有大概2釐米見方
* 支持Over-The-Air,也就是不連電腦直接通過BLE寫程序

Pinout

還有官方Kit,多了USB讀寫器DAPLink
DAPLink

開發板介紹:
Kickstarter page
nRF5x/nRF52832 at master · redbear/nRF5x · GitHub
RedBear (注意:官網是找不到Nano2介紹頁面的=͟͟͞͞(HㅍP),只有
基於nRF51832的一代Nano的介紹,兩代非常不同 )

官方還有擴展板

RedBear BLE Nano Kit v2開箱

開箱

可以看到其實BLE Nano的板子只比USB插口大了一點點,大概就是正常人的拇指那麼大吧。下面作對比的是ESP32。

插電前必須注意插入讀寫器的方向,白色的小熊logo是朝外的。

插電後就可以進行BLE測試,本來已經預先安裝了心率服務:nRF5x/Getting_Started_Guide.md at master · redbear/nRF5x · GitHub

windows系統可能需要先安裝mbed的驅動:https://developer.mbed.org/handbook/Windows-serial-configuration

Arduino IDE追加庫

按照官方介紹操作:nRF5x/Arduino_Board_Package_Installation_Guide.md at master · redbear/nRF5x · GitHub

安裝完了之後就可以看到IDE裏面出現了BLE_Nano2的板子,注意不要搞混一代Nano和二代了,兩者不通用。

這時候可以進行Arduino標準的LED測試,記得端口換成D13就行。

BLE Simple Chat測試

先安裝官方的APP:BLEController
Arduino IDE裏面打開File>Examples>BLE_Examples>SimpleChat並上傳

官方APP裏面找到設備並連接,
在手機裏面輸入文字,Serial Monitor裏面就有反應。

simple chat

反過來Serial Monitor裏面輸入文字,手機就有輸出。
實現簡單的文字傳輸功能。

Serial Monitor

並非Arduino風格的BLE語法

好了,用是可以使用,看一下具體代碼的話就會發現,BLE部分的語法並不是一般arduino裏面常用的那種,而是類似mbed的語法,這個說明又是一個大坑了。
另外可以用Nordic SDK,自由度更高,開發HID等高級功能逃不過,當然這個坑更大更深。

/*
 * Copyright (c) 2016 RedBear
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */
#include <nRF5x_BLE_API.h>

#define DEVICE_NAME            "BLE_Peripheral"   // 被搜索的時候看到的名字
#define TXRX_BUF_LEN           20      // 這個是BLE每次傳輸緩衝的最大字節數,最大20

BLE                            ble;
Timeout                        timeout;

static uint8_t rx_buf[TXRX_BUF_LEN];  // 這個是BLE每次傳輸緩衝的最大字節數,最大20
static uint8_t rx_buf_num;
static uint8_t rx_state=0;

// 需要自己定義16進制的uuid
// The uuid of service and characteristics
static const uint8_t service1_uuid[]        = {0x71, 0x3D, 0, 0, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
static const uint8_t service1_tx_uuid[]     = {0x71, 0x3D, 0, 3, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
static const uint8_t service1_rx_uuid[]     = {0x71, 0x3D, 0, 2, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
static const uint8_t uart_base_uuid_rev[]   = {0x1E, 0x94, 0x8D, 0xF1, 0x48, 0x31, 0x94, 0xBA, 0x75, 0x4C, 0x3E, 0x50, 0, 0, 0x3D, 0x71};

uint8_t tx_value[TXRX_BUF_LEN] = {0,};
uint8_t rx_value[TXRX_BUF_LEN] = {0,};

// Initialize value of chars
GattCharacteristic  characteristic1(service1_tx_uuid, tx_value, 1, TXRX_BUF_LEN, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE );      // 定義特徵的讀寫權限等
GattCharacteristic  characteristic2(service1_rx_uuid, rx_value, 1, TXRX_BUF_LEN, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
GattCharacteristic *uartChars[] = {&characteristic1, &characteristic2};
GattService         uartService(service1_uuid, uartChars, sizeof(uartChars) / sizeof(GattCharacteristic *));

// BLE斷開後的操作
void disconnectionCallBack(const Gap::DisconnectionCallbackParams_t *params) {
  Serial.println("Disconnected!");
  Serial.println("Restarting the advertising process");
  ble.startAdvertising();  // 開始advertising
}

// central設備有write請求時候的操作
void gattServerWriteCallBack(const GattWriteCallbackParams *Handler) {
  uint8_t buf[TXRX_BUF_LEN];
  uint8_t index;
  uint16_t bytesRead = TXRX_BUF_LEN;

  Serial.println("onDataWritten : ");
  if (Handler->handle == characteristic1.getValueAttribute().getHandle()) {
    // 讀出特徵的數據
ble.readCharacteristicValue(characteristic1.getValueAttribute().getHandle(), buf, &bytesRead);
    Serial.print("bytesRead: ");
    Serial.println(bytesRead, HEX);
    for(index=0; index<bytesRead; index++) {
      Serial.write(buf[index]);
    }
    Serial.println("");
  }
}

void m_uart_rx_handle() {   //update characteristic data
  ble.updateCharacteristicValue(characteristic2.getValueAttribute().getHandle(), rx_buf, rx_buf_num);
  memset(rx_buf, 0x00,20);
  rx_state = 0;
}

void uart_handle(uint32_t id, SerialIrq event) {   /* Serial rx IRQ */
  if(event == RxIrq) {
    if(rx_state == 0) {
      rx_state = 1;
      timeout.attach_us(m_uart_rx_handle, 100000);
      rx_buf_num=0;
    }
    while(Serial.available()) {
      if(rx_buf_num < 20) {
        rx_buf[rx_buf_num] = Serial.read();
        rx_buf_num++;
      }
      else {
        Serial.read();
      }
    }
  }
}

void setup() {
  // put your setup code here, to run once
  Serial.begin(9600);
  Serial.attach(uart_handle);

  ble.init();
  ble.onDisconnection(disconnectionCallBack);
  ble.onDataWritten(gattServerWriteCallBack);

  // setup adv_data and srp_data
  ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
  ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
                                   (const uint8_t *)"TXRX", sizeof("TXRX") - 1);
  ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
                                   (const uint8_t *)uart_base_uuid_rev, sizeof(uart_base_uuid_rev));
  // set adv_type
  ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
  // add service
  ble.addService(uartService);
  // set device name
  ble.setDeviceName((const uint8_t *)"Simple Chat");
  // set tx power,valid values are -40, -20, -16, -12, -8, -4, 0, 4
  ble.setTxPower(4);
  // set adv_interval, 100ms in multiples of 0.625ms.
  ble.setAdvertisingInterval(160);
  // set adv_timeout, in seconds
  ble.setAdvertisingTimeout(0);
  // start advertising
  ble.startAdvertising();
  Serial.println("Advertising Start!");
}

void loop() {
    ble.waitForEvent();
}

諸多參考

BLE Nanoを試してみました - surga Lab
RedBearLab BLE Nano の設定方法とOTA | Home Made Garbage
BLE Car01
blenanov2をarduinoideを使ってプログラミングする方法
【Arduino】BLE NanoでスマートフォンとBLE通信する - おもちゃラボ
ArduinoRedBearLab BLE Nanoを使ってみる : 工作と競馬
BLE NanoではじめてのBLE通信!クラゲのIoTテクノロジー
BLE Nano2ではじめてのBLE通信!クラゲのIoTテクノロジー
BLEnanoで必要なときだけLCDに情報を表示する方法 : 試行錯誤な日々

有事別忘了騷擾官方論壇:BLE Nano 2 (nRF52832) - Discussion Forums

վ HᴗP ի

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章