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 |
|---|---|---|---|
PCA10184 |
|
||
PCA10156 |
|
To test this sample, you also need to program the following samples:
The Zigbee Network Coordinator sample from the Zigbee R23 add-on on one separate device.
The Matter and Zigbee: Light bulb sample on one or more separate devices.
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_PROTOCOLKconfig option (Zigbee by default) and behaves as a Zigbee End Device (Dimmer Switch, sleepy whenCONFIG_LIGHT_SWITCH_ZIGBEE_SLEEPYis enabled) when Zigbee is active. In parallel, the Matter stack advertises for commissioning over Bluetooth LE (CHIPoBLE) for the duration configured byCONFIG_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:
Pass
matter_zigbee_coexistence_pre_server_initasmPreServerInitClbkinNrf::Matter::InitDatabefore callingNrf::Matter::PrepareServer(). This temporarily transfers the 802.15.4 radio to OpenThread so thatInitThreadStack()can initialize the OT radio platform safely while Zigbee owns the dispatcher.Call
matter_zigbee_coexistence_on_server_started()immediately afterNrf::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:
CONFIG_MATTER_ZIGBEE_COEXISTENCE_BT_ADV_WHILE_ZIGBEE(default enabled) — Matter may advertise for commissioning over Bluetooth LE while Zigbee owns the 802.15.4 radio. When disabled, the Zigbee worker is unblocked directly frommatter_zigbee_coexistence_on_server_started()without waiting for CHIPoBLE advertising.CONFIG_MATTER_ZIGBEE_COEXISTENCE_BUTTON_SWITCH— Enable or disable the button-triggered protocol switch.
Onboarding data (discriminator, passcode, QR code) is produced by the Matter factory data module (CONFIG_CHIP_FACTORY_DATA_BUILD) at build time.
Touchlink commissioning
When CONFIG_ZIGBEE_TOUCHLINK_INITIATOR is enabled, the light switch can act as a Touchlink initiator.
This lets the device commission directly with a nearby Touchlink target (for example, the Matter and Zigbee: Light bulb) and form a distributed-security Zigbee network without a Zigbee Coordinator.
Short-press Button 1 during normal operation to start Touchlink commissioning. If the devices are not paired within 5–7 seconds, short-press Button 1 once again. A long press on the same button switches protocol instead; see Limitations.
Note
Touchlink in the Matter and Zigbee add-on for the nRF Connect SDK is provided as an experimental feature with basic functionality.
Note
Touchlink commissioning does not work when the CONFIG_LIGHT_SWITCH_ZIGBEE_SLEEPY Kconfig option is enabled.
The sample disables Sleepy End Device behavior automatically when CONFIG_ZIGBEE_TOUCHLINK_INITIATOR is selected.
See KRKNWK-22343: Zigbee Touchlink initiator does not work when Zigbee Sleepy End Device behavior is enabled.
Note
Touchlink commissioning does not work reliably when the CONFIG_ZIGBEE_FOTA is enabled.
To test Touchlink, disable Zigbee FOTA.
See :ref:`known_isses`_ and the Zigbee R23 add-on known issues for more details.
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_SWITCHKconfig 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 theCONFIG_MATTER_ZIGBEE_PROTOCOL_STATE_DEFAULT_PROTOCOLKconfig option.The memory footprint is tuned empirically for
nrf54lm20dk/nrf54lm20a/cpuappandnrf54lm20dk/nrf54lm20b/cpuapp; porting to other targets requires revisiting the libc heap, ZBOSS thread, system work queue and partition sizes used byprj.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
mainfile is the application entry point only.The
app_task_zigbeefile manages the application task flow, user input handling, and Zigbee-specific startup and control logic.The
app_task_matterfile implements the Matter application task flow: button input, timers, and delegating control actions to bound lighting devices.The
light_switchfile 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_OTAsysbuild Kconfig option, which setsCONFIG_CHIP_OTA_REQUESTORon 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_FOTAKconfig option or by using the dedicatedzigbee_fota.confconfiguration 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_SMPKconfig option. The feature is disabled by default in Kconfig but enabled for this sample through itsprj.conffile.
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:
When Zigbee is active, you can configure the device as a Sleepy End Device using the
CONFIG_LIGHT_SWITCH_ZIGBEE_SLEEPYKconfig option (enabled by default). This option is not available whenCONFIG_ZIGBEE_TOUCHLINK_INITIATORis enabled, see KRKNWK-22343: Zigbee Touchlink initiator does not work when Zigbee Sleepy End Device behavior is enabled.When Matter is active, the device is a Thread Minimal Thread Device with Intermittently Connected Device support.
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_DFUis 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_SECONDSfrom 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_SWITCHis enabled): Switches the active protocol afterCONFIG_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_INITIATORis enabled (see Touchlink commissioning).Matter active: Triggers ICD User Active Mode when
CONFIG_CHIP_ICD_UAT_SUPPORTis 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:
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.
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.
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.
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:
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:
Power the light bulb (Touchlink target).
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_ZIGBEEis enabled.Optionally, long-press Button 1 for
CONFIG_MATTER_ZIGBEE_COEXISTENCE_SWITCH_BUTTON_PRESS_TIME_SECONDSto 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.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.
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.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:
Build and flash the sample (see Build variants).
Confirm the device is running the Matter stack (see Testing).
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_NAMEKconfig option in theprj.conffile.Perform the update using one of the following methods:
Install nRF Connect Device Manager.
Use the
dfu_application.zipfile from the build directory.
For detailed instructions, see FOTA updates on nRF54L Series devices.
Upload the signed images from the build directory:
On single-core SoCs (for example, nRF54L Series), upload the application image:
mcumgr --conntype ble --hci 0 --connstring peer_name='MatterZigbeeSw' image upload build/light_switch/zephyr/zephyr.signed.bin -n 0 -w 1
After uploading, list the images, mark each new slot as pending, and reset the device. For the full procedure, see Performing Device Firmware Upgrade in the nRF Connect examples.
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_coexistenceandmatter_zigbee_protocol_statelibraries, 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.