Xbee（APIモード）でLEDコントローラーを作ろう！

##<font color="Red">注意</font>
この記事は、プログラミングの「いろは」の「い」も十分に理解していない学生が作った記事です。生暖かい目で見守ってくださるとうれしいです:relaxed:　間違いがあれば、どんどん指摘してください！！
##コントローラーを作ってみよう！
 手軽に開発ボード間の通信などを無線化できるモジュール、「<font color="Red">Xbee</font>」の簡単なコントローラーの作り方について紹介します。Xbeeを「クロスビー」と読むと、某有名な国産メーカーの車の方と認識されてしまうので、「エックスビー」と読みましょう。~~（どうでもいい）~~
 
今回は、透過モード（有線のシリアル通信を無線化するモード）ではなく、APIモード（Xbeeとマイコンをつなぐモード）でコントローラーを作っていきたいと思います。

## Xbeeって？
多分、この記事を見てくださっている方なら、ある程度のXbeeの知識があると思うので、詳しくは紹介しませんが、私自身も全く知らない中でコントローラーを作ろうとしていたので、一応紹介しておきます。

Xbeeとは「Digi international」が販売している通信モジュールのことで、通信規格は2.4GHz帯の「Zigbee」を使用しています。海外では長距離の「900MHz帯」仕様のものもあるそうです。（日本で販売されているXbeeモジュールは2.4GHz帯のみです）2.4GHzやったらBluetoothでよくね？って思う方もいるかもしれません。もちろんBluetoothでいいと思うのですが、Zigbeeにもメリットがあって、Zigbee はBluetoothと比べて消費電力が少ない、<font color="Red">低消費電力</font>なんです。（今回のコントローラーはあまり恩恵を得られていませんが）

また、今回使うXbee(S2C)には「Coordinator」と「Router」の2つのデバイスタイプが選択できて、今回は、CoordinatorのXbeeをマイコン側の受信として、RouterのXbeeをコントローラー側の送信として使用します。

##準備するもの
### ハード
* Xbee(S2C)：2個
* Xbeeピッチ変換基板：2個
（できれば[こっち](https://www.switch-science.com/catalog/1791/)を使ったほうがいいです）
* Arduino Nano：1個 ~~(たまたま持っていたので)~~
* 乾電池BOX(単3乾電池)：1個（コントローラー側の電力供給）
* ブレッドボード：2個
* 可変抵抗：1個
* タクトスイッチ：1個
* LED：1個
* ピンコード：20本くらい？

### 開発環境
* Windows10 home(64bit)
* X-CTU(ver6.5.4) (Xbeeのファームウェア書き込み用)
* Arduino IDE (Arduino用)

##実際に作ってみよう！
###ソフトウェアのダウンロード
まず、開発環境でも紹介した「X-CTU」と「Arduino IDE」をインストールしていきます。

[注]Arduino IDEは、Xbeeを使おうと思っている人はすでにインストールしていると思うので、今回は、IDEのインストール方法は割愛して、「X-CTU」の方のインストール方法を紹介します。

1. まずここの[サイト](https://www.digi.com/products/embedded-systems/digi-xbee/digi-xbee-tools/xctu)にいきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619784/45017353-f82b-89b3-0d9a-bb447414d674.png)


2. 「DOWNLOAD XCTU」をクリックして、自分のパソコン環境に合ったexeファイルをダウンロードします。今回は「XCTU v. 6.5.4 Windows x86/x64」をダウンロードしました。

3. ダウンロードが完了したら、ライセンスの同意などをしてインストール先を決めて、インストールをします。
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619784/4bcbf29d-b38b-a035-e2c7-cb5ff8bcff8d.png alt="属性" title="XCTU">

4. インストールが完了したら、ソフトを起動します。ここでファームウェアの書き込みをします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619784/7f44114d-11a9-a4b7-e0d0-91f775002553.png)

###ファームウェアの書き込み
1. Xbee本体に、ファームウェアの書き込みをしていきます。XbeeのUSBシリアル変換基板があればそのまま書き込みができますが、ピッチ変換基板のみの場合は、Arduinoを使用してファームウェアを書き込みます。まず、Arduino Nanoに空のプログラムを書き込みます。

2. 書き込みが終わったら、Xbeeの「VCC(1)」と「GND(10)」ピンを、Arduinoの「3.3V」と「GND」にそれぞれピンコードで接続します。また、Xbeeの「DOUT(2)」にArduinoの「D1」を「DIN(2)」に「D0」を接続することで、シリアル変換基板がなくても書き込みができます。<font color="Red">5VピンをXbeeのVCCにつながないように！</font>
![207710.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619784/8a0dab76-5407-a487-1abc-29baea1ee0f0.jpeg)

3. 次にX-CTUを開いて、「Discover devices」を選択して、接続したArduinoのCOMポートを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619784/d16829fb-1134-613d-d18b-cfbc969ad559.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619784/eb5d16e3-77ff-fe2c-ad20-a79e4ce14380.png)

4. Xbeeの初期設定では「Set port parameters」で検索範囲を絞っていきます。全てを選択して探すのもいいですが、結構時間がかかってしまうので、あらかじめ知っているパラメーター（デフォルトのボーレートは9600）は絞っておいた方がいいかもしれません。

5. 無事認識されると「1 device(s) found」とでてきます。このXbeeを「Coordinator」とします。

6. 次にファームウェアの設定をしていきます。まず、PAN(Personal Area Network)IDを決めます。これは、ネットワークの識別の時に使用されるIDのことです。これを親機（Coordinator）と子機（Router）で合わせていなと、通信ができなくなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619784/2018ed8e-c002-8177-f0c6-1c4d626160e5.png)

7. PAN IDを設定したら、次は「Coordinator Enable」と「API Enable」をEnable[1]にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619784/973ddf8f-b44b-d972-d3d2-8f4bcb56d9ec.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619784/9a8320e6-774f-2ff1-0fcc-4842452cde93.png)
最後に「Wtite」をクリックしてファームウェアの書き込みをします。

8. 次に、RouterのXbeeにファームウェアを書き込みます。CoordinatorのXbeeの配線を外して、Xbeeを付け替えます。付け替えられたら、3と同じようにXbeeを接続します。

9. 接続が上手くいったら、Coordinatorと同じようにPAN IDを設定します。API Enableは「Transparent mode」にしておいてください。

10. 次にXbeeのGPIOの入力設定をします。今回はスイッチ1個と可変抵抗1個なので、20番ピンをスイッチの入力に19番ピンを可変抵抗のアナログ入力に使います。ピンによってはアナログ入力が使えない場合があるので、データシートなどで確認しておいた方が無難です。設定方法は図の通りです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619784/f79dcc93-fc2a-0eab-2c5b-c8039d3deb14.png)

11. 最後にスイッチ用の内部プルアップの有効とサンプリングレートの設定をします。Xbeeには、Arduinoと同じように内部プルアップ機能があります。内部プルアップの設定は、「PR」に「F7」と入力して書き込みます。また、サンプリングレートは、50(ms)~65(s)までの範囲で設定できます。横の計算機マークで、パラメーターの計算をしてくれます。今回は50(ms)の周期でサンプリングをします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619784/a9adba4b-ab30-effd-1b0a-b7c4f37fc4c8.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619784/7d982789-da1e-2989-894d-4efe15dcac95.png)

試しに通信ができているかどうかの確認をしてみましょう！CoordinatorのXbeeを接続し直して、X-CTUを「Consoles working mode」にします。「Open」をクリックして、以下のような反応が返ってきたらファームウェアの設定は成功しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619784/09816522-2dc0-6811-793c-a7140ab0ed47.png)
ここで注意として、Scanを実行したままコンソールの確認を行うと「Explicit RX Indicator」と表示されると思います。「IO Data Sample RX Indicator」を確認する場合は、一度、RouterのXbeeとX-CTUの接続を切るとうまくいきます。

あとたまに、Coordinatorの「AO」のパラメーターが、「Explicit」に変更されてしまうので「Native」に直しておいてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619784/5c010a13-9551-9a45-0f57-e9fd65e4c577.png)


###実際に動かしてみる
1. ファームウェアの設定を終えたところで、次は、実際にコントローラーを作ってみます。まず、画像のように受信側の回路をブレットボード上に作ります。
![Untitled Sketch_ブレッドボード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619784/fb08c13d-307f-fede-44ac-c4fd1c588f86.png)


2. 次にコントローラー側の回路を作っていきます。ここで注意したいのが、Xbee(S2C)の<font color="Red">アナログ最大入力電圧は1.2V</font>です。3.3Vを入力してしまうと、壊れることはありませんが、値の幅が非常に狭くなってしまいます。抵抗器で簡単に分圧ができるので、今回は電源電圧3.3Vを分圧(330Ωと220Ω)して、大体1.2Vになるようにしました。
![Untitled Sketch 3_ブレッドボード2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619784/bba5f318-642b-856c-373e-790a2d70f0ef.png)

3. 回路が完成したら、あとはArduinoに以下のコードを書き込むだけです。コード自体は非常に単純で、欲しいデータを抜き出して、そのままLEDのPWMに変換しているだけです。スイッチを押すとLEDが点灯し、半固定抵抗で明るさを調節できます。

```
#define LED 11

byte byte_discarded;
volatile int IO_State, button; //デジタル入力（ボタン）
volatile int analog_value1, analog_value2, total_value;//アナログ入力（半固定抵抗）

void setup() {
  Serial.begin(9600);
  pinMode(LED, OUTPUT);
}

void loop() {
  if (Serial.available() >= 21) {
    if (Serial.read() == 0x7E) {
      for (int i = 0; i < 19; i++) {
        byte_discarded = Serial.read();
      }
      IO_State = Serial.read();//IOピンの状態
      delay(5);
      analog_value1 = Serial.read();
      analog_value2 = Serial.read();
      total_value = (analog_value2 + (analog_value1 * 256)) / 4;//アナログ入力をLEDのPWMに変換
      button = bitRead(IO_State, 0);

      Serial.print("Connection");
      Serial.print(" ");
      Serial.print("button_State:");
      Serial.print(button);
      Serial.print(" ");
      Serial.print("Analog_State:");
      Serial.print(total_value);
      Serial.print(" ");
      if (button == 0) {
        Serial.println("Push!! OK");
        analogWrite(LED, total_value);
      } else {
        Serial.println("No Pushed");
        digitalWrite(LED, LOW);
      }
    }
  }
}
```
4.　最後にシリアルモニタで、通信ができているか確認してみてください。ちゃんと通信ができていれば、図のようにシリアルモニタに文字が表示されるはずです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619784/2bdcca53-5ae1-401b-9e25-d10a7df969c8.png)



##最後に
拙い文章でしたが、最後までご覧いただきありがとうございます。これからも趣味程度に色々作って、ある程度まとまったら、また記事にしてあげたいと思います。最後に、今回の電子工作でお世話になったサイトを載せて終わります。
###参考文献リスト
* [ＸＢｅｅ(無線通信)の実験パート４](http://zattouka.net/GarageHouse/micon/XBee/XBee4.htm)
* [Chapter 4. Ins and Outs](https://www.oreilly.com/library/view/building-wireless-sensor/780596807757/ch04.html)
* [XBee S2–Digital sampling with API frame data](https://alselectro.wordpress.com/2014/09/07/xbee-s2digital-sampling-with-api-frame-data/)
* [ZigBee入門](http://www.skyley.com/wiki/index.php?ZigBee%E5%85%A5%E9%96%80)