• Skip to main content
  • Skip to primary sidebar
  • Skip to footer
  • HOME
  • Arduino
    • Arduino初心者編
    • Arduino基礎編
    • Arduino応用編
    • Arduino実践編
  • Raspberry Pi
  • microbit
  • XBee
  • Scratch
  • Contact Us
  • Privacy Policy

STEMSHIP

ものづくりを通して、科学を学ぼう!

現在の場所:ホーム / XBee / Arduinoベースのセンサノード:スケッチ(プログラム)の作製

Arduinoベースのセンサノード:スケッチ(プログラム)の作製

2021年10月4日 by STEMSHIP コメントを書く

これまで使用してきたセンサと同様、XBeeモジュールをArduinoに接続して使用するためのライブラリをインストールします。ライブラリを使用すると、自分で1からXBeeモジュールとの通信をプログラムするよりも簡単に通信を行えます。

Arduino IDEを開き、ライブラリマネージャでXBeeライブラリをインストールします。メニューバー上の、「スケッチ」>「ライブラリをインクルード」>「ライブラリを管理」をクリックするとライブラリマネージャが起動します。検索欄に「XBee」と入力し、「by Andrew Rapp」となっているライブラリを見つけてインストールします。

図1 XBeeライブラリのインストール

ライブラリをインストールしたらArduino IDEを再起動し、XBeeモジュールからデータを読み込むスケッチを書いていきます。

このライブラリには、XBeeモジュールとの間でデータを送受信するための一般的なXBeeデータパケットのクラスが用意されています。ここでは、IOサンプルクラスを使用します。

まず、データパケットを読み取るために必要な設定を行います。XBeeとソフトウェア・シリアルのライブラリをインクルードします。

#include <XBee.h>
#include <SoftwareSerial.h>

続いて、XBeeモジュールとの通信に使用するピンを定義します。

先述の通り、D0ピン・D1ピンはPCとの接続にも使用するピンです。動作確認用の出力デバイスとしてシリアルモニタを使用したいので、別のピンを割り当てます。

ここでは、受信(Rx)にD2ピン、送信(Tx)にD3ピンを使用することにしました。ピンを定義したら、ソフトウェア・シリアル・ライブラリを初期化します。D2ピンとD3ピンを使って、XBeeモジュールと通信を行うことになります。

uint8_t recv = 2;
uint8_t trans = 3;
SoftwareSerial soft_serial(recv,trans);

次に、XBeeライブラリとヘルパークラスのインスタンスを生成します。

XBee xbee = XBee();
ZBRxIoSampleResponse ioSample = ZBRxIoSampleResponse();

以上で、スケッチを作成する準備ができました。

続いて、Arduinoが起動した際に一度だけ実行する、「setup」メソッドを作ります。

ソフトウェア・シリアル・ライブラリを起動し、XBeeライブラリに渡してXBeeモジュールとの通信に使用できるようにします。

また、(ソフトウェア・シリアルではない)通常のシリアルクラスを初期化して、print()文を使用して受信したデータをPC上で表示できるようにします。

void setup(){ 
  Serial.begin(9600);
  while(!Serial);
  soft_serial.begin(115200);
  xbee.setSerial(soft_serial);
}

3行目のwhileループは、Arduino Leonardoでスケッチを実行した際にXBeeモジュールが動作しなくなる場合があるため入れてあります。

今度は、受信したパケットからデータを読み取るためのメソッドをスケッチ上で作成してみましょう。

XBeeモジュールからパケットを読み取る方法は後ほど紹介します。まず、データパケットのソースアドレスを取得する方法を見てみましょう。

void get_address(ZBRxIoSampleResponse *ioSample){
  Serial.print("Received I/O Sample from: ");
  Serial.print(ioSample->getRemoteAddress64().getMsb(), HEX);  
  Serial.print(ioSample->getRemoteAddress64().getLsb(), HEX);  
  Serial.println("");  
}

ioSampleクラスのインスタンスを使用して、getRemoteAddress64()メソッドとgetMsb()メソッドを呼び出しています。これはRemoteAddress64というサブクラスとそのメソッドであるgetMsb()を呼び出しています。これらにより、64ビットアドレスの上位32ビットを取得できます。

同様に、getRemoteAddress64()メソッドとgetLsb()メソッドを呼び出すことで下位32ビットについても同様に処理を行います。

これらの読みだした値を16進数表記でPC(Arduino IDEのシリアルモニタ)上に表示します。複数のXBeeノードからデータを読み取る場合には、アドレスに応じで「bed room」や「living room」、「kitchen」など名前を付けると便利でしょう。詳しく紹介しませんが、各自工夫してみてください。

次に、データのペイロードを読み取ります。XBeeコーディネーターはXBeeセンサノードが作成した温度データを受信し、XBeeモジュールでセンサを読み取る:センサノードの設定と測定の例と同様に、XBeeモジュールのAD変換値からセンサが出力したミリボルト単位の電圧、読み取った温度に変換します。まず摂氏単位の温度に変換し、さらに華氏単位にも変換します。

void get_temperature(ZBRxIoSampleResponse *ioSample){
  float adc_data = ioSample-> getAnalog(3);
  Serial.print("Temperature : ");
  float temperatureC = ((adc_data * 1250.0 / 1023.0) - 500.0) / 10.0;
  Serial.print(temperatureC);
  Serial.print("C, ");
  float temperatureF = ((temperatureC * 9.0)/5.0) + 32.0;
  Serial.print(temperatureF);
  Serial.println("F");
}

最後に、データパケットから電源電圧を読み取ります。

残念ながら、XBeeライブラリにはIOサンプルパケットから直接電源電圧を取得できるようになっていません。そこで、ライブラリが保存したIOサンプルパケットの「生のデータ」からデータを取り出すサブクラスを活用します。

電源電圧はAD変換で読み取ったデータの後、チェックサムの手前で送信されており、この例では受信したデータの18バイト目と19バイト目に保存されています。

温度データと同様に、XBeeモジュールでセンサを読み取る:センサノードの設定と測定の例と同様に、読み取った値をボルト単位の電源電圧に変換します。

void get_supply_voltage(){
  Serial.print("Supply Voltage : ");
  int ref = xbee.getResponse().getFrameData()[17] << 8;
  ref += xbee.getResponse().getFrameData()[18];
  float volts = (float(ref)*float(1200.0/1024.0))/1000.0;
  Serial.print(volts);
  Serial.println("volts.");
}

先ほど、電源電圧として読み取るべきデータは「18バイト目と19バイト目」としました。

Arduino IDEで使用している言語の仕様で、データは「配列」というデータのまとまりとして保存されていて、先頭を「0番目」としてカウントするため、結果「17」「18」という数字が出てきます。また、2つの8ビットデータを結合して1つの16ビットデータとするために、上位のデータを8回左にビットシフトしています。

これらのメソッドを実装したら、XBeeモジュールからデータを読み取るメソッドをloop()メソッドに配置し、作成したメソッドを呼び出してデータを解読し、シリアルモニタに出力します。

void loop(){
  xbee.readPacket();
  if(xbee.getResponse().isAvailable()){
    if(xbee.getResponse().getApiId() == ZB_IO_SAMPLE_RESPONSE){
      xbee.getResponse().getZBRxIoSampleResponse(ioSample);
      get_address(&ioSample);
      get_temperature(&ioSample);
      get_supply_voltage();
    }else{
      Serial.print("Expected I/O Sample, but got ");
      Serial.print(xbee.getResponse().getApiId(),HEX);
    }
  }else if(xbee.getResponse().isError()){
    Serial.print("Packet Read Error. Error Code : ");
    Serial.println(xbee.getResponse().getErrorCode());
  }
}

loop()メソッドは繰り返し実行されるので、XBeeクラスのメソッドを使ってパケットを読み込み、そのパケットがIOサンプルパケットかどうかを判断します。

IOサンプルパケットであればパケットから各データを読み込みます。そうでなかった場合にArduinoが停止してしまわないよう、簡単なエラー処理を追加しました。

受信したパケットが利用可能であれば読み込みを行います。そのパケットが正しいフレームタイプ(ここではIOサンプルパケット:ZB_IO_SAMPLE_RESPONSE)であれば、ここまでで作成したメソッドにデータを渡し、シリアルモニタ上にデータを表示します。

パケットの読み取りにエラーがあった場合には、エラーの内容をシリアルモニタに表示します。

これで必要なメソッドが揃いましたので、Arduinoで実行するために1つのスケッチにまとめます。完成したスケッチを以下に示します。

#include <XBee.h>
#include <SoftwareSerial.h>

//XBeeシールド用の設定
uint8_t recv = 2;
uint8_t trans = 3;
SoftwareSerial soft_serial(recv,trans);

//XBeeライブラリのインスタンスを生成
XBee xbee = XBee();
//IOサンプルクラスのインスタンス化
ZBRxIoSampleResponse ioSample = ZBRxIoSampleResponse();

void setup(){ 
  Serial.begin(9600);
  while(!Serial);  //Arduino Leonardoのフリーズ対策
  soft_serial.begin(115200);
  xbee.setSerial(soft_serial);
}

//XBeeモジュールのアドレスを表示する
void get_address(ZBRxIoSampleResponse *ioSample){
  Serial.print("Received I/O Sample from: ");
  Serial.print(ioSample->getRemoteAddress64().getMsb(), HEX);  
  Serial.print(ioSample->getRemoteAddress64().getLsb(), HEX);  
  Serial.println("");  
}

//温度を取得して表示する
void get_temperature(ZBRxIoSampleResponse *ioSample){
  float adc_data = ioSample-> getAnalog(3);
  Serial.print("Temperature : ");
  float temperatureC = ((adc_data * 1250.0 / 1023.0) - 500.0) / 10.0;
  Serial.print(temperatureC);
  Serial.print("C, ");
  float temperatureF = ((temperatureC * 9.0)/5.0) + 32.0;
  Serial.print(temperatureF);
  Serial.println("F");
}

//電源電圧を取得して表示する
void get_supply_voltage(){
  Serial.print("Supply Voltage : ");
  int ref = xbee.getResponse().getFrameData()[19] << 8;
  ref += xbee.getResponse().getFrameData()[20];
  float volts = (float(ref)*float(1200.0/1024.0))/1000.0;
  Serial.print(volts);
  Serial.println("volts.");
}

void loop(){
  xbee.readPacket();  //パケット読み込み
  if(xbee.getResponse().isAvailable()){
    //パケットを受信していた
    if(xbee.getResponse().getApiId() == ZB_IO_SAMPLE_RESPONSE){
      //パケット取得
      xbee.getResponse().getZBRxIoSampleResponse(ioSample);

      //データの読み込みと表示
      get_address(&ioSample);
      get_temperature(&ioSample);
      get_supply_voltage();
    }else{
      Serial.print("Expected I/O Sample, but got ");
      Serial.print(xbee.getResponse().getApiId(),HEX);
    }
  }else if(xbee.getResponse().isError()){
    Serial.print("Packet Read Error. Error Code : ");
    Serial.println(xbee.getResponse().getErrorCode());
  }
}

動作テスト

スケッチが書き込めたら動作テストを行います。

まず、Arduino(XBeeコーディネーター側)を起動し、続いてセンサノード(XBeeルーター側)を起動します。

Arduino IDEのシリアルモニタを開きます。XBeeセンサノードとコーディネーターとなるXBeeモジュールとでネットワークが繋がり通信が始まりしばらくすると、シリアルモニタにデータが表示されます。同時に、XBeeブレイクアウトボード上の通信確認用のLEDが点滅する様子も確認できるでしょう。

■シリアルモニタ出力の例

Received I/O Sample from: 13A20041C199CA
Temperature : 15.78C, 60.40F
Supply Voltage : 3.85volts.
Received I/O Sample from: 13A20041C199CA
Temperature : 15.65C, 60.18F
Supply Voltage : 3.85volts.
Received I/O Sample from: 13A20041C199CA
Temperature : 15.78C, 60.40F
Supply Voltage : 3.85volts.
Received I/O Sample from: 13A20041C199CA
Temperature : 15.78C, 60.40F
Supply Voltage : 3.85volts.
Received I/O Sample from: 13A20041C199CA
Temperature : 16.02C, 60.84F
Supply Voltage : 3.85volts.
Received I/O Sample from: 13A20041C199CA
Temperature : 15.90C, 60.62F
Supply Voltage : 3.85volts.
Received I/O Sample from: 13A20041C199CA
Temperature : 15.78C, 60.40F
Supply Voltage : 3.85volts.

うまくいったでしょうか?

これで、センサノードと、Arduinoを活用したセンサデータアグリゲータを構築する最初の一歩が踏み出せました。

シリアルモニタに出力が表示されない場合は、ArduinoとXBeeモジュールが正しく接続されているか(すべてのXBeeシールドがD2ピン・D3ピンを使用しているとは限りません)、それぞれのXBeeモジュールのファームウェアが間違っていないか確認しましょう。XBeeモジュールでセンサを読み取る:センサノードの設定と測定に一度立ち返り、センサノードが正常に動作するか確認すると良いでしょう。

また、Arduinoとセンサノードの両方とも一度電源を切り、先にArduino、続いて10秒ほどたってからセンサノードの電源を入れてみてください。時折、ネットワークの構築がうまくいかない場合があり、この手順で電源を入れなおすと構築をはじめからやり直すことができます。

さらにステップアップ

センサノードを2つ、3つと増やし、Arduinoのスケッチを工夫して各センサノードがどこに置いてあるかを送信してみましょう。

例えば、「kitchen」「living room」など、センサノードに名前を付け、Arduinoスケッチからシリアルモニタに表示する際にセンサデータとセンサの名前を表示すると実現できます。


使用したパーツのリスト

最後に、このセクションで紹介したチュートリアルを実行するために必要な電子部品を表1にリストアップします。

項目製品例参考価格必要数
ブレッドボードhttps://www.switch-science.com/catalog/313/¥275-1
ジャンプワイヤーhttps://www.switch-science.com/catalog/620/¥440-1
DHT22 もしくはDHT11https://www.sengoku.co.jp/¥1,782-1
抵抗器4.7kΩhttps://www.switch-science.com/catalog/1084/¥1,073-1*
温度センサTMP36https://www.marutsu.co.jp/pc/i/171271/¥160-1
Arduino XBeeシールドhttps://www.switch-science.com/catalog/1972/¥2,203-1
XBee-ZBシリーズ2/2.5/3https://www.switch-science.com/catalog/5311/¥2,546-2
XBee Explorer ドングルhttps://www.switch-science.com/catalog/1790/¥3,243-1 **
XBee Explorer USBhttps://www.switch-science.com/catalog/1791/¥3,243-1 **
Arduino UNOhttps://www.switch-science.com/catalog/789/¥3,300-1
表1 必要な電子パーツ

* 必要なのは4.7kΩ1本だけですが、1セット持っておくと何かと役に立ちます。他サイトやショップでは同じ値の抵抗器100本や、1本単位でも販売されています。

** いずれか1つ使用します。

Filed Under: XBee

Reader Interactions

コメントを残す コメントをキャンセル

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください。

最初のサイドバー

CONTACT US

  • Facebook
  • Twitter
  • Youtube

More to See

Arduinoベースのセンサノード:XBeeデータ収集ノードの製作

2021年9月27日 By STEMSHIP

Arduinoベースのセンサノード:Arduinoを使った温度センサの作製

2021年9月21日 By STEMSHIP

XBeeモジュールとBMP280センサを使用してデータ収集する

2021年5月31日 By STEMSHIP

XBeeモジュールでMicroPythonを使ってセンサを読み取る

2021年5月24日 By STEMSHIP

XBeeモジュールでセンサを読み取る:センサノードの設定と測定

2021年5月17日 By STEMSHIP

カテゴリー

  • Arduino (44)
    • Arduino初心者編 (15)
    • Arduino基礎編 (11)
    • Arduino実践編 (4)
    • Arduino応用編 (11)
    • Arduino番外編 (3)
  • MakeyMakey (1)
  • microbit (11)
  • Raspberry Pi (13)
  • Scratch (6)
  • STEM教育 (5)
  • XBee (15)
  • ものづくり教育 (2)
  • 子供の教育 (2)
  • 科学 (6)
  • 算数 (5)

Tags

BLE DCモータ EEPROM ELEGOO ESP32 ESP8266 IoT LCD LED makeymakey MQTT Node-RED scratch STEM教育 WiFi XBee アニメーション オンラインゲーム カメラ クローン ゲーム コスチュームの変更 サーボモータ ステッピングモータ ステートマシン スピーカ タイマー ピンポン ブロック定義 ペン ライントレース ラジコン リスト 分数 割り込み 実験 工作 幼児 当たり判定 温度センサ 無線通信 物理 角度制御 重力 音楽

Footer

最近の投稿

  • Arduinoベースのセンサノード:スケッチ(プログラム)の作製
  • Arduinoベースのセンサノード:XBeeデータ収集ノードの製作
  • Arduinoベースのセンサノード:Arduinoを使った温度センサの作製
  • XBeeモジュールとBMP280センサを使用してデータ収集する
  • XBeeモジュールでMicroPythonを使ってセンサを読み取る

タグ

BLE DCモータ EEPROM ELEGOO ESP32 ESP8266 IoT LCD LED makeymakey MQTT Node-RED scratch STEM教育 WiFi XBee アニメーション オンラインゲーム カメラ クローン ゲーム コスチュームの変更 サーボモータ ステッピングモータ ステートマシン スピーカ タイマー ピンポン ブロック定義 ペン ライントレース ラジコン リスト 分数 割り込み 実験 工作 幼児 当たり判定 温度センサ 無線通信 物理 角度制御 重力 音楽

Search

2025年5月
月 火 水 木 金 土 日
 1234
567891011
12131415161718
19202122232425
262728293031  
« 10月    

Copyright © 2025 · STEMSHIP.COM