Arduino環境でSeeed XIAO BLE nRF52840 / Sense を使う

コンピュータ、組み込み

Seeed Studio の Seeed XIAO BLE nRF52840とSeeed XIAO BLE nRF52840 Senseを入手しました。
こちらの基板を使ってBluetoothを使った通信をします。

紹介するもの

Seeed XIAO BLE nRF52840 と Seeed XIAO BLE nRF52840 Sense

XIAO規格の基板にnRF52480が搭載されBluetooth5.0が使用できる。
Bluetooth を使用したシリアル通信、BLEキーボードやマウスに使用できる。
Seeed XIAO BLE nRF52840 Senseには6軸IMU搭載。

接続Type C
CPUNordic nRF52840 64MHz
フラッシュMemory1MB + 2MB(オンボード)
ADC16(12bit)
ADC6
GPIO11
UART1
I2C1
SPI1
そのほか6軸IMU (Seeed XIAO BLE nRF52840 Senseのみ)
リセットボタン
3カラーLED

Seeed Studio XIAO製品ページ

ピン配置

外観

画像左側はSeeed XIAO BLE nRF52840
画像右側はSeeed XIAO BLE nRF52840 Sense (基板右上にセンサがあります)


400穴ブレッドボードでは、2列と3列使用することができます。

XIAO規格 ESP32 C3搭載基板

[2023/6/21]
XIAOシリーズにESP32-S3搭載基板が登場しました。
XIAO互換基板に、拡張基板を使ってTFカードリーダとOV2640カメラモジュールを接続できます。

amanegi.digick.jp/computer-embedded/mcuboa/xiaos3

準備

ライブラリ

ボードライブラリ

Arduino IDEのボードマネージャからSeeed XIAO BLE nRF52840用のライブラリのインストールとボードの選択をします。

ボードマネージャのURLhttps://sandeepmistry.github.io/arduino-nRF5/package_nRF5_boards_index.json
検索XIAO
ボードライブラリSeeed nRF52 Boards by Seeed Studio バージョン x.x.x
選択するボードSeeed nRF52 Boards > Seeed XIAO nRF52840 (XIAO nRF52840の場合)
Seeed nRF52 Boards > Seeed XIAO nRF52840 sense (XIAO nRF52840 senseの場合)
※ x.x.x Aug/2022 では1.0.0

スケッチの書き込み方

パソコンとSeeed XIAO BLE nRF52840をUSBケーブルで接続します。
Arduino IDEから接続したPort番号を選択し、プログラムを書き込むボタンを押下します。

スケッチを書きこんだ後、時々シリアル認識されないことがあります。
画像赤○の極小RSTボタンを素早く2回押下する(0.5秒に2回くらい)ことでシリアル認識されます。
[2022/11/24 記事修正]

BTペアリング

BT通信をする場合こちらの作業が必要になります。

ノートPC、スマートフォン、タブレットまた、BTレシーバを準備してください。
ペアリングの方法については一般のBT製品と同じですので詳細は省略します。
個々のマニュアルを参照してください。

今回当方の確認方法としてAndroidスマートフォンでのペアリングを掲載します。

1.スケッチを書き込み、マイコンボードを起動させます。

2.BT設定画面から周囲のBT機器を検索します。
  今回のサンプルでは [XIAO nRF52840]という名前で見つかります。

画像はNODE MCU ESP-32Sのものを流用しています。
作業の方法は同じです。

3.シリアル通信をする場合、シリアル通信用のアプリケーションをインストールします。
  参考として当方が利用している「Serial Bluetooth Terminal」を紹介します。

画像はNODE MCU ESP-32Sのものを流用しています。
作業の方法は同じです。

基本スケッチ

ボタンLED

説明

ボタンが押下されている間LEDを点灯させます。
ボタンが離されている間LEDは消灯させます。

スケッチ
/**********************************************************************
【ライセンスについて】
Copyright(c) 2022 by tamanegi
Released under the MIT license
'http://tamanegi.digick.jp/about-licence/

【マイコン基板】
XIAO nRF52840 (Sense)で利用できます。

【スケッチの説明】
プルダウンしたピンの状態がHighならLEDを点灯、LowならLEDを消灯させます。

【ライブラリ】
Seeed nRF52 Boards > Seeed XIAO nRF52840 (Sense)

【準備】
GPIO10  -> 保護抵抗(約200Ω) -> LED -> GND
3.3V -> GPIO9

保護抵抗は目安です。使用されるLEDの適値を求めてください。

【バージョン情報】
2022/11/23 : 新規
**********************************************************************/

#define LED 10       //LED
#define BUTTON 9     //タクトスイッチ

void setup()
{
  pinMode(LED, OUTPUT);               //ピン出力設定
  pinMode(BUTTON, INPUT_PULLDOWN);    //プルダウンで入力
}

void loop()
{
  int iStat = digitalRead(BUTTON);
  digitalWrite(LED, iStat);           //ボタンの状態をLEDに出力
}
結果

ボタンを押下するとLEDが点灯しました。
ボタンを離すとLEDが消灯しました。

PWM

説明

PWMでLEDをゆっくり点灯しゆっくり消灯します。

スケッチ
/**********************************************************************
【ライセンスについて】
Copyright(c) 2022 by tamanegi
Released under the MIT license
'http://tamanegi.digick.jp/about-licence/

【マイコン基板】
XIAO nRF52840 (Sense)で利用できます。

【スケッチの説明】
 PWMでLEDをゆっくり点灯しゆっくり消灯します。

【ライブラリ】
Seeed nRF52 Boards > Seeed XIAO nRF52840 (Sense)

【準備】
GPIO10  -> 保護抵抗(約200Ω) -> LED -> GND

【バージョン情報】
2022/11/24 : 新規
**********************************************************************/

#define PWM 10

void setup()
{
  pinMode(PWM , OUTPUT);
}

void loop()
{
  for(int i = 0; i < 256; i ++)
  {
    analogWrite(PWM, i);
    delay(2);
  }

  for(int i = 0; i < 256; i ++)
  {
    analogWrite(PWM, 255 - i);
    delay(2);
  }
}
結果

LEDがゆっくり点灯し、ゆっくり消灯しました。

I2C(SSD1306)

説明

I2Cを使ってSSD1306(OLED 0.96inch)モニタのサンプルを動作させます。

図形の描画やそのほかの命令はArduinoサンプルスケッチを参照してください。
ファイル(F) > スケッチ例 > Adafruit SSD1306 > ssd1306_128x64_i2c

配線
XIAO nRF25840 (Sense)配線SSD1306(0.96inch)
3.3VVCC
GNDGND
GPIO4(SDA)SDA
GPIO5(SCL)SCL
スケッチ
/**********************************************************************
【ライセンスについて】
Copyright(c) 2022 by tamanegi
Released under the MIT license
'http://tamanegi.digick.jp/about-licence/

【マイコン基板】
XIAO nRF25840 (Sense) 基板で利用できます。

【スケッチの説明】
SSD1306 OLEDの制御をします。

【ライブラリ】
Seeed nRF25 Boards > Seeed nRF258240
Adafruit SSD1306 by Adafruit
Adafruit GFX Library by Adafruit

【準備】
マイコン基板 <-> SSD1306
3V3         <-> VCC
GND         <-> GND
GPIO4(SDA)  <-> SDA
GPIO5(SCL)  <-> SCL

【バージョン情報】
2022/11/22 : 新規
**********************************************************************/

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128                //解像度 128 x 64 で使用します。
#define SCREEN_HEIGHT 64                //SCREEN_HEIGHTは 32 に設定することができます。

#define OLED_RESET     -1               //使用しないので -1を設定する。
#define SCREEN_ADDRESS 0x3C             //I2Cアドレスは 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
                                        //表示制御にはAdafruit製 SSD1306を使用する。
                                        
void setup()
{
  

  if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    for(;;);
  }

  display.clearDisplay();               //何か表示されている場合に備えて表示クリア

  display.setTextSize(2);               //フォントサイズは2(番目に小さい)
  display.setTextColor(SSD1306_WHITE);  //色指定はできないが必要
  display.setCursor(20, 5);            //テキストの表示開始位置
  display.print(F("TAMANEGI"));         //表示文字列
  display.setCursor(45, 25);
  display.print(F("XIAO"));
  display.setCursor(20, 45);
  display.print(F("nRF25840"));

  display.display();                    //バッファ転送(表示)
}

void loop()
{
}
結果

SSD1306のサンプルスケッチが動作しました。

SPI(ST7735)

説明

SPIを使ってST7735(LCD 1.8inch)モニタのサンプルを動作させます。

図形の描画やそのほかの命令はArduinoサンプルスケッチを参照してください。
ファイル(F) > スケッチ例 > Adafruit ST7735 and ST7789 Library > graphicstest

配線
XIAO nRF25840 (Sense)配線ST7735(1.8inch)
3.3VVCC
3.3VLED
GNDGND
GPIO0(SPI CS)CS
GPIO1Reset
GPIO2AO(DC)
GPIO10(SPI MOSI)SDA
GPIO8(SPI SCK)SCK
スケッチ
/**********************************************************************
【ライセンスについて】
Copyright(c) 2022 by tamanegi
Released under the MIT license
'http://tamanegi.digick.jp/about-licence/

【マイコン基板】
Seeed XIAO nRF52840 (Sense) 基板で利用できます。

【スケッチの説明】
ST7735 LCDの表示制御します。
H/W SPIを使用するための方法についてサンプル記載します。

【ライブラリ】
Seeed nRF52 Boards > Seeed XIAO nRF52840 (Sense)

【準備】
マイコン基板 <-> ST7735
3V3           <-> VCC
GND           <-> GND
GPIO0(CS)     <-> CS
GPIO1(Reset)  <-> Reset
GPIO2(DC)     <-> AO
GPIO10(MOSI)  <-> SDA
GPIO8(SCK)    <-> SCK

【バージョン情報】
2022/11/21 : 新規
**********************************************************************/

#include <Adafruit_GFX.h> 
#include <Adafruit_ST7735.h>
#include <SPI.h>

#define TFT_CS          0  // CS
#define TFT_RST         1  // Reset 
#define TFT_DC          2  // DC
#define TFT_MOSI        10  // MOSI
#define TFT_SCK         8  // SCK


Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);

void setup(void) 
{
  tft.initR(INITR_BLACKTAB);                  //Init ST7735S初期化
  
  tft.fillScreen(ST77XX_BLACK);               //背景の塗りつぶし

  //テキスト表示
  tft.setRotation(3);                         //画面回転
  tft.setTextSize(3);                         //サイズ

  tft.setCursor(0, 20);                      //カーソル位置                      
  tft.setTextColor(ST77XX_RED);              //赤
  tft.printf("TAMANEGI\n");

  tft.setTextColor(ST77XX_GREEN);            //緑
  tft.printf("TAMANEGI\n");

  tft.setTextColor(ST77XX_BLUE);             //青
  tft.printf("TAMANEGI\n");

  tft.setTextColor(ST77XX_YELLOW);           //黄
  tft.printf("TAMANEGI\n");
}

void loop()
{
}
結果

ST7735のサンプルスケッチが動作しました。

スケッチと配線はSeeed XIAO BLE nRF52840 Senseでも共通です。

特別な機能スケッチ

BLE-HID(マウス)

準備

使うもの

名称(型名)用途
Seeed XIAO BLE nRF52840
または
Seeed XIAO BLE nRF52840 Sense
マウスになってもらいます
ブレッドボードマイコンや部品の配置
タクトスイッチ マウスカーソルの移動ボタンに
なってもらいます
ジャンパワイヤ 数本

配線

Seeed XIAO BLE nRF52840配線色ボタン青配線色ボタン黒
3.3V入力側端子
GPIO 0出力側端子
3.3V入力側端子
GPIO 1出力側端子

サンプルスケッチ

BLEマウスは、Arduinoサンプルをもとに修正しています。
Examples > Adafruit Bluefruit nRF52 Libraries > Peripheral > blehid_mouse

サンプルスケッチからタクトスイッチによる制御に変更をする修正をしています。

サンプルスケッチライブラリの参照元

/**********************************************************************
【ライセンスについて】
Copyright(c) 2022 by たまねぎ
Released under the MIT license
'http://tamanegi.digick.jp/about-licence/

【スケッチの説明】
XIAO nRF25840 または、 XIAO nRF25840 senseで使用できます。

BLEマウスとして動作します。
ペアリング後、ボタンを押下することでマウスカーソルの動作を移動します。

【準備】
スケッチ書き込み後は、スマートホン、タブレット、ノートPC、またはBluetoothレシーバとペアリングをしてください。

XIAO nRF25840(XIAO nRF25840 sense) - タクトボタン
3.3V - ボタン青の入力側端子
GND  - ボタン青の出力側端子
3.3V - ボタン黒の入力側端子
GND  - ボタン黒の出力側端子

【バージョン情報】
2022/8/21 : 新規
**********************************************************************/

#include <bluefruit.h>

BLEDis bledis;
BLEHidAdafruit blehid;

#define BLUEBUTTON 0                  //青いボタンはGPIO 0を使う
#define BLACKBUTTON 1                 //黒いボタンはGPIO 1を使う
#define MOUSECOUNT 5                  //5カウントずつ移動
void setup() 
{

  pinMode(BLUEBUTTON, INPUT_PULLDOWN);
  pinMode(BLACKBUTTON, INPUT_PULLDOWN);

  Bluefruit.begin();
  // HID Device can have a min connection interval of 9*1.25 = 11.25 ms
  Bluefruit.Periph.setConnInterval(9, 16); // min = 9*1.25=11.25 ms, max = 16*1.25=20ms
  Bluefruit.setTxPower(4);    // Check bluefruit.h for supported values

  // Configure and Start Device Information Service
  bledis.setManufacturer("Adafruit Industries");
  bledis.setModel("Bluefruit Feather 52");
  bledis.begin();

  // BLE HID
  blehid.begin();

  // Set up and start advertising
  startAdv();
}

void startAdv(void)
{  
  // Advertising packet
  Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
  Bluefruit.Advertising.addTxPower();
  Bluefruit.Advertising.addAppearance(BLE_APPEARANCE_HID_MOUSE);
  
  // Include BLE HID service
  Bluefruit.Advertising.addService(blehid);

  // There is enough room for 'Name' in the advertising packet
  Bluefruit.Advertising.addName();
  
  /* Start Advertising
   * - Enable auto advertising if disconnected
   * - Interval:  fast mode = 20 ms, slow mode = 152.5 ms
   * - Timeout for fast mode is 30 seconds
   * - Start(timeout) with timeout = 0 will advertise forever (until connected)
   * 
   * For recommended advertising interval
   * https://developer.apple.com/library/content/qa/qa1931/_index.html   
   */
  Bluefruit.Advertising.restartOnDisconnect(true);
  Bluefruit.Advertising.setInterval(32, 244);    // in unit of 0.625 ms
  Bluefruit.Advertising.setFastTimeout(30);      // number of seconds in fast mode
  Bluefruit.Advertising.start(0);                // 0 = Don't stop advertising after n seconds  
}

void loop() 
{
    //青いボタンが押されていればマウスカーソルを左へ移動
  int blue = digitalRead(BLUEBUTTON);
  if (blue == HIGH)
  {
    blehid.mouseMove(MOUSECOUNT, 0);
  }

  //黒いボタンが押されていればマウスカーソルを右へ移動
  int black = digitalRead(BLACKBUTTON);
  if (black == HIGH)
  {
    blehid.mouseMove(MOUSECOUNT, 0);
  }
  blehid.mouseButtonPress( ));

}
/*
マウス制御関数参照

    blehid.mouseMove(int8_t x, int8_t y);
    動作 : マウスカーソルの移動
    パラメータ :
     x = 水平軸(負数は左、正数は右へ移動)
     y = 垂直軸(負数は上、正数は下へ移動)
 
    blehid.mouseButtonPress(uint8_t buttons);
    動作 : マウスボタンの押下
    パラメータ : 
     buttons = 押下ボタンの種類
      MOUSE_BUTTON_LEFT     = Left button
      MOUSE_BUTTON_RIGHT    = Right button
      MOUSE_BUTTON_MIDDLE   = Middle button
      MOUSE_BUTTON_BACKWARD = Backward button
      MOUSE_BUTTON_FORWARD  = Forward button

    blehid.mouseButtonRelease();
    動作 : 押下状態のボタンの解放

スケッチの説明

BLEマウスとしての動作をします。
GPIO0(青ボタン)とGPIO1(黒ボタン)は、PullDown入力です。
ボタンが押されている間はHIGHになります。

青いボタンを押している間マウスカーソルが左へ移動します。
黒いボタンを押している間マウスカーソルが右へ移動します。

結果

ノートパソコンとSeeed XIAO BLE nRF52840 はBLEペアリング済みです。

BLE-HID(キーボード)

準備

BLE-HID(マウスと同じ配線を使用します)

使うもの

名称(型名)用途
Seeed XIAO BLE nRF52840
または
Seeed XIAO BLE nRF52840 Sense
キーボードになってもらいます
ブレッドボードマイコンや部品の配置
タクトスイッチ キーボードのボタンに
なってもらいます
ジャンパワイヤ 数本

配線

Seeed XIAO BLE nRF52840配線色ボタン青配線色ボタン黒
3.3V入力側端子
GPIO 0出力側端子
3.3V入力側端子
GPIO 1出力側端子

サンプルスケッチ

BLEキーボードは、Arduinoサンプルをもとに修正しています。
Examples > Adafruit Bluefruit nRF52 Libraries > Peripheral > blehid_keyboard

サンプルスケッチからタクトスイッチによる制御に変更をする修正をしています。

サンプルスケッチライブラリの参照元

/**********************************************************************
【ライセンスについて】
Copyright(c) 2022 by たまねぎ
Released under the MIT license
'http://tamanegi.digick.jp/about-licence/

【スケッチの説明】
XIAO nRF25840 または、 XIAO nRF25840 senseで使用できます。

BLEマウスとして動作します。
ペアリング後、BLEキーボードとして動作します。
ボタン青の押下するごとに "tamanegi"を一文字ずつ入力します。
ボタン黒を押下すると"TAMANEGI"をまとめて入力します。

【準備】
スケッチ書き込み後は、スマートホン、タブレット、ノートPC、またはBluetoothレシーバとペアリングをしてください。

XIAO nRF25840(XIAO nRF25840 sense) - タクトボタン
3.3V - ボタン青の入力側端子
GND  - ボタン青の出力側端子
3.3V - ボタン黒の入力側端子
GND  - ボタン黒の出力側端子

【バージョン情報】
2022/8/21 : 新規
**********************************************************************/

#include <bluefruit.h>

BLEDis bledis;
BLEHidAdafruit blehid;

bool hasKeyPressed = false;

#define BLUEBUTTON 0                  //青いボタンはGPIO 0を使う
#define BLACKBUTTON 1                 //黒いボタンはGPIO 1を使う
const char strKey[] = "tamanegi";     //1文字ずつ出力するための文字列
const char strKey2[] = "TAMANEGI";
uint iIndexKey = 0;                   //配列の出力インデックス
uint iSizeKey = 0;                    //文字列サイズの保存

bool bButtonBlueOn = false;           //ボタン押下状態の保存
bool bButtonBlackOn = false;


void setup() 
{
  pinMode(BLUEBUTTON, INPUT_PULLDOWN);
  pinMode(BLACKBUTTON, INPUT_PULLDOWN);

  Bluefruit.begin();
  Bluefruit.setTxPower(4);    // Check bluefruit.h for supported values

  // Configure and Start Device Information Service
  bledis.setManufacturer("Adafruit Industries");
  bledis.setModel("Bluefruit Feather 52");
  bledis.begin();

  /* Start BLE HID
   * Note: Apple requires BLE device must have min connection interval >= 20m
   * ( The smaller the connection interval the faster we could send data).
   * However for HID and MIDI device, Apple could accept min connection interval 
   * up to 11.25 ms. Therefore BLEHidAdafruit::begin() will try to set the min and max
   * connection interval to 11.25  ms and 15 ms respectively for best performance.
   */
  blehid.begin();

  // Set callback for set LED from central
  blehid.setKeyboardLedCallback(set_keyboard_led);

  /* Set connection interval (min, max) to your perferred value.
   * Note: It is already set by BLEHidAdafruit::begin() to 11.25ms - 15ms
   * min = 9*1.25=11.25 ms, max = 12*1.25= 15 ms 
   */
  /* Bluefruit.Periph.setConnInterval(9, 12); */

  // Set up and start advertising
  startAdv();
}

void startAdv(void)
{  
  // Advertising packet
  Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
  Bluefruit.Advertising.addTxPower();
  Bluefruit.Advertising.addAppearance(BLE_APPEARANCE_HID_KEYBOARD);
  
  // Include BLE HID service
  Bluefruit.Advertising.addService(blehid);

  // There is enough room for the dev name in the advertising packet
  Bluefruit.Advertising.addName();
  
  /* Start Advertising
   * - Enable auto advertising if disconnected
   * - Interval:  fast mode = 20 ms, slow mode = 152.5 ms
   * - Timeout for fast mode is 30 seconds
   * - Start(timeout) with timeout = 0 will advertise forever (until connected)
   * 
   * For recommended advertising interval
   * https://developer.apple.com/library/content/qa/qa1931/_index.html   
   */
  Bluefruit.Advertising.restartOnDisconnect(true);
  Bluefruit.Advertising.setInterval(32, 244);    // in unit of 0.625 ms
  Bluefruit.Advertising.setFastTimeout(30);      // number of seconds in fast mode
  Bluefruit.Advertising.start(0);                // 0 = Don't stop advertising after n seconds
}

void loop() 
{
  //青いボタンが押されたら 押されるたびに"tamanegi"を一文字ずつキーボード出力
  if(digitalRead(BLUEBUTTON) == HIGH)
  {
    delay(10);
    if(digitalRead(BLUEBUTTON) == HIGH)       //チャタリング対策
    {
      if(bButtonBlueOn == false)              //ボタンが押されていない状態から押された状態への変化を確認。キーを連発させないための処理
      {    
        bButtonBlueOn = true;                 //ボタン押下フラグOn

        blehid.keyPress(strKey[iIndexKey]);    //一文字ずつキーボード出力
        blehid.keyRelease();
        iIndexKey ++;
        if(strKey[iIndexKey] == 0x00)iIndexKey = 0;       //NULL文字を検出したら最初から
      }
    }
  }
  else 
  {
    bButtonBlueOn = false;                //ボタン押下フラグをOff
  }

  //黒いボタンが押されたら "TAMANEGI"をまとめてキーボード出力
  if(digitalRead(BLACKBUTTON) == HIGH)
  {
    delay(10);
    if(digitalRead(BLACKBUTTON) == HIGH)       //チャタリング対策
    {
      if(bButtonBlackOn == false)              //ボタンが押されていない状態から押された状態への変化を確認。キーを連発させないための処理
      {
        bButtonBlackOn = true;                 //ボタン押下フラグOn

        //まとめてキー出力
        for(int i = i; i < strlen(strKey2); i ++)
        {
          blehid.keyPress(strKey2[i]);
          blehid.keyRelease();
        }
      }
    }
  }
  else 
  {
    bButtonBlackOn = false;                //ボタン押下フラグをOff
  }
}


/**
 * Callback invoked when received Set LED from central.
 * Must be set previously with setKeyboardLedCallback()
 *
 * The LED bit map is as follows: (also defined by KEYBOARD_LED_* )
 *    Kana (4) | Compose (3) | ScrollLock (2) | CapsLock (1) | Numlock (0)
 */
void set_keyboard_led(uint16_t conn_handle, uint8_t led_bitmap)
{
  (void) conn_handle;
  
  // light up Red Led if any bits is set
  if ( led_bitmap )
  {
    ledOn( LED_RED );
  }
  else
  {
    ledOff( LED_RED );
  }
}

スケッチの説明

BLEキーボードとしての動作をします。
GPIO0(青ボタン)とGPIO1(黒ボタン)は、PullDown入力です。
ボタンが押されている間はHIGHになります。

青いボタンが押されたら 押されるたびに”tamanegi”を一文字ずつキーボード出力。
黒いボタンが押されたら “TAMANEGI”をまとめてキーボード出力。

ボタン押下確認後のウエイトと再度のボタン押下確認は簡易的なチャタリング対策です。

結果

ノートパソコンとSeeed XIAO BLE nRF52840 はBLEペアリング済みです。

BLE-UART

準備

配線はありませんがパソコンとのUSB接続と、Bluetooth端末とペアリングをします。
※ペアリングはスケッチを書きこんだ後に行います。

Bluetooth端末の通信アプリケーションとして「Serial Bluetooth Terminal」を使用します。
パソコン側は「Teraterm」を使用します。

パソコン<-(USB)->Seeed XIAO nRF52840 (BLEペアリング) Bluetooth端末

サンプルスケッチ

BLE-UARTは、Arduinoサンプルを紹介します。
Examples > Adafruit Bluefruit nRF52 Libraries > Peripheral > bleuart

/*********************************************************************
 This is an example for our nRF52 based Bluefruit LE modules

 Pick one up today in the adafruit shop!

 Adafruit invests time and resources providing this open source code,
 please support Adafruit and open-source hardware by purchasing
 products from Adafruit!

 MIT license, check LICENSE for more information
 All text above, and the splash screen below must be included in
 any redistribution
*********************************************************************/
#include <bluefruit.h>
#include <Adafruit_LittleFS.h>
#include <InternalFileSystem.h>

// BLE Service
BLEDfu  bledfu;  // OTA DFU service
BLEDis  bledis;  // device information
BLEUart bleuart; // uart over ble
BLEBas  blebas;  // battery

void setup()
{
  Serial.begin(115200);

#if CFG_DEBUG
  // Blocking wait for connection when debug mode is enabled via IDE
  while ( !Serial ) yield();
#endif
  
  Serial.println("Bluefruit52 BLEUART Example");
  Serial.println("---------------------------\n");

  // Setup the BLE LED to be enabled on CONNECT
  // Note: This is actually the default behavior, but provided
  // here in case you want to control this LED manually via PIN 19
  Bluefruit.autoConnLed(true);

  // Config the peripheral connection with maximum bandwidth 
  // more SRAM required by SoftDevice
  // Note: All config***() function must be called before begin()
  Bluefruit.configPrphBandwidth(BANDWIDTH_MAX);

  Bluefruit.begin();
  Bluefruit.setTxPower(4);    // Check bluefruit.h for supported values
  //Bluefruit.setName(getMcuUniqueID()); // useful testing with multiple central connections
  Bluefruit.Periph.setConnectCallback(connect_callback);
  Bluefruit.Periph.setDisconnectCallback(disconnect_callback);

  // To be consistent OTA DFU should be added first if it exists
  bledfu.begin();

  // Configure and Start Device Information Service
  bledis.setManufacturer("Adafruit Industries");
  bledis.setModel("Bluefruit Feather52");
  bledis.begin();

  // Configure and Start BLE Uart Service
  bleuart.begin();

  // Start BLE Battery Service
  blebas.begin();
  blebas.write(100);

  // Set up and start advertising
  startAdv();

  Serial.println("Please use Adafruit's Bluefruit LE app to connect in UART mode");
  Serial.println("Once connected, enter character(s) that you wish to send");
}

void startAdv(void)
{
  // Advertising packet
  Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
  Bluefruit.Advertising.addTxPower();

  // Include bleuart 128-bit uuid
  Bluefruit.Advertising.addService(bleuart);

  // Secondary Scan Response packet (optional)
  // Since there is no room for 'Name' in Advertising packet
  Bluefruit.ScanResponse.addName();
  
  /* Start Advertising
   * - Enable auto advertising if disconnected
   * - Interval:  fast mode = 20 ms, slow mode = 152.5 ms
   * - Timeout for fast mode is 30 seconds
   * - Start(timeout) with timeout = 0 will advertise forever (until connected)
   * 
   * For recommended advertising interval
   * https://developer.apple.com/library/content/qa/qa1931/_index.html   
   */
  Bluefruit.Advertising.restartOnDisconnect(true);
  Bluefruit.Advertising.setInterval(32, 244);    // in unit of 0.625 ms
  Bluefruit.Advertising.setFastTimeout(30);      // number of seconds in fast mode
  Bluefruit.Advertising.start(0);                // 0 = Don't stop advertising after n seconds  
}

void loop()
{
  // Forward data from HW Serial to BLEUART
  while (Serial.available())
  {
    // Delay to wait for enough input, since we have a limited transmission buffer
    delay(2);

    uint8_t buf[64];
    int count = Serial.readBytes(buf, sizeof(buf));
    bleuart.write( buf, count );
  }

  // Forward from BLEUART to HW Serial
  while ( bleuart.available() )
  {
    uint8_t ch;
    ch = (uint8_t) bleuart.read();
    Serial.write(ch);
  }
}

// callback invoked when central connects
void connect_callback(uint16_t conn_handle)
{
  // Get the reference to current connection
  BLEConnection* connection = Bluefruit.Connection(conn_handle);

  char central_name[32] = { 0 };
  connection->getPeerName(central_name, sizeof(central_name));

  Serial.print("Connected to ");
  Serial.println(central_name);
}

/**
 * Callback invoked when a connection is dropped
 * @param conn_handle connection where this event happens
 * @param reason is a BLE_HCI_STATUS_CODE which can be found in ble_hci.h
 */
void disconnect_callback(uint16_t conn_handle, uint8_t reason)
{
  (void) conn_handle;
  (void) reason;

  Serial.println();
  Serial.print("Disconnected, reason = 0x"); Serial.println(reason, HEX);
}

スケッチの説明

BLEUART通信をします。
パソコン側(Teraterm)から文字を入力すると、Bluetooth端末上(Serial Bluetooth Terminal)に文字が表示される。
Bluetooth端末上(Serial Bluetooth Terminal)から文字を入力すると、パソコン側(Teraterm)に文字が表示される。

結果

コメント

タイトルとURLをコピーしました