Google is committed to advancing racial equity for Black communities. See how.
इस पेज का अनुवाद Cloud Translation API से किया गया है.
Switch to English

OpenThread API के साथ विकास करना

26b7f4f6b3ea0700.png

OpenThread नेस्ट द्वारा जारी की एक खुला स्रोत कार्यान्वयन है Thread® नेटवर्किंग प्रोटोकॉल। नेस्ट ने कनेक्टेड होम के लिए उत्पादों के विकास में तेजी लाने के लिए डेवलपर्स के लिए व्यापक रूप से नेस्ट उत्पादों में उपयोग की जाने वाली तकनीक बनाने के लिए ओपनथ्रेड जारी किया है।

थ्रेड विनिर्देशन IPv6- आधारित विश्वसनीय, सुरक्षित और कम-शक्ति वाले वायरलेस डिवाइस-टू-डिवाइस संचार प्रोटोकॉल को घरेलू अनुप्रयोगों के लिए परिभाषित करता है। OpenThread IPv6, 6LoWPAN, IEEE 802.15.4 सहित सभी थ्रेड नेटवर्किंग लेयर्स को मैक सिक्योरिटी, मेश लिंक इंस्टालेशन और मेश राउटिंग के साथ लागू करता है।

इस कोडेलैब में, आप थ्रेड नेटवर्क शुरू करने के लिए OpenThread API का उपयोग करेंगे, डिवाइस रोल्स में बदलाव की निगरानी और प्रतिक्रिया करेंगे, और UDP संदेश भेजेंगे, साथ ही इन क्रियाओं को वास्तविक हार्डवेयर पर बटन और एल ई डी से बाँधेंगे।

2a6db2e258c32237.png

आप क्या सीखेंगे

  • नॉर्डिक nRF52840 देव बोर्डों पर बटन और एलईडी कैसे प्रोग्राम करें
  • सामान्य OpenThread API और otInstance क्लास का उपयोग कैसे करें
  • OpenThread अवस्था परिवर्तन पर निगरानी और प्रतिक्रिया कैसे करें
  • थ्रेड नेटवर्क में सभी डिवाइसों को UDP संदेश कैसे भेजें
  • Makefiles को कैसे संशोधित करें

आपको किस चीज़ की ज़रूरत पड़ेगी

हार्डवेयर:

  • 3 नॉर्डिक सेमीकंडक्टर nRF52840 देव बोर्ड
  • बोर्डों को जोड़ने के लिए 3 यूएसबी टू माइक्रो-यूएसबी केबल
  • कम से कम 3 यूएसबी पोर्ट के साथ एक लिनक्स मशीन

सॉफ्टवेयर:

  • जीएनयू टूलचिन
  • नॉर्डिक nRF5x कमांड लाइन उपकरण
  • सीगर जे-लिंक सॉफ्टवेयर
  • OpenThread
  • गित

अन्यथा नोट किए गए के अलावा, इस कोडेलैब की सामग्री को क्रिएटिव कॉमन्स एट्रीब्यूशन 3.0 लाइसेंस के तहत लाइसेंस प्राप्त है, और कोड नमूने Apache 2.0 लाइसेंस के तहत लाइसेंस प्राप्त हैं

हार्डवेयर कोडेलैब को पूरा करें

इस कोडलेब को शुरू करने से पहले, आपको बिल्ड थ्रेड नेटवर्क को nRF52840 बोर्ड और ओपनथ्रेड कोडेलैब के साथ पूरा करना चाहिए, जो:

  • निर्माण और चमकती के लिए आपके द्वारा आवश्यक सभी सॉफ़्टवेयर का विवरण
  • आपको सिखाता है कि ओपनथ्रेड का निर्माण कैसे करें और इसे नॉर्डिक nRF52840 बोर्डों पर फ्लैश करें
  • एक थ्रेड नेटवर्क की मूल बातें प्रदर्शित करता है

OpenThread और फ़्लैश बोर्ड बनाने के लिए आवश्यक कोई भी वातावरण सेट नहीं है, इस कोडेलैब में विस्तृत है- केवल बोर्ड को चमकाने के लिए बुनियादी निर्देश। यह माना जाता है कि आपने बिल्ड थ्रेड नेटवर्क कोडेलैब पहले ही पूरा कर लिया है।

बिल्ड थ्रेड नेटवर्क कोडेलैब को पूरा करें

लिनक्स मशीन

यह कोडेलैब सभी थ्रेड डेवलपमेंट बोर्ड को फ्लैश करने के लिए i386- या x86- आधारित लिनक्स मशीन का उपयोग करने के लिए डिज़ाइन किया गया था। सभी चरणों को Ubuntu 14.04.5 LTS (भरोसेमंद तहर) पर परीक्षण किया गया था।

नॉर्डिक सेमीकंडक्टर nRF52840 बोर्ड

यह कोडेलैब तीन nRF52840 PDK बोर्डों का उपयोग करता है।

a6693da3ce213856.png

सॉफ्टवेर अधिस्थापित करो

OpenThread को बनाने और फ्लैश करने के लिए, आपको SEGGER J-Link, nRF5x कमांड लाइन टूल, ARM GNU टूलचैन और विभिन्न लिनक्स पैकेजों को स्थापित करना होगा। यदि आपने बिल्ड थ्रेड नेटवर्क कोडेलैब पूरा कर लिया है, तो आपके पास पहले से ही वह सब कुछ होगा जो आपको स्थापित करना होगा। यदि नहीं, तो सुनिश्चित करने से पहले उस कोडेलैब को पूरा करें और OpenRhread को nRF52840 देव बोर्डों पर फ्लैश कर सकते हैं।

बिल्ड थ्रेड नेटवर्क कोडेलैब को पूरा करें

OpenThread उदाहरण एप्लिकेशन कोड के साथ आता है जिसे आप इस कोडेलैब के लिए शुरुआती बिंदु के रूप में उपयोग कर सकते हैं।

क्लोन करें और OpenThread स्थापित करें:

$ cd ~
$ git clone --recursive https://github.com/openthread/openthread.git
$ cd openthread
$ ./bootstrap

OpenThread की सार्वजनिक API OpenThread रिपॉजिटरी में include/openthread में include/openthread है। ये एपीआई आपके अनुप्रयोगों में उपयोग के लिए थ्रेड- और प्लेटफ़ॉर्म-स्तर दोनों पर कई ओपनथ्रेड सुविधाओं और कार्यक्षमता तक पहुँच प्रदान करते हैं:

  • OpenThread उदाहरण सूचना और नियंत्रण
  • IPv6, UDP और CoAP जैसी एप्लिकेशन सेवाएं
  • कमिश्नर और जॉइनर भूमिकाओं के साथ नेटवर्क क्रेडेंशियल मैनेजमेंट
  • बॉर्डर राउटर प्रबंधन
  • चाइल्ड सुपरविजन और जैम डिटेक्शन जैसी बढ़ी हुई विशेषताएं

सभी OpenThread एपीआई पर संदर्भ जानकारी पर उपलब्ध हैं openthread.io/reference

एक एपीआई का उपयोग करना

API का उपयोग करने के लिए, अपनी हेडर फ़ाइल को अपनी किसी एप्लिकेशन फ़ाइल में शामिल करें। फिर वांछित फ़ंक्शन को कॉल करें।

उदाहरण के लिए, OpenThread के साथ शामिल सीएलआई उदाहरण ऐप निम्नलिखित एपीआई हेडर का उपयोग करता है:

उदाहरण / एप्लिकेशन / cli / main.c

#include <openthread/config.h>
#include <openthread/cli.h>
#include <openthread/diag.h>
#include <openthread/tasklet.h>
#include <openthread/platform/logging.h>

OpenThread उदाहरण

OpenThread API के साथ काम करते समय otInstance संरचना कुछ है otInstance आप अक्सर उपयोग करेंगे। एक बार शुरू होने के बाद, यह संरचना ओपनथ्रेड लाइब्रेरी के एक स्थिर उदाहरण का प्रतिनिधित्व करती है और उपयोगकर्ता को ओपनथ्रेड एपीआई कॉल करने की अनुमति देती है।

उदाहरण के लिए, OpenThread उदाहरण CLI उदाहरण ऐप के main() फ़ंक्शन में आरंभिक है:

उदाहरण / एप्लिकेशन / cli / main.c

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

...

#if OPENTHREAD_ENABLE_MULTIPLE_INSTANCES
    // Call to query the buffer size
    (void)otInstanceInit(NULL, &otInstanceBufferLength);

    // Call to allocate the buffer
    otInstanceBuffer = (uint8_t *)malloc(otInstanceBufferLength);
    assert(otInstanceBuffer);

    // Initialize OpenThread with the buffer
    instance = otInstanceInit(otInstanceBuffer, &otInstanceBufferLength);
#else
    instance = otInstanceInitSingle();
#endif

...

    return 0;
}

मंच-विशिष्ट कार्य

यदि आप OpenThread के साथ शामिल किए गए उदाहरण एप्लिकेशन में से किसी एक में प्लेटफ़ॉर्म-विशिष्ट फ़ंक्शंस जोड़ना चाहते हैं, तो पहले उन्हें सभी फ़ंक्शंस के लिए otSys नाम स्थान का उपयोग करके examples/platforms/openthread-system.h शीर्ष लेख में घोषित करें। फिर उन्हें एक प्लेटफ़ॉर्म-विशिष्ट स्रोत फ़ाइल में लागू करें। इस तरह से, आप अन्य उदाहरण प्लेटफार्मों के लिए एक ही फ़ंक्शन हेडर का उपयोग कर सकते हैं।

उदाहरण के लिए, GPIO फ़ंक्शंस हम nRF52840 बटन और एल ई डी में हुक करने के लिए उपयोग करने जा रहे हैं, उन्हें openthread-system.h में घोषित किया जाना चाहिए।

अपने पसंदीदा टेक्स्ट एडिटर में examples/platforms/openthread-system.h फ़ाइल खोलें।

उदाहरण / मंच / openthread-system.h

कार्रवाई: प्लेटफ़ॉर्म-विशिष्ट GPIO फ़ंक्शन घोषणाएँ जोड़ें

इन फ़ंक्शन घोषणाओं को फ़ाइल के भीतर कहीं भी जोड़ें:

/**
 * Init LED module.
 *
 */
void otSysLedInit(void);
void otSysLedSet(uint8_t aLed, bool aOn);
void otSysLedToggle(uint8_t aLed);

/**
* A callback will be called when GPIO interrupts occur.
*
*/
typedef void (*otSysButtonCallback)(otInstance *aInstance);
void otSysButtonInit(otSysButtonCallback aCallback);
void otSysButtonProcess(otInstance *aInstance);

हम अगले चरण में इन्हें लागू करेंगे।

ध्यान दें कि otSysButtonProcess फ़ंक्शन घोषणा एक otInstance का उपयोग otInstance । इस तरह से जब एक बटन दबाया जाता है तो एप्लिकेशन ओपनट्रेड उदाहरण के बारे में जानकारी तक पहुंच सकता है, यदि आवश्यक हो। यह सब आपके आवेदन की जरूरतों पर निर्भर करता है। यदि आपको फ़ंक्शन के अपने कार्यान्वयन में इसकी आवश्यकता नहीं है, तो आप कुछ टूलकिन के लिए अप्रयुक्त चर के आसपास त्रुटियों को दबाने के लिए OpenThread API से OT_UNUSED_VARIABLE मैक्रो का उपयोग कर सकते हैं। हम इसके उदाहरण बाद में देखेंगे।

पिछले चरण में, हम प्लेटफ़ॉर्म-विशिष्ट फ़ंक्शन घोषणाओं examples/platforms/openthread-system.h जिनका उपयोग GPIO के लिए किया जा सकता है। NRF52840 देव बोर्डों पर बटन और एल ई डी का उपयोग करने के लिए, आपको उन कार्यों को nRF52840 प्लेटफ़ॉर्म के लिए लागू करने की आवश्यकता है। इस कोड में, आप ऐसे कार्य जोड़ेंगे:

  • GPIO पिन और मोड को इनिशियलाइज़ करें
  • एक पिन पर वोल्टेज को नियंत्रित करें
  • GPIO इंटरप्ट को सक्षम करें और कॉलबैक पंजीकृत करें

examples/platforms/nrf528xx/src निर्देशिका में, gpio.c नामक एक फ़ाइल gpio.c । इस नई फ़ाइल में, निम्न सामग्री जोड़ें।

उदाहरण / मंच / nrf528xx / src / gpio.c (नया फ़ाइल)

कार्रवाई: परिभाषित जोड़ें

ये परिभाषित OpenThread एप्लिकेशन स्तर पर उपयोग किए गए nRF52840- विशिष्ट मान और चर के बीच अमूर्त के रूप में कार्य करते हैं।

/**
 * @file
 *   This file implements the system abstraction for GPIO and GPIOTE.
 *
 */

#define BUTTON_GPIO_PORT 0x50000300UL
#define BUTTON_PIN 11 // button #1

#define GPIO_LOGIC_HI 0
#define GPIO_LOGIC_LOW 1

#define LED_GPIO_PORT 0x50000300UL
#define LED_1_PIN 13 // turn on to indicate leader role
#define LED_2_PIN 14 // turn on to indicate router role
#define LED_3_PIN 15 // turn on to indicate child role
#define LED_4_PIN 16 // turn on to indicate UDP receive

NRF52840 बटन और एलईडी के बारे में अधिक जानकारी के लिए, नॉर्डिक सेमीकंडक्टर इन्फोकेंटर देखें।

कार्रवाई: शीर्ष लेख में शामिल हैं

इसके बाद, शीर्ष लेख को शामिल करें जिसमें आपको GPIO कार्यक्षमता की आवश्यकता होगी।

/* Header for the functions defined here */
#include "openthread-system.h"

#include <string.h>

/* Header to access an OpenThread instance */
#include <openthread/instance.h>

/* Headers for lower-level nRF52840 functions */
#include "platform-nrf5.h"
#include "hal/nrf_gpio.h"
#include "hal/nrf_gpiote.h"
#include "nrfx/drivers/include/nrfx_gpiote.h"

कार्रवाई: बटन 1 के लिए कॉलबैक और इंटरप्ट फ़ंक्शन जोड़ें

इस कोड को आगे जोड़ें। in_pin1_handler फ़ंक्शन वह कॉलबैक है जो तब दर्ज किया जाता है जब बटन प्रेस की कार्यक्षमता आरंभीकृत होती है (बाद में इस फ़ाइल में)।

ध्यान दें कि यह कॉलबैक OT_UNUSED_VARIABLE मैक्रो का उपयोग कैसे करता है, क्योंकि OT_UNUSED_VARIABLE में दिए गए चर वास्तव में फ़ंक्शन में उपयोग नहीं in_pin1_handler जाते हैं।

/* Declaring callback function for button 1. */
static otSysButtonCallback sButtonHandler;
static bool                sButtonPressed;

/**
 * @brief Function to receive interrupt and call back function
 * set by the application for button 1.
 *
 */
static void in_pin1_handler(uint32_t pin, nrf_gpiote_polarity_t action)
{
    OT_UNUSED_VARIABLE(pin);
    OT_UNUSED_VARIABLE(action);
    sButtonPressed = true;
}

कार्रवाई: एल ई डी को कॉन्फ़िगर करने के लिए एक फ़ंक्शन जोड़ें

प्रारंभ के दौरान सभी एल ई डी के मोड और स्थिति को कॉन्फ़िगर करने के लिए इस कोड को जोड़ें।

/**
 * @brief Function for configuring: PIN_IN pin for input, PIN_OUT pin for output,
 * and configures GPIOTE to give an interrupt on pin change.
 */

void otSysLedInit(void)
{
    /* Configure GPIO mode: output */
    nrf_gpio_cfg_output(LED_1_PIN);
    nrf_gpio_cfg_output(LED_2_PIN);
    nrf_gpio_cfg_output(LED_3_PIN);
    nrf_gpio_cfg_output(LED_4_PIN);

    /* Clear all output first */
    nrf_gpio_pin_write(LED_1_PIN, GPIO_LOGIC_LOW);
    nrf_gpio_pin_write(LED_2_PIN, GPIO_LOGIC_LOW);
    nrf_gpio_pin_write(LED_3_PIN, GPIO_LOGIC_LOW);
    nrf_gpio_pin_write(LED_4_PIN, GPIO_LOGIC_LOW);

    /* Initialize gpiote for button(s) input.
     Button event handlers are set in the application (main.c) */
    ret_code_t err_code;
    err_code = nrfx_gpiote_init();
    APP_ERROR_CHECK(err_code);
}

कार्रवाई: एक एलईडी के मोड को सेट करने के लिए एक फ़ंक्शन जोड़ें।

डिवाइस की भूमिका बदलने पर इस फ़ंक्शन का उपयोग किया जाएगा।

/**
 * @brief Function to set the mode of an LED.
 */

void otSysLedSet(uint8_t aLed, bool aOn)
{
    switch (aLed)
    {
    case 1:
        nrf_gpio_pin_write(LED_1_PIN, (aOn == GPIO_LOGIC_HI));
        break;
    case 2:
        nrf_gpio_pin_write(LED_2_PIN, (aOn == GPIO_LOGIC_HI));
        break;
    case 3:
        nrf_gpio_pin_write(LED_3_PIN, (aOn == GPIO_LOGIC_HI));
        break;
    case 4:
        nrf_gpio_pin_write(LED_4_PIN, (aOn == GPIO_LOGIC_HI));
        break;
    }
}

कार्रवाई: एक एलईडी के मोड को चालू करने के लिए एक फ़ंक्शन जोड़ें।

इस फ़ंक्शन का उपयोग LED4 को टॉगल करने के लिए किया जाएगा जब डिवाइस को एक मल्टीकास्ट यूडीपी संदेश प्राप्त होता है।

/**
 * @brief Function to toggle the mode of an LED.
 */
void otSysLedToggle(uint8_t aLed)
{
    switch (aLed)
    {
    case 1:
        nrf_gpio_pin_toggle(LED_1_PIN);
        break;
    case 2:
        nrf_gpio_pin_toggle(LED_2_PIN);
        break;
    case 3:
        nrf_gpio_pin_toggle(LED_3_PIN);
        break;
    case 4:
        nrf_gpio_pin_toggle(LED_4_PIN);
        break;
    }
}

कार्रवाई: बटन प्रेस को इनिशियलाइज़ और प्रोसेस करने के लिए फ़ंक्शन जोड़ें।

पहला फ़ंक्शन बटन प्रेस के लिए बोर्ड को आरंभीकृत करता है, और दूसरा जब बटन 1 दबाया जाता है तो मल्टीकास्ट यूडीपी संदेश भेजता है।

/**
 * @brief Function to initialize the button.
 */
void otSysButtonInit(otSysButtonCallback aCallback)
{
    nrfx_gpiote_in_config_t in_config = NRFX_GPIOTE_CONFIG_IN_SENSE_LOTOHI(true);
    in_config.pull                    = NRF_GPIO_PIN_PULLUP;

    ret_code_t err_code;
    err_code = nrfx_gpiote_in_init(BUTTON_PIN, &in_config, in_pin1_handler);
    APP_ERROR_CHECK(err_code);

    sButtonHandler = aCallback;
    sButtonPressed = false;

    nrfx_gpiote_in_event_enable(BUTTON_PIN, true);
}

void otSysButtonProcess(otInstance *aInstance)
{
    if (sButtonPressed)
    {
        sButtonPressed = false;
        sButtonHandler(aInstance);
    }
}

कार्रवाई: सहेजें और बंद करें

gpio.c फ़ाइल।

हमारे आवेदन में, हम डिवाइस की भूमिका के आधार पर अलग-अलग एलईडी को प्रकाश में लाना चाहते हैं। आइए निम्नलिखित भूमिकाओं को ट्रैक करें: लीडर, राउटर, एंड डिवाइस। हम उन्हें एल ई डी के लिए असाइन कर सकते हैं:

  • LED1 = नेता
  • LED2 = राउटर
  • LED3 = एंड डिवाइस

इस कार्यक्षमता को सक्षम करने के लिए, एप्लिकेशन को यह जानना होगा कि डिवाइस की भूमिका कब बदल गई है और प्रतिक्रिया में सही एलईडी कैसे चालू करें। हम पहले भाग के लिए OpenThread उदाहरण और दूसरे के लिए GPIO प्लेटफ़ॉर्म अमूर्त का उपयोग करेंगे।

अपने पसंदीदा पाठ संपादक में examples/apps/cli/main.c फ़ाइल खोलें।

उदाहरण / एप्लिकेशन / cli / main.c

कार्रवाई: शीर्ष लेख में शामिल हैं

main.c फ़ाइल के अनुभाग में, एपीआई हेडर फ़ाइलों को जोड़ें जो आपको भूमिका परिवर्तन सुविधा के लिए चाहिए।

#include <openthread/instance.h>
#include <openthread/thread.h>
#include <openthread/thread_ftd.h>

कार्रवाई: OpenThread उदाहरण स्थिति परिवर्तन के लिए हैंडलर फ़ंक्शन घोषणा जोड़ें

हेडर शामिल करने और किसी भी #if कथन से पहले, इस घोषणा को main.c जोड़ें। यह फ़ंक्शन मुख्य एप्लिकेशन के बाद परिभाषित किया जाएगा।

void handleNetifStateChanged(uint32_t aFlags, void *aContext);

कार्रवाई: राज्य परिवर्तन हैंडलर फ़ंक्शन के लिए कॉलबैक पंजीकरण जोड़ें

में main.c , को यह समारोह जोड़ने main() के बाद समारोह otCliUartInit कॉल। यह कॉलबैक पंजीकरण OpenThread को बताता है कि जब भी OpenThread उदाहरण स्थिति में परिवर्तन होता है, तो handleNetifStateChange फ़ंक्शन को कॉल करें।

/* Register Thread state change handler */
otSetStateChangedCallback(instance, handleNetifStateChanged, instance);

कार्रवाई: राज्य परिवर्तन कार्यान्वयन जोड़ें

में main.c , के बाद main() समारोह, को लागू handleNetifStateChanged कार्य करते हैं। यह फ़ंक्शन OpenThread उदाहरण के OT_CHANGED_THREAD_ROLE ध्वज की जांच करता है और यदि यह बदल गया है, तो आवश्यकतानुसार एलईड को चालू / बंद कर देता है।

void handleNetifStateChanged(uint32_t aFlags, void *aContext)
{
   if ((aFlags & OT_CHANGED_THREAD_ROLE) != 0)
   {
       otDeviceRole changedRole = otThreadGetDeviceRole(aContext);

       switch (changedRole)
       {
       case OT_DEVICE_ROLE_LEADER:
           otSysLedSet(1, true);
           otSysLedSet(2, false);
           otSysLedSet(3, false);
           break;

       case OT_DEVICE_ROLE_ROUTER:
           otSysLedSet(1, false);
           otSysLedSet(2, true);
           otSysLedSet(3, false);
           break;

       case OT_DEVICE_ROLE_CHILD:
           otSysLedSet(1, false);
           otSysLedSet(2, false);
           otSysLedSet(3, true);
           break;

       case OT_DEVICE_ROLE_DETACHED:
       case OT_DEVICE_ROLE_DISABLED:
           /* Clear LED4 if Thread is not enabled. */
           otSysLedSet(4, false);
           break;
        }
    }
}

हमारे आवेदन में, हम नेटवर्क में अन्य सभी उपकरणों के लिए UDP संदेश भेजना चाहते हैं जब Button1 एक बोर्ड पर दबाया जाता है। संदेश की प्राप्ति की पुष्टि करने के लिए, हम प्रतिक्रिया में अन्य बोर्डों पर LED4 को टॉगल करेंगे।

इस कार्यक्षमता को सक्षम करने के लिए, आवेदन करने की आवश्यकता है:

  • स्टार्ट अप पर यूडीपी कनेक्शन शुरू करें
  • मेष-स्थानीय मल्टीकास्ट पते पर एक यूडीपी संदेश भेजने में सक्षम हो
  • आने वाले यूडीपी संदेशों को संभालें
  • आने वाले UDP संदेशों के जवाब में LED4 को टॉगल करें

अपने पसंदीदा पाठ संपादक में examples/apps/cli/main.c फ़ाइल खोलें।

उदाहरण / एप्लिकेशन / cli / main.c

कार्रवाई: शीर्ष लेख में शामिल हैं

main.c फ़ाइल के शीर्ष पर शामिल अनुभाग में, main.c शीर्ष UDP सुविधा के लिए आपको आवश्यक API हेडर फ़ाइलों को जोड़ना होगा।

#include <string.h>

#include <openthread/message.h>
#include <openthread/udp.h>

#include "utils/code_utils.h"

code_utils.h हेडर का उपयोग otEXPECT और otEXPECT_ACTION मैक्रोज़ के लिए किया जाता है जो रन-टाइम स्थितियों को मान्य करता है और इनायत त्रुटियों को संभालता है।

कार्रवाई: परिभाषित और स्थिरांक जोड़ें:

main.c फ़ाइल में, शामिल अनुभाग के बाद और किसी भी #if कथन से पहले, UDP- विशिष्ट स्थिरांक और परिभाषित जोड़ें:

#define UDP_PORT 1212

static const char UDP_DEST_ADDR[] = "ff03::1";
static const char UDP_PAYLOAD[]   = "Hello OpenThread World!";

ff03::1 मेष-स्थानीय मल्टीकास्ट पता है। इस पते पर भेजे गए किसी भी संदेश को नेटवर्क में सभी पूर्ण थ्रेड डिवाइसों पर भेजा जाएगा। OpenThread में मल्टीकास्ट समर्थन के बारे में अधिक जानकारी के लिए मल्टीचैस्ट को opIIIread.io पर देखें।

क्रिया: फ़ंक्शन घोषणाएँ जोड़ें

में main.c फ़ाइल, के बाद otTaskletsSignalPending परिभाषा और इससे पहले कि main() समारोह, यूडीपी-विशिष्ट कार्यों के साथ-साथ एक स्थिर चर UDP सॉकेट प्रतिनिधित्व करने के लिए जोड़ें:

static void initUdp(otInstance *aInstance);
static void sendUdp(otInstance *aInstance);

static void handleButtonInterrupt(otInstance *aInstance);

void handleUdpReceive(void *aContext, otMessage *aMessage, 
                      const otMessageInfo *aMessageInfo);

static otUdpSocket sUdpSocket;

कार्रवाई: GPIO एल ई डी और बटन को शुरू करने के लिए कॉल जोड़ें

main.c , इन फ़ंक्शन कॉल को otSetStateChangedCallback कॉल के बाद main() फ़ंक्शन में otSetStateChangedCallback । ये फ़ंक्शन GPIO और GPIOTE पिन को इनिशियलाइज़ करते हैं और बटन पुश ईवेंट्स को हैंडल करने के लिए एक बटन हैंडलर सेट करते हैं।

/* init GPIO LEDs and button */
otSysLedInit();
otSysButtonInit(handleButtonInterrupt);

कार्रवाई: यूडीपी आरंभीकरण कॉल जोड़ें

में main.c , को यह समारोह जोड़ने main() के बाद समारोह otSysButtonInit कॉल तुम सिर्फ कहा:

initUdp(instance);

यह कॉल सुनिश्चित करता है कि एक यूडीपी सॉकेट आवेदन शुरू होने पर आरम्भ किया जाता है। इसके बिना, डिवाइस UDP संदेश नहीं भेज या प्राप्त कर सकता है।

कार्रवाई: GPIO बटन ईवेंट को संसाधित करने के लिए कॉल जोड़ें

main.c , इस फ़ंक्शन कॉल को main() फ़ंक्शन के बाद otSysProcessDrivers कॉल के while लूप में जोड़ें। यह फ़ंक्शन, gpio.c में घोषित किया gpio.c , जाँचता है कि बटन दबाया गया था या नहीं, और यदि हैंडलर ( handleButtonInterrupt ) को कॉल करता है जो उपरोक्त चरण में सेट किया गया था।

otSysButtonProcess(instance);

कार्रवाई: बटन इंटरप्ट हैंडलर लागू करें

में main.c , के कार्यान्वयन जोड़ने handleButtonInterrupt के बाद समारोह handleNetifStateChanged समारोह पिछले चरण में कहा:

/**
 * Function to handle button push event
 */
void handleButtonInterrupt(otInstance *aInstance)
{
    sendUdp(aInstance);
}

कार्रवाई: यूडीपी आरंभीकरण लागू करें

में main.c , के कार्यान्वयन जोड़ने initUdp के बाद समारोह handleButtonInterrupt समारोह तुम सिर्फ कहा:

/**
 * Initialize UDP socket
 */
void initUdp(otInstance *aInstance)
{
    otSockAddr  listenSockAddr;

    memset(&sUdpSocket, 0, sizeof(sUdpSocket));
    memset(&listenSockAddr, 0, sizeof(listenSockAddr));

    listenSockAddr.mPort    = UDP_PORT;

    otUdpOpen(aInstance, &sUdpSocket, handleUdpReceive, aInstance);
    otUdpBind(aInstance, &sUdpSocket, &listenSockAddr);
}

UDP_PORT वह पोर्ट है जिसे आपने पहले (1212) में परिभाषित किया था। otUdpOpen समारोह सॉकेट और रजिस्टरों एक कॉलबैक फ़ंक्शन (खोलता handleUdpReceive जब एक यूडीपी संदेश प्राप्त होता है के लिए)।

कार्रवाई: UDP संदेश को लागू करें

में main.c , के कार्यान्वयन जोड़ने sendUdp के बाद समारोह initUdp समारोह तुम सिर्फ कहा:

/**
 * Send a UDP datagram
 */
void sendUdp(otInstance *aInstance)
{
    otError       error = OT_ERROR_NONE;
    otMessage *   message;
    otMessageInfo messageInfo;
    otIp6Address  destinationAddr;

    memset(&messageInfo, 0, sizeof(messageInfo));

    otIp6AddressFromString(UDP_DEST_ADDR, &destinationAddr);
    messageInfo.mPeerAddr    = destinationAddr;
    messageInfo.mPeerPort    = UDP_PORT;

    message = otUdpNewMessage(aInstance, NULL);
    otEXPECT_ACTION(message != NULL, error = OT_ERROR_NO_BUFS);

    error = otMessageAppend(message, UDP_PAYLOAD, sizeof(UDP_PAYLOAD));
    otEXPECT(error == OT_ERROR_NONE);

    error = otUdpSend(aInstance, &sUdpSocket, message, &messageInfo);

 exit:
    if (error != OT_ERROR_NONE && message != NULL)
    {
        otMessageFree(message);
    }
}

otEXPECT और otEXPECT_ACTION मैक्रो पर ध्यान दें। ये सुनिश्चित करते हैं कि UDP संदेश वैध है और बफर में सही तरीके से आवंटित किया गया है, और यदि नहीं, तो फ़ंक्शन ग्रेसफुल तरीके से exit ब्लॉक पर कूदकर त्रुटियों को संभालता है, जहां यह बफर को मुक्त करता है।

UDP को प्रारंभ करने के लिए उपयोग किए जाने वाले फ़ंक्शन के बारे में अधिक जानकारी के लिए opIIIread.io पर IPv6 और UDP संदर्भ देखें।

कार्रवाई: यूडीपी संदेश हैंडलिंग लागू करें

में main.c , के कार्यान्वयन जोड़ने handleUdpReceive के बाद समारोह sendUdp समारोह तुम सिर्फ गयी। यह कार्य केवल LED4 को चालू करता है।

/**
 * Function to handle UDP datagrams received on the listening socket
 */
void handleUdpReceive(void *aContext, otMessage *aMessage,
                      const otMessageInfo *aMessageInfo)
{
    OT_UNUSED_VARIABLE(aContext);
    OT_UNUSED_VARIABLE(aMessage);
    OT_UNUSED_VARIABLE(aMessageInfo);

    otSysLedToggle(4);
}

प्रदर्शन में आसानी के लिए, हम चाहते हैं कि हमारे उपकरण थ्रेड को तुरंत शुरू करें और जब वे चालू हों तो एक नेटवर्क में शामिल हों। ऐसा करने के लिए, हम otOperationalDataset संरचना का उपयोग करेंगे। यह संरचना थ्रेड नेटवर्क क्रेडेंशियल्स को एक डिवाइस में संचारित करने के लिए आवश्यक सभी मापदंडों को रखती है।

इस संरचना का उपयोग OpenThread में निर्मित नेटवर्क डिफॉल्ट्स को ओवरराइड करेगा, हमारे एप्लिकेशन को अधिक सुरक्षित और हमारे नेटवर्क में थ्रेड नोड्स को सीमित करने के लिए जो केवल एप्लिकेशन चला रहे हैं।

फिर से, अपने पसंदीदा पाठ संपादक में examples/apps/cli/main.c फ़ाइल खोलें।

उदाहरण / एप्लिकेशन / cli / main.c

कार्रवाई: शीर्ष लेख में शामिल हैं

main.c फ़ाइल के शीर्ष पर शामिल अनुभाग के भीतर, API हैडर फ़ाइल जोड़ें जो आपको थ्रेड नेटवर्क को कॉन्फ़िगर करने की आवश्यकता होगी:

#include <openthread/dataset_ftd.h>

कार्रवाई: नेटवर्क कॉन्फ़िगरेशन सेट करने के लिए फ़ंक्शन घोषणा जोड़ें

हेडर शामिल करने और किसी भी #if कथन से पहले, इस घोषणा को main.c जोड़ें। यह फ़ंक्शन मुख्य एप्लिकेशन फ़ंक्शन के बाद परिभाषित किया जाएगा।

static void setNetworkConfiguration(otInstance *aInstance);

कार्रवाई: नेटवर्क कॉन्फ़िगरेशन कॉल जोड़ें

main.c , इस फ़ंक्शन कॉल को otSetStateChangedCallback कॉल के बाद main() फ़ंक्शन में otSetStateChangedCallback । यह फ़ंक्शन थ्रेड नेटवर्क डेटासेट को कॉन्फ़िगर करता है।

/* Override default network credentials */
setNetworkConfiguration(instance);

कार्रवाई: थ्रेड नेटवर्क इंटरफ़ेस और स्टैक को सक्षम करने के लिए कॉल जोड़ें

main.c , इन फ़ंक्शन कॉल को otSysButtonInit कॉल के बाद main() फ़ंक्शन में otSysButtonInit

/* Start the Thread network interface (CLI cmd > ifconfig up) */
otIp6SetEnabled(instance, true);

/* Start the Thread stack (CLI cmd > thread start) */
otThreadSetEnabled(instance, true);

कार्रवाई: थ्रेड नेटवर्क कॉन्फ़िगरेशन लागू करें

में main.c , के कार्यान्वयन जोड़ने setNetworkConfiguration के बाद समारोह main() समारोह:

/**
 * Override default network settings, such as panid, so the devices can join a
 network
 */
void setNetworkConfiguration(otInstance *aInstance)
{
    static char          aNetworkName[] = "OTCodelab";
    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                      = 15;
    aDataset.mComponents.mIsChannelPresent = true;

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

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

    /* Set master key to 1234C0DE1AB51234C0DE1AB51234C0DE */
    uint8_t key[OT_MASTER_KEY_SIZE] = {0x12, 0x34, 0xC0, 0xDE, 0x1A, 0xB5, 0x12, 0x34, 0xC0, 0xDE, 0x1A, 0xB5, 0x12, 0x34, 0xC0, 0xDE};
    memcpy(aDataset.mMasterKey.m8, key, sizeof(aDataset.mMasterKey));
    aDataset.mComponents.mIsMasterKeyPresent = true;

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

#if OPENTHREAD_FTD
    otDatasetSetActive(aInstance, &aDataset);

    /* Set the router selection jitter to override the 2 minute default.
       CLI cmd > routerselectionjitter 20
       Warning: For demo purposes only - not to be used in a real product */
    uint8_t jitterValue = 20;
    otThreadSetRouterSelectionJitter(aInstance, jitterValue);
#else
    OT_UNUSED_VARIABLE(aInstance);
#endif
}

फ़ंक्शन में विस्तृत, थ्रेड नेटवर्क पैरामीटर जो हम इस एप्लिकेशन के लिए उपयोग कर रहे हैं:

  • चैनल = 15
  • पैन आईडी = 0x2222
  • विस्तारित पैन आईडी = C0DE1AB5C0DE1AB5
  • नेटवर्क मास्टर कुंजी = 1234C0DE1AB51234C0DE1AB51234C0DE
  • नेटवर्क नाम = OTCodelab

इसके अलावा, यह वह जगह है जहां हम राउटर सिलेक्शन जिटर को कम करते हैं, इसलिए हमारे डिवाइस डेमो उद्देश्यों के लिए भूमिकाओं को तेजी से बदलते हैं। ध्यान दें कि यह केवल तभी किया जाता है जब नोड एक FTD (फुल थ्रेड डिवाइस) हो। इसके बारे में अगले चरण में।

OpenThread के कुछ एपीआई सेटिंग्स को संशोधित करते हैं जिन्हें केवल डेमो या परीक्षण उद्देश्यों के लिए संशोधित किया जाना चाहिए। इन APIs का उपयोग OpenThread का उपयोग करते हुए किसी अनुप्रयोग के उत्पादन परिनियोजन में नहीं किया जाना चाहिए।

उदाहरण के लिए, otThreadSetRouterSelectionJitter फ़ंक्शन उस समय (सेकंड में) को समायोजित करता है जो किसी राउटर में खुद को बढ़ावा देने के लिए एक एंड डिवाइस के लिए लेता है। थ्रेड स्पेसिफिकेशन के अनुसार इस मान के लिए डिफ़ॉल्ट 120 है। इस कोडेलैब में उपयोग में आसानी के लिए, हम इसे 20 में बदलने जा रहे हैं, इसलिए आपको भूमिकाओं को बदलने के लिए थ्रेड नोड के लिए बहुत लंबा इंतजार नहीं करना होगा।

हालाँकि, आपने देखा होगा कि इस फ़ंक्शन को प्रीप्रोसेसर निर्देश के भीतर कहा जाता है:

#if OPENTHREAD_FTD
    otDatasetSetActive(aInstance, &aDataset);

    /* Set the router selection jitter to override the 2 minute default.
       CLI cmd >routerselectionjitter 20
       Warning: For demo purposes only - not to be used in a real product */
    uint8_t jitterValue = 20;
    otThreadSetRouterSelectionJitter(aInstance, jitterValue);
#else
    OT_UNUSED_VARIABLE(aInstance);
#endif

यह एक MTD (मिनिमल थ्रेड डिवाइस) बिल्ड में जोड़े जाने से रोकने के लिए है। MTD डिवाइस राउटर नहीं बनते हैं, और एक फ़ंक्शन के लिए समर्थन जैसे कि otThreadSetRouterSelectionJitter एक MTD बिल्ड में शामिल नहीं है।

आप को देख कर इस बात की पुष्टि कर सकते हैं otThreadSetRouterSelectionJitter समारोह परिभाषा है, जो भी की एक पूर्वप्रक्रमक निर्देश के भीतर निहित है OPENTHREAD_FTD :

src / core / api / thread_ftd_api.cpp

#if OPENTHREAD_FTD

#include <openthread/thread_ftd.h>

...

void otThreadSetRouterSelectionJitter(otInstance *aInstance, uint8_t aRouterJitter)
{
    Instance &instance = *static_cast<Instance *>(aInstance);

    instance.GetThreadNetif().GetMle().SetRouterSelectionJitter(aRouterJitter);
}

...

#endif // OPENTHREAD_FTD

इससे पहले कि आप अपना एप्लिकेशन बनाएं, तीन मेकफाइल्स के लिए कुछ मामूली अपडेट की आवश्यकता होती है। इनका उपयोग बिल्ड सिस्टम द्वारा आपके एप्लिकेशन को संकलित करने और लिंक करने के लिए किया जाता है।

उदाहरण / Makefile-nrf52840

अब कुछ झंडे nrf52840 मेकफिल में जोड़ें, यह सुनिश्चित करने के लिए कि GPIO फ़ंक्शन एप्लिकेशन में परिभाषित हैं।

कार्रवाई: nrf52840 मेकफाइल में झंडे जोड़ें

अपने पसंदीदा पाठ संपादक में examples/Makefile-nrf52840 खोलें, और include ... common-switches.mk होने के बाद निम्नलिखित COMMONCFLAGS जोड़ें include ... common-switches.mk लाइन:

...

include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/common-switches.mk

# Defined in third_party/NordicSemiconductor/nrfx/templates/nRF52840/nrfx_config.h
COMMONCFLAGS += -DGPIOTE_ENABLED=1
COMMONCFLAGS += -DGPIOTE_CONFIG_IRQ_PRIORITY=7
COMMONCFLAGS += -DGPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS=1

...

उदाहरण / मंच / nrf528xx / nrf52840 / Makefile.am

अब नई gpio.c फ़ाइल को प्लेटफ़ॉर्म nrf52840 Makefile.am फ़ाइल में जोड़ें।

कार्रवाई: nrf52840 प्लेटफॉर्म मेकफाइल में gpio स्रोत जोड़ें

अपने पसंदीदा पाठ संपादक में examples/platforms/nrf528xx/nrf52840/Makefile.am खोलें और $(NULL) कथन से ठीक पहले PLATFORM_COMMON_SOURCES अनुभाग के अंत में फ़ाइल जोड़ें। लाइन के अंत में एक बैकस्लैश डालना मत भूलना!

...

PLATFORM_COMMON_SOURCES
...
src/gpio.c             \
$(NULL)

...

third_party / नॉर्डिकस्मेटिक / Makefile.am

अंत में, nrfx_gpiote.c ड्राइवर फ़ाइल को नॉर्डिकस्मेट्रिक थर्ड-पार्टी मेकफाइल में जोड़ें, इसलिए यह नॉर्डिक ड्राइवरों के लाइब्रेरी बिल्ड के साथ शामिल है।

कार्रवाई: grio ड्राइवर को nrf52840 प्लेटफ़ॉर्म मेकफाइल में जोड़ें

अपने पसंदीदा टेक्स्ट एडिटर में third_party/NordicSemiconductor/Makefile.am खोलें, और $(NULL) स्टेटमेंट से ठीक पहले NORDICSEMI_COMMON_SOURCES अनुभाग के अंत में फ़ाइल जोड़ें। लाइन के अंत में एक बैकस्लैश डालना मत भूलना!

...

NORDICSEMI_COMMON_SOURCES
...
nrfx/drivers/src/nrfx_gpiote.c             \

$(NULL)

...

किए गए सभी कोड अपडेट के साथ, आप सभी तीन नॉर्डिक nRF52840 देव बोर्डों में एप्लिकेशन को बनाने और फ्लैश करने के लिए तैयार हैं। प्रत्येक उपकरण एक पूर्ण थ्रेड डिवाइस (FTD) के रूप में कार्य करेगा।

OpenThread बनाएँ

NRF52840 उदाहरण मंच का निर्माण करें। चूंकि मेकफाइल्स पिछले चरण में बदल गए थे, इसलिए आपको निर्माण से पहले bootstrap स्क्रिप्ट को चलाने की आवश्यकता है:

$ cd ~/openthread
$ ./bootstrap
$ make -f examples/Makefile-nrf52840

OpenThread FTD CLI बाइनरी के साथ डायरेक्टरी में नेविगेट करें, और ARM एंबेडेड डिस्चार्ज के साथ इसे हेक्स फॉर्मेट में कन्वर्ट करें:

$ cd ~/openthread/output/nrf52840/bin
$ arm-none-eabi-objcopy -O ihex ot-cli-ftd ot-cli-ftd.hex

बोर्डों को फ्लैश करें

प्रत्येक nRF52840 बोर्ड में ot-cli-ftd.hex फ़ाइल को फ्लैश करें।

NRF52840 बोर्ड पर बाहरी पावर पिन के बगल में माइक्रो-यूएसबी डिबग पोर्ट में यूएसबी केबल संलग्न करें, और फिर इसे अपने लिनक्स मशीन में प्लग करें। सही ढंग से सेट करें, LED5 चालू है।

20a3b4b480356447.png

पहले की तरह, nRF52840 बोर्ड के सीरियल नंबर पर ध्यान दें:

c00d519ebec7e5f0.jpeg

NRFx कमांड लाइन टूल्स के स्थान पर नेविगेट करें, और बोर्ड के सीरियल नंबर का उपयोग करते हुए nRF52840 बोर्ड पर OpenThread CLI FTD हेक्स फाइल को फ्लैश करें:

$ cd ~/nrfjprog
$ ./nrfjprog -f nrf52 -s 683704924 --chiperase --program \
       ~/openthread/output/nrf52840/bin/ot-cli-ftd.hex --reset

LED5 चमकती के दौरान संक्षेप में बंद हो जाएगा। निम्नलिखित आउटपुट सफलता पर उत्पन्न होता है:

Parsing hex file.
Erasing user available code and UICR flash areas.
Applying system reset.
Checking that the area to write is not protected.
Programing device.
Applying system reset.
Run.

अन्य दो बोर्डों के लिए इस "फ्लैश द बोर्ड" कदम को दोहराएं। प्रत्येक बोर्ड को उसी तरह से लिनक्स मशीन से जोड़ा जाना चाहिए, और फ्लैश करने का कमांड बोर्ड के सीरियल नंबर को छोड़कर, समान है। प्रत्येक बोर्ड के अद्वितीय सीरियल नंबर का उपयोग करना सुनिश्चित करें

nrfjprog चमकती कमांड।

सफल होने पर, प्रत्येक बोर्ड पर LED1, LED2 या LED3 या तो जलाया जाएगा। तुम भी चमकती (डिवाइस भूमिका परिवर्तन सुविधा) के बाद जल्द ही 3 से 2 (या 2 से 1) से एलईडी स्विच देख सकते हैं।

सभी तीन nRF52840 बोर्ड अब संचालित होने चाहिए और हमारे OpenThread एप्लीकेशन को चलाना चाहिए। जैसा कि पहले विस्तृत था, इस एप्लिकेशन में दो प्राथमिक विशेषताएं हैं।

डिवाइस रोल संकेतक

प्रत्येक बोर्ड पर लगी एलईडी थ्रेड नोड की वर्तमान भूमिका को दर्शाती है:

  • LED1 = नेता
  • LED2 = राउटर
  • LED3 = एंड डिवाइस

जैसे-जैसे भूमिका बदलती जाती है, वैसे-वैसे एलईडी जलती जाती है। आपको पहले से ही प्रत्येक उपकरण को 20 सेकंड के भीतर बोर्ड पर या दो बार इन परिवर्तनों को देखना चाहिए।

यूडीपी मल्टीकास्ट

जब Button1 को एक बोर्ड पर दबाया जाता है, तो एक UDP संदेश मेष-स्थानीय मल्टीकास्ट पते पर भेजा जाता है, जिसमें थ्रेड नेटवर्क में अन्य सभी नोड्स शामिल होते हैं। इस संदेश को प्राप्त करने के लिए, अन्य सभी बोर्ड पर LED4 चालू या बंद टॉगल करता है । LED4 प्रत्येक बोर्ड के लिए तब तक चालू या बंद रहता है, जब तक उसे एक और UDP संदेश प्राप्त नहीं होता है।

203dd094acca1f97.png

9bb96969b1c63504.png

आपके द्वारा फ्लैश किए गए डिवाइस एक विशेष प्रकार के फुल थ्रेड डिवाइस (FTD) हैं, जिन्हें राउटर योग्य एंड डिवाइस (REED) कहा जाता है। इसका अर्थ है कि वे राउटर या एंड डिवाइस के रूप में कार्य कर सकते हैं और एंड डिवाइस से राउटर तक खुद को बढ़ावा दे सकते हैं।

थ्रेड 32 राउटर तक का समर्थन कर सकता है, लेकिन 16 और 23 के बीच राउटर की संख्या को रखने की कोशिश करता है। अगर एक आरईडी एक एंड डिवाइस के रूप में संलग्न करता है और राउटर की संख्या 16 से नीचे है, तो यह स्वतः ही एक राउटर को बढ़ावा देता है। यह परिवर्तन आप अनुप्रयोग (20 सेकंड) में otThreadSetRouterSelectionJitter मान सेट करने वाले सेकंड की संख्या के भीतर एक यादृच्छिक समय पर हो सकते हैं।

प्रत्येक थ्रेड नेटवर्क में एक लीडर भी होता है, जो एक राउटर है जो थ्रेड नेटवर्क में राउटर के सेट को प्रबंधित करने के लिए जिम्मेदार है। सभी उपकरणों के साथ, 20 सेकंड के बाद उनमें से एक लीडर (LED1 ऑन) और अन्य दो राउटर (LED2 ऑन) होने चाहिए।

4e1e885861a66570.png

नेता को हटाओ

यदि लीडर को थ्रेड नेटवर्क से हटा दिया जाता है, तो एक अलग राउटर अपने आप को एक लीडर को बढ़ावा देता है, यह सुनिश्चित करने के लिए कि नेटवर्क में अभी भी लीडर है।

पावर स्विच का उपयोग करके लीडर बोर्ड (LED1 के साथ एक) को बंद करें। लगभग 20 सेकंड तक प्रतीक्षा करें। शेष दो बोर्डों में से, LED2 (राउटर) बंद हो जाएगा और LED1 (लीडर) चालू हो जाएगा। यह डिवाइस अब थ्रेड नेटवर्क का लीडर है।

4c57c87adb40e0e3.png

मूल लीडर बोर्ड को वापस चालू करें। यह स्वचालित रूप से थ्रेड नेटवर्क को एंड डिवाइस (LED3 जलाया जाता है) के रूप में फिर से जुड़ना चाहिए। 20 सेकंड (राउटर सिलेक्शन जटर) के भीतर यह खुद को एक राउटर (LED2 जलाया जाता है) को बढ़ावा देता है।

5f40afca2dcc4b5b.png

बोर्डों को रीसेट करें

सभी तीन बोर्डों को बंद करें, फिर उन्हें फिर से चालू करें और एलईडी का निरीक्षण करें। पहला बोर्ड जो संचालित किया गया था, उसे लीडर रोल में शुरू किया जाना चाहिए (LED1 जलाया गया) - थ्रेड नेटवर्क में पहला राउटर स्वचालित रूप से लीडर बन जाता है।

अन्य दो बोर्ड शुरू में एंड डिवाइस (LED3 जलाया जाता है) के रूप में नेटवर्क से कनेक्ट होते हैं, लेकिन 20 सेकंड के भीतर खुद को Routers (LED2 जलाया जाता है) को बढ़ावा देना चाहिए।

नेटवर्क विभाजन

यदि आपके बोर्ड पर्याप्त शक्ति प्राप्त नहीं कर रहे हैं, या उनके बीच का रेडियो कनेक्शन कमजोर है, थ्रेड नेटवर्क विभाजन में विभाजित हो सकता है और आपके पास लीडर के रूप में एक से अधिक डिवाइस हो सकता है।

थ्रेड आत्म-चिकित्सा है, इसलिए विभाजन को अंततः एक नेता के साथ एक ही विभाजन में वापस विलय करना चाहिए।

यदि पिछले अभ्यास से जारी है, तो LED4 को किसी भी उपकरण पर नहीं जलाया जाना चाहिए।

कोई भी बोर्ड चुनें और Button1 दबाएँ। आवेदन चलाने वाले थ्रेड नेटवर्क के अन्य सभी बोर्डों पर LED4 को अपने राज्य को चालू करना चाहिए। यदि पिछले अभ्यास से जारी है, तो उन्हें अब चालू होना चाहिए।

f186a2618fdbe3fd.png

उसी बोर्ड के लिए फिर से Button1 दबाएँ। अन्य सभी बोर्डों पर LED4 को फिर से टॉगल करना चाहिए।

एक अलग बोर्ड पर Button1 दबाएँ और अन्य बोर्डों पर LED4 टॉगल कैसे देखें। उन दोनों में से एक पर बटन दबाएं जहां वर्तमान में LED4 है। LED4 उस बोर्ड के लिए बना रहता है, लेकिन दूसरों पर टॉगल करता है।

f5865ccb8ab7aa34.png

नेटवर्क विभाजन

यदि आपके बोर्डों ने विभाजन किया है और उनमें से एक से अधिक नेता हैं, तो मल्टीकास्ट संदेश का परिणाम बोर्डों के बीच भिन्न होगा। यदि आप एक बोर्ड पर Button1 दबाते हैं जिसने विभाजन किया है (और इस तरह से विभाजित थ्रेड नेटवर्क का एकमात्र सदस्य है), तो अन्य बोर्डों पर LED4 प्रतिक्रिया में प्रकाश नहीं करेगा। यदि ऐसा होता है, तो बोर्डों को रीसेट करें - आदर्श रूप से वे एक एकल थ्रेड नेटवर्क में सुधार करेंगे और यूडीपी मैसेजिंग को सही ढंग से काम करना चाहिए।

आपने एक एप्लिकेशन बनाया है जो OpenThread API का उपयोग करता है!

अब आप जानते हैं:

  • नॉर्डिक nRF52840 देव बोर्डों पर बटन और एलईडी कैसे प्रोग्राम करें
  • सामान्य OpenThread API और otInstance क्लास का उपयोग कैसे करें
  • OpenThread अवस्था परिवर्तन पर निगरानी और प्रतिक्रिया कैसे करें
  • थ्रेड नेटवर्क में सभी डिवाइसों को UDP संदेश कैसे भेजें
  • Makefiles को कैसे संशोधित करें

अगले कदम

इस कोडेलैब का निर्माण, निम्नलिखित अभ्यासों को आज़माएं:

  • GPIO पिन को ऑनबोर्ड एलईडी के बजाय उपयोग करने के लिए GPIO मॉड्यूल को संशोधित करें, और R RGB भूमिका के आधार पर रंग बदलने वाले बाहरी RGB LED को कनेक्ट करें
  • एक अलग उदाहरण प्लेटफ़ॉर्म के लिए GPIO समर्थन जोड़ें
  • एक बटन प्रेस से सभी उपकरणों को पिंग करने के लिए मल्टीकास्ट का उपयोग करने के बजाय, एक व्यक्तिगत डिवाइस का पता लगाने और पिंग करने के लिए राउटर / लीडर एपीआई का उपयोग करें।
  • OpenThread Border Router का उपयोग करके अपने जाल नेटवर्क को इंटरनेट से कनेक्ट करें और एल ई डी को जलाने के लिए उन्हें थ्रेड नेटवर्क के बाहर से मल्टीकास्ट करें।

अग्रिम पठन

OpenThread संसाधनों की एक किस्म के लिए opIIIread.io और GitHub देखें :

संदर्भ: