RN4020 を Arduino で操作する

トラ技JrでRN4020について記事を書かせていただいたのですが、

”ねこむに”を前提に紹介したので、もっと手軽にArduinoで操作する方法を簡単に紹介します。

 

■準備

・Arduino  — 今回は秋月のArduino Pro Mini互換使用

・RN4020  — 主役のBLEデバイス

・ロジックレベル変換IC  — 今回はFXMA108を使用

・FT232 USBtoUART変換(必要あれば)

・5V to 3.3Vレギュレータ(必要あれば)

接続は以下を参考に。

 

%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-10-17-2-00-53

 

Arduino Unoなど、USBシリアル変換がすでに実装されているものはFT232や3.3V用レギュレータはいらないので、適宜変更します。

実際に接続した例は、以下になります。

アクティブのLEDが光るとRN4020の準備はOKです。

 

img_1466

 

■プログラム

以下、Arduinoに書いたスケッチ。

githubにもプッシュ済み。


#include <SoftwareSerial.h>;

SoftwareSerial rn4020(2, 3);

struct commandTable {
 char comm[50];
 int len;
};

struct commandTable echo = {"+",1};
struct commandTable reboot = {"R,1",3};
struct commandTable list = {"LS",2};
struct commandTable advertise = {"A",1};
struct commandTable rssi = {"M",1};
struct commandTable stopAdv = {"Y",1};
struct commandTable serviceRole = {"SS,40000001",11}; //Battery + private
struct commandTable battService = {"SUW,2A19,32",11};
struct commandTable devName = {"S-,NR4020",9};
struct commandTable priService = {"PS,cb9cf8fba8104baf9ad8da094ffd166c",35};
struct commandTable priCharact = {"PC,B6F0FB56216441CFBC5867AE76320782,02,04",41}; //readOnly : 4byte Length
struct commandTable priClear = {"PZ",2};
struct commandTable reset = {"SF,2",4};
struct commandTable baudRate = {"SB,1",4}; //baud rate 9600

char recvChar;

void setup() {
 // put your setup code here, to run once:
 Serial.begin(57600);
 delay(100);

 /* First Setting */
 rn4020.begin(115200);
 delay(500);
 sendRN4020(baudRate.comm, baudRate.len);
 delay(100);
 sendRN4020(reboot.comm, reboot.len);
 delay(2000);
 rn4020.begin(9600);
 delay(100);
 /* First Setting */

 rn4020.begin(9600);
 delay(100);

 pinMode(4,OUTPUT); //WAKE_SW
 pinMode(5,OUTPUT); //CMD
 pinMode(6,OUTPUT); //WAKE_HW
 pinMode(A0,INPUT); 

 digitalWrite(4,HIGH); //Active mode
 digitalWrite(5,LOW); //MLDP Disable
 digitalWrite(6,HIGH); //Wake up
}

void loop() {
 // put your main code here, to run repeatedly:
 while
 (Serial.available()){
  recvChar = Serial.read();
  switch (recvChar){
   case '1':
     Serial.println("◆send : + -- Echo On/Off");
     sendRN4020(echo.comm, echo.len);
     break;
   case '2':
     Serial.println("◆send : S- -- Device Name Setting");
     sendRN4020(devName.comm, devName.len);
     delay(100);
     sendRN4020(reboot.comm, reboot.len);
     break;
   case '3':
     Serial.println("◆send : SUW,2A19 -- Battery Service Charact Setting");
     sendRN4020(battService.comm, battService.len);
     delay(100);
     sendRN4020(reboot.comm, reboot.len);
     break;
   case '4':
     Serial.println("◆send : LS -- Display Service List");
     sendRN4020(list.comm, list.len);
     break;
   case '5':
     Serial.println("◆send : SS -- Server Role Setting");
     sendRN4020(serviceRole.comm, serviceRole.len);
     delay(100);
     sendRN4020(reboot.comm, reboot.len);
     break;
   case '6':
     Serial.println("◆send : PS,PC -- Private Service/Charact Setting");
     sendRN4020(priService.comm, priService.len);
     delay(500);
     sendRN4020(priCharact.comm, priCharact.len);
     delay(500);
     sendRN4020(reboot.comm, reboot.len);
     delay(2000);
     break;
   case '7':
     Serial.println("◆send : SF -- Factory Reset");
     sendRN4020(reset.comm, reset.len);
     delay(300);
     sendRN4020(reboot.comm, reboot.len);
     delay(1000);
     read();
     delay(1000);
     rn4020.begin(115200);
     delay(300);
     sendRN4020(baudRate.comm, baudRate.len);
     delay(300);
     sendRN4020(reboot.comm, reboot.len);
     rn4020.begin(9600);
     break;
   case '8':
     Serial.println("◆send : R,1 -- Reboot");
     sendRN4020(reboot.comm, reboot.len);
     break;
   case '9':
     Serial.println("◆send : A -- Advertize");
     sendRN4020(advertise.comm, advertise.len);
     break;
   case 'A':
     Serial.println("◆send : Y -- Stop Advertize");
     sendRN4020(stopAdv.comm, stopAdv.len); 
     break;
   case'B':
     Serial.println("◆send : PZ -- Private Service Clear");
     sendRN4020(priClear.comm, priClear.len);
     delay(500);
     break;
  }
 }
 while(rn4020.available()){
  Serial.print((char)rn4020.read());
 }
}

void read(){
 while(rn4020.available()){
  Serial.print((char)rn4020.read());
 }
}

void sendRN4020(char *p,int l){
 for(int i=0;i&lt;l;i++){
  rn4020.write(p[i]);
  delay(20);
 }
 rn4020.write('\n');
}

 

流れとしては、以下になります。

⑴RN4020のデフォルトのBaud Rateが115200bpsなので、9600bpsに変える。(ソフトウェアシリアルを使うので動作安定対策)

⑵RN4020のモード選択端子を制御して、アクティブモードにする。

⑶Arduinoのシリアルモニタを開いて、打ちたいコマンドに対応した数字orアルファベットを入力。

コマンドは一部しか用意していません。

プライベートサービスの設定ができるようにコマンドを用意しているので、試してみてください。BLEの理解がちょっと深まると思います。(サービスに対して、キャラクたりスティックを登録する流れです)

 

以下、実際に操作してみた例(Arduinoのシリアルモニタ)です。

%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-10-17-0-01-56

 

スマホと接続すると、コネクトのLEDも光ります。

shareimage

 

iOSだと、LightBlueというアプリを使うと、簡単にBLEのアドバタイズ情報を見れます。

 

shareimage-2

 

BLEは通信時の消費電力がとても低いので、Arduinoで操作感を確かめたら、

なるべく低消費電力を活かせるような、ちゃんとした回路を組むとカッコいいい!

 

shareimage-3

このブレッドボード回路だと、BLEの通信していない時に18mAも食っちゃいます。

これだとボタン電池使った時、220mAh/18mA = 12hくらいで電池切れちゃいますね。

ただ、ずっと電源供給が担保されているところに使うのであれば、このシステムで十分だと思います。

Arduino使うと、RN4020の使いやすさがさらに上がる気がする。。。

コメントを残す

メールアドレスが公開されることはありません。