
前回はXBee3には12ビットADCを用いてMicroPython Terminalから3軸加速度センサKXR94-2050モジュールからX,Y,Z軸方向の加速度データを読み出し、ローカルXBeeで受信する方法について解説しました。その際に、ローカルXBeeで受信したフレームのFrames LogのTimeの欄を確認するとリモートXBeeで100msのスリープを設定したにも関わらず約128ms間隔でデータを受信していることが確認できました。今回はこの時間ズレについて解説します。
ローカルXBeeのXCTUのConsoleタブやFramesタブで表示されるTimeはXCTUアプリケーション側で受信したタイミングを記録したものであり、リモートXBeeが送信した時間ではないということです。
リモートXBeeとローカルXBeeの送受信のタイミングを調べるために以下のリモートXBeeのMicroPythonで送信周期を調べるコード作成しました。 MicroPython Terminalのダイアログを開き、以下のコードを張り付けます。4行目のCOORDINATOR_64BIT_ADDRはご自分のローカルXBeeのシリアルナンバーに変更します。
import xbee
import utime
from machine import Pin, ADC
COORDINATOR_64BIT_ADDR = b'\x00\x13\xA2\x00\x41\xAE\x36\x69'
# Initialize ADC for DIO0, DIO1, DIO2
adc_pin0 = Pin("D0", Pin.IN, Pin.PULL_UP)
adcx = ADC(adc_pin0)
adc_pin1 = Pin("D1", Pin.IN, Pin.PULL_UP)
adcy = ADC(adc_pin1)
adc_pin2 = Pin("D2", Pin.IN, Pin.PULL_UP)
adcz = ADC(adc_pin2)
print("Starting data transmission to coordinator...")
def precise_delay_ms(delay_ms):
start = utime.ticks_ms()
while utime.ticks_diff(utime.ticks_ms(), start) < delay_ms:
pass
while True:
start_time = utime.ticks_ms()
voltage_mv = xbee.atcmd('%V')
supply_voltage_v = voltage_mv / 1000.0
rssi_val = xbee.atcmd("DB")
rssi_dbm = -rssi_val
raw_adcx_value = adcx.read()
raw_adcy_value = adcy.read()
raw_adcz_value = adcz.read()
adcx_voltage = (raw_adcx_value / 4095.0) * supply_voltage_v
adcy_voltage = (raw_adcy_value / 4095.0) * supply_voltage_v
adcz_voltage = (raw_adcz_value / 4095.0) * supply_voltage_v
adcx_voltage = adcx_voltage - supply_voltage_v / 2
adcy_voltage = adcy_voltage - supply_voltage_v / 2
adcz_voltage = adcz_voltage - supply_voltage_v / 2
accelx = adcx_voltage / 0.66
accely = adcy_voltage / 0.66
accelz = adcz_voltage / 0.66
data_payload = "Vref: {:.3f}V, RSSI: {:d}dBm, Accel_x: {:.3f}g, Accel_y: {:.3f}g, Accel_z: {:.3f}g".format(
supply_voltage_v, rssi_dbm, accelx, accely, accelz
)
print("\n--- Sending Data ---")
print("Payload: {}".format(data_payload))
try:
xbee.transmit(COORDINATOR_64BIT_ADDR, data_payload.encode('utf8'))
print("Data sent successfully.")
except Exception as e:
print("Error sending data: {}".format(e))
precise_delay_ms(100) # ディレイ
end_time = utime.ticks_ms()
loop_time = utime.ticks_diff(end_time, start_time)
print("Loop time: {} ms".format(loop_time))
リモートXBeeのMicroPython Terminalで上記のコードを実行し、Ctrl+Cで実行を停止しました。上記コードのディレイは100msを設定していましたが、約134ms周期で送信されていることが分かります。

これはローカルXBeeのコンソール画面です。

上記のFrames Logの中のTime欄の時間から各フレームの時間をms単位で読み取った一部を以下に示します。約128ms間隔で周期的に受信していることが分かりますが、時間間隔が190msの場合が存在しています。
128, 127, 128, 190, 128, 128, 127, 128, 128, 127, 128, 191, 131, 128, 128, 128, 128, 128, 128, 128, 129, 191, 129, 128, 127, 128, 129, 128,
時間間隔190msは128msに比べ約60ms遅延しております。この原因は通信レイヤの遅延によるものと思われます。Zigbeeでは、CSMA/CA(チャネル利用可否確認)やACK待ち時間・リトライ及び通信混雑や干渉が通信に時間を要する要因です。
上記コードのディレイを70msに設定した場合のリモートXBeeのMicroPython Terminalのダイアログを示します。ループタイムが約100msになっていることが確認できます。
