Skip to main content

XIAO nRF54L15の消費電力例 (PlatformIO)

以下のサンプルコードはPlatformIO用に設計されていますが、nRF Connect SDKとも互換性があります。

tip

VS Codeベースで、nRF Connect SDKで以下のケースを使用したい場合は、提供されている接続を参照し、app.overlayファイルを追加してprj.confの内容を変更してください

XIAO nRF54L15 オーバーレイファイルの追加とconfファイルの変更

Bluetooth接続

このセクションでは、デバイスがBluetooth Low Energy (BLE) ペリフェラルとしてアクティブにアドバタイジングしている間の消費電力特性について詳しく説明します。デバイスはカスタムBLEサービスを実装し、他のセントラルデバイスが接続して相互作用できるようにします。

以下のグラフは、デバイスが継続的にアドバタイジングしている際の典型的な消費電力プロファイルを示しています:

XIAO nRF54L15 BLE Advertising Power Consumption

BLEアドバタイジング中のデバイス消費電力

グラフに示されているように、デバイスは各アドバタイジングイベントに対応する周期的な電流ピークを示し、その後に低い電流消費期間が続きます。アドバタイジング中の平均消費電力は、システムオフモードよりも高く、ブロードキャストに必要なアクティブな無線操作を反映しています。


BLEアドバタイジングコード例


以下は、BLEアドバタイジング中の消費電力をテストするために使用されたコードです:

#include <stdio.h>

#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/hci.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/uuid.h>
#include <zephyr/bluetooth/gatt.h>

// Custom 128-bit UUID for the ONOFF Service
#define BT_UUID_ONOFF_VAL BT_UUID_128_ENCODE(0x8e7f1a23, 0x4b2c, 0x11ee, 0xbe56, 0x0242ac120002)
#define BT_UUID_ONOFF BT_UUID_DECLARE_128(BT_UUID_ONOFF_VAL)

// Custom 128-bit UUID for the ONOFF Action Characteristic (Write)
#define BT_UUID_ONOFF_ACTION_VAL \
BT_UUID_128_ENCODE(0x8e7f1a24, 0x4b2c, 0x11ee, 0xbe56, 0x0242ac120002)
#define BT_UUID_ONOFF_ACTION BT_UUID_DECLARE_128(BT_UUID_ONOFF_ACTION_VAL)

// Custom 128-bit UUID for the ONOFF Read Characteristic (Read)
#define BT_UUID_ONOFF_READ_VAL \
BT_UUID_128_ENCODE(0x8e7f1a25, 0x4b2c, 0x11ee, 0xbe56, 0x0242ac120003)
#define BT_UUID_ONOFF_READ BT_UUID_DECLARE_128(BT_UUID_ONOFF_READ_VAL)

// Static flag to hold the on/off state, initialized to 0 (off)
static uint8_t onoff_flag = 0;

// Advertising data: flags and complete device name
static const struct bt_data ad[] = {
BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), // General Discoverable, No BR/EDR
BT_DATA(BT_DATA_NAME_COMPLETE, CONFIG_BT_DEVICE_NAME, sizeof(CONFIG_BT_DEVICE_NAME) - 1), // Device Name
};

// Scan response data: include the 128-bit UUID of our custom service
static const struct bt_data sd[] = {
BT_DATA_BYTES(BT_DATA_UUID128_ALL, BT_UUID_ONOFF_VAL), // Service UUID
};

/**
* @brief GATT read callback for the ONOFF Read characteristic.
*
* This function is called when a connected central device attempts to read
* the ONOFF Read characteristic. It returns the current value of onoff_flag.
*
* @param conn Pointer to the connection object.
* @param attr Pointer to the GATT attribute being read.
* @param buf Buffer to store the read value.
* @param len Maximum length of the buffer.
* @param offset Offset from which to read the attribute value.
* @return Number of bytes read, or a negative error code.
*/
static ssize_t read_onoff_val(struct bt_conn *conn, const struct bt_gatt_attr *attr,
void *buf, uint16_t len, uint16_t offset)
{
// The user_data field of the attribute points to onoff_flag
const uint8_t *value = attr->user_data;
// Perform the GATT attribute read operation
return bt_gatt_attr_read(conn, attr, buf, len, offset, value, sizeof(*value));
}

/**
* @brief GATT write callback for the ONOFF Action characteristic.
*
* This function is called when a connected central device attempts to write
* to the ONOFF Action characteristic. It updates the onoff_flag based on
* the received value.
*
* @param conn Pointer to the connection object.
* @param attr Pointer to the GATT attribute being written.
* @param buf Buffer containing the value to be written.
* @param len Length of the value in the buffer.
* @param offset Offset at which to write the attribute value.
* @param flags Flags for the write operation.
* @return Number of bytes written, or a negative error code.
*/
static ssize_t write_onoff_val(struct bt_conn *conn, const struct bt_gatt_attr *attr,
const void *buf, uint16_t len, uint16_t offset, uint8_t flags)
{
uint8_t val;

// Ensure the length of the written data is 1 byte
if (len != 1U) {
return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
}

// Ensure the write operation starts from offset 0
if (offset != 0) {
return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
}

// Get the value from the buffer
val = *((uint8_t *)buf);

// Update onoff_flag based on the received value
if (val == 0x00U) {
printf("Write: 0\n");
onoff_flag = 0; // Set to off
} else if (val == 0x01U) {
printf("Write: 1\n");
onoff_flag = 1; // Set to on
} else {
// Return error if value is not 0 or 1
return BT_GATT_ERR(BT_ATT_ERR_VALUE_NOT_ALLOWED);
}

return len; // Return number of bytes successfully written
}

// Define the custom GATT service and its characteristics
BT_GATT_SERVICE_DEFINE(lbs_svc,
BT_GATT_PRIMARY_SERVICE(BT_UUID_ONOFF), // Primary Service: ONOFF Service
BT_GATT_CHARACTERISTIC(BT_UUID_ONOFF_ACTION, BT_GATT_CHRC_WRITE, // Characteristic: ONOFF Action (Write)
BT_GATT_PERM_WRITE, NULL, write_onoff_val, NULL), // Permissions, callbacks
BT_GATT_CHARACTERISTIC(BT_UUID_ONOFF_READ, BT_GATT_CHRC_READ, // Characteristic: ONOFF Read (Read)
BT_GATT_PERM_READ, read_onoff_val, NULL, &onoff_flag), // Permissions, callbacks, user_data (onoff_flag)
);

/**
* @brief Callback function for successful Bluetooth connection.
*
* @param conn Pointer to the connection object.
* @param err Error code (0 if successful).
*/
static void connected(struct bt_conn *conn, uint8_t err)
{
if (err != 0U) {
printf("Connection failed (%02x, %s)\n", err, bt_hci_err_to_str(err));
return;
}

printf("Connected\n");
}

/**
* @brief Callback function for Bluetooth disconnection.
*
* @param conn Pointer to the connection object.
* @param reason Reason for disconnection.
*/
static void disconnected(struct bt_conn *conn, uint8_t reason)
{
printf("Disconnected (%02x, %s)\n", reason, bt_hci_err_to_str(reason));
}

// Define connection callbacks
BT_CONN_CB_DEFINE(conn_callbacks) = {
.connected = connected,
.disconnected = disconnected,
};

/**
* @brief Main function of the application.
*
* Initializes the Bluetooth stack, starts advertising, and enters the main loop.
* @return 0 on success, negative error code on failure.
*/
int main(void)
{
int err;

// Enable the Bluetooth stack
err = bt_enable(NULL);
if (err < 0) {
printf("Bluetooth enable failed (err %d)", err);
return err;
}

// Start BLE advertising
err = bt_le_adv_start(BT_LE_ADV_CONN_FAST_1, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
if (err < 0) {
printf("Advertising failed to start (err %d)", err);
return err;
}

printf("Bluetooth enabled");
return 0;
}

超低消費電力状態

デバイスの極めて低い消費電力を実現するため、システムオフモードでの消費電力テストを実施しました。システムオフモードは、Zephyr OSが提供するディープスリープモードで、ほとんどのペリフェラルとCPUがオフになり、必要最小限のウェイクアップソース(GPIOインタラプトなど)のみを保持して消費電力を最小化します。

以下のグラフは、デバイスがシステムオフモードに入った後の典型的な消費電力カーブを示しています:

XIAO nRF54L15 Ultra-low Power Consumption in System Off Mode

システムオフモードでのデバイス消費電力

グラフに示されているように、System Offモードに入った後、消費電力は大幅に削減され、マイクロアンペアレベルのみを維持し、バッテリー寿命を大幅に延長します。sw0ボタンが押されると、デバイスはSystem Offモードから復帰し、再起動します。


消費電力コード例


以下は、上記で説明したSystem Offモードでの消費電力をテストするために使用されるコードです:

/*
* Copyright (c) 2019 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <inttypes.h>
#include <stdio.h>

#include <zephyr/device.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/hwinfo.h>
#include <zephyr/drivers/comparator.h>
#include <zephyr/kernel.h>
#include <zephyr/pm/device.h>
#include <zephyr/sys/poweroff.h>
#include <zephyr/sys/util.h>

static const struct gpio_dt_spec sw0 = GPIO_DT_SPEC_GET(DT_ALIAS(sw0), gpios);

void print_reset_cause(void)
{
uint32_t reset_cause;

hwinfo_get_reset_cause(&reset_cause);
if (reset_cause & RESET_DEBUG) {
printf("Reset by debugger.\n");
} else if (reset_cause & RESET_CLOCK) {
printf("Wakeup from System OFF by GRTC.\n");
} else {
printf("Other wake up cause 0x%08X.\n", reset_cause);
}
}

int main(void)
{
int rc;
const struct device *const cons = DEVICE_DT_GET(DT_CHOSEN(zephyr_console));

if (!device_is_ready(cons)) {
printf("%s: device not ready.\n", cons->name);
return 0;
}

printf("\n%s system off demo\n", CONFIG_BOARD);
print_reset_cause();


/* configure sw0 as input, interrupt as level active to allow wake-up */
rc = gpio_pin_configure_dt(&sw0, GPIO_INPUT);
if (rc < 0) {
printf("Could not configure sw0 GPIO (%d)\n", rc);
return 0;
}

rc = gpio_pin_interrupt_configure_dt(&sw0, GPIO_INT_LEVEL_LOW);
if (rc < 0) {
printf("Could not configure sw0 GPIO interrupt (%d)\n", rc);
return 0;
}

printf("Entering system off; press sw0 to restart\n");


rc = pm_device_action_run(cons, PM_DEVICE_ACTION_SUSPEND);
if (rc < 0) {
printf("Could not suspend console (%d)\n", rc);
return 0;
}

hwinfo_clear_reset_cause();
sys_poweroff();

return 0;
}

技術サポート & 製品ディスカッション

弊社製品をお選びいただき、ありがとうございます!弊社製品での体験が可能な限りスムーズになるよう、さまざまなサポートを提供いたします。さまざまな好みやニーズに対応するため、複数のコミュニケーションチャンネルを提供しています。

Loading Comments...