XBeeモジュールの使い方(カラー画像転送:802.15.4ファームウェア)


 前回はファームウェアが802.15.4で動作するモノクロ画像転送方法について解説しました。今回は、802.15.4ファームウェアでカラー画像をエンドデバイスXBeeからコーディネータXBeeに転送する方法について解説します。今回の解説では、以下の50×50ピクセルのカラー画像(ファイル名:Matisse.png)を例にコーディネータXBeeへの転送を試みます。

 画像を送信するルータXBeeのMicroPythonのサンプルコードを以下に示します。 MicroPython Terminalでエンターを押してCtrl+Fで1^^^のプロンプトにしてから、マウスの右クリックでCopyを選択して貼り付けます。その後、Ctrl+Dでコンパイルして、スタートで自動実行に同意する「Y」を押して、一旦このままにしておきます。File System Managerでコンパイルされた実行ファイルmain.mpyが生成されています。ここで、File System Managerを用いて/flashにMatisse.pngを書き込んでおきます。

import xbee
import os
import utime

COORD_ADDR = b'\x00\x13\xA2\x00\x41\xAE\x36\x69'
CHUNK_SIZE = 64

def send_file():
    png_files = [f for f in os.listdir("/flash") if f.endswith(".png")]
    if not png_files:
        print("No PNG file found in /flash!")
        return

    print("Select file to send:")
    for idx, fname in enumerate(png_files):
        print("{}: {}".format(idx, fname))

    try:
        sel = int(input("Enter number: ").strip())
        if sel < 0 or sel >= len(png_files):
            print("Invalid selection")
            return
    except Exception as e:
        print("Input error:", e)
        return

    filename = png_files[sel]
    file_path = "/flash/" + filename
    print("Sending file:", file_path)

    # 最初にファイル名を送信(特別チャンク)
    xbee.transmit(COORD_ADDR, b"__FILENAME__:" + filename.encode())
    utime.sleep(0.1)

    # ファイル送信
    with open(file_path, "rb") as f:
        while True:
            chunk = f.read(CHUNK_SIZE)
            if not chunk:
                break
            xbee.transmit(COORD_ADDR, chunk)
            utime.sleep(0.1)

    # 終了チャンク送信
    xbee.transmit(COORD_ADDR, b"__EOF__")
    print("Send complete")

send_file()

 画像を受信するコーディネータXBeeのMicroPythonのサンプルコードを以下に示します。 エンドデバイスXBeeの場合と同様にMicroPython Terminalでエンターを押してコンパイルし、Ctrl+Rであらかじめ実行しておきます。

from xbee import receive
import os
import time

RECEIVED_CHUNKS = []
FILE_PATH = None  # 最初はNoneにしておく

def receive_file_loop():
    global FILE_PATH
    while True:
        pkt = receive()
        if pkt:
            payload = pkt['payload']
            if len(payload) < 1:
                print("Invalid payload")
                continue

            if payload.startswith(b"__FILENAME__:"):
                # ファイル名を取得
                filename = payload[len(b"__FILENAME__:"):].decode()
                FILE_PATH = "/flash/" + filename
                print("Receiving file:", FILE_PATH)
                RECEIVED_CHUNKS.clear()  # 念のためクリア
                continue

            if payload == b"__EOF__": 
                print("EOF detected. Saving file.")
                save_file()
                continue

            RECEIVED_CHUNKS.append(payload)
            print("Received chunk. Total:", len(RECEIVED_CHUNKS))

def save_file():
    global FILE_PATH
    if FILE_PATH is None:
        print("No filename received! Cannot save file.")
        return
    with open(FILE_PATH, "wb") as f:
        for chunk in RECEIVED_CHUNKS:
            f.write(chunk)
    print("File save completed!:", FILE_PATH)
    RECEIVED_CHUNKS.clear()
    FILE_PATH = None  # 次のファイル受信に備えてリセット

receive_file_loop()

 コーディネータXBeeのコードが実行されていることを確認してから、エンドデバイスXBeeからCtrl+Rでコードを実行します。エンドデバイスXBeeのコードを実行すると、/flashの中にあるファイルが表示されます。Enter numberに送信するファイル番号を入れてエンターキーを押すと送信が開始されます。

この図はエンドデバイスXBeeの送信が完了した状態を示すMicroPython Terminalです。

 コーディネータXBeeのMicroPython Terminalにはチャンクが受信され、画像ファイルが保存されたメッセージが表示されます。

 さらに、コーディネータXBeeのFile System Managerを用いて/flashを確認してみると、Matisse.pngが保存されていることを確認できます。この画像をPC側の適当なディレクトリにダウンロードし、ファイルを開くと以下のように元画像と同じ画像であることを確認することができます。