You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
IoT-For-Beginners/translations/km/2-farm/lessons/4-migrate-your-plant-to-the.../wio-terminal-connect-hub.md

20 KiB

តភ្ជាប់ឧបករណ៍ IoT របស់អ្នកទៅកាន់ពពក - Wio Terminal

នៅផ្នែកនេះនៃមេរៀន អ្នកនឹងតភ្ជាប់ Wio Terminal របស់អ្នកទៅកាន់ IoT Hub ដើម្បីផ្ញើព័ត៌មាន telemetry និងទទួលការបញ្ជា។

តភ្ជាប់ឧបករណ៍របស់អ្នកទៅ IoT Hub

ជំហានបន្ទាប់គឺតភ្ជាប់ឧបករណ៍របស់អ្នកទៅ IoT Hub។

ការងារ - តភ្ជាប់ទៅ IoT Hub

  1. បើកគម្រោង soil-moisture-sensor នៅក្នុង VS Code

  2. បើកឯកសារ platformio.ini។ យកការពឹងផ្អែកលើបណ្ណាល័យ knolleary/PubSubClient ចេញ។ នេះត្រូវបានប្រើសម្រាប់តភ្ជាប់ទៅ broker MQTT សាធារណៈ ហើយមិនចាំបាច់ទេដើម្បីតភ្ជាប់ទៅ IoT Hub។

  3. បន្ថែមការពឹងផ្អែកលើបណ្ណាល័យដូចខាងក្រោម៖

    seeed-studio/Seeed Arduino RTC @ 2.0.0
    arduino-libraries/AzureIoTHub @ 1.6.0
    azure/AzureIoTUtility @ 1.6.1
    azure/AzureIoTProtocol_MQTT @ 1.6.0
    azure/AzureIoTProtocol_HTTP @ 1.6.0
    azure/AzureIoTSocket_WiFi @ 1.0.2
    

    បណ្ណាល័យ Seeed Arduino RTC ផ្តល់កូដដើម្បីអន្តរសកម្មជាមួយនឹងម៉ោងពិតនៅក្នុង Wio Terminal ដែលប្រើសម្រាប់តាមដានពេលវេលា។ បណ្ណាល័យដែលនៅសល់អនុញាតឲ្យឧបករណ៍ IoT របស់អ្នកតភ្ជាប់ទៅ IoT Hub។

  4. បន្ថែមអ្វីខាងក្រោមទៅចុងឯកសារ platformio.ini

    build_flags =
        -DDONT_USE_UPLOADTOBLOB
    

    នេះកំណត់ស្លាកកូដដែលត្រូវការពេលកូដ Arduino IoT Hub ត្រូវបានបញ្ចូល។

  5. បើកឯកសារ header config.h។ លុបការកំណត់ MQTT ទាំងអស់ចេញ ហើយបន្ថែមអចលនៈខាងក្រោមសម្រាប់ខ្សែផ្សារតភ្ជាប់ឧបករណ៍៖

    // ការកំណត់ IoT Hub
    const char *CONNECTION_STRING = "<connection string>";
    

    ប្ដូរទៅ <connection string> ជាខ្សែផ្សារតភ្ជាប់សម្រាប់ឧបករណ៍របស់អ្នកដែលអ្នកបានចម្លងមុននេះ។

  6. ការតភ្ជាប់ទៅ IoT Hub ប្រើ token ដែលផ្អែកលើពេលវេលា។ នេះមានន័យថាឧបករណ៍ IoT ត្រូវការដឹងពេលវេលាបច្ចុប្បន្ន។ ខុសពីប្រព័ន្ធប្រតិបត្តិការដូចជា Windows, macOS ឬ Linux, មីក្រូកុងត្រូលឡើងដោយស្វ័យប្រវត្តិមិនត្រូវបាន đồng bộ ពេលវេលាបច្ចុប្បន្នតាមអ៊ីនធឺណិតទេ។ នេះមានន័យថាអ្នកត្រូវបន្ថែមកូដដើម្បីទទួលបានពេលវេលាបច្ចុប្បន្នពីម៉ាស៊ីនបម្រើ NTP។ បន្ទាប់ពីទទួលបានពេលវេលា វានឹងអាចរក្សាទុកនៅម៉ោងពិតនៅក្នុង Wio Terminal ដែលអនុញ្ញាតឲ្យសំណើពេលវេលាត្រឹមត្រូវនៅថ្ងៃក្រោយបាន ដោយផ្អែកលើថាឧបករណ៍មិនបាត់បង់ថាមពល។ បន្ថែមឯកសារថ្មីដែលមានឈ្មោះ ntp.h ជាមួយកូដដូចខាងក្រោម៖

    #pragma once
    
    #include "DateTime.h"
    #include <time.h>
    #include "samd/NTPClientAz.h"
    #include <sys/time.h>
    
    static void initTime()
    {
        WiFiUDP _udp;
        time_t epochTime = (time_t)-1;
        NTPClientAz ntpClient;
    
        ntpClient.begin();
    
        while (true)
        {
            epochTime = ntpClient.getEpochTime("0.pool.ntp.org");
    
            if (epochTime == (time_t)-1)
            {
                Serial.println("Fetching NTP epoch time failed! Waiting 2 seconds to retry.");
                delay(2000);
            }
            else
            {
                Serial.print("Fetched NTP epoch time is: ");
    
                char buff[32];
                sprintf(buff, "%.f", difftime(epochTime, (time_t)0));
                Serial.println(buff);
                break;
            }
        }
    
        ntpClient.end();
    
        struct timeval tv;
        tv.tv_sec = epochTime;
        tv.tv_usec = 0;
    
        settimeofday(&tv, NULL);
    }
    

    ព័ត៌មានលម្អិតនៃកូដនេះកន្លងពីវិសាលភាពនៃមេរៀននេះ។ វាដាក់ពាក្យបញ្ជាទៅនូវមុខងារមួយឈ្មោះ initTime ដែលទទួលពេលវេលាបច្ចុប្បន្នពីម៉ាស៊ីនបម្រើ NTP ហើយប្រើវាដើម្បីកំណត់ម៉ោងលើ Wio Terminal។

  7. បើកឯកសារ main.cpp ហើយលុបកូដ MQTT ទាំងអស់ រួមទាំងឯកសារ header PubSubClient.h, ការបញ្ជាក់អថេរ PubSubClient, វិធីសាស្ត្រ reconnectMQTTClient និង createMQTTClient, និងការហៅទៅអថេរ និងវិធីសាស្ត្រទាំងនេះ។ ឯកសារនេះគួរតែមានកូដសម្រាប់តភ្ជាប់ WiFi, ទទួលសំណើរជាតិដី និងបង្កើតឯកសារ JSON ពីវា ប៉ុណ្ណោះ។

  8. បន្ថែមនូវការបញ្ជាក់ #include ខាងលើឯកសារ main.cpp ដើម្បីបញ្ចូលបណ្ណាល័យ IoT Hub និងការកំណត់ពេលវេលា៖

    #include <AzureIoTHub.h>
    #include <AzureIoTProtocol_MQTT.h>
    #include <iothubtransportmqtt.h>
    #include "ntp.h"
    
  9. បន្ថែមការហៅខាងក្រោមចុងមុខងារ setup ដើម្បីកំណត់ពេលវេលាបច្ចុប្បន្ន៖

    initTime();
    
  10. បន្ថែមការបញ្ជាក់អថេរខាងលើឯកសារ ក្រោមការបញ្ចូល #include

    IOTHUB_DEVICE_CLIENT_LL_HANDLE _device_ll_handle;
    

    នេះបញ្ជាក់អថេរ IOTHUB_DEVICE_CLIENT_LL_HANDLE ដែលជាឈរជាប់ទៅកាន់ការតភ្ជាប់ទៅ IoT Hub។

  11. ក្រោមនេះ បន្ថែមកូដដូចខាងក្រោម៖

    static void connectionStatusCallback(IOTHUB_CLIENT_CONNECTION_STATUS result, IOTHUB_CLIENT_CONNECTION_STATUS_REASON reason, void *user_context)
    {
        if (result == IOTHUB_CLIENT_CONNECTION_AUTHENTICATED)
        {
            Serial.println("The device client is connected to iothub");
        }
        else
        {
            Serial.println("The device client has been disconnected");
        }
    }
    

    នេះបញ្ជាក់មុខងារត្រឡប់ប្រតិកម្មមួយដែលនឹងត្រូវហៅពេលកម្រិតស្ថានភាពនៃការតភ្ជាប់ទៅ IoT Hub ផ្លាស់ប្ដូរ ដូចជាការតភ្ជាប់ឬដាច់ការតភ្ជាប់។ ស្ថានភាពនេះត្រូវបានផ្ញើទៅច្រកស៊េរី។

  12. ក្រោមនេះ បន្ថែមមុខងារមួយសម្រាប់តភ្ជាប់ទៅ IoT Hub៖

    void connectIoTHub()
    {
        IoTHub_Init();
    
        _device_ll_handle = IoTHubDeviceClient_LL_CreateFromConnectionString(CONNECTION_STRING, MQTT_Protocol);
    
        if (_device_ll_handle == NULL)
        {
            Serial.println("Failure creating Iothub device. Hint: Check your connection string.");
            return;
        }
    
        IoTHubDeviceClient_LL_SetConnectionStatusCallback(_device_ll_handle, connectionStatusCallback, NULL);
    }
    

    កូដនេះចាប់ផ្តើមបណ្ណាល័យ IoT Hub រួចបង្កើតការតភ្ជាប់ដោយប្រើខ្សែផ្សារតភ្ជាប់នៅក្នុងឯកសារ header config.h។ ការតភ្ជាប់នេះផ្អែកលើ MQTT។ បើការតភ្ជាប់បរាជ័យ នេះនឹងត្រូវផ្ញើទៅច្រកស៊េរី - ប្រសិនបើអ្នកឃើញនេះនៅក្នុងលទ្ធផល សូមពិនិត្យខ្សែផ្សារតភ្ជាប់។ ចុងក្រោយ ការត្រឡប់ប្រតិកម្មស្ថានភាពត្រូវបានកំណត់។

  13. ហៅមុខងារនេះនៅក្នុងមុខងារ setup ខាងក្រោមការហៅ initTime

    connectIoTHub();
    
  14. ដូចគ្នា និងកម្រិត MQTT client កូដនេះរត់នៅលើខ្សែទិន្នន័យតែមួយ ដូច្នេះត្រូវការពេលវេលាគ្រប់គ្រាន់សម្រាប់ដំណើរការសារ របស់ hub ផ្ញើ និងទទួល។ បន្ថែមខាងក្រោមទៅខាងលើមុខងារ loop ដើម្បីធ្វើដូចនេះ៖

    IoTHubDeviceClient_LL_DoWork(_device_ll_handle);
    
  15. បង្កើត និងផ្ទុកឡើងកូដនេះ។ អ្នកនឹងឃើញការតភ្ជាប់នៅក្នុងមន្រ្តីមើលស៊េរី៖

    Connecting to WiFi..
    Connected!
    Fetched NTP epoch time is: 1619983687
    Sending telemetry {"soil_moisture":391}
    The device client is connected to iothub
    

    នៅក្នុងលទ្ធផល អ្នកអាចឃើញពេលវេលា NTP ត្រូវបានយកមក តាមក្រោយដោយការតភ្ជាប់ឧបករណ៍ client។ វាអាចប្រើពេលប៉ុន្មានវិនាទីដើម្បីតភ្ជាប់ ដូច្នេះអ្នកអាចឃើញជាតិដីក្នុងលទ្ធផល ខណៈពេលឧបករណ៍កំពុងតភ្ជាប់។

    💁 អ្នកអាចបម្លែងពេលវេលា UNIX សម្រាប់ NTP ទៅជាចំលងអាចអានបានជាងនេះដោយប្រើវេបសាយដូចជា unixtimestamp.com

ផ្ញើ telemetry

ឥឡូវនេះឧបករណ៍របស់អ្នកត្រូវបានតភ្ជាប់ អ្នកអាចផ្ញើ telemetry ទៅ IoT Hub ជំនួស broker MQTT។

ការងារ - ផ្ញើ telemetry

  1. បន្ថែមមុខងារខាងលើមុខងារ setup

    void sendTelemetry(const char *telemetry)
    {
        IOTHUB_MESSAGE_HANDLE message_handle = IoTHubMessage_CreateFromString(telemetry);
        IoTHubDeviceClient_LL_SendEventAsync(_device_ll_handle, message_handle, NULL, NULL);
        IoTHubMessage_Destroy(message_handle);
    }
    

    កូដនេះបង្កើតសារពីខ្សែអក្សរដែលផ្ទេរជាពារ៉ាម៉ែត្រ បញ្ជូនទៅ hub បន្ទាប់លុបវត្ថុសារនោះ។

  2. ហៅកូដនេះនៅក្នុងមុខងារ loop ខាងក្រោមជួរដែលផ្ញើ telemetry ទៅច្រកស៊េរី៖

    sendTelemetry(telemetry.c_str());
    

គ្រប់គ្រងការបញ្ជា

ឧបករណ៍របស់អ្នកត្រូវតែគ្រប់គ្រងការបញ្ជាមួយពីកូដម៉ាស៊ីនបម្រើ ដើម្បីគ្រប់គ្រង relay។ នេះត្រូវបានផ្ញើជាការស្នើសុំមុខងារ និងទទួលបានដោយផ្ទាល់។

ការងារ - គ្រប់គ្រងការស្នើសុំមុខងារផ្ទាល់

  1. បន្ថែមកូដខាងក្រោមមុនមុខងារ connectIoTHub

    int directMethodCallback(const char *method_name, const unsigned char *payload, size_t size, unsigned char **response, size_t *response_size, void *userContextCallback)
    {
        Serial.printf("Direct method received %s\r\n", method_name);
    
        if (strcmp(method_name, "relay_on") == 0)
        {
            digitalWrite(PIN_WIRE_SCL, HIGH);
        }
        else if (strcmp(method_name, "relay_off") == 0)
        {
            digitalWrite(PIN_WIRE_SCL, LOW);
        }
    }
    

    កូដនេះកំណត់មុខងារត្រឡប់ប្រតិកម្មដែលបណ្ណាល័យ IoT Hub អាចហៅពេលវាទទួលបានសំណើសុំមុខងារផ្ទាល់។ មុខងារដែលត្រូវរកសូនឹងត្រូវផ្ញើក្នុងប៉ារ៉ាម៉ែត្រ method_name។ មុខងារនេះព្រីនមុខងារដែលត្រូវហៅទៅច្រកស៊េរី ហើយបិទឬបើក relay ដោយផ្អែកលើឈ្មោះមុខងារ។

    💁 នេះក៏អាចអនុវត្តបានជាការស្នើសុំមុខងារផ្ទាល់តែមួយ ដោយផ្ញើស្ថានភាព relay ដែលចង់បានក្នុងគ្រាប់Payload ដែលអាចផ្ញើជាមួយសំណើនិងអាចប្រើបានពីប៉ារ៉ាម៉ែត្រ payload

  2. បន្ថែមកូដខាងក្រោមចុងមុខងារ directMethodCallback

    char resultBuff[16];
    sprintf(resultBuff, "{\"Result\":\"\"}");
    *response_size = strlen(resultBuff);
    *response = (unsigned char *)malloc(*response_size);
    memcpy(*response, resultBuff, *response_size);
    
    return IOTHUB_CLIENT_OK;
    

    សំណើសុំមុខងារផ្ទាល់ត្រូវការឆ្លើយតប ហើយការឆ្លើយតបមានពីរផ្នែក - ជាអត្ថបទផ្តល់ចម្លើយ និងកូដបញ្ជូនត្រឡប់។ កូដនេះនឹងបង្កើតលទ្ធផលជាឯកសារ JSON ដូចខាងក្រោម៖

    {
        "Result": ""
    }
    

    នេះបន្ទាប់ត្រូវបានចម្លងទៅប៉ារ៉ាម៉ែត្រ response ហើយទំហំនេះត្រូវបានកំណត់នៅប៉ារ៉ាម៉ែត្រ response_size។ កូដនេះប្រគល់តម្លៃ IOTHUB_CLIENT_OK ដើម្បីបង្ហាញថាមុខងារត្រូវបានគ្រប់គ្រងបានត្រឹមត្រូវ។

  3. ភ្ជាប់ callback ដោយបន្ថែមខាងក្រោមចុងមុខងារ connectIoTHub

    IoTHubClient_LL_SetDeviceMethodCallback(_device_ll_handle, directMethodCallback, NULL);
    
  4. មុខងារ loop នឹងហៅមុខងារ IoTHubDeviceClient_LL_DoWork ដើម្បីដំណើរការការកើតហេតុដែលផ្ញើដោយ IoT Hub។ នេះមានកំណត់ហៅរៀងរាល់ ១០ វិនាទីដោយសារពេលយឺត delay ដែលមានន័យថាមុខងារផ្ទាល់ត្រូវបានដំណើរការរៀងរាល់ ១០ វិនាទីទេ។ ដើម្បីធ្វើឲ្យមានប្រសិទ្ធភាពល្អជាងនេះ អ្នកអាចអនុវត្តពេលយឺត ១០ វិនាទីជា ពេលយឺតខ្លីជាច្រើន ដែលហៅ IoTHubDeviceClient_LL_DoWork រៀងរាល់ដង។ សូមបន្ថែមកូដខាងក្រោមមុនមុខងារ loop

    void work_delay(int delay_time)
    {
        int current = 0;
        do
        {
            IoTHubDeviceClient_LL_DoWork(_device_ll_handle);
            delay(100);
            current += 100;
        } while (current < delay_time);
    }
    

    កូដនេះនឹងរត់ច្រើនដង ដើម្បីហៅ IoTHubDeviceClient_LL_DoWork ហើយពន្លឿនដល់ ១០០ms រៀងរាល់ដង។ វានឹងធ្វើបែបនេះប៉ុន្មានដងដើម្បីពន្លឿនរហូតដល់ចំនួនពេលដែលបានផ្តល់នៅប៉ារ៉ាម៉ែត្រ delay_time។ នេះមានន័យថាឧបករណ៍រង់ចាំកម្រិតអតិបរមា ១០០ms ដើម្បីដំណើរការការស្នើសុំមុខងារផ្ទាល់។

  5. ក្នុងមុខងារ loop លុបការហៅទៅ IoTHubDeviceClient_LL_DoWork ហើយប្តូរ delay(10000) ជាកូដខាងក្រោមដើម្បីហៅមុខងារថ្មីនេះ៖

    work_delay(10000);
    

💁 អ្នកអាចស្វែងរកកូដនេះនៅក្នុងថត code/wio-terminal

😀 កម្មវិធីឧបករណ៍ចាប់សំណើរសំណល់ជាតិដីរបស់អ្នកត្រូវបានផ្ទៀងទៅកាន់ IoT Hub របស់អ្នកហើយ!


ការបដិសេធ
ឯកសារនេះត្រូវបានបកប្រែក្នុងការប្រើប្រាស់សេវាកម្មបកប្រែអេไអាយ Co-op Translator។ ខណៈពេលយើងខិតខំសំរាប់ភាពត្រឹមត្រូវ សូមយល់ឲ្យបានច្បាស់ថាការបកប្រែដោយស្វ័យប្រវត្តិនេះអាចមានកំហុស ឬភាពមិនត្រឹមរបស់វា។ ឯកសារដើមភាសាទីបាក់បណ្តុះត្រូវត្រូវបានគិតថាជាប្រភពដែលមានសុពលភាពត្រឹមត្រូវ។ សម្រាប់ព័ត៌មានសំខាន់ៗ ដំណើរការបកប្រែដោយមនុស្សជំនាញត្រូវបានណែនាំឲ្យប្រើ។ យើងមិនទទួលខុសត្រូវចំពោះការយល់ច្រឡំ ឬការបកស្រាយខុសៗដែលកើតឡើងពីការប្រើប្រាស់ការបកប្រែនេះឡើយ។