秋月の技適付き無線開発基板 AE-nRF52840 BLEを使う

コンピュータ、組み込み

秋月さんから販売されているnRF52840搭載基板、AE-nRF52840を入手しました。
Arduino環境でのセットアップ、基本的な入出力、通信(UART, I2C, SPI)とBLEによるHIDやUARTを試してみます。

紹介するもの

AE-nRF52840 BLE

秋月電子通商さんから販売されているnRF52840 搭載基板です。
技適マーク付きのモジュールで、無線を使用できます。

接続Type C
CPUNordic nRF52840 64MHz(クロック推定)
ロジックレベル3.3V
GPIO21
PWM21(8bit) 一度に16chまで使用できる
ADC6(10bit)
UART1
I2C1
SPI1
そのほかリセットボタン
JST PH 1mm 4pin (Qwiic配線と互換)

ピン配置

基本的な入出力と、通信機能を備えています。
JST SH 1.0mm 4pinコネクタがあり、Qwiicと同じピンが配置されています。

外観

ピン数と配置は違いますが、近い時期に発売されたAE-RP2040と同じサイズです。

400穴ブレッドボードでは左右2列ずつ使用することができます。

梱包物には、ピンヘッダ20pinが2本が付属していました。

ピンヘッダは直径の細いタイプのものです。(SWD用は太い
下図画像の左側が付属の細いピン、右は太いピンです。


どちらが正解でもありませんが、それぞれのメリットとデメリットは相対の関係です。

メリットデメリット
細いピンヘッダブレッドボードへの挿抜が楽接触不良が起きやすい
ジャンパワイヤのソケットではゆるくて抜ける
ピン曲がりが起きやすい
太いピンヘッダ接触不良が起きにくい
ジャンパワイヤのソケットでも接触する
ブレッドボードの挿抜が固くて大変
ピン曲がりが起きやすい

使ってみて

以前に SeeedのXIAO nRF52840を評価したことがあるので、躓くことなく評価はできました。
基本的な入出力と通信機能に、無線による通信を利用できます。
nRF52840搭載基板の中では珍しく、センサー類があまりついていないシンプルな設計ですので評価や学習に躓きが少なく、同Soc搭載基板では比較的安価に入手できます。

ESP32系技適取得品が増えてきたので、無線の選択肢も増えたところにこちらの基板がリリースされてうれしい限りです。

多くのマイコン基板では、パソコンとの通信やデバッグの出力にCOM通信をすると思いますが、COMを使用するために”Adafruit_TinyUSB.h”をインクルードする必要があるので記載忘れがないように注意が必要です。

nRF52840 搭載基板XIAO nRF52840の記事はこちら

準備

ライブラリ

ボードライブラリ

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

ボードマネージャのURLhttps://adafruit.github.io/arduino-board-index/package_adafruit_index.json
検索nRF52
ボードライブラリAdafruit nRF52 by Adafruit バージョン x.x.x
選択するボードAdafruit nRF52 > Feather nRF52840 Express
※ x.x.x Mar/2023 では1.3.0

スケッチの書き込み方

パソコンとAE-nRF52840をUSBケーブルで接続します。
Arduino IDEから接続したCOMポート番号を選択し、プログラムを書き込むボタンを押下します。
シリアル認識されない場合(スケッチ書き込み後など)、基板上のRSTボタンを素早く2回押下する(0.5秒に2回くらい)ことでシリアル認識されます。

BTペアリング

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

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

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

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

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

画像は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/

【マイコン基板】
AK-nRF52840

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

【ライブラリ】
Adafruit nRF52 > Adafruit Feather nRF52840 Express

【準備】
GPIO2(OUTPUT) -> 保護抵抗(約200Ω) -> LED -> GND
3.3V -> タクトボタン -> GPIO0(INPUT)

LEDの保護抵抗は適値を求めて使用してください。
 
【バージョン情報】
2023/3/3 : 新規
**********************************************************************/


#define LED 2       //LED
#define BUTTON 0    //タクトスイッチ

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/

【マイコン基板】
AK-nRF52840

【スケッチの説明】
PWMを使ってLEDをゆっくり点灯、ゆっくり消灯を繰り返します。

【ライブラリ】
Adafruit nRF52 > Adafruit Feather nRF52840 Express

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

LEDの保護抵抗は適値を求めて使用してください。
 
【バージョン情報】
2023/3/3 : 新規
**********************************************************************/

#define PWM 2

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がゆっくり点灯し、ゆっくり消灯しました。

ADC

説明

ADCに入力された電圧を読み取りCOMに出力します。

電圧の入力にLOLIN32 Liteを使用します。
0~255(約3.3V) まで2msごとに1ずつ上昇し、255(約3.3V)~0までを2msごとに1ずつ下降する設定を繰り返します。

配線
AE-nRF52840配線LOLIN32 Lite
GPIO14(ADC)GPIO26(DAC)
GNDGND
スケッチ
/**********************************************************************
【ライセンスについて】
Copyright(c) 2022 by tamanegi
Released under the MIT license
'http://tamanegi.digick.jp/about-licence/

【マイコン基板】
AE-nRF52840

【スケッチの説明】
入力された電圧を読み取ります。

【ライブラリ】
Adafruit nRF52 > Adafruit Feather nRF52840 Express

【準備】
AE-nRF52840 <-> LOLIN32 Lite
GPIO14(ADC)       <-> GPIO26(DAC)
GND               <-> GND

【バージョン情報】
2023/3/3 : 新規
**********************************************************************/

#include <Adafruit_TinyUSB.h>   // COM用

#define ADC 14

void setup()
{
  Serial.begin(115200);
  pinMode(ADC, INPUT);
}

void loop()
{
  int iADC = 0;

  //外部から入力された電圧を読み取り、結果をCOMに出力します。
  iADC = analogRead(ADC);
  Serial.printf("(ADC) = %d\r\n", iADC);
  delay(2);
}

結果

入力した電圧を読み取った結果をグラフにしました。
電圧の変化は0V -> 3.3Vまでを約500msで上昇し、3.3V -> 0Vまで約500msで下降します。

ADC読み取り値は低値から高値まで直線でキレイな波形になっています。
頂点付近の3.3V時点では900(A/D)前後なので、1割程度傾きが小さいようです。

電圧と読み取り値の同期はできていませんが、参考程度に入力電圧を添付します。

UART

説明

COMから読み取ったデータをS/W UARTに送信します。
S/W UARTから読み取ったデータをCOMに送信します。

配線
AE-nRF52840配線FT232RL
GP0(UART0 TX)RX
GP1(UART0 RX)TX
スケッチ
/**********************************************************************
【ライセンスについて】
Copyright(c) 2022 by tamanegi
Released under the MIT license
'http://tamanegi.digick.jp/about-licence/

【マイコン基板】
AE-nRF52840

【スケッチの説明】
COMとS/W ARTを使って双方向通信をします。
S/W UARTにはFT232RLを使います。

【ライブラリ】
Adafruit nRF52 > Adafruit Feather nRF52840 Express

【準備】
AE-nRF52840 <-> FT232RL
GPIO0 (S/W UART TX) <-> RX
GPIO1 (S/W UART RX) <-> TX

【バージョン情報】
2023/3/3 : 新規
**********************************************************************/

#include <Adafruit_TinyUSB.h>   // COM用
#include <SoftwareSerial.h>
SoftwareSerial mySerial(1, 0);  // RX = GPIO1, TX = GPIO0

void setup()
{
  Serial.begin(9600);                  //SerialオブジェクトはUART0 (COM)
  mySerial.begin(9600);                //mySerialオブジェクトはUART1
}

void loop()
{
  if(mySerial.available() != 0)        //S/W uartにデータがあれば、読み取った内容をCOMに送信
  {
      Serial.write(mySerial.read());
  }

  if(Serial.available() != 0)           //COMにデータがあれば、読み取った内容をS/W uartに送信
  {
      mySerial.write(Serial.read());
  }
}

結果

結果はTeratermを2つ起動して確認します。
1つはCOM 用で、もう一つはS/W UART用です。
結果は省略します。

COM用のTeratermに入力された文字は、S/W UART用のTeraterm画面に表示されます。
S/W UART用のTeratermに入力された文字は、COM用のTeraterm画面に表示されます。

I2C(SSD1306)

説明

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

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

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

【マイコン基板】
AE-nRF52840

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

【ライブラリ】
Adafruit nRF52 > Adafruit Feather nRF52840 Express
Adafruit SSD1306 by Adafruit
Adafruit GFX Library by Adafruit

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

【バージョン情報】
2023/03/03 : 新規
**********************************************************************/

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

#define PIN_SDA 22
#define PIN_SCL 23

#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()
{
  
  //Wire.setPins(PIN_SDA, PIN_SCL);    //デフォルトピンから変更する場合は、定義のピン番号を変更してコメントを外す。
  
  if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    for(;;);
  }

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

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

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

void loop()
{
}
結果

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

SPI(ST7735)

説明

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

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

配線
AE-nRF52840配線ST7735(1.8inch)
3.3VVCC
3.3VLED
GNDGND
GPIO5CS
GPIO6Reset
GPIO9AO(DC)
GPIO25(SPI MOSI)SDA
GPIO26(SPI SCK)SCK
スケッチ
/**********************************************************************
【ライセンスについて】
Copyright(c) 2022 by tamanegi
Released under the MIT license
'http://tamanegi.digick.jp/about-licence/

【マイコン基板】
AK-nRF52840

【スケッチの説明】
ST7735 LCDの表示制御します。

【ライブラリ】
Adafruit nRF52 > Adafruit Feather nRF52840 Express
Adafruit ST7735 and ST7789 Library
Adafruit GFX Library

【準備】
マイコン基板 <-> ST7735
3V3              <-> VCC
GND              <-> GND
GPIO5            <-> CS
GPIO6            <-> Reset
GPIO9            <-> AO
GPIO25(SPI MOSI) <-> SDA
GPIO26(SPI SCK)  <-> SCK

【バージョン情報】
2023/3/3 : 新規
**********************************************************************/

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

#define TFT_CS    5
#define TFT_RST   6
#define TFT_DC    9
#define TFT_MOSI  25
#define TFT_SCK   26

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

//S/W SPIはこちら。遅いが任意のピンを使用できる。
//Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCK, TFT_RST);

void setup(void) 
{
  //SPI.setPins(-1, TFT_SCK, TFT_MOSI);         //デフォルトピンから変更する場合は、定義のピン番号を変更してコメントを外す。
  tft.initR(INITR_BLACKTAB);                  //Init ST7735S初期化
  
  tft.fillScreen(ST77XX_BLACK);               //背景の塗りつぶし

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

  tft.setCursor(0, 10);                       //カーソル位置                      
  tft.setTextColor(ST77XX_GREEN);             //緑
  tft.printf("TAMANEGI\n");

  tft.setCursor(0, 50);                       //カーソル位置                      
  tft.setTextSize(2);                         //サイズ
  tft.setTextColor(ST77XX_RED);               //赤
  tft.printf("1.8inch LCD\n");
  tft.setTextColor(ST77XX_YELLOW);            //黄
  tft.printf("Res=128 x 160\n");
  tft.setTextColor(ST77XX_BLUE);              //青
  tft.printf("ST7735\n");
}

void loop()
{
}
結果

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

特別な機能スケッチ

BLE-HID(マウス)

スケッチの説明

BLEマウスとしての動作をします。
ボタンの押下状態によりマウスカーソルを移動させます。

入力は当サイトで紹介しているI2Cコントローラモジュールを使用しています。
タクトボタンの押下状態を各ビットのLow/Highにして通知するモジュールです。

同じnRF52840搭載 Seeed XIAO BLE nRF52840 では単純なタクトボタンの読み取りで左右に移動するサンプルを掲載しています。

準備

使うもの

名称(型名)用途
AE-nRF52840マウスになってもらいます
I2Cコントローラモジュールマウス制御のための入力装置
Qwiic ケーブル
(ストレート)
ボードとモジュールの接続
サンプルスケッチ

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/

【スケッチの説明】
AE-nRF52840

BLEマウスとして動作します。
上下左右動作のサンプルを記載しています。

マウスのボタン、ホイール動作を含めた完成状態はこちら

I2Cモジュールの作成(コントローラ)
RP2040ではI2Cスレーブとして通信する機能があります。 タクトボタンの押下状態を読み取りI2Cスレーブとしてマスターに返答するモジュールを作成します。
【準備】 スケッチ書き込み後は、スマートホン、タブレット、ノートPC、またはBluetoothレシーバとペアリングをしてください。 Qwiicコネクタより、I2Cコントローラモジュールを接続します。 【バージョン情報】 2023/3/4 : 新規 **********************************************************************/ #include <bluefruit.h> #include <Wire.h> BLEDis bledis; BLEHidAdafruit blehid; #define MOUSECOUNT 5 //5カウントずつ移動 #define I2C_ADDR 0x10 //I2CコントローラモジュールのI2Cアドレスは 0x10 void setup() { 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(); //Qwiic I2Cコントローラモジュールとの接続 Wire.begin(); //I2Cマスター通信開始 } 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() { char cStat = 0; if(Wire.requestFrom(I2C_ADDR, 2) != 0) { cStat = Wire.read(); //ボタン上 if((cStat & 0x10) != 0) { blehid.mouseMove(0, -MOUSECOUNT); } //ボタン下 if((cStat & 0x20) != 0) { blehid.mouseMove(0, MOUSECOUNT); } //ボタン左 if((cStat & 0x40) != 0) { blehid.mouseMove(-MOUSECOUNT, 0); } //ボタン右 if((cStat & 0x80) != 0) { blehid.mouseMove(MOUSECOUNT, 0); } } }
結果

動作結果は省略します。
I2Cコントローラモジュールの上下左右ボタンに対応して、マウスカーソルが移動します。

BLE-HID(キーボード)

スケッチの説明

BLEマウスとしての動作をします。
ボタンの押下状態によりマウスカーソルを移動させます。

入力は当サイトで紹介しているI2Cコントローラモジュールを使用しています。
タクトボタンの押下状態を各ビットのLow/Highにして通知するモジュールです。

同じnRF52840搭載 Seeed XIAO BLE nRF52840 では単純なタクトボタンの読み取りでキーボードの入力を行います。

準備

使うもの

名称(型名)用途
AE-nRF52840キーボードになってもらいます
I2Cコントローラモジュールキーボード制御のための入力装置
Qwiic ケーブル
(ストレート)
ボードとモジュールの接続

サンプルスケッチ

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/

【スケッチの説明】
AE-nRF52840

BLEマウスとして動作します。
ペアリング後、BLEキーボードとして動作します。

I2Cコントローラモジュールを使用したサンプルです。
ボタン右を押下するごとに "tamanegi"を一文字ずつ入力します。
ボタン左を押下すると"TAMANEGI"をまとめて入力します。

I2Cコントローラモジュールは創作物でこちらで紹介しています。

I2Cモジュールの作成(コントローラ)
RP2040ではI2Cスレーブとして通信する機能があります。 タクトボタンの押下状態を読み取りI2Cスレーブとしてマスターに返答するモジュールを作成します。
【準備】 スケッチ書き込み後は、スマートホン、タブレット、ノートPC、またはBluetoothレシーバとペアリングをしてください。 Qwiicコネクタより、I2Cコントローラモジュールを接続します。 【バージョン情報】 2023/3/4 : 新規 **********************************************************************/ #include <bluefruit.h> #include <Wire.h> BLEDis bledis; BLEHidAdafruit blehid; bool hasKeyPressed = false; #define I2C_ADDR 0x10 //I2CコントローラモジュールのI2Cアドレスは 0x10 const char strKey[] = "tamanegi"; //1文字ずつ出力するための文字列 const char strKey2[] = "TAMANEGI"; uint iIndexKey = 0; //配列の出力インデックス uint iSizeKey = 0; //文字列サイズの保存 bool bButtonBlueOn = false; //ボタン押下状態の保存 bool bButtonBlackOn = false; void setup() { 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(); //Qwiic I2Cコントローラモジュールとの接続 Wire.begin(); //I2Cマスター通信開始 } 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() { char cStat = 0; if(Wire.requestFrom(I2C_ADDR, 2) != 0) { cStat = Wire.read(); //右側のボタンが押されたら 押されるたびに"tamanegi"を一文字ずつキーボード出力 if((cStat & 0x08) != 0) { //チャタリング対策 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((cStat & 0x04) != 0) { //チャタリング対策 if(bButtonBlackOn == false) //ボタンが押されていない状態から押された状態への変化を確認。キーを連発させないための処理 { bButtonBlackOn = true; //ボタン押下フラグOn //まとめてキー出力 for(int i = 0; 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 ); } }
結果

I2Cコントローラモジュールの最も右のボタン(右側)が押されたら 押されるたびに”tamanegi”を一文字ずつキーボード出力。
その左側のボタン(左側)が押されたら “TAMANEGI”をまとめてキーボード出力。

BLE-UART

スケッチの説明

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

準備

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

パソコン <-(USB)-> AE-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);
}
結果

スマートフォンからBLE接続を行いました。
スマートフォンアプリケーションにはSerial Bluetoothを使用します。

アプリケーションを起動し、画面左上のメニューから「Devices」を選択します。
「Bluetooth LE」を選択し、SCANを押します。
スケッチが正常に動作していれば「Feather nRF52840 Express」が表示されるので選択することで接続できます。

パソコン側からはArduinoIDEのシリアルモニタを使用します。
シリアルモニタから入力した文字がアプリケーション上に表示(水色の楕円)されます。
「Serial Bluetooth」アプリケーションから入力した文字が、シリアルモニタに表示(赤色の楕円)されます。

コメント

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