If your existing Host-NCP solution is lacking Green Power proxy support and you want to add it to the design these steps will walk you through the process of adding it.
First, go to the ZCL Clusters tab and find the Multiple endpoint configuration section at the top. Click the New button to add an endpoint to your device, this will create a second endpoint on the device with identifier 2. Now we need to convert this to a green power endpoint.
In the Configuration column, click the Primary name, which will bring up a button with 3 dots
Click the box to bring up the Endpoint type window
Select the option Create new endpoint type and name your new endpoint Green Power. Click OK.
Keeping the endpoint selected, go to the pull-down menu for ZCL Device Type and change the device to GP Proxy Basic (under GP devices). When this is selected, this will make the endpoint change to number 242. This should also enable Cluster 0x0021, the Green Power cluster, on the device.
Now go to the Plugins tab and on the search bar, enter Green – this will find 4 plugins in the Green Power section:
Check the box next to the Green Power Client and Green Power Common plugins, this will enable them. There isn't any need to change any of the default settings within the plugins, so you can leave those alone.
At this point you should be able to generate and build your host application with no issue and Green Power will be supported. However support for green power needs to be enabled within the NCP.
As you are configuring your NCP application, go to the plugins tab and enable the Green Power Stack Library plugin. Make sure the Green Power Stack Stub Library is disabled:
Since this is just a proxy, you can leave the settings as defaulted, proxy table size of 5 and sink table size of 0. However you will need to consider your potential network when configuring your table sizes. A larger proxy table might be needed for supporting all devices on the network.
This is all you need for NCP support. You can generate and build your NCP and combined with your new host code, green power proxy support should be ready to go.
What is the maximum allowed power for ZigBee applications under ETSI EN 300 328?
Although ETSI EN 300 328 allows 20dBm RF output power, there is a limitation for PSD (Power Spectral Density) for wide band modulations other than FHSS. This PSD limit restricts the maximum allowed power for ZigBee applications.
Section 188.8.131.52 in EN 300 328 V2.1.1 details the test method for PSD. The ZigBee modulated signal measured according to Option 2, Step 3 (with sweep time set to 10s):
CW signal with the same power level and spectrum analyzer settings:
The peak power difference between the ZigBee and CW signal measured with RMS detector is ~2.3dB. In order to meet the PSD limit of 10dBm per MHz, the maximum allowed power is 12.3dBm (EIRP).
Note: The 12.3dBm power limit is radiated (EIRP), which means that in case of an antenna with 0dBi, the maximum conducted power allowed is 12.3dBm. For antennas with lower gain than 0dBi, conducted power can be increased, while for antennas with higher gain than 0dBi, conducted power should be reduced.
Measurements were performed on an EFR32MG13 based reference board (BRD4158A Rev A01).
We are now in the home stretch and ready to build our switch to work interfacing a button. The first thing we need to do is put some hooks into our project to give us a place to put our code.
If you remember back when you made the switch project, we enabled the Button Interface plugin, as the name suggests, this gives you an interface for buttons within our callbacks section. If you look at the callbacks tab, you will see these callbacks under the Plugin-specific callbacks. There are callbacks for different button states as well as long and short presses. For this example, let’s pick button 0 as it is generally clear of the ribbon cable on the Thunderboard. We also don’t need much more than a single button press, so let’s make use of the Button0 Pressed Short callback, check the box next to that identifier. *
* Quick note – a short press is by default defined as less than 250 mSec, you can look through the plugin code and the button timeout definition within the plugin to see how this is defined.
Like the light, make sure at the bottom of your callbacks page you have the “Generate project-specific callbacks file” box checked. This will ensure your new callbacks file is generated for your application. You can then save your .ISC file and hit generate to add this new callback. You will get a box that talks about overwriting files. Make sure your Project_callsbacks.c file is checked, you should also create backups, just in case. Then hit OK.
When you see the Generation Successful window, you’re ready to move to the next step.
Locate your project callbacks file on the left view titled Project Explorer and open the file in your editor. You will see that your callbacks file now includes a new, blank function named emberAfPluginButtonInterfaceButton0PressedShortCallback(). This function is called anytime the button is pressed for a short time.
Now we need to take our CLI calls and use this function to make these calls happen within this function. Looking back at our configuration, we send two commands via the CLI to send a message:
zcl on-off toggle
and then either
send 0 1 1
which sent our message outright to a node and endpoint we specified, or
which used a binding table entry to remove our need to know the exact device we were sending a message to.
First let’s look at zcl on-off toggle. To do this, we need something that will construct our message for us. We can look in the Application Framework reference guide and then refer to the Ember Application Framework API Reference and then the Application Framework Command Buffer Loading Interface. In here you will find a number of commands that will help load command or response buffers which can be sent out with some form of a send command.
If you search for the word ‘toggle’ through this document, it should find the function
which is a basic command which constructs our command buffer for us automatically. The benefit of this command is that it handled much of the overhead by utilizing the command buffer, making sending the message much easier later. So, add a call to this function to your button callback function.
Now we need to find a command to send our buffer over the air for us. So let’s return to the Application Framework and click over to the General Application Framework Interface and search for functions that deal with sending messages. On this page, you can search for the word messaging, which locates the function that deal with sending messages within the application framework. If you look through this section, there are a lot of functions which you can call.
You could use a function like emberAfSendUnicast. But this has a lot of parameters. And as we noted, the benefit we had about using the a FillCommand function is that the command buffer overhead has been handled for us. If you look down the list, you will find a number of functions that start out emberAfSendCommand… these are the functions we want to look at. Since this is a specific command send directly to a single node, you can use emberAfSendCommandUnicast(). This takes two options, the first is a messages type and the second is some sort of integer argument that differs based on what your message type is.
emberAfSendCommandUnicast (EmberOutgoingMessageType type, uint16_t indexOrDestination)
If you follow the link for the EmberOutgoingMessageType, you will see a number of different message types. EMBER_OUTGOING_DIRECT would allow you to send a message directly to a node id. Alternatively, a few lines down, you will find EMBER_OUTGOING_VIA_BINDING, which would allow you to leverage a previously made binding to send your message. Let’s take a look at each of these and you can pick the way you want to send your toggle.
If you choose to send a direct unicast to your node ID, this is the same operation as using the command send 0 1 1 to send your message. If you take a look at the send command’s help you will see the pieces you are providing with the numbers:
send (args) short id of the device to send the message to The endpoint to send the message from The endpoint to send the message to
Looking at the emberAfSendCommandUnicast function, your two options are a type and destination. In the case of using type EMBER_OUTGOING_DIRECT, the destination is our short ID of our target. As we noted before, you can use 0x0000 since this is a short id.
emberAfSendCommandUnicast (EMBER_OUTGOING_DIRECT, 0x0000);
This takes care of your node address. But we set our endpoints in the send command, and these are not yet handled. We need some function to configure the endpoints. And we need to configure this before we send our message otherwise it will be too late. Let’s return to the top level of the application framework and look around at operations that manipulate endpoints. If you search for the word endpoints, you will eventually come across the command emberAfSetCommandEndpoints(), which requires a source and destination endpoint. In our case we know both end points are 1, so you can hard code that if you would like, If you want, you can use emberAfPrimaryEndpoint() as the first argument because it’s the only endpoint of our device. However, in the case of the destination endpoint, you can only specify 1 as you need to hard code this.
Now you can test this out. Save your callbacks file and compile your code. Put this new application on your “switch” Thunderboard and press button 0, you should see your light turn on and off.
Alternative to sending a direct message to your node, you can leverage the fact that you have already created a binding and send directly to that. The advantage of this is that it already takes care of all of your settings like node address and endpoints. However, now you must know your binding entry to where you can send this to the on/off cluster.
So go to your console and enter the command ‘option binding-table print’ to display your binding table.
# type nwk loc rem clus node eui 0: UNICA 0 0x01 0x01 0x0003 0x0000 (>)000B57FFFEDEA263 1: UNICA 0 0x01 0x01 0x0006 0x0000 (>)000B57FFFEDEA263
The on-off cluster is 0x0006, so we want to send this to binding table entry 1. You can place this in as the second argument to your function:
emberAfSendCommandUnicast (EMBER_OUTGOING_VIA_BINDING, 1);
Like in _DIRECT format, now test this out. Save your callbacks file and compile your code. Put this new application on your “switch” Thunderboard and press button 0, you should see your light turn on and off.
In the end, this isn’t the cleanest code possible. Because this function is hard coded on the button, we are always sending our message. In the included MySwitch_callbacks.c file we have included some code that you can use to check that your network is currently up. We also have print statements to display sensible messages when your light or switch are operating.
Now that we have formed a network, it’s time to verify that we can successfully send messages between our light and switch. To do this will be using simple ZCL commands to start and
First click on the serial console of the switch. At the prompt enter:
zcl on-off toggle
This builds a Zigbee Clusters Library command frame. You can tell it was constructed correctly because of the output:
Msg: clus 0x0006, cmd 0x02, len 3 buffer: 01 00 02
Cluster 0x0006 corresponds to the on-off cluster.
Command 0x02 is the toggle command and length 3 corresponds to the length of the command buffer.
The buffer is 01 for the frame control, 00 for the sequence number and 02 for the command id for toggle.
Now we want to send this command to our light. Because our light is the coordinator, we know it’s Zigbee node ID is 0x0000. Because we want to send these commands from end point 1 on the switch and to endpoint 1 on the light our command to send this would be:
send 0 1 1
Hitting enter you will see on the light that it received a message for it’s 0x0006 cluster with command 02.
T00000000:RX len 3, ep 01, clus 0x0006 (On/off) FC 01 seq 00 cmd 02 payload
On the switch, you will see it received a message as well.
T00000000:RX len 5, ep 01, clus 0x0006 (On/off) FC 08 seq 05 cmd 0B payload[02 00 ]
This is a default response as it is sent back from the light to the switch.
If we look at App Builder, you can see these messages sent in the transaction view, a ZCL: Toggle followed by a ZCL: DefaultResponse. You can look at details of each message as they are sent on the side panel. For example, if you look within the event details of the the DefaultResponse, you can see that the response is Status: SUCCESS, meaning that the message was sent and properly handled.
Because our light is our network coordinator, we know that it’s address is 0x0000. However, most of the time we can’t trust that this will be the case. We need some sort of functionality to get our switch to look for and find our light and then join with the light so that it can easily send messages to the light instead of needing to know the address of the light. Additionally, the switch and light need some means of discovering if they share common clusters, like the off-off cluster. To assist with this, Zigbee provides finding & binding as a standard means of performing just this action.
If you remember back when we created our light and switch, we added a Find and Bind plugin to each device. The Light utilized the Find and Bind Target plugin while the Switch utilized the Find and Bind Initiator plugin. With these plugins, it makes finding and binding easy. Instead of having our light looking for ZCL messages doing endpoint discovery and having to manually construct a full set of ZCL messages to be sent across our network, asking for nodes to identify themselves as well as their endpoints and clusters and then binding like clusters, the plugins will take care of it all for us.
What we will first do is make the light a find and bind target for its endpoints. This will make it monitor network traffic and look for devices which are doing Find and Bind Initiation. To do this we will enter the following command:
plugin find-and-bind target 1
This tells endpoint 1 to act as an endpoint target. You will know the command works because you will see:
Find and Bind Target: Start target: 0x00
Now on the switch we must start it as an initiator. This is a similar function, but instead of target, we use:
plugin find-and-bind initiator 1
When you enter on this, you will see traffic in both the serial window as well as the network capture window as well. The process will be complete when you see
Find and Bind Initiator: Complete: 0x00
In the serial console.
Looking at the network traffic, you can see:
1. Our switch sends out a broadcast ZCL: IdentifyQuery. This is responded to by our light.
2. Then the switch asks the light for its full EUI64 address, the light responds to this with its EUI64.
3. Then finally the switch sends a simple descriptor request to get cluster information from the light. The light responds with 5 clusters which it is server: 0, 3, 4, 5 and 6 and no clusters which it is a client.
From this information our switch with then creates binding with clusters that it matches. For the 5 server clusters on the light, it looks to see if it is a client cluster on any of those, for the switch those are clusters 3 (identify) and 6 (on-off). So if you go to the CLI of the switch and print the binding table, you will see these new bindings, which are bound to the EUI64, not just the short ID. To print the binding table, use the following command:
option binding-table print
The output will look like this:
# type nwk loc rem clus node eui 0: UNICA 0 0x01 0x01 0x0003 0x0000 (>)000B57FFFEDEA263 1: UNICA 0 0x01 0x01 0x0006 0x0000 (>)000B57FFFEDEA263
With these bindings we can then use a bsend command to tell our device to send commands to a binding for a particular endpoint.
zcl on-off toggle bsend 1
This sends a command to our bindings on endpoint 1.
With this information, we can get to the step of making our light and switch act like a light and switch. The light will turn on or off LEDs based on attribute state, while our switch will respond to a button press instead of sending commands due to CLI entries.
First dock the Mini-Simplicity connectors onto your WSTKs are shown here:
Also connect your ribbon cable as shown. Then connect your Thunderboards on their corresponding 10 pin header. If your mini simplicity connectors do not have keyed headers, make sure to match your pin 1s of both 10 pin headers.
Since we are using Thurnderboards connected externally to our WSTKs, we must make sure our WSTKs are set to debug mode OUT. This can be done via commander. For each WSTK run the following command
commander adapter dbgmode OUT -s XXXXXXX
where XXXXXXX is the serial number of your WSTK.
This can also be performed within Studio from the Launcher perspective. Under the Debug Adapters pane near the top left, you should see the two boards/adapters show up as “J-Link Silicon Labs (4400xxxxx). Highlight each adapter and change the Debug Mode to “OUT”. If you are prompted to update the board firmware, please proceed with the update. Note that when the Debug Mode is OUT, Simplicity Studio does not know about the Thunderboard Sense 2 board anymore and this is expected. (WSTK main board is still recognized.)
Because neither of our applications will run without a bootloader, we want to create a bootloader for each. Fortunately, a default Gecko application bootloader will work for each board in this example.
To generate this bootloader:
Once your App Builder project opens, click the generate button to generate your project without any changes. Once the Generation successful window appears, you are done. Then use the Hammer icon on the toolbar to invoke your compiler and build your project. This will give you the binaries to flash onto your board. You will need to locate the file named -combined.s37, it should be located in your projects binary folder.
You should flash this application to each of your Thunderboards, making sure to erase each board as you do this. Because you are flashing an external part, it will ask you to use the device option (-d) to identify the part connected to your board, using EFR32 will be enough to proceed.
commander flash TB-app-BL-combined.s37 --masserase -s XXXXXXX -d EFR32
Once you have completed this, you will be ready to begin creating your projects.
In this tutorial we are going to be demonstrating how to build two simple Zigbee 3.0 applications for a light and a switch using Simplicity Studio on the Thunderboard Sense 2.
This project will start by building up a basic set of applications using AppBuilder which will start out as the framework for our light and switch. Then we will add some custom hardware definitions as well as some custom code and expand the base projects provided to tie the software in with the hardware.
When you are finished you will have a light application that controls the states of LEDs based on software attributes and you will have a switch which reacts to a button to send ZCL messages over the air to update the attributes of the light. Below you will find some basic instructions which walk you along the next few lessons as well as code examples and hardware configuration files to get you started.
Some prerequisites you will need for this tutorial:
NOTE: Version 2.6 of the Gecko SDK introduced EmberZNet 6.6.0. This version of the SDK made fundamental changes in the looks and behaviour of the Application Framework. This Tutorial has been updated to accommodate these changes. The new default wording of the tutorial represents the state of EmberZnet 6.6.0 but for users of the older versions the previous instructions were left in with the following note: "Pre Znet 6.6.0:"
Simplicity Studio 4 with the latest updates
EmberZNet 6.6.3 or later
Pre Znet 6.6.0: EmberZnet 6.4.0 or later (earlier than 6.6.0)
Two Thunderboard Sense 2 boards (BRD4166A)
Two WSTKs (BRD4001A)
Two Mini-Simplicity connectors (BRD8010A) and the included 10 pin ribbon cable
You will also need easy access to Simplicity Commander's CLI interface. While it isn't the only way to program your chips, there are a few steps, like token programming, that require Commander.
The videos that went with the older lesson can be found here:
ZigBee Home Automation Developer Tutorial: Light and Switch Overview
ZigBee Home Automation - Light and Switch - part 1
ZigBee Home Automation - Light and Switch - part 2
ZigBee Home Automation - Light and Switch - part 3
ZigBee Home Automation - Light and Switch - part 4
ZigBee Home Automation - Light and Switch - part 5
ZigBee Home Automation - Light and Switch - part 6
ZigBee Home Automation - Light and Switch - part 7
ZigBee Home Automation - Light and Switch - part 8
ZigBee Home Automation - Light and Switch - part 9
ZigBee Home Automation - Light and Switch - part 10
ZigBee Home Automation - Light and Switch - part 11
ZigBee Home Automation - Light and Switch - part 12
Once you have created your projects, it's time to use App Builder to configure the projects for the types of devices they are going to. As we introduce new parts of app builder, we will do our best to explain to you the pieces which you are using and hopefully educate you on making the best use of app builder.
Let's take a look at the MyLight.isc file.
By default you should be on the General tab of your project. It consist of the Application configuration panel and the Information configuration panel. The application configuration panel gives you information about location of the project and the name of the device. This panel also allows you the view the Board, chip and compiler and configure them with the Edit Architecture button.
Pre 6.6.0: By default you should be on the General tab of your project. This gives some basic settings for your project, such as board, chip, and compiler. Below this is the Application configuration, which outlines the version of EmberZNet you are using and the location of the project. If you had an example project from the stack, this would give you a description of the operation of the application. And directly underneath this is multi-network configuration. This isn't something we will use today, but if you are looking for details, AN724 will outline multi-networking.
Pre 6.6.0: The next tab is the ZCL global tab. This is identification and versioning information for your part. You don't want to make any changes here for this project.
After this is the ZCL clusters tab, here is where we will make our first changes. On this tab you configure the ZCL elements of your device, namely your endpoints, the clusters which are enabled on your endpoints, and the attributes and commands that are supported by these clusters. After version 6.6.0 the Manufacturer ID and Default response policy can be changed on this tab as well as the ZCL global tab has been removed.
For our light device we only need a single endpoint, which is the default, but we need to pick a device type that will work for our needs. While you can build custom devices with whatever clusters and attributes you want supported, AppBuilder includes a number of ZCL device types which contain the preconfigured clusters and attributes which are normal for a particular device type. Since we are building a light, we can use a default device included with the stack, for this project find the LO On/Off Light Switch under the LO devices. This light definition has a number of default clusters for you, such as Basic, Identify, Groups, Scenes and On/Off. For this project we are going to focus on the On/Off cluster. But after you are done you can explore the other settings or even extend this light to be dimmable or color control, to add more functionality.
Moving to the Zigbee stack tab (Pre 6.6.0: Znet stack tab) we will configure the Zigbee device and security level. This tab is where many of the Zigbee options are set. For the light, it will be a Coordinator/Router and utilize Zigbee 3.0 Security. These should be the default settings for this device, but if these settings aren’t correct they can be changed here. There are also some settings here for Radio configugration, ZDO and Inter-PAN settings, but they are beyond the scope of this project. After 6.6.0 you can also configure multi-networking related features on this tab and add custom ZCL additions.
Proceeding to the Printing and CLI tab we find the configuration of Debug printing as well as the setup of the CLI. Debug printing allows you to add additional printing options beyond the ones that are supported by a standard application. The Cluster debugging includes print statements that are specific to the clusters enabled for your device. The General-purpose debug printing gives you additional printing within different aspects of your application, such as security or service discovery. You can even created your own custom messaging within this block. Along the bottom you will settings for customizing your CLI. In this section you can enable different CLI commands for your device beyond the standard ones which are included. For our needs, we are going to enable the On/Off cluster printing can be found in the Debug Configuration panel under Application specific debug printing (Pre 6.6.0: On/off cluster printing can be found along the top), so check box boxes next to this so that these print statements are compiled in and enabled at startup. But the normal CLI as it's built will be fine for our needs, so there are no changes needed for the bottom section.
The next tab is the HAL configuration tab. As noted, this is where some hardware settings are made. You want to be sure that your device is setup for the Application bootloader, any other changes, we will make in a future step. This is also one of the places where you can access Hardware Configurator which we will use in a later step.
Finally, we need to configure the required plugins, which can be found on the corresponding tab. Plugins are the EmberZNet method to quickly enable or disable functionality supported by our application layer with a simple click of the button. For plugins, you should use all of the plugins which are included by default with the project and add the following:
Just to be safe, save your project to prevent anything from being lost. We aren't quite done yet, so don't hit the generate button just yet.
Now, let's open up MySwitch.isc and configure the Switch similar to the light. Since you know where to find these settings, they should be much easier to set up.
Like the light, your device will have 1 endpoint. But the ZCL device type will be an LO On/Off Light Switch.
It will utilize Zigbee 3.0 Security but will be an End Device. Don't make it a sleepy end device, you won't be able to get as much response from the CLI, and we need to be able to interact with the device as we make our settings.
For plugins, you should use all of the plugins which are included by default with the project and add the following:
Because the switch is an end device you can exchange the Zigbee PRO Stack Library Plugin for the Zigbee Pro Leaf Library. This is an optional step, but the leaf library removes many of the additional stack libraries which are only needed for routers and coordinators. The result is a smaller library which consumes less power. While we aren't using the sleepy end device, this would help you achieve a much lower current draw when your device sleeps.
Finally, located the Binding Table Library plugin. It has one option to configure – the size of the binding table, we need to make sure our table has at least 6 entries. We probably won't need this many entries, but we want to make sure we have them, just in case.
There is one final setting you need to make to both devices to make sure you can run the CLI. This involves making sure that the serial port is configured correctly.
On both mySwitch and myLight go back to the plugins tab and you want to make sure that the Serial plugin is enabled. From within the Serial plugin you need to ensure both SERIAL and USART0 are enabled (select each in the peripheral box). Finally, because the Thunderboard doesn’t support hardware flow control, we need to change the flow control type within the USART0 peripheral (in the serial plugin), make sure that Flow Control mode is set to Xon-Xoff.
Once you have configured both applications, you want to save each project.
Next, click the Generate button on each project. Just like our bootloader this will create or link to all of the files necessary to build the project. It shouldn't take too long, but you will have a few moments of waiting until the Generation successful window appears. Once you get that, click OK.
Finally, you can click the hammer icon on the toolbar
(or any other command that will begin building your application) and build your application. This will take a minute or two, depending on the speed of your computer. You can follow the progress in your Console window at the bottom. Once the files are compiled and linked, some post build scripts will run. If these run correctly you will get the following message:
Image-builder not invoked since "OTA Bootload Cluster Policy plugin" is not enabled 16:55:26 Build Finished (took 48s.142ms)
The key is the Image-builder message. Image-builder is run after your project compiles correctly. Once you see that, you know that your project has compiled successfully. Next we need to flash it to our device and test it.
If you get some sort of error during your build, return to your project .ISC file and check your work setting on your device and see if you missed any steps or have an incorrect setting.
Now it is time to build our projects for our light and switch. We will be modifying them over the course of a few steps to give them the features they require.
Our first step will be to create two blank projects, from these blank templates, we will start to add the pieces which are required for building a full Zigbee light and switch.
So, let’s get started:
After some time, Studio will display your newly created .ISC file, this will mean your project is ready for editing. Don't forget you need to create two projects, one for the light and one for the switch, so make sure to have both before you move on.
Unlike our bootloader, we will need to make some modifications to this application to build it, so let’s do this for our next step, starting with the light.
Locate your files in the binary folder within Studio and select either the .GBL .EBL or .S37 files for your project.
Flash each binary to a separate Thunderboard, making one Thunderboard the light and one the switch.
commander flash -s XXXXXXXX MyLight.s37 -d EFR32 commander flash -s XXXXXXXX MySwitch.s37 -d EFR32
We need to verify that each application is properly flashed and running. We will check them from the CLI. To connect to the serial terminals, enter either the Simplicity IDE or Network Analyzer view in Studio. Find your WSTKs under Debug Adapters. Right click on each of them and select “Launch Console.” This will bring up your console window. Switch to the Serial 1 header and press enter a few times, this should cause your Project name to appear as your application prompt.
Ensure that both your Light and Switch are working.
Next, we will step through joining each device onto a network and adding the pieces to each so that you can activate the LEDs of your light and the buttons of your switch.