Openthread without raspberry pi

200 views
Skip to first unread message

Sri Naga Chaitanya Gandhavalla

unread,
Mar 8, 2021, 2:38:47 AM3/8/21
to openthread-users
Dear,

I am using efr32mg12 2.4ghz BRD4161A Radio broads using simplicity studio V5.

my project raget is i want create mesh network.

I want make LED light ON/OFF in light device(3-4 devices) FROM THE SWITCH device BUTTON.

i am thinking to use you can use a Thread FTD (Full Thread Device) to act as Thread leader to form Thread network. Then, use some other FTD to act as Thread router and MTD (Minimal Thread Device) to act as end device to join the network for testing Thread mesh network. For controlling 3-4 lights from switch device, i am thinking to  implement light functionality on routers and switch on end device to make it.

for the over communicate i am Thinking to use UDP Protocol to make light on/off in light devices from the switch button. 

Can you any help me how can i make this functionality in code.

can you anyone suggest me any example code to achieve this functionality. 

I will wait for your kind response regarding this here.

Thanking you in advance.  

Jonathan Hui

unread,
Mar 8, 2021, 1:20:12 PM3/8/21
to Sri Naga Chaitanya Gandhavalla, openthread-users
Our Developing with OpenThread APIs codelab might be helpful.

--
Jonathan Hui


--
You received this message because you are subscribed to the Google Groups "openthread-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to openthread-use...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/openthread-users/aed9f2f7-5101-447d-8aa2-f700f0a22e00n%40googlegroups.com.

Sri Naga Chaitanya Gandhavalla

unread,
Mar 9, 2021, 9:15:32 AM3/9/21
to openthread-users
Dear, 

Thanks for your kind response.


I understand that  here coding involves more with C++. 

As a embedded developer i have good knowledge on C compare to c++.

can you suggest what will be better way to approach my target because i am not good at C++  programming.

 my target is to  make on /off  Led in light device from switch device button using mesh network openthread ipv6.

 i am using efr32mg12p silicon lab BRD4161A REV 03 mesh networking kit. 

please see the image attachment below for better understand about my doubt. 

I will wait for kind reply regarding this, thanking you.
InkedTCFxg-Captureddd_LI.jpg

Jonathan Hui

unread,
Mar 9, 2021, 1:07:53 PM3/9/21
to Sri Naga Chaitanya Gandhavalla, openthread-users
While OpenThread is implemented using C++, the APIs are all C. You should see that the Developing with OpenThread APIs codelab does not require any C++ programming.

Many vendors supporting OpenThread offer examples as well. If you are using Silicon Labs HW, you could reach out to Silicon Labs to see if they provide any examples in their SDK.

--
Jonathan Hui


Sébastien Parent-Charette

unread,
Mar 9, 2021, 1:21:22 PM3/9/21
to openthread-users
Hello!

Jonathan's recommendation is quite spot on. Since you are using Silicon Labs hardware, you may want to look at the following page. The training includes details about the technology and also a hands-on lab about creating a network. The two main videos are broken down into chapters which you can select at the bottom left corner of the player.

Sincerely,

P.-S.: Viewing the videos require you to login with a free account from Silicon Labs but I figure it is quite likely you already have one since you use their hardware.

Sébastien Parent-Charette

unread,
Mar 9, 2021, 4:57:14 PM3/9/21
to openthread-users
Oh I forgot to mention, even though our training page mentions using SLWRB4170A you can also use other radio boards that are supported for OpenThread when creating example projects in Simplicity Studio. This of course includes the radio module you mentioned (BRD4161A) and plenty of others (full list of thread capable parts here and click kits and boards).

Sri Naga Chaitanya Gandhavalla

unread,
Mar 10, 2021, 11:56:22 AM3/10/21
to openthread-users

Dear, 


Thanks for your references and information.


i have a doubt did i need to add-- coap static void ddl_state_coapHandler(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo) or not? in this application. 


can i use voidUdp() without the coapHANDLER(coap static void ddl_state_coapHandler(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo)) ?

and i understand that why bsp_button is not working here. because it is not defined by hal.configh_h here in  ot-cli-ftd with your expalination.


As per the above suggestion and information i made my main.c using ot-ctl-mtd (child-switch) with button drivers.


please see the below code. i add  gpio_main() , init Udpmain(), and i made button_init and button_get_state and also with some other required functions.

please let me how can i integrate this Udp protocol with button on/off. thanking you. 

#include "sl_component_catalog.h"
#include "sl_system_init.h"
#include "app.h"
#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
#include "sl_power_manager.h"
#endif // SL_CATALOG_POWER_MANAGER_PRESENT
#if defined(SL_CATALOG_KERNEL_PRESENT)
#include "sl_system_kernel.h"
#else // !SL_CATALOG_KERNEL_PRESENT
#include "sl_system_process_action.h"
#endif // SL_CATALOG_KERNEL_PRESENT

#include <string.h>
#include <assert.h>

#include <openthread/cli.h>
#include <openthread/dataset_ftd.h>
#include <openthread/instance.h>
#include <openthread/message.h>
#include <openthread/thread.h>
#include <openthread/udp.h>
#include <openthread/platform/logging.h>
#include <common/logging.hpp>
#include "sl_led.h"
#include "code_utils.h"
#include "sl_simple_led.h"
#include "em_gpio.h"
#include "sl_simple_led_led0_config.h"
#include "em_chip.h"
#include "em_cmu.h"
#include "em_gpio.h"
#include "sl_simple_button.h"
#include "sl_simple_button_config.h"
#include <openthread/coap.h>
#include "utils/code_utils.h"
#include "sl_button.h"
#include "gpiointerrupt.h"
#include "em_cmu.h"
#include "sl_button.h"
#include "sl_simple_button.h"
#include "sl_simple_button_instances.h"
#include <openthread/dataset.h>
#include <openthread/error.h>
#include "sl_component_catalog.h"
#ifdef SL_CATALOG_POWER_MANAGER_PRESENT
#include "sl_power_manager.h"
#endif

void setNetworkConfiguration();
void handleNetifStateChanged();
void initUdp();
void mtdReceiveCallback();

#define MULTICAST_ADDR "ff03::1"
#define MULTICAST_PORT 123
#define RECV_PORT 234
#define SLEEPY_POLL_PERIOD_MS 2000
#define MTD_MESSAGE "mtd button"
#define FTD_MESSAGE "ftd button"
static otInstance *        instance;
static otUdpSocket         sMtdSocket;
static bool                sButtonPressed                 = false;
static bool                sRxOnIdleButtonPressed         = false;
static bool                sAllowSleep                    = false;

int main(int argc, char *argv[])
{

  otLinkModeConfig config;
  otSysInit(argc, argv);
  // Initialize Silicon Labs device, system, service(s) and protocol stack(s).
  // Note that if the kernel is present, processing task(s) will be created by
  // this call.

  sl_system_init();

instance =otInstanceInitSingle();
assert(instance);

otLinkSetPollPeriod(instance, 2000);
setNetworkConfiguration(instance);
otSetStateChangedCallback(instance, handleNetifStateChanged, instance);


      config.mRxOnWhenIdle = true;
      config.mDeviceType   = 0;
      config.mNetworkData  = 0;
      otThreadSetLinkMode(instance, config);

      sl_status_t sl_simple_button_init();
      sl_button_state_t sl_simple_button_get_state();
      void sl_simple_button_enable();
      setNetworkConfiguration();
      handleNetifStateChanged();
      applicationTick();
      gpio_main();

      initUdp();
      otIp6SetEnabled(instance, true);
      otThreadSetEnabled(instance, true);

while (!otSysPseudoResetWasRequested()) {

       otTaskletsProcess(instance);
           otSysProcessDrivers(instance);
           applicationTick();
   }
  #if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
    // Let the CPU go to sleep if the system allows it.
    sl_power_manager_sleep();
#endif
  }

void setNetworkConfiguration(void)
{
    static char          aNetworkName[] = "SleepyEFR32";
    otOperationalDataset aDataset;

    memset(&aDataset, 0, sizeof(otOperationalDataset));

    /*
     * Fields that can be configured in otOperationDataset to override defaults:
     *     Network Name, Mesh Local Prefix, Extended PAN ID, PAN ID, Delay Timer,
     *     Channel, Channel Mask Page 0, Network Master Key, PSKc, Security Policy
     */
    aDataset.mActiveTimestamp                      = 1;
    aDataset.mComponents.mIsActiveTimestampPresent = true;

    /* Set Channel to 15 */
    aDataset.mChannel                      = 13;
    aDataset.mComponents.mIsChannelPresent = true;

    /* Set Pan ID to 2222 */
    aDataset.mPanId                      = (otPanId)0x1234;
    aDataset.mComponents.mIsPanIdPresent = true;

    /* Set Extended Pan ID to C0DE1AB5C0DE1AB5 */
    uint8_t extPanId[OT_EXT_PAN_ID_SIZE] = {0x11, 0x11, 0x11, 0x11, 0x22, 0x22, 0x22, 0x22};
    memcpy(aDataset.mExtendedPanId.m8, extPanId, sizeof(aDataset.mExtendedPanId));
    aDataset.mComponents.mIsExtendedPanIdPresent = true;

    /* Set master key to 1234C0DE1AB51234C0DE1AB51234C0DE */
    uint8_t key[OT_MASTER_KEY_SIZE] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
    memcpy(aDataset.mMasterKey.m8, key, sizeof(aDataset.mMasterKey));
    aDataset.mComponents.mIsMasterKeyPresent = true;

    /* Set Network Name to SleepyEFR32 */
    size_t length = strlen(aNetworkName);
    assert(length <= OT_NETWORK_NAME_MAX_SIZE);
    memcpy(aDataset.mNetworkName.m8, aNetworkName, length);
    aDataset.mComponents.mIsNetworkNamePresent = true;

    otDatasetSetActive(instance, &aDataset);
}
void handleNetifStateChanged(uint32_t aFlags, void *aContext)
{
    otLinkModeConfig config;


    if ((aFlags & OT_CHANGED_THREAD_ROLE) != 0)
    {
        otDeviceRole changedRole = otThreadGetDeviceRole(aContext);

        switch (changedRole)
        {
        case OT_DEVICE_ROLE_LEADER:
        case OT_DEVICE_ROLE_ROUTER:
            break;

        case OT_DEVICE_ROLE_CHILD:
            config.mRxOnWhenIdle       = 0;
            config.mDeviceType         = 0;
            config.mNetworkData        = 0;
            otThreadSetLinkMode(instance, config);
            break;

        case OT_DEVICE_ROLE_DETACHED:
        case OT_DEVICE_ROLE_DISABLED:
            break;
        }
    }
}


void initUdp(void)
{
    otError    error;
    otSockAddr bindAddr;

    // Initialize bindAddr
    memset(&bindAddr, 0, sizeof(bindAddr));
    bindAddr.mPort = RECV_PORT;

    error = otUdpOpen(otGetInstance(), &sMtdSocket, mtdReceiveCallback, NULL);

    if (error != OT_ERROR_NONE)
    {
        return;
    }

    error = otUdpBind(otGetInstance(), &sMtdSocket, &bindAddr);
    if (error != OT_ERROR_NONE)
    {
        otUdpClose(otGetInstance(), &sMtdSocket);
        return;
    }
}


void applicationTick(void)
{
    otError          error = 0;
    otMessageInfo    messageInfo;
    otMessage *      message = NULL;
    const char *     payload = MTD_MESSAGE;
    otLinkModeConfig config;

    if (sRxOnIdleButtonPressed == true)
    {
        sRxOnIdleButtonPressed = false;
        sAllowSleep            = !sAllowSleep;
        config.mRxOnWhenIdle   = !sAllowSleep;
        config.mDeviceType     = 0;
        config.mNetworkData    = 0;
        otThreadSetLinkMode(otGetInstance(), config);

#if (defined(SL_CATALOG_KERNEL_PRESENT) && defined(SL_CATALOG_POWER_MANAGER_PRESENT))
        if (sAllowSleep) {
            sl_power_manager_remove_em_requirement(SL_POWER_MANAGER_EM1);
        } else {
            sl_power_manager_add_em_requirement(SL_POWER_MANAGER_EM1);
        }
#endif
    }

    if (sButtonPressed == true)
    {
        sButtonPressed = false;

        memset(&messageInfo, 0, sizeof(messageInfo));
        otIp6AddressFromString(MULTICAST_ADDR, &messageInfo.mPeerAddr);
        messageInfo.mPeerPort = MULTICAST_PORT;

        message = otUdpNewMessage(otGetInstance(), NULL);

        if (message != NULL)
        {
            error = otMessageAppend(message, payload, (uint16_t)strlen(payload));

            if (error == OT_ERROR_NONE)
            {
                error = otUdpSend(otGetInstance(), &sMtdSocket, message, &messageInfo);

                if (error == OT_ERROR_NONE)
                {
                    return;
                }
            }
        }

        if (message != NULL)
        {
            otMessageFree(message);
        }
    }
}


void mtdReceiveCallback(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo)
{
    OT_UNUSED_VARIABLE(aContext);
    OT_UNUSED_VARIABLE(aMessage);
    OT_UNUSED_VARIABLE(aMessageInfo);
    uint8_t buf[64];
    int     length;

    length      = otMessageRead(aMessage, otMessageGetOffset(aMessage), buf, sizeof(buf) - 1);
    buf[length] = '\0';

    if (strncmp((char *)buf, FTD_MESSAGE, sizeof(FTD_MESSAGE)) != 0)
    {
        return;
    }

    sl_simple_led_init_instances();
    otCliOutputFormat("Message Received: %s\r\n", buf);
}

int gpio_main(void)
{
  CHIP_Init();

    /* Enable GPIO clock */
    CMU_ClockEnable(cmuClock_GPIO, true);

    /* Configure Push Button 0 as input*/
      GPIO_PinModeSet(gpioPortF, 6, gpioModeInput, 1);

      while (1)
        {
          /* Check if button is pressed - when pressed, value will be 0 */
          if (!GPIO_PinInGet(gpioPortF, 6))
          {
            GPIO_PinOutSet(gpioPortF, 6);
          }
          else
          {
            GPIO_PinOutClear(gpioPortF, 6);
          }
        }
}

Jonathan Hui

unread,
Mar 10, 2021, 1:59:01 PM3/10/21
to Sri Naga Chaitanya Gandhavalla, openthread-users
If you just want to send/receive UDP messages, you don't need to do anything with CoAP.

It appears that gpio_main() will never return - it contains a while(1) loop.

As mentioned, I would reach out to Silicon Labs via their support or community channels for examples specific to their platform.

--
Jonathan Hui



Reply all
Reply to author
Forward
0 new messages