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/th/6-consumer/lessons/3-spoken-feedback/wio-terminal-set-timer.md

16 KiB

ตั้งเวลานับถอยหลัง - Wio Terminal

ในส่วนนี้ของบทเรียน คุณจะเรียกใช้โค้ดแบบเซิร์ฟเวอร์เลสเพื่อแปลงคำพูดเป็นข้อความ และตั้งเวลานับถอยหลังบน Wio Terminal ตามผลลัพธ์ที่ได้

ตั้งเวลานับถอยหลัง

ข้อความที่ได้จากการแปลงคำพูดเป็นข้อความจะต้องถูกส่งไปยังโค้ดเซิร์ฟเวอร์เลสของคุณเพื่อให้ LUIS ประมวลผล และส่งกลับมาด้วยจำนวนวินาทีสำหรับตั้งเวลา จำนวนวินาทีนี้จะถูกใช้ในการตั้งเวลานับถอยหลัง

ไมโครคอนโทรลเลอร์ไม่มีการรองรับการทำงานแบบมัลติเธรดใน Arduino โดยตรง ดังนั้นจึงไม่มีคลาสตั้งเวลาแบบมาตรฐานเหมือนที่คุณอาจพบใน Python หรือภาษาโปรแกรมระดับสูงอื่น ๆ แต่คุณสามารถใช้ไลบรารีตั้งเวลาที่ทำงานโดยการวัดเวลาที่ผ่านไปในฟังก์ชัน loop และเรียกใช้ฟังก์ชันเมื่อเวลาหมด

งาน - ส่งข้อความไปยังฟังก์ชันเซิร์ฟเวอร์เลส

  1. เปิดโปรเจกต์ smart-timer ใน VS Code หากยังไม่ได้เปิด

  2. เปิดไฟล์เฮดเดอร์ config.h และเพิ่ม URL สำหรับแอปฟังก์ชันของคุณ:

    const char *TEXT_TO_TIMER_FUNCTION_URL = "<URL>";
    

    แทนที่ <URL> ด้วย URL ของแอปฟังก์ชันที่คุณได้จากขั้นตอนสุดท้ายของบทเรียนก่อนหน้า โดยชี้ไปยังที่อยู่ IP ของเครื่องที่รันแอปฟังก์ชัน

  3. สร้างไฟล์ใหม่ในโฟลเดอร์ src ชื่อ language_understanding.h ไฟล์นี้จะถูกใช้เพื่อกำหนดคลาสสำหรับส่งข้อความที่แปลงจากคำพูดไปยังแอปฟังก์ชันเพื่อแปลงเป็นวินาทีโดยใช้ LUIS

  4. เพิ่มโค้ดต่อไปนี้ที่ด้านบนของไฟล์นี้:

    #pragma once
    
    #include <Arduino.h>
    #include <ArduinoJson.h>
    #include <HTTPClient.h>
    #include <WiFiClient.h>
    
    #include "config.h"
    

    โค้ดนี้รวมไฟล์เฮดเดอร์ที่จำเป็น

  5. กำหนดคลาสชื่อ LanguageUnderstanding และประกาศอินสแตนซ์ของคลาสนี้:

    class LanguageUnderstanding
    {
    public:
    private:
    };
    
    LanguageUnderstanding languageUnderstanding;
    
  6. เพื่อเรียกใช้แอปฟังก์ชันของคุณ คุณต้องประกาศ WiFi client เพิ่มโค้ดต่อไปนี้ในส่วน private ของคลาส:

    WiFiClient _client;
    
  7. ในส่วน public ให้ประกาศเมธอดชื่อ GetTimerDuration เพื่อเรียกใช้แอปฟังก์ชัน:

    int GetTimerDuration(String text)
    {
    }
    
  8. ในเมธอด GetTimerDuration เพิ่มโค้ดต่อไปนี้เพื่อสร้าง JSON ที่จะถูกส่งไปยังแอปฟังก์ชัน:

    DynamicJsonDocument doc(1024);
    doc["text"] = text;
    
    String body;
    serializeJson(doc, body);
    

    โค้ดนี้แปลงข้อความที่ส่งไปยังเมธอด GetTimerDuration ให้เป็น JSON ดังนี้:

    {
        "text" : "<text>"
    }
    

    โดยที่ <text> คือข้อความที่ส่งไปยังฟังก์ชัน

  9. ด้านล่างนี้ เพิ่มโค้ดต่อไปนี้เพื่อเรียกใช้แอปฟังก์ชัน:

    HTTPClient httpClient;
    httpClient.begin(_client, TEXT_TO_TIMER_FUNCTION_URL);
    
    int httpResponseCode = httpClient.POST(body);
    

    โค้ดนี้ทำการ POST request ไปยังแอปฟังก์ชัน โดยส่ง JSON body และรับ response code

  10. เพิ่มโค้ดต่อไปนี้ด้านล่าง:

    int seconds = 0;
    if (httpResponseCode == 200)
    {
        String result = httpClient.getString();
        Serial.println(result);
    
        DynamicJsonDocument doc(1024);
        deserializeJson(doc, result.c_str());
    
        JsonObject obj = doc.as<JsonObject>();
        seconds = obj["seconds"].as<int>();
    }
    else
    {
        Serial.print("Failed to understand text - error ");
        Serial.println(httpResponseCode);
    }
    

    โค้ดนี้ตรวจสอบ response code หากเป็น 200 (สำเร็จ) จะดึงจำนวนวินาทีจาก response body มิฉะนั้นจะส่งข้อผิดพลาดไปยัง serial monitor และตั้งจำนวนวินาทีเป็น 0

  11. เพิ่มโค้ดต่อไปนี้ที่ท้ายเมธอดนี้เพื่อปิดการเชื่อมต่อ HTTP และคืนค่าจำนวนวินาที:

    httpClient.end();
    
    return seconds;
    
  12. ในไฟล์ main.cpp ให้ include เฮดเดอร์ใหม่นี้:

    #include "speech_to_text.h"
    
  13. ที่ท้ายฟังก์ชัน processAudio เรียกใช้เมธอด GetTimerDuration เพื่อรับค่าระยะเวลาของตัวจับเวลา:

    int total_seconds = languageUnderstanding.GetTimerDuration(text);
    

    โค้ดนี้แปลงข้อความจากการเรียกใช้คลาส SpeechToText เป็นจำนวนวินาทีสำหรับตั้งเวลา

งาน - ตั้งเวลานับถอยหลัง

จำนวนวินาทีสามารถใช้ในการตั้งเวลานับถอยหลังได้

  1. เพิ่มไลบรารีที่ต้องการในไฟล์ platformio.ini เพื่อเพิ่มไลบรารีสำหรับตั้งเวลา:

    contrem/arduino-timer @ 2.3.0
    
  2. เพิ่มคำสั่ง include สำหรับไลบรารีนี้ในไฟล์ main.cpp:

    #include <arduino-timer.h>
    
  3. เหนือฟังก์ชัน processAudio เพิ่มโค้ดต่อไปนี้:

    auto timer = timer_create_default();
    

    โค้ดนี้ประกาศตัวจับเวลาชื่อ timer

  4. ด้านล่างนี้ เพิ่มโค้ดต่อไปนี้:

    void say(String text)
    {
        Serial.print("Saying ");
        Serial.println(text);
    }
    

    ฟังก์ชัน say นี้ในอนาคตจะถูกใช้เพื่อแปลงข้อความเป็นเสียงพูด แต่ตอนนี้จะเพียงแค่เขียนข้อความที่ส่งเข้ามาไปยัง serial monitor

  5. ด้านล่างฟังก์ชัน say เพิ่มโค้ดต่อไปนี้:

    bool timerExpired(void *announcement)
    {
        say((char *)announcement);
        return false;
    }
    

    นี่คือฟังก์ชัน callback ที่จะถูกเรียกเมื่อเวลาหมด ฟังก์ชันนี้จะรับข้อความเพื่อพูดเมื่อเวลาหมด ตัวจับเวลาสามารถทำซ้ำได้ และสามารถควบคุมได้ด้วยค่าที่ return จาก callback - โค้ดนี้ return false เพื่อบอกให้ตัวจับเวลาไม่ทำงานซ้ำ

  6. เพิ่มโค้ดต่อไปนี้ที่ท้ายฟังก์ชัน processAudio:

    if (total_seconds == 0)
    {
        return;
    }
    
    int minutes = total_seconds / 60;
    int seconds = total_seconds % 60;
    

    โค้ดนี้ตรวจสอบจำนวนวินาทีทั้งหมด และหากเป็น 0 จะ return ออกจากฟังก์ชันเพื่อไม่ให้ตั้งเวลา จากนั้นจะแปลงจำนวนวินาทีทั้งหมดเป็นนาทีและวินาที

  7. ด้านล่างโค้ดนี้ เพิ่มโค้ดต่อไปนี้เพื่อสร้างข้อความที่จะแจ้งเมื่อเริ่มตั้งเวลา:

    String begin_message;
    if (minutes > 0)
    {
        begin_message += minutes;
        begin_message += " minute ";
    }
    if (seconds > 0)
    {
        begin_message += seconds;
        begin_message += " second ";
    }
    
    begin_message += "timer started.";
    
  8. ด้านล่างนี้ เพิ่มโค้ดที่คล้ายกันเพื่อสร้างข้อความที่จะแจ้งเมื่อเวลาหมด:

    String end_message("Times up on your ");
    if (minutes > 0)
    {
        end_message += minutes;
        end_message += " minute ";
    }
    if (seconds > 0)
    {
        end_message += seconds;
        end_message += " second ";
    }
    
    end_message += "timer.";
    
  9. หลังจากนี้ ให้พูดข้อความแจ้งเริ่มตั้งเวลา:

    say(begin_message);
    
  10. ที่ท้ายฟังก์ชันนี้ เริ่มตัวจับเวลา:

    timer.in(total_seconds * 1000, timerExpired, (void *)(end_message.c_str()));
    

    โค้ดนี้เริ่มตัวจับเวลา ตัวจับเวลาถูกตั้งค่าโดยใช้มิลลิวินาที ดังนั้นจำนวนวินาทีทั้งหมดจะถูกคูณด้วย 1,000 เพื่อแปลงเป็นมิลลิวินาที ฟังก์ชัน timerExpired ถูกส่งเป็น callback และ end_message ถูกส่งเป็นอาร์กิวเมนต์ไปยัง callback ซึ่ง callback นี้รับเฉพาะอาร์กิวเมนต์แบบ void * ดังนั้นข้อความจึงถูกแปลงให้เหมาะสม

  11. สุดท้าย ตัวจับเวลาจำเป็นต้อง tick และสิ่งนี้ทำในฟังก์ชัน loop เพิ่มโค้ดต่อไปนี้ที่ท้ายฟังก์ชัน loop:

    timer.tick();
    
  12. สร้างโค้ดนี้ อัปโหลดไปยัง Wio Terminal ของคุณ และทดสอบผ่าน serial monitor เมื่อคุณเห็นคำว่า Ready ใน serial monitor ให้กดปุ่ม C (ปุ่มด้านซ้ายมือ ใกล้กับสวิตช์เปิดปิด) และพูด เสียงพูด 4 วินาทีจะถูกจับ แปลงเป็นข้อความ จากนั้นส่งไปยังแอปฟังก์ชันของคุณ และตั้งเวลานับถอยหลัง ตรวจสอบให้แน่ใจว่าแอปฟังก์ชันของคุณกำลังทำงานอยู่ในเครื่อง

    คุณจะเห็นเมื่อเวลานับถอยหลังเริ่มต้น และเมื่อเวลาหมด

    --- Available filters and text transformations: colorize, debug, default, direct, hexlify, log2file, nocontrol, printable, send_on_enter, time
    --- More details at http://bit.ly/pio-monitor-filters
    --- Miniterm on /dev/cu.usbmodem1101  9600,8,N,1 ---
    --- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
    Connecting to WiFi..
    Connected!
    Got access token.
    Ready.
    Starting recording...
    Finished recording
    Sending speech...
    Speech sent!
    {"RecognitionStatus":"Success","DisplayText":"Set a 2 minute and 27 second timer.","Offset":4700000,"Duration":35300000}
    Set a 2 minute and 27 second timer.
    {"seconds": 147}
    2 minute 27 second timer started.
    Times up on your 2 minute 27 second timer.
    

💁 คุณสามารถหาโค้ดนี้ได้ในโฟลเดอร์ code-timer/wio-terminal

😀 โปรแกรมตั้งเวลาของคุณสำเร็จแล้ว!


ข้อจำกัดความรับผิดชอบ:
เอกสารนี้ได้รับการแปลโดยใช้บริการแปลภาษา AI Co-op Translator แม้ว่าเราจะพยายามอย่างเต็มที่เพื่อความถูกต้อง แต่โปรดทราบว่าการแปลอัตโนมัติอาจมีข้อผิดพลาดหรือความไม่แม่นยำ เอกสารต้นฉบับในภาษาต้นทางควรถือเป็นแหล่งข้อมูลที่เชื่อถือได้ สำหรับข้อมูลที่สำคัญ แนะนำให้ใช้บริการแปลภาษามนุษย์ที่เป็นมืออาชีพ เราไม่รับผิดชอบต่อความเข้าใจผิดหรือการตีความที่ผิดพลาดซึ่งเกิดจากการใช้การแปลนี้