Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

While we wait for more development what are you testing on your board? Please share ideas and code. #19

Open
pawilli opened this issue Dec 30, 2022 · 12 comments

Comments

@pawilli
Copy link

pawilli commented Dec 30, 2022

This git page gets updated too slowly. If you are like me you would have gotten frustrated and started testing on your own.

Please share applications, ideas, code or suggestions - lets help them make this t-zigbee board reach its full potential.

I will start with two applications that I find useful -

a) Battery backup Zigbee Router

Works on mains but automatically switches to battery with no lose of connectivity for those times when you lose power.
T-zigbee as a Battery backup Zigbee Router

b) WLED on T-zigbee board

Yes the board comes with an ESP32-C3 MCU but you can download the source code from Aircookie and use a customized platformio_override.ini to compile your own firmware.
Button works with macros in WLED but I can't find a way to initiate the Telink TLSR8258 MCU for concurrent zigbee operations yet...

Battery backup Zigbee

I will post a full description of each for you to try and improve on.

Thanks

@joshuajonah
Copy link

joshuajonah commented Feb 14, 2023

Nothing that exciting yet. Just modified the sensor_demo to support a DS18B20 via OneWire so I can keep track of the water temperature in my pool pipes. Nobody makes a ZigBee device that does this so I had to take things into my own hands to avoid wifi.

PXL_20230214_015347849

@pawilli
Copy link
Author

pawilli commented Feb 14, 2023

Nothing that exciting yet. Just modified the sensor_demo to support a DS18B20 via OneWire so I can keep track of the water temperature in my pool pipes. Nobody makes a ZigBee device that does this so I had to take things into my own hands to avoid wifi.

PXL_20230214_015347849

This is actually a great idea. I tried to do it and failed. Can you share your modified code please? I want to use the DS18B20 to monitor my freezer temperature. i am currently using a Xiaomi WSDCGQ11LM in a ziplock bag but the battery is draining fast.

Thank you

@joshuajonah
Copy link

joshuajonah commented Feb 14, 2023

It's pretty straight forward. This sends a zigbee message with the current temp every 5 seconds. It's just a standard DS18B20 with a 4.7k pull-up resistor connected to GPIO5 of the board.

#include <Arduino.h>
#include <zbhci.h>
#include <OneButton.h>
#include "esp_task_wdt.h"
#include <OneWire.h>
#include <DS18B20.h>

#define CONFIG_ZIGBEE_MODULE_PIN 0
#define CONFIG_USR_BUTTON_PIN 2
#define CONFIG_BLUE_LIGHT_PIN 3
#define CONFIG_DS18B20_PIN 5

#define REPORTING_PERIOD 10

OneWire oneWire(CONFIG_DS18B20_PIN);
DS18B20 sensor(&oneWire);

const uint8_t au8ManufacturerName[] = {13,'L','I','L','Y','G','O', '.', 'S', 'e', 'n', 's', 'o', 'r'};

QueueHandle_t msg_queue;

/**
 * Initialize a new OneButton instance for a button
 * connected to digital pin 4 and GND, which is active low
 * and uses the internal pull-up resistor.
 */
OneButton btn = OneButton(CONFIG_USR_BUTTON_PIN,     // Input pin for the button
                          true,  // Button is active LOW
                          true); // Enable internal pull-up resistor

ts_DstAddr sDstAddr;

void setup()
{
    sDstAddr.u16DstAddr = 0x0000;

    Serial.begin(9600);
    sensor.begin();
    delay(10);
    Serial.printf("Init\n");

    sensor.requestTemperatures();
    while (!sensor.isConversionComplete());

    pinMode(CONFIG_ZIGBEE_MODULE_PIN, OUTPUT);
    digitalWrite(CONFIG_ZIGBEE_MODULE_PIN, HIGH);
    delay(500);

    pinMode(CONFIG_BLUE_LIGHT_PIN, OUTPUT);
    digitalWrite(CONFIG_BLUE_LIGHT_PIN, LOW);

    btn.attachClick(handleClick);
    btn.attachDoubleClick(handleDoubleClick);
    btn.setPressTicks(3000);
    btn.attachLongPressStart(handleLongPress);

    msg_queue = xQueueCreate(10, sizeof(ts_HciMsg));
    zbhci_Init(msg_queue);

    xTaskCreatePinnedToCore(
        zbhciTask,
        "zbhci",   // A name just for humans
        4096,          // This stack size can be checked & adjusted by reading the Stack Highwater
        NULL,
        5,             // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
        NULL ,
        ARDUINO_RUNNING_CORE);

    // zbhci_BdbFactoryReset();
    delay(100);
    zbhci_NetworkStateReq();
    
}


void loop()
{
    static unsigned long last_time = 0;
    
    if(millis() - last_time > 5000) {
        sensor.requestTemperatures();
        int16_t t = (int) (sensor.getTempC()*100);
        zbhci_ZclSendReportCmd(0x02, sDstAddr, 1, 1, 0, 1, 0x0402, 0x0000, ZCL_DATA_TYPE_DATA16, 2, (uint8_t *)&t);
        btn.tick();
        last_time = millis();
    }
}

uint8_t ledState = 0;
uint8_t netState = 0;
uint8_t autoReport = 0;

void handleClick(void)
{
    
    if (netState == 1)
    {
        sensor.requestTemperatures();
        int16_t t = (int) (sensor.getTempC()*100);
        Serial.printf("temp=%f", (float)(t/100.0));
        zbhci_ZclSendReportCmd(0x02, sDstAddr, 1, 1, 0, 1, 0x0402, 0x0000, ZCL_DATA_TYPE_DATA16, 2, (uint8_t *)&t);
        delay(100);
    }
    else
    {
        Serial.println("Not joined the zigbee network");
    }

    digitalWrite(CONFIG_BLUE_LIGHT_PIN, true);
    delay(2000);
    digitalWrite(CONFIG_BLUE_LIGHT_PIN, false);
}

void reportTask(void *pvParameters)
{
    while (autoReport)
    {
        digitalWrite(CONFIG_BLUE_LIGHT_PIN, true);

        sensor.requestTemperatures();
        int16_t t = (int) (sensor.getTempC()*100);
        zbhci_ZclSendReportCmd(0x02, sDstAddr, 1, 1, 0, 1, 0x0402, 0x0000, ZCL_DATA_TYPE_DATA16, 2, (uint8_t *)&t);
        
        vTaskDelay(100 / portTICK_PERIOD_MS);
        
        digitalWrite(CONFIG_BLUE_LIGHT_PIN, false);
        vTaskDelay(REPORTING_PERIOD * 1000 / portTICK_PERIOD_MS);    
    }
}

void handleDoubleClick(void)
{
    if (autoReport == 0)
    {
        autoReport = 1;
        xTaskCreatePinnedToCore(
            reportTask,
            "report",      // A name just for humans
            4096,          // This stack size can be checked & adjusted by reading the Stack Highwater
            NULL,
            6,             // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
            NULL ,
            ARDUINO_RUNNING_CORE);
    }
    else
    {
        autoReport = 0;
        Serial.println("Stop report task");
        delay(1000);
    }
}

void handleLongPress()
{
    if (netState == 0)
    {
        Serial.println("Joining the zigbee network");
        zbhci_BdbCommissionSteer();
        vTaskDelay(100 / portTICK_PERIOD_MS);
    }
    else if (netState == 1)
    {
        Serial.println("leave the zigbee network");
        zbhci_BdbFactoryReset();
        vTaskDelay(1000 / portTICK_PERIOD_MS);
        netState = 0;
    }
}


void zbhciTask(void *pvParameters)
{
    ts_HciMsg sHciMsg;
    ts_DstAddr sDstAddr;

    while (1)
    {
        bzero(&sHciMsg, sizeof(sHciMsg));
        if (xQueueReceive(msg_queue, &sHciMsg, portMAX_DELAY))
        {
            switch (sHciMsg.u16MsgType)
            {
                case ZBHCI_CMD_ACKNOWLEDGE:
                    // displayAcknowledg(&sHciMsg.uPayload.sAckPayload);
                break;

                case ZBHCI_CMD_NETWORK_STATE_RSP:
                    if (sHciMsg.uPayload.sNetworkStateRspPayloasd.u16NwkAddr == 0x0000)
                    {
                        zbhci_BdbFactoryReset();
                        vTaskDelay(1000 / portTICK_PERIOD_MS);
                        zbhci_NetworkStateReq();
                    }
                    else if (sHciMsg.uPayload.sNetworkStateRspPayloasd.u16NwkAddr != 0xFFFF)
                    {
                        netState = 1;
                    }
                break;

                case ZBHCI_CMD_NETWORK_STATE_REPORT:
                    netState = 1;
                    sDstAddr.u16DstAddr = 0x0000;
                    zbhci_ZclSendReportCmd(0x02, sDstAddr, 1, 1, 0, 1, 0x0000, 0x0005, ZCL_DATA_TYPE_CHAR_STR, sizeof(au8ManufacturerName), (uint8_t *)&au8ManufacturerName);
                break;

                case ZBHCI_CMD_ZCL_ONOFF_CMD_RCV:
                    /*
                    if (sHciMsg.uPayload.sZclOnOffCmdRcvPayload.u8CmdId == 0)
                    {
                        digitalWrite(CONFIG_BLUE_LIGHT_PIN, LOW);
                        ledState = 0;
                    }
                    else if (sHciMsg.uPayload.sZclOnOffCmdRcvPayload.u8CmdId == 1)
                    {
                        digitalWrite(CONFIG_BLUE_LIGHT_PIN, HIGH);
                        ledState = 1;
                    }
                    else if (sHciMsg.uPayload.sZclOnOffCmdRcvPayload.u8CmdId == 2)
                    {
                        ledState = !ledState;
                        digitalWrite(CONFIG_BLUE_LIGHT_PIN, ledState);
                    }
                    zbhci_ZclSendReportCmd(0x02, sDstAddr, 1, 1, 0, 1, 0x0006, 0x0000, ZCL_DATA_TYPE_BOOLEAN, 1, &ledState);
                    */
                break;

                default:
                    Serial.printf("u16MsgType %d\n", sHciMsg.u16MsgType);
                break;
            }
        }
        vTaskDelay(100 / portTICK_PERIOD_MS);
    }
}

@wes58
Copy link

wes58 commented Apr 28, 2023

Hi, @pawilli
If you want to useTLSR8258 MCU for concurrent zigbee/Ble mode you need to replace TLRS8258 with a 1MB chip. 512k chip doesn't work with concurrent SDK. I did that, and it works fine.

@jrossouw
Copy link

jrossouw commented Sep 7, 2023

I have started a project to replace an existing custom Z-Wave product with the new T-Zigbee module. It is a driveway sensor which alerts my Homey Pro controller of movement in the driveway - which in turn switches on the driveway lights. The whole system runs of a 12V AGM battery charged by a solar panel. The device also reports the battery voltage (so that the controller can switch off the lights when the battery runs low) as well as the temperature and humidity.

I currently have the light-switch (onoff), humidity and temperature sensors working. What is not working is reporting the motion alarm (via IAS Zone cluster) and the battery voltage (via the Electrical measurement cluster). I am sure the zbhci_ZclSendReportCmd call for these needs to be passsed a stuct, but I cannot find any documentation on how to set that up? Can anyone assist.

The full source code is available here:

https://github.com/jrossouw/zigbee-driveway

I am also happy to share the app I developed for the Homey Pro (early 2023) if anyone is interested.

@wes58
Copy link

wes58 commented Sep 8, 2023

I currently have the light-switch (onoff), humidity and temperature sensors working. What is not working is reporting the motion alarm (via IAS Zone cluster) and the battery voltage (via the Electrical measurement cluster). I am sure the zbhci_ZclSendReportCmd call for these needs to be passsed a stuct, but I cannot find any documentation on how to set that up? Can anyone assist.

Hi,
The IAS_Zone Cluster reply is not through zbhci_ZclSendReportCmd.
What I have for door sensor or Motion Sensor is something like this, which is sent when the sensor is activated:
` epInfo_t dstEpInfo;
memset((u8 *)&dstEpInfo, 0, sizeof(epInfo_t));
dstEpInfo.dstAddrMode = APS_SHORT_DSTADDR_WITHEP;
dstEpInfo.dstEp = DEST_ENDPOINT; //1
dstEpInfo.dstAddr.shortAddr = 0xFFFC; //Broadcast to routers only
dstEpInfo.profileId = HA_PROFILE_ID;
zoneStatusChangeNoti_t statusChangeNotification;
statusChangeNotification.zoneStatus = ZONE_STATUS_BIT_ALARM1; //alarm that triggered
statusChangeNotification.extStatus = 0;
statusChangeNotification.zoneId = g_zcl_iasZoneAttrs.zoneId; //front door ZCL_ZONE_ID_INVALID;
statusChangeNotification.delay = g_zcl_iasZoneAttrs.zoneDelay;
zcl_iasZone_statusChangeNotificationCmd(DOOR_SENSOR_ENDPOINT, &dstEpInfo, TRUE, &statusChangeNotification);

`
Of course, if you do it only for yourself you can change the structure zoneStatusChangeNoti_t to suit your needs.
For example, because zoneStatus in structure zoneStatusChangeNoti_t is 16bit - I send the status/change of the device in 1byte and battery voltage in the second byte.

By the way, I don't know what you are doing, but I am using zigbee modules in my home automation to control light, power outlets, air con, motion sensor, door sensor etc.
I am using T-ZigBee module only for the gateway, And as I wrote before, I have replaced TLSR8258 in the module with 1MB flash type so I can use Zigbee and BLE Concurrent mode.
For the rest of devices I use ZYZB010 TLSR8258 modules from AliExpress. There is no need for ESP32 modules on the devices, and the current consumption is very low. They have pre-programmed different functions but I always write and flash my code.

@jrossouw
Copy link

jrossouw commented Sep 8, 2023

Hi,
I have a number of custom Z-Wave sensors that are based on Z-Uno - but that is becoming to expensive to maintain. Was looking for a cheaper option hence trying out Zigbee. I stumbled across the LILYGO T-Zigbee module and that looked like a nice simple solution. I will check out those modules you have listed as well.
It does not look like the zbhci library supplied with the T-Zigbee exposes that API. I will have to figure out how to update the firmware for the TLSR8258 to add that then? Do you have code you are willing to share?

@wes58
Copy link

wes58 commented Sep 8, 2023

Hi,
My code is for Telink Zigbee TLSR8258 not for ESP32.
So you would have to learn a bit.

  1. Download Telink IDE http://wiki.telink-semi.cn/wiki/IDE-and-Tools/IDE-for-TLSR8-Chips/
  2. Download Telink ZigBee SDK http://wiki.telink-semi.cn/wiki/chip-series/TLSR825x-Series/
  3. Read about ZigBee, Have a look at example projects in ZigBee SDK.
  4. You will find an example of ZigBee Gateway there - that's what T-ZigBee is using. It has the code to receive response for IAS Notification. There is also an example of the IAS Sensor.
  5. When you are ready to flash the chip - you can buy Telink Burning Tool for example at Mouser TLSRGSOCBK56B https://www.mouser.com/ProductDetail/Telink/TLSRGSOCBK56B?qs=81r%252BiQLm7BQAbjiF1EZxkg%3D%3D It costs a bit, but like I now have around 20 ZigBee modules it is not much.
  6. Download Software for flashing http://wiki.telink-semi.cn/wiki/IDE-and-Tools/Burning-and-Debugging-Tools-for-all-Series/

I know that it will take some time to learn about ZigBee (I started from knowing nothing), but it works well and if you make your own devices it is quite chip.

@jrossouw
Copy link

I have started a new Dokuwiki page for sharing home automation related stuff

https://www.homeautomation-projects.net/doku.php?id=start

Send me an email at johan@rossouw.page if you would like to contribute

@mozolin
Copy link

mozolin commented Jan 31, 2024

It's pretty straight forward. This sends a zigbee message with the current temp every 5 seconds. It's just a standard DS18B20 with a 4.7k pull-up resistor connected to GPIO5 of the board.

#include <Arduino.h>
#include <zbhci.h>
#include <OneButton.h>
#include "esp_task_wdt.h"
#include <OneWire.h>
#include <DS18B20.h>

#define CONFIG_ZIGBEE_MODULE_PIN 0
#define CONFIG_USR_BUTTON_PIN 2
#define CONFIG_BLUE_LIGHT_PIN 3
#define CONFIG_DS18B20_PIN 5

#define REPORTING_PERIOD 10

OneWire oneWire(CONFIG_DS18B20_PIN);
DS18B20 sensor(&oneWire);

const uint8_t au8ManufacturerName[] = {13,'L','I','L','Y','G','O', '.', 'S', 'e', 'n', 's', 'o', 'r'};

QueueHandle_t msg_queue;

/**
 * Initialize a new OneButton instance for a button
 * connected to digital pin 4 and GND, which is active low
 * and uses the internal pull-up resistor.
 */
OneButton btn = OneButton(CONFIG_USR_BUTTON_PIN,     // Input pin for the button
                          true,  // Button is active LOW
                          true); // Enable internal pull-up resistor

ts_DstAddr sDstAddr;

void setup()
{
    sDstAddr.u16DstAddr = 0x0000;

    Serial.begin(9600);
    sensor.begin();
    delay(10);
    Serial.printf("Init\n");

    sensor.requestTemperatures();
    while (!sensor.isConversionComplete());

    pinMode(CONFIG_ZIGBEE_MODULE_PIN, OUTPUT);
    digitalWrite(CONFIG_ZIGBEE_MODULE_PIN, HIGH);
    delay(500);

    pinMode(CONFIG_BLUE_LIGHT_PIN, OUTPUT);
    digitalWrite(CONFIG_BLUE_LIGHT_PIN, LOW);

    btn.attachClick(handleClick);
    btn.attachDoubleClick(handleDoubleClick);
    btn.setPressTicks(3000);
    btn.attachLongPressStart(handleLongPress);

    msg_queue = xQueueCreate(10, sizeof(ts_HciMsg));
    zbhci_Init(msg_queue);

    xTaskCreatePinnedToCore(
        zbhciTask,
        "zbhci",   // A name just for humans
        4096,          // This stack size can be checked & adjusted by reading the Stack Highwater
        NULL,
        5,             // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
        NULL ,
        ARDUINO_RUNNING_CORE);

    // zbhci_BdbFactoryReset();
    delay(100);
    zbhci_NetworkStateReq();
    
}


void loop()
{
    static unsigned long last_time = 0;
    
    if(millis() - last_time > 5000) {
        sensor.requestTemperatures();
        int16_t t = (int) (sensor.getTempC()*100);
        zbhci_ZclSendReportCmd(0x02, sDstAddr, 1, 1, 0, 1, 0x0402, 0x0000, ZCL_DATA_TYPE_DATA16, 2, (uint8_t *)&t);
        btn.tick();
        last_time = millis();
    }
}

uint8_t ledState = 0;
uint8_t netState = 0;
uint8_t autoReport = 0;

void handleClick(void)
{
    
    if (netState == 1)
    {
        sensor.requestTemperatures();
        int16_t t = (int) (sensor.getTempC()*100);
        Serial.printf("temp=%f", (float)(t/100.0));
        zbhci_ZclSendReportCmd(0x02, sDstAddr, 1, 1, 0, 1, 0x0402, 0x0000, ZCL_DATA_TYPE_DATA16, 2, (uint8_t *)&t);
        delay(100);
    }
    else
    {
        Serial.println("Not joined the zigbee network");
    }

    digitalWrite(CONFIG_BLUE_LIGHT_PIN, true);
    delay(2000);
    digitalWrite(CONFIG_BLUE_LIGHT_PIN, false);
}

void reportTask(void *pvParameters)
{
    while (autoReport)
    {
        digitalWrite(CONFIG_BLUE_LIGHT_PIN, true);

        sensor.requestTemperatures();
        int16_t t = (int) (sensor.getTempC()*100);
        zbhci_ZclSendReportCmd(0x02, sDstAddr, 1, 1, 0, 1, 0x0402, 0x0000, ZCL_DATA_TYPE_DATA16, 2, (uint8_t *)&t);
        
        vTaskDelay(100 / portTICK_PERIOD_MS);
        
        digitalWrite(CONFIG_BLUE_LIGHT_PIN, false);
        vTaskDelay(REPORTING_PERIOD * 1000 / portTICK_PERIOD_MS);    
    }
}

void handleDoubleClick(void)
{
    if (autoReport == 0)
    {
        autoReport = 1;
        xTaskCreatePinnedToCore(
            reportTask,
            "report",      // A name just for humans
            4096,          // This stack size can be checked & adjusted by reading the Stack Highwater
            NULL,
            6,             // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
            NULL ,
            ARDUINO_RUNNING_CORE);
    }
    else
    {
        autoReport = 0;
        Serial.println("Stop report task");
        delay(1000);
    }
}

void handleLongPress()
{
    if (netState == 0)
    {
        Serial.println("Joining the zigbee network");
        zbhci_BdbCommissionSteer();
        vTaskDelay(100 / portTICK_PERIOD_MS);
    }
    else if (netState == 1)
    {
        Serial.println("leave the zigbee network");
        zbhci_BdbFactoryReset();
        vTaskDelay(1000 / portTICK_PERIOD_MS);
        netState = 0;
    }
}


void zbhciTask(void *pvParameters)
{
    ts_HciMsg sHciMsg;
    ts_DstAddr sDstAddr;

    while (1)
    {
        bzero(&sHciMsg, sizeof(sHciMsg));
        if (xQueueReceive(msg_queue, &sHciMsg, portMAX_DELAY))
        {
            switch (sHciMsg.u16MsgType)
            {
                case ZBHCI_CMD_ACKNOWLEDGE:
                    // displayAcknowledg(&sHciMsg.uPayload.sAckPayload);
                break;

                case ZBHCI_CMD_NETWORK_STATE_RSP:
                    if (sHciMsg.uPayload.sNetworkStateRspPayloasd.u16NwkAddr == 0x0000)
                    {
                        zbhci_BdbFactoryReset();
                        vTaskDelay(1000 / portTICK_PERIOD_MS);
                        zbhci_NetworkStateReq();
                    }
                    else if (sHciMsg.uPayload.sNetworkStateRspPayloasd.u16NwkAddr != 0xFFFF)
                    {
                        netState = 1;
                    }
                break;

                case ZBHCI_CMD_NETWORK_STATE_REPORT:
                    netState = 1;
                    sDstAddr.u16DstAddr = 0x0000;
                    zbhci_ZclSendReportCmd(0x02, sDstAddr, 1, 1, 0, 1, 0x0000, 0x0005, ZCL_DATA_TYPE_CHAR_STR, sizeof(au8ManufacturerName), (uint8_t *)&au8ManufacturerName);
                break;

                case ZBHCI_CMD_ZCL_ONOFF_CMD_RCV:
                    /*
                    if (sHciMsg.uPayload.sZclOnOffCmdRcvPayload.u8CmdId == 0)
                    {
                        digitalWrite(CONFIG_BLUE_LIGHT_PIN, LOW);
                        ledState = 0;
                    }
                    else if (sHciMsg.uPayload.sZclOnOffCmdRcvPayload.u8CmdId == 1)
                    {
                        digitalWrite(CONFIG_BLUE_LIGHT_PIN, HIGH);
                        ledState = 1;
                    }
                    else if (sHciMsg.uPayload.sZclOnOffCmdRcvPayload.u8CmdId == 2)
                    {
                        ledState = !ledState;
                        digitalWrite(CONFIG_BLUE_LIGHT_PIN, ledState);
                    }
                    zbhci_ZclSendReportCmd(0x02, sDstAddr, 1, 1, 0, 1, 0x0006, 0x0000, ZCL_DATA_TYPE_BOOLEAN, 1, &ledState);
                    */
                break;

                default:
                    Serial.printf("u16MsgType %d\n", sHciMsg.u16MsgType);
                break;
            }
        }
        vTaskDelay(100 / portTICK_PERIOD_MS);
    }
}

It would be great to see the entire code of your project - I mean, you changed more than just sensor_demo.ino, I guess... ;-)
Thanks a million in advance!

@omegasxxi
Copy link

It's pretty straight forward. This sends a zigbee message with the current temp every 5 seconds. It's just a standard DS18B20 with a 4.7k pull-up resistor connected to GPIO5 of the board.

#include <Arduino.h>
#include <zbhci.h>
#include <OneButton.h>
#include "esp_task_wdt.h"
#include <OneWire.h>
#include <DS18B20.h>

#define CONFIG_ZIGBEE_MODULE_PIN 0
#define CONFIG_USR_BUTTON_PIN 2
#define CONFIG_BLUE_LIGHT_PIN 3
#define CONFIG_DS18B20_PIN 5

#define REPORTING_PERIOD 10

OneWire oneWire(CONFIG_DS18B20_PIN);
DS18B20 sensor(&oneWire);

const uint8_t au8ManufacturerName[] = {13,'L','I','L','Y','G','O', '.', 'S', 'e', 'n', 's', 'o', 'r'};

QueueHandle_t msg_queue;

/**
 * Initialize a new OneButton instance for a button
 * connected to digital pin 4 and GND, which is active low
 * and uses the internal pull-up resistor.
 */
OneButton btn = OneButton(CONFIG_USR_BUTTON_PIN,     // Input pin for the button
                          true,  // Button is active LOW
                          true); // Enable internal pull-up resistor

ts_DstAddr sDstAddr;

void setup()
{
    sDstAddr.u16DstAddr = 0x0000;

    Serial.begin(9600);
    sensor.begin();
    delay(10);
    Serial.printf("Init\n");

    sensor.requestTemperatures();
    while (!sensor.isConversionComplete());

    pinMode(CONFIG_ZIGBEE_MODULE_PIN, OUTPUT);
    digitalWrite(CONFIG_ZIGBEE_MODULE_PIN, HIGH);
    delay(500);

    pinMode(CONFIG_BLUE_LIGHT_PIN, OUTPUT);
    digitalWrite(CONFIG_BLUE_LIGHT_PIN, LOW);

    btn.attachClick(handleClick);
    btn.attachDoubleClick(handleDoubleClick);
    btn.setPressTicks(3000);
    btn.attachLongPressStart(handleLongPress);

    msg_queue = xQueueCreate(10, sizeof(ts_HciMsg));
    zbhci_Init(msg_queue);

    xTaskCreatePinnedToCore(
        zbhciTask,
        "zbhci",   // A name just for humans
        4096,          // This stack size can be checked & adjusted by reading the Stack Highwater
        NULL,
        5,             // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
        NULL ,
        ARDUINO_RUNNING_CORE);

    // zbhci_BdbFactoryReset();
    delay(100);
    zbhci_NetworkStateReq();
    
}


void loop()
{
    static unsigned long last_time = 0;
    
    if(millis() - last_time > 5000) {
        sensor.requestTemperatures();
        int16_t t = (int) (sensor.getTempC()*100);
        zbhci_ZclSendReportCmd(0x02, sDstAddr, 1, 1, 0, 1, 0x0402, 0x0000, ZCL_DATA_TYPE_DATA16, 2, (uint8_t *)&t);
        btn.tick();
        last_time = millis();
    }
}

uint8_t ledState = 0;
uint8_t netState = 0;
uint8_t autoReport = 0;

void handleClick(void)
{
    
    if (netState == 1)
    {
        sensor.requestTemperatures();
        int16_t t = (int) (sensor.getTempC()*100);
        Serial.printf("temp=%f", (float)(t/100.0));
        zbhci_ZclSendReportCmd(0x02, sDstAddr, 1, 1, 0, 1, 0x0402, 0x0000, ZCL_DATA_TYPE_DATA16, 2, (uint8_t *)&t);
        delay(100);
    }
    else
    {
        Serial.println("Not joined the zigbee network");
    }

    digitalWrite(CONFIG_BLUE_LIGHT_PIN, true);
    delay(2000);
    digitalWrite(CONFIG_BLUE_LIGHT_PIN, false);
}

void reportTask(void *pvParameters)
{
    while (autoReport)
    {
        digitalWrite(CONFIG_BLUE_LIGHT_PIN, true);

        sensor.requestTemperatures();
        int16_t t = (int) (sensor.getTempC()*100);
        zbhci_ZclSendReportCmd(0x02, sDstAddr, 1, 1, 0, 1, 0x0402, 0x0000, ZCL_DATA_TYPE_DATA16, 2, (uint8_t *)&t);
        
        vTaskDelay(100 / portTICK_PERIOD_MS);
        
        digitalWrite(CONFIG_BLUE_LIGHT_PIN, false);
        vTaskDelay(REPORTING_PERIOD * 1000 / portTICK_PERIOD_MS);    
    }
}

void handleDoubleClick(void)
{
    if (autoReport == 0)
    {
        autoReport = 1;
        xTaskCreatePinnedToCore(
            reportTask,
            "report",      // A name just for humans
            4096,          // This stack size can be checked & adjusted by reading the Stack Highwater
            NULL,
            6,             // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
            NULL ,
            ARDUINO_RUNNING_CORE);
    }
    else
    {
        autoReport = 0;
        Serial.println("Stop report task");
        delay(1000);
    }
}

void handleLongPress()
{
    if (netState == 0)
    {
        Serial.println("Joining the zigbee network");
        zbhci_BdbCommissionSteer();
        vTaskDelay(100 / portTICK_PERIOD_MS);
    }
    else if (netState == 1)
    {
        Serial.println("leave the zigbee network");
        zbhci_BdbFactoryReset();
        vTaskDelay(1000 / portTICK_PERIOD_MS);
        netState = 0;
    }
}


void zbhciTask(void *pvParameters)
{
    ts_HciMsg sHciMsg;
    ts_DstAddr sDstAddr;

    while (1)
    {
        bzero(&sHciMsg, sizeof(sHciMsg));
        if (xQueueReceive(msg_queue, &sHciMsg, portMAX_DELAY))
        {
            switch (sHciMsg.u16MsgType)
            {
                case ZBHCI_CMD_ACKNOWLEDGE:
                    // displayAcknowledg(&sHciMsg.uPayload.sAckPayload);
                break;

                case ZBHCI_CMD_NETWORK_STATE_RSP:
                    if (sHciMsg.uPayload.sNetworkStateRspPayloasd.u16NwkAddr == 0x0000)
                    {
                        zbhci_BdbFactoryReset();
                        vTaskDelay(1000 / portTICK_PERIOD_MS);
                        zbhci_NetworkStateReq();
                    }
                    else if (sHciMsg.uPayload.sNetworkStateRspPayloasd.u16NwkAddr != 0xFFFF)
                    {
                        netState = 1;
                    }
                break;

                case ZBHCI_CMD_NETWORK_STATE_REPORT:
                    netState = 1;
                    sDstAddr.u16DstAddr = 0x0000;
                    zbhci_ZclSendReportCmd(0x02, sDstAddr, 1, 1, 0, 1, 0x0000, 0x0005, ZCL_DATA_TYPE_CHAR_STR, sizeof(au8ManufacturerName), (uint8_t *)&au8ManufacturerName);
                break;

                case ZBHCI_CMD_ZCL_ONOFF_CMD_RCV:
                    /*
                    if (sHciMsg.uPayload.sZclOnOffCmdRcvPayload.u8CmdId == 0)
                    {
                        digitalWrite(CONFIG_BLUE_LIGHT_PIN, LOW);
                        ledState = 0;
                    }
                    else if (sHciMsg.uPayload.sZclOnOffCmdRcvPayload.u8CmdId == 1)
                    {
                        digitalWrite(CONFIG_BLUE_LIGHT_PIN, HIGH);
                        ledState = 1;
                    }
                    else if (sHciMsg.uPayload.sZclOnOffCmdRcvPayload.u8CmdId == 2)
                    {
                        ledState = !ledState;
                        digitalWrite(CONFIG_BLUE_LIGHT_PIN, ledState);
                    }
                    zbhci_ZclSendReportCmd(0x02, sDstAddr, 1, 1, 0, 1, 0x0006, 0x0000, ZCL_DATA_TYPE_BOOLEAN, 1, &ledState);
                    */
                break;

                default:
                    Serial.printf("u16MsgType %d\n", sHciMsg.u16MsgType);
                break;
            }
        }
        vTaskDelay(100 / portTICK_PERIOD_MS);
    }
}

Hi, I'm looking for exactly for the same you did but I have no experience with this board. Could you share the complete code?
It will also help me to understand the programming
Thanks in advance

@mozolin
Copy link

mozolin commented Mar 29, 2024

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants