Matter and Zigbee: Light switch

##

This sample demonstrates a combined Matter and Zigbee application on a single SoC. It implements a Zigbee Dimmer Switch (End Device) and a Matter Dimmer Switch that controls remote Matter lights through the client-side binding cluster.

You can use it together with the Network coordinator and Light bulb samples from the Zigbee R23 add-on to set up a basic Zigbee network, or pair it directly with the Matter and Zigbee: Light bulb using Touchlink commissioning.

The ZBOSS stack and OpenThread (used by Matter) share the same 802.15.4 radio, with ownership handed over at commissioning time by the matter_zigbee_coexistence library. The Light switch is a sleepy device in both protocols:

  • A Zigbee Sleepy End Device when Zigbee is active.

  • An OpenThread Minimal Thread Device (MTD) when Matter is active.

See Low power operation for the related configuration options.

Requirements

The sample supports the following development kits:

Hardware platforms

PCA

Board name

Board target

Developing with nRF54L Series

PCA10184

nrf54lm20dk

nrf54lm20dk/nrf54lm20b/cpuapp nrf54lm20dk/nrf54lm20a/cpuapp

Developing with nRF54L Series

PCA10156

nrf54l15dk

nrf54l15dk/nrf54l15/cpuapp

To test this sample, you also need to program the following samples:

Alternatively, if both light bulb and light switch devices support Touchlink, you can use it for Zigbee commissioning without a Zigbee Coordinator.

Overview

Once the light switch is successfully commissioned to a Zigbee network, it sends a broadcast message to find devices with the implemented Level Control and On/Off clusters. The light switch remembers the device network address from the first response. At this point, you can start using the buttons on the development kit to control the clusters on the newly found devices.

Protocol selection is time-separated and persisted across reboots:

  • On first boot, the device starts on the protocol selected by the CONFIG_MATTER_ZIGBEE_PROTOCOL_STATE_DEFAULT_PROTOCOL Kconfig option (Zigbee by default) and behaves as a Zigbee End Device (Dimmer Switch, sleepy when CONFIG_LIGHT_SWITCH_ZIGBEE_SLEEPY is enabled) when Zigbee is active. In parallel, the Matter stack advertises for commissioning over Bluetooth LE (CHIPoBLE) for the duration configured by CONFIG_CHIP_BLE_ADVERTISING_DURATION (60 s by default).

  • When a Matter commissioner completes commissioning (first CASE session established while Thread is not yet attached), the coexistence layer stops the Zigbee stack, hands the radio over to OpenThread, and persists the selected protocol. From this point on, the device operates as a Matter Dimmer Switch that controls remote Matter lights through the client-side binding cluster.

  • On subsequent boots, the device resumes the persisted protocol. If Matter was selected, the Zigbee stack is skipped entirely and the radio goes directly to OpenThread.

  • A Matter factory reset wipes the Zigbee network information when Zigbee was active, resets the persisted protocol to the value selected by CONFIG_MATTER_ZIGBEE_PROTOCOL_STATE_DEFAULT_PROTOCOL, wipes Matter commissioning data, and reboots the device in that default state.

The default protocol on a factory-fresh device is selected by the CONFIG_MATTER_ZIGBEE_PROTOCOL_STATE_DEFAULT_PROTOCOL Kconfig choice (Zigbee by default). A Matter factory reset (including last-fabric removal when CONFIG_CHIP_LAST_FABRIC_REMOVED_ERASE_AND_REBOOT is enabled) applies the same default again and wipes Matter commissioning data. After the first run, the persisted protocol state in settings takes precedence until a factory reset or explicit protocol switch changes it.

When CONFIG_MATTER_ZIGBEE_COEXISTENCE_BUTTON_SWITCH is enabled (the default), you can long-press the selected button to switch the active protocol. Configure the required hold time by setting the CONFIG_MATTER_ZIGBEE_COEXISTENCE_SWITCH_BUTTON_PRESS_TIME_SECONDS Kconfig option. By default, this option is set to 5 seconds. From Zigbee, the coexistence layer stops the ZBOSS stack and hands the 802.15.4 radio to OpenThread for Matter. From Matter, the device persists Zigbee as the active protocol and reboots. The protocol switch is ignored while the device is joining a Zigbee network or undergoing Matter commissioning.

Switching protocols does not discard network credentials. A device that is switched back to a previously commissioned protocol rejoins the same network. Only a factory reset clears credentials.

Integrating the coexistence layer in AppTask::Init() requires two call sites:

  1. Pass matter_zigbee_coexistence_pre_server_init as mPreServerInitClbk in Nrf::Matter::InitData before calling Nrf::Matter::PrepareServer(). This temporarily transfers the 802.15.4 radio to OpenThread so that InitThreadStack() can initialize the OT radio platform safely while Zigbee owns the dispatcher.

  2. Call matter_zigbee_coexistence_on_server_started() immediately after Nrf::Matter::StartServer() succeeds. This restores the 802.15.4 dispatcher to Zigbee, disables the OT IP6 interface so OpenThread does not access the radio while inactive, and unblocks the Zigbee worker thread.

The following example shows the required structure:

Nrf::Matter::InitData initData{};
initData.mPostServerInitClbk = []() -> CHIP_ERROR {
    /* sample-specific init */
    return CHIP_NO_ERROR;
};
initData.mPreServerInitClbk  = []() -> CHIP_ERROR {
    matter_zigbee_coexistence_pre_server_init();
    return CHIP_NO_ERROR;
};
ReturnErrorOnFailure(Nrf::Matter::PrepareServer(initData));
// ...
ReturnErrorOnFailure(Nrf::Matter::StartServer());
matter_zigbee_coexistence_on_server_started();

Other Kconfig options in the coexistence layer:

Onboarding data (discriminator, passcode, QR code) is produced by the Matter factory data module (CONFIG_CHIP_FACTORY_DATA_BUILD) at build time.

Limitations

The combined Matter and Zigbee application has the following limitations:

  • The 802.15.4 radio is time-shared, never concurrent: once the device runs on Matter, Zigbee is torn down until the active protocol changes again. To switch back to Zigbee, ensure the CONFIG_MATTER_ZIGBEE_COEXISTENCE_BUTTON_SWITCH Kconfig option is enabled, then long-press the button. Removing all Matter fabrics or triggering a Matter factory reset wipes Matter storage and resets the persisted protocol to the value selected by the CONFIG_MATTER_ZIGBEE_PROTOCOL_STATE_DEFAULT_PROTOCOL Kconfig option.

  • The memory footprint is tuned empirically for nrf54lm20dk/nrf54lm20a/cpuapp and nrf54lm20dk/nrf54lm20b/cpuapp; porting to other targets requires revisiting the libc heap, ZBOSS thread, system work queue and partition sizes used by prj.conf.

Configuration

See Configuring and building in the nRF Connect SDK documentation for information about how to permanently or temporarily change the configuration.

Source file setup

This sample is split into the following source files:

  • The main file is the application entry point only.

  • The app_task_zigbee file manages the application task flow, user input handling, and Zigbee-specific startup and control logic.

  • The app_task_matter file implements the Matter application task flow: button input, timers, and delegating control actions to bound lighting devices.

  • The light_switch file implements the light switch application logic and interaction with Zigbee clusters.

Build variants

The sample provides predefined configuration files in the samples/light_switch directory.

The samples in this add-on are combined Matter and Zigbee builds by default. The default prj.conf enables Matter (CONFIG_CHIP), the CONFIG_MATTER_ZIGBEE_COEXISTENCE orchestration layer, and the matching static partition layout with the MCUboot secondary slot in internal RRAM.

west build samples/light_switch -b nrf54l15dk/nrf54l15/cpuapp --sysbuild

The same configuration is supported on nrf54lm20dk/nrf54lm20a/cpuapp and nrf54lm20dk/nrf54lm20b/cpuapp.

On the nRF54L15 DK, the combined Matter and Zigbee image requires external flash for the MCUboot secondary slot due to the available internal slot size. To place the MCUboot secondary slot on external SPI NOR flash instead, pass the ext_flash snippet.

west build samples/light_switch -b nrf54l15dk/nrf54l15/cpuapp -S ext_flash --sysbuild
west build samples/light_switch -b nrf54lm20dk/nrf54lm20a/cpuapp -S ext_flash --sysbuild

To produce a size-optimized release build (no logging, console or shell), add release.conf as an extra overlay:

west build samples/light_switch -b nrf54l15dk/nrf54l15/cpuapp -S ext_flash --sysbuild -DEXTRA_CONF_FILE='release.conf'

Use nrf54lm20dk/nrf54lm20b/cpuapp as the board target for the nRF54LM20B SoC variant.

Over-the-air firmware upgrade

You can update your device’s firmware over the air using three methods.

  • Matter OTA – Updates your device through MCUboot, satisfying the Matter specification’s requirement to support at least one over-the-air software update method. Enable it with the SB_CONFIG_MATTER_OTA sysbuild Kconfig option, which sets CONFIG_CHIP_OTA_REQUESTOR on the application image. Both options are enabled by default when building with sysbuild.

  • Zigbee Firmware-Over-the-Air (FOTA) - Updates the device over the Zigbee network using the Zigbee Cluster Library (ZCL) OTA upgrade cluster. MCUboot then applies the downloaded image. Enable this feature with the CONFIG_ZIGBEE_FOTA Kconfig option or by using the dedicated zigbee_fota.conf configuration file. The feature is disabled by default.

  • Device Firmware Upgrade (DFU) over Bluetooth LE - Updates the device using the Simple Management Protocol (SMP). Enable this feature with the CONFIG_CHIP_DFU_OVER_BT_SMP Kconfig option. The feature is disabled by default in Kconfig but enabled for this sample through its prj.conf file.

Matter OTA, Zigbee FOTA, and SMP DFU are independent transports. SMP is not part of the Matter specification. Use mcumgr or nRF Connect Device Manager to perform SMP updates. For Zigbee FOTA, use an OTA Upgrade Server on the network, or see the Zigbee FOTA library documentation in the Zigbee R23 add-on.

For step-by-step instructions on testing the update process, see Testing DFU over Bluetooth SMP.

See Limitations for supported board targets and incompatible options.

For the board name to use instead of the board_target, see Programming board names.

See Providing CMake options in the nRF Connect SDK documentation for instructions on how to add flags to your build. For more information about configuration files in the nRF Connect SDK, see Build and configuration system in the nRF Connect SDK documentation.

Low power operation

The light switch is a sleepy device:

For low power operation, use the matter_fota_release.conf overlay described in Build variants. In addition to stripping logging, the console, and the shell, it enables CONFIG_PM_DEVICE and CONFIG_PM_DEVICE_RUNTIME to suspend idle peripherals. For additional power savings, disable all DK LED indications with CONFIG_MATTER_ZIGBEE_UI_DISABLE_LEDS.

Note

While Zigbee is active, the Matter stack advertises for commissioning over Bluetooth LE as described in the Overview section. During Zigbee operation, the power consumption is increased until the advertising duration configured by CONFIG_CHIP_BLE_ADVERTISING_DURATION elapses.

User interface

All the Matter and Zigbee combined samples share button and status-LED handling through the matter_zigbee_ui library (include/matter_zigbee_ui_config.h). Sample-specific buttons and LEDs are defined in each sample’s include/app_ui_config.h.

The descriptions below apply while the device runs either protocol. Sample-specific controls are active only for the persisted active protocol (see the sample overview).

LED 0 (Matter):

Matter connectivity and commissioning readiness.

  • Matter active: Solid on when the device is provisioned on Thread. Slow blink while waiting for commissioning; fast blink while a Bluetooth LE commissioning connection is active.

  • Zigbee active: Off when Matter is already provisioned. Otherwise mirrors Bluetooth LE commissioning advertising (slow or fast blink) so you can commission over CHIPoBLE while Zigbee owns the 802.15.4 radio.

LED 1 (Zigbee):

Zigbee network status when Zigbee is the active protocol.

  • Off when Matter is active.

  • Blinks while Zigbee is active but not joined to a network (even when paired using Zigbee touchlink)

  • Solid on when joined.

LED 2 (Identify):

Blinks during Identify mode (Zigbee Identify cluster or Matter Identify cluster / TriggerEffect).

Button 0:

Multiplexed factory reset and (optionally) SMP DFU entry.

  • Short press (when CONFIG_MATTER_ZIGBEE_UI_SMP_DFU is enabled): Starts Bluetooth LE advertising for SMP firmware update. If the device is not commissioned to a Matter fabric, Matter commissioning advertising is started as well; if already commissioned, only the SMP server is enabled.

  • Long press — factory reset:

    • Zigbee active: Uses the Zigbee application utilities factory-reset gesture on Button 0 (CONFIG_FACTORY_RESET_PRESS_TIME_SECONDS from the Zigbee R23 add-on).

    • Matter active: Two-step gesture on Button 0 controlled by CONFIG_MATTER_ZIGBEE_UI_FACTORY_RESET_PRESS_TIME_SECONDS (5 s by default): hold for the first half of the timeout, then either release to cancel or keep pressed through the cancel window to confirm.

Button 1:

Long press (when CONFIG_MATTER_ZIGBEE_COEXISTENCE_BUTTON_SWITCH is enabled): Switches the active protocol after CONFIG_MATTER_ZIGBEE_COEXISTENCE_SWITCH_BUTTON_PRESS_TIME_SECONDS (5 s by default). Ignored during Zigbee join or Matter commissioning.

Button 3:

Zigbee active: Short press and release toggles local Identify mode (LED 2 blinks).

Matter active: Identify is driven by the Matter Identify cluster (controller or binding peer); Button 3 is not used for local identify.

Sample-specific (light switch)

LED 3:

Zigbee active: Solid on when the switch has found a controllable light bulb on the Zigbee network (Match Descriptor succeeded). Off before a bulb is found. Matter active: Off (not used).

Button 1:

Short press on the light switch (in addition to the protocol-switch long press described above):

  • Zigbee active: Starts Touchlink commissioning when CONFIG_ZIGBEE_TOUCHLINK_INITIATOR is enabled (see Touchlink commissioning).

  • Matter active: Triggers ICD User Active Mode when CONFIG_CHIP_ICD_UAT_SUPPORT is enabled.

Button 2:

Both Matter and Zigbee: Controls bound lights. Available after LED 3 turns on (Zigbee) or after Matter binding is set up (Matter).

  • Short press and release: Toggle on/off.

  • Press and hold (≥ 500 ms): Increase the level by 15 every 500 ms while held, turning the light on if needed and wrapping to the minimum level after reaching the maximum. Releasing after dimming does not toggle.

Building and running

Make sure the Zigbee R23 add-on is included in your workspace and configured before building and testing this sample.

This sample can be found under samples/light_switch in the Matter and Zigbee add-on folder structure.

To build the sample, follow the instructions in Building an application in the nRF Connect SDK documentation for your preferred building environment. See also Programming an application for programming steps and Testing and optimization for general information about testing and debugging in the nRF Connect SDK.

Note

When building repository applications in the Matter and Zigbee add-on which is an SDK repository, building with sysbuild is enabled by default. If you work with out-of-tree freestanding applications, you need to manually pass the --sysbuild parameter to every build command or configure west to always use it.

Testing

After programming the sample to your development kits, complete the following steps to test basic Zigbee operation:

  1. Turn on the development kit that runs the Network coordinator sample.

    When LED 2 turns on, this development kit has become the Coordinator of the Zigbee network.

  2. Turn on the development kit that runs the Zigbee-only Light bulb sample.

    When LED 1 turns on, the light bulb has become a Router inside the network.

    Note

    If LED 1 does not turn on, press Button 0 on the Coordinator to reopen the network.

  3. Turn on the development kit that runs the Light switch sample.

    When LED 1 turns on, the light switch has become an End Device, connected directly to the Coordinator.

  4. Wait until LED 3 on the light switch node turns on.

    This LED indicates that the light switch found a light bulb to control.

You can now use buttons on the development kit to control the light bulb, as described in User interface.

Testing the full Zigbee-to-Matter flow

To test the full combined application flow, you need:

  • A light switch built as described in Build variants.

  • A Zigbee test setup to verify Zigbee operation before Matter commissioning. You can use either the standard setup (a Network coordinator and a Zigbee light bulb) or, alternatively, only a Touchlink-capable light bulb (for example, the Matter and Zigbee: Light bulb), in which case the Zigbee Coordinator is not needed.

  • A Matter controller that can commission a Thread device over Bluetooth LE, for example CHIP Tool or an ecosystem app (Apple Home, Google Home, Amazon Alexa).

  • A Thread Border Router reachable by the Matter fabric.

  • Optionally, a Matter light commissioned to the same Thread fabric to be bound to the light switch (for example, the Matter and Zigbee: Light bulb).

Complete the following steps:

  1. Verify Zigbee operation in one of the following ways:

    • Follow the standard Testing procedure with a Zigbee Network coordinator and a Zigbee light bulb.

    • Or, skip the Zigbee Coordinator and pair the light switch directly with a Touchlink-capable light bulb:

      1. Power the light bulb (Touchlink target).

      2. Power the light switch and press the Touchlink button (see Touchlink commissioning). The two devices form a distributed-security Zigbee network and the light switch finds the bulb to control, without a Zigbee Coordinator on the network.

    While the device is still a Zigbee End Device, it also advertises for Matter commissioning over Bluetooth LE if CONFIG_MATTER_ZIGBEE_COEXISTENCE_BT_ADV_WHILE_ZIGBEE is enabled.

  2. Optionally, long-press Button 1 for CONFIG_MATTER_ZIGBEE_COEXISTENCE_SWITCH_BUTTON_PRESS_TIME_SECONDS to switch to Matter. The Zigbee stack is stopped and the radio is handed to OpenThread. Skip the next step if you use this path and Matter was already commissioned in a previous session.

  3. Commission the device using the onboarding payload produced by the Matter factory data build (QR code or manual pairing code). After the Matter CASE session is established, the light switch hands the radio over to Thread and stops participating in the Zigbee network.

  4. Bind the light switch to a Matter light (for example, with chip-tool binding write binding ) and use the dimmer button to toggle or dim the bound light over Thread.

  5. To return the device to Zigbee operation, use one of the following:

    • Long-press Button 1 for CONFIG_MATTER_ZIGBEE_COEXISTENCE_SWITCH_BUTTON_PRESS_TIME_SECONDS. The device reboots and resumes as a Zigbee End Device.

    • Or trigger a Matter factory reset from the controller (for example, chip-tool pairing unpair ). The device reboots as a fresh Zigbee End Device with Matter Bluetooth LE advertising active again, and Matter storage is cleared.

Testing DFU over Bluetooth SMP

To test DFU over Bluetooth LE SMP, complete the following steps:

  1. Build and flash the sample (see Build variants).

  2. Confirm the device is running the Matter stack (see Testing).

  3. Briefly press Button 0 to start Bluetooth LE advertising for SMP.

    The behavior depends on the device’s commissioning state:

    • If the device is not commissioned to a Matter fabric, this starts both Matter commissioning advertising and the SMP server.

    • If the device is already commissioned, this re-enables only the SMP server for firmware transfer. Firmware transfer over SMP works with both Matter and Zigbee.

    On the Matter and Zigbee: Light switch and matter_zigbee_light_bulb_sample, Button 0 also activates factory reset, when pressed for few seconds (5 s by default). Make sure to short click to start Bluetooth LE advertising for SMP and to avoid accidentally performing a factory reset.

    LED 0 blinks while Bluetooth LE advertising for SMP is active. The advertised device name is MatterZigbeeSw, set by the CONFIG_BT_DEVICE_NAME Kconfig option in the prj.conf file.

  4. Perform the update using one of the following methods:

    1. Install nRF Connect Device Manager.

    2. Use the dfu_application.zip file from the build directory.

    For detailed instructions, see FOTA updates on nRF54L Series devices.

After the update completes, MCUboot applies the new image on the next reboot.

Sample output

You can observe the sample logging output through a serial port after connecting with a terminal emulator (for example, nRF Connect Serial Terminal). See Testing and optimization in the nRF Connect SDK documentation for the required settings and steps.

Dependencies

This sample uses the following nRF Connect SDK libraries and components:

  • The Matter stack (CONFIG_CHIP) shipped with the nRF Connect SDK, including the Binding and Identify clusters and the Matter factory data module.

  • OpenThread (used by Matter on 802.15.4) and the SoftDevice Controller (used for CHIPoBLE commissioning).

  • The matter_zigbee_coexistence and matter_zigbee_protocol_state libraries, which orchestrate the 802.15.4 radio hand-over and persist the selected protocol.

  • The nrf_802154_callbacks_dispatcher (CONFIG_NRF_802154_CALLBACKS_DISPATCHER) with runtime re-init (CONFIG_NRF_802154_DRV_REINIT_ENABLED).

  • The Zigbee R23 add-on for ZBOSS stack support, Zigbee application utilities, and error handling.

  • DK Buttons and LEDs