QCA4020 Zigbee Lamp

Skill LevelArea of FocusOperating SystemPlatform/HardwareCloud Services/Platform
IntermediateIoT, Smart HomeRTOSQCA 402x WiFi/BLE/ZigBeeMicrosoft Azure IoT

This project is designed to use the QCA4020 development kit to control the Sengled Zigbee bulb using an Android mobile phone and demonstrates Home Automation. You can control the bulb, turn it on/off, change the color temperature and dim via the app ”Home_Console”.

The main objective of this demo is to create intelligent lighting using the QCA4020 development kit. This is done by using an application on the mobile phone, running Android O, to connect to the QCA4020 via Zigbee and control the Sengled bulb.

Parts used

Below are the items used in this project.

Parts used for the QCA4020 development kit Zigbee lamp project.

  1. Mobile Phone with Android O operating system.
  2. QCA4020 development board
  3. Zigbee Lamp
  4. Transformer/power supply to turn on the Zigbee Lamp.

Deploying the project

  1. Download code from the github repository.
  2. Compile the code and flash the image as described in “QCLI_demo with QCA4020 Development Kit” project.
  3. Install the application found in the Github repository on the Android phone.

How does it work?

The QCA4020 development board is designed to control the on/off status, color temperature and intensity of the bulb via Zigbee protocol. The sections below will show you how the various controls and interfaces in this demo have been implemented, and how the QCA4020 development kit can control the bulb via these interfaces.

Initialize Zigbee protocol and build Zigbee network.
Global variable "flag_form" is used to judge whether the Zigbee network is successful or not. Add the following code to the file

“/quartz/demo/QCLI_demo/src/qcli/pal.c”
	int flag_form = 0;
	
	void init_Zigbee()
	{
		d_cmd_ZB_Initialize(0,NULL);
	
		QCLI_Parameter_t param_setBIB[4];
		param_setBIB[0].Integer_Value = 0x100f;
		param_setBIB[0].Integer_Is_Valid = true;
		param_setBIB[1].Integer_Value = 1;
		param_setBIB[1].Integer_Is_Valid = true;
		param_setBIB[2].Integer_Value = 4;
		param_setBIB[2].Integer_Is_Valid = true;
		param_setBIB[3].Integer_Value = 0;
		param_setBIB[3].Integer_Is_Valid = true;
		d_cmd_ZB_SetBIB(4, param_setBIB);
	
		QCLI_Parameter_t param_CE[2];
		param_CE[0].Integer_Value = 1;
		param_CE[0].Integer_Is_Valid = true;
		param_CE[1].Integer_Value = 6;
		param_CE[1].Integer_Is_Valid = true;
		d_cmd_ZB_CL_CreateEndpoint(2, param_CE);
	
		QCLI_Parameter_t param_form[1];
		param_form[0].Integer_Value = 1;
		param_form[0].Integer_Is_Valid = true;
		d_cmd_ZB_Form(1, param_form);
		
		while(true)
		{
		if(flag_form == 1)
		{
		zigbee_printf("Form Zigbee network success!");
		break;
		}
		qurt_thread_sleep(50);
		zigbee_printf("wait for forming Zigbee network!");
		}
	}	

Zigbee devices connection
The function "Connect_ZigbeeDevice()" is to wait for connection of Zigbee bulb, "flag_connect" is used to judge whether the bulb joins into the network successfully or not. Add the following code to the file “/quartz/demo/QCLI_demo/src/qcli/pal.c”.

int flag_connect = 0;

void Connect_ZigbeeDevice()
{
	while(true)
	{
	if(flag_connect == 1)
	{
	zigbee_printf("Device join success!");
	break;
	}
	qurt_thread_sleep(50);
	zigbee_printf("wait that blub join in Zigbee network!");
	}
}

Building the Zigbee network
"flag_form" is set to 1 after the network architecture is built successfully.
Add the following code to the file “/quartz/demo/QCLI_demo/src/ zigbee/zigbee_demo.c”.

extern int flag_form;
static void ZB_Event_CB()
{
          flag_form = 1;
}

Zigbee network devices connection
We can set "flag_form" to 1 after the devices connect successfully.

Add the following code to the file “/quartz/demo/QCLI_demo/src/zigbee/zdp_demo.c”.

extern int flag_connect;
static void ZB_ZDP_Event_CB(qapi_ZB_Handle_t ZB_Handle, const qapi_ZB_ZDP_Event_t *ZDP_Event_Data, uint32_t CB_Param)
{
	QCLI_Parameter_t param[3];
	param[0].Integer_Value = 2;
	param[0].Integer_Is_Valid = true;
	param[1].Integer_Value = ZDP_Event_Data?
	Event_Data.Device_Annce.NwkAddr;
	device_addr = ZDP_Event_Data?
	Event_Data.Device_Annce.NwkAddr;
	QCLI_Printf(ZDP_Demo_Context.QCLI_Handle, NetworkAddress: %d\n", ZDP_Event_Data?Event_Data.Device_Annce.NwkAddr);
	param[1].Integer_Is_Valid = true;
		param[2].Integer_Value = 1;
		param[2].Integer_Is_Valid = true;
		d_cmd_ZB_AddDevice(3, param);
		flag_connect = 1;
}		

Turning the Zigbee bulb on/off
Add the function "Control_ZigbeeLightOnOff" to turn the bulb on/off in the file “/quartz/demo/QCLI_demo/src/qcli/pal.c”.

int Control_ZigbeeLightOnOff(int on)
{
	if(on > 1)
	{
	QCLI_Parameter_t param_on[2];
	param_on[0].Integer_Value = 1;
	param_on[0].Integer_Is_Valid = true;
	param_on[1].Integer_Value = 1;
	param_on[1].Integer_Is_Valid = true;
	d_cmd_ZCL_OnOff_On(2, param_on);
	}
	else{
	QCLI_Parameter_t param_off[2];
	param_off[0].Integer_Value = 1;
	param_off[0].Integer_Is_Valid = true;
	param_off[1].Integer_Value = 1;
	param_off[1].Integer_Is_Valid = true;
	d_cmd_ZCL_OnOff_Off(2, param_off);
	}

	return 0;
}

Adjust the intensity of the light bulb
To dim the light bulb, add the function "Control_ZigbeeLightLevel" to the file “/quartz/demo/QCLI_demo/src/qcli/pal.c”.

int Control_ZigbeeLightLevel(int level)
{
	QCLI_Parameter_t param_level[5];
	param_level[0].Integer_Value = 1;
	param_level[0].Integer_Is_Valid = true;
	param_level[1].Integer_Value = 1;
	param_level[1].Integer_Is_Valid = true;
	param_level[2].Integer_Value = 1;
	param_level[2].Integer_Is_Valid = true;
	param_level[3].Integer_Value = level;
	param_level[3].Integer_Is_Valid = true;
	param_level[4].Integer_Value = 5;
	param_level[4].Integer_Is_Valid = true;
	d_cmd_ZCL_LevelControl_MoveToLevel(5, param_level);

	return 0;
}

Adjust color temperature of the light bulb
To control the color temperature of the bulb, add the function "Control_ZigbeeColorTemperature" to the file “/quartz/demo/QCLI_demo/src/qcli/pal.c”.

int Control_ZigbeeColorTemperaturn(int temp)
{
	QCLI_Parameter_t param_temp[4];
	param_temp[0].Integer_Value = 1;
	param_temp[0].Integer_Is_Valid = true;
	param_temp[1].Integer_Value = 1;
	param_temp[1].Integer_Is_Valid = true;
	param_temp[2].Integer_Value = temp;
	param_temp[2].Integer_Is_Valid = true;
	param_temp[3].Integer_Value = 5;
	param_temp[3].Integer_Is_Valid = true;
	d_cmd_ZCL_ColorControl_MoveToColorTemp(4, param_temp);
	return 0;
}

Saving Internet address of bulb
Here is how to save the network address of the bulb, the code is located in the file "/quartz/demo/QCLI_demo/src/zigbee/zigbee_demo.c".

uint64_t device_addr = 0;
	static QCLI_Command_Status_t cmd_ZB_AddDevice(uint32_t Parameter_Count,	QCLI_Parameter_t *Parameter_List)
	{
		(Verify_Integer_Parameter(&Parameter_List[0], QAPI_ZB_ADDRESS_MODE_GROUP_ADDRESS_E, QAPI_ZB_ADDRESS_MODE_EXTENDED_ADDRESS_E)) &&
		(Hex_String_To_ULL(Parameter_List[1].String_Value, &DevAddr)))
		(Verify_Integer_Parameter(&Parameter_List[0], QAPI_ZB_ADDRESS_MODE_GROUP_ADDRESS_E,API_ZB_ADDRESS_MODE_EXTENDED_ADDRESS_E))/*&&(Hex_String_To_ULL(Parameter_List[1].String_Value, &DevAddr))*/)
	{
 		DevAddr = device_addr;   
 }
}

Function encapsulation
Finally, we need to do function encapsulation process. The code related to color temperature is located in the file "/quartz/demo/QCLI_demo/src/zigbee/clusters/zcl_colorcontrol_demo.c".

QCLI_Command_Status_t d_cmd_ZCL_ColorControl_MoveToColorTemp(uint32_t Parameter_Count, QCLI_Parameter_t *Parameter_List);
	
	QCLI_Command_Status_t d_cmd_ZCL_ColorControl_MoveToColorTemp(uint32_t Parameter_Count, QCLI_Parameter_t *Parameter_List)
	{
		return cmd_ZCL_ColorControl_MoveToColorTemp(Parameter_Count, Parameter_List);
	}

The code related to level control is located in the file "/quartz/demo/QCLI_demo/src/zigbee/clusters/zcl_levelcontrol_demo.c".

QCLI_Command_Status_t d_cmd_ZCL_LevelControl_MoveToLevel(uint32_t Parameter_Count, QCLI_Parameter_t *Parameter_List);
QCLI_Command_Status_t d_cmd_ZCL_LevelControl_MoveToLevel(uint32_t Parameter_Count, QCLI_Parameter_t *Parameter_List)
	{
		return cmd_ZCL_LevelControl_MoveToLevel(Parameter_Count, Parameter_List);
	}
	param_temp[3].Integer_Is_Valid = true;
	d_cmd_ZCL_ColorControl_MoveToColorTemp(4, param_temp);
	return 0;

The code related to color on or off status is located in the file "/quartz/demo/QCLI_demo/src/zigbee/clusters/zcl_onoff_demo.c"

QCLI_Command_Status_t	d_cmd_ZCL_OnOff_On(uint32_t	Parameter_Count, QCLI_Parameter_t *Parameter_List);
	QCLI_Command_Status_t	d_cmd_ZCL_OnOff_Off(uint32_t	Parameter_Count, QCLI_Parameter_t *Parameter_List);
	
	QCLI_Command_Status_t	d_cmd_ZCL_OnOff_On(uint32_t	Parameter_Count, QCLI_Parameter_t *Parameter_List)
	{
 
		return cmd_ZCL_OnOff_On(Parameter_Count, Parameter_List);
	}
	
	QCLI_Command_Status_t	d_cmd_ZCL_OnOff_Off(uint32_t	Parameter_Count, QCLI_Parameter_t *Parameter_List)
	{
		return cmd_ZCL_OnOff_Off(Parameter_Count, Parameter_List);
	}

The code related to endpoint creation is located at "/quartz/demo/QCLI_demo/src/zigbee/zcl_demo.c".

QCLI_Command_Status_t d_cmd_ZB_CL_CreateEndpoint(uint32_t Parameter_Count, QCLI_Parameter_t *Parameter_List);
	
	QCLI_Command_Status_t d_cmd_ZB_CL_CreateEndpoint(uint32_t Parameter_Count, QCLI_Parameter_t *Parameter_List)
	{
		return cmd_ZB_CL_CreateEndpoint(Parameter_Count, Parameter_List);
	}

Encapsulate below functions "d_cmd_ZB_AddDevice", “d_cmd_ZB_AddDevice", "d_cmd_ZB_SetBIB", "d_cmd_ZB_Initialize".

QCLI_Command_Status_t d_cmd_ZB_AddDevice(uint32_t Parameter_Count, QCLI_Parameter_t *Parameter_List);
QCLI_Command_Status_t d_cmd_ZB_AddDevice(uint32_t Parameter_Count, QCLI_Parameter_t *Parameter_List);
QCLI_Command_Status_t d_cmd_ZB_SetBIB(uint32_t Parameter_Count, QCLI_Parameter_t *Parameter_List);
QCLI_Command_Status_t d_cmd_ZB_Initialize(uint32_t Parameter_Count,
QCLI_Parameter_t *Parameter_List);
QCLI_Command_Status_t d_cmd_ZB_Initialize(uint32_t Parameter_Count,
QCLI_Parameter_t *Parameter_List)
{
return cmd_ZB_Initialize(Parameter_Count, Parameter_List);
}
QCLI_Command_Status_t d_cmd_ZB_AddDevice(uint32_t Parameter_Count, QCLI_Parameter_t *Parameter_List)
{
	return cmd_ZB_AddDevice(Parameter_Count, Parameter_List);
}
QCLI_Command_Status_t d_cmd_ZB_Form(uint32_t Parameter_Count, QCLI_Parameter_t *Parameter_List)
{
	return cmd_ZB_Form(Parameter_Count, Parameter_List);
}
QCLI_Command_Status_t d_cmd_ZB_SetBIB(uint32_t Parameter_Count, QCLI_Parameter_t *Parameter_List)
{
	return cmd_ZB_SetBIB(Parameter_Count, Parameter_List);
}

Now that you understand how controlling the light bulb is implemented in the project, below are some usage instructions to test the project.

  1. Power on the QCA4020 via the power button, and the QCA4020 will build the Zigbee network automatically.
  2. Power on the Zigbee bulb, and it will join the Zigbee network automatically.
  3. Use the “Azure_console” app on the mobile phone to:
    1. Control on or off status of bulb via clicking “Open” or “Close” button
    2. Control color temperature via setting the values ranged from “0x0000~0xFFFF”
    3. Control dim via setting the values ranged from “0~255”
NameEmailCompany
Yang[email protected]Thundersoft
Jay[email protected]Thundersoft
Scott[email protected]Thundersoft