10 KiB
타이머 설정 - Wio Terminal
이 수업의 이 부분에서는 서버리스 코드를 호출하여 음성을 이해하고, 결과를 기반으로 Wio Terminal에 타이머를 설정합니다.
타이머 설정
음성을 텍스트로 변환한 결과 텍스트는 서버리스 코드로 전송되어 LUIS로 처리되어야 하며, 타이머를 위한 초 단위 숫자를 반환받습니다. 이 초 단위 숫자를 사용하여 타이머를 설정할 수 있습니다.
마이크로컨트롤러는 Arduino에서 기본적으로 멀티스레드를 지원하지 않으므로, Python이나 다른 고급 언어에서 찾을 수 있는 표준 타이머 클래스가 없습니다. 대신 loop
함수에서 경과 시간을 측정하고 시간이 다 되었을 때 함수를 호출하는 방식으로 작동하는 타이머 라이브러리를 사용할 수 있습니다.
작업 - 텍스트를 서버리스 함수로 전송하기
-
VS Code에서
smart-timer
프로젝트를 열어둡니다. 열려 있지 않다면 프로젝트를 엽니다. -
config.h
헤더 파일을 열고 함수 앱의 URL을 추가합니다:const char *TEXT_TO_TIMER_FUNCTION_URL = "<URL>";
<URL>
을 이전 수업의 마지막 단계에서 얻은 함수 앱의 URL로 바꿉니다. 이는 함수 앱을 실행 중인 로컬 머신의 IP 주소를 가리킵니다. -
src
폴더에language_understanding.h
라는 새 파일을 만듭니다. 이 파일은 인식된 음성을 함수 앱으로 전송하여 LUIS를 사용해 초 단위로 변환하는 클래스를 정의하는 데 사용됩니다. -
이 파일 상단에 다음을 추가합니다:
#pragma once #include <Arduino.h> #include <ArduinoJson.h> #include <HTTPClient.h> #include <WiFiClient.h> #include "config.h"
필요한 헤더 파일을 포함합니다.
-
LanguageUnderstanding
라는 클래스를 정의하고 이 클래스의 인스턴스를 선언합니다:class LanguageUnderstanding { public: private: }; LanguageUnderstanding languageUnderstanding;
-
함수 앱을 호출하려면 WiFi 클라이언트를 선언해야 합니다. 클래스의
private
섹션에 다음을 추가합니다:WiFiClient _client;
-
public
섹션에 함수 앱을 호출하는GetTimerDuration
이라는 메서드를 선언합니다:int GetTimerDuration(String text) { }
-
GetTimerDuration
메서드에서 함수 앱으로 보낼 JSON을 생성하는 다음 코드를 추가합니다:DynamicJsonDocument doc(1024); doc["text"] = text; String body; serializeJson(doc, body);
이 코드는
GetTimerDuration
메서드에 전달된 텍스트를 다음 JSON으로 변환합니다:{ "text" : "<text>" }
여기서
<text>
는 함수에 전달된 텍스트입니다. -
이 아래에 함수 앱 호출을 수행하는 다음 코드를 추가합니다:
HTTPClient httpClient; httpClient.begin(_client, TEXT_TO_TIMER_FUNCTION_URL); int httpResponseCode = httpClient.POST(body);
이 코드는 함수 앱에 POST 요청을 보내 JSON 본문을 전달하고 응답 코드를 받습니다.
-
이 아래에 다음 코드를 추가합니다:
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); }
이 코드는 응답 코드를 확인합니다. 응답 코드가 200(성공)인 경우 응답 본문에서 타이머 시간을 초 단위로 가져옵니다. 그렇지 않으면 오류가 시리얼 모니터에 출력되고 초 단위 시간이 0으로 설정됩니다.
-
이 메서드 끝에 HTTP 연결을 닫고 초 단위 시간을 반환하는 다음 코드를 추가합니다:
httpClient.end(); return seconds;
-
main.cpp
파일에서 이 새 헤더를 포함합니다:#include "speech_to_text.h"
-
processAudio
함수 끝에서GetTimerDuration
메서드를 호출하여 타이머 시간을 가져옵니다:int total_seconds = languageUnderstanding.GetTimerDuration(text);
이 코드는
SpeechToText
클래스 호출에서 반환된 텍스트를 타이머 시간을 초 단위로 변환합니다.
작업 - 타이머 설정
초 단위 시간은 타이머를 설정하는 데 사용할 수 있습니다.
-
타이머를 설정하기 위한 라이브러리를 추가하려면
platformio.ini
파일에 다음 라이브러리 종속성을 추가합니다:contrem/arduino-timer @ 2.3.0
-
이 라이브러리를 포함하기 위한 include 지시문을
main.cpp
파일에 추가합니다:#include <arduino-timer.h>
-
processAudio
함수 위에 다음 코드를 추가합니다:auto timer = timer_create_default();
이 코드는
timer
라는 타이머를 선언합니다. -
이 아래에 다음 코드를 추가합니다:
void say(String text) { Serial.print("Saying "); Serial.println(text); }
이
say
함수는 나중에 텍스트를 음성으로 변환하지만, 지금은 전달된 텍스트를 시리얼 모니터에 출력합니다. -
say
함수 아래에 다음 코드를 추가합니다:bool timerExpired(void *announcement) { say((char *)announcement); return false; }
이 콜백 함수는 타이머가 만료되었을 때 호출됩니다. 타이머가 만료되었을 때 출력할 메시지가 전달됩니다. 타이머는 반복될 수 있으며, 이 콜백의 반환 값으로 이를 제어할 수 있습니다. 여기서는
false
를 반환하여 타이머가 다시 실행되지 않도록 합니다. -
processAudio
함수 끝에 다음 코드를 추가합니다:if (total_seconds == 0) { return; } int minutes = total_seconds / 60; int seconds = total_seconds % 60;
이 코드는 총 초 단위 시간을 확인하고, 0이면 함수 호출을 종료하여 타이머가 설정되지 않도록 합니다. 그런 다음 총 초 단위 시간을 분과 초로 변환합니다.
-
이 코드 아래에 타이머가 시작될 때 출력할 메시지를 생성하는 다음 코드를 추가합니다:
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.";
-
이 아래에 타이머가 만료되었을 때 출력할 메시지를 생성하는 유사한 코드를 추가합니다:
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.";
-
이 후에 타이머 시작 메시지를 출력합니다:
say(begin_message);
-
이 함수 끝에 타이머를 시작합니다:
timer.in(total_seconds * 1000, timerExpired, (void *)(end_message.c_str()));
이 코드는 타이머를 트리거합니다. 타이머는 밀리초 단위로 설정되므로 총 초 단위 시간을 1,000으로 곱해 밀리초로 변환합니다.
timerExpired
함수가 콜백으로 전달되며,end_message
가 콜백에 전달할 인수로 전달됩니다. 이 콜백은void *
인수만 받으므로 문자열이 적절히 변환됩니다. -
마지막으로, 타이머는 tick해야 하며, 이는
loop
함수에서 수행됩니다.loop
함수 끝에 다음 코드를 추가합니다:timer.tick();
-
이 코드를 빌드하고 Wio Terminal에 업로드한 후 시리얼 모니터를 통해 테스트합니다. 시리얼 모니터에서
Ready
가 표시되면 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를 사용하여 번역되었습니다. 정확성을 위해 최선을 다하고 있지만, 자동 번역에는 오류나 부정확성이 포함될 수 있습니다. 원본 문서를 해당 언어로 작성된 상태에서 권위 있는 자료로 간주해야 합니다. 중요한 정보의 경우, 전문적인 인간 번역을 권장합니다. 이 번역 사용으로 인해 발생하는 오해나 잘못된 해석에 대해 당사는 책임을 지지 않습니다.