10 KiB
Ustaw timer - Wio Terminal
W tej części lekcji wywołasz swój kod serverless, aby zrozumieć mowę i ustawić timer na Wio Terminal na podstawie wyników.
Ustaw timer
Tekst, który wraca z wywołania funkcji zamiany mowy na tekst, musi zostać przesłany do Twojego kodu serverless, aby został przetworzony przez LUIS, który zwróci liczbę sekund dla timera. Ta liczba sekund może być użyta do ustawienia timera.
Mikrokontrolery nie mają natywnego wsparcia dla wielu wątków w Arduino, więc nie ma standardowych klas timerów, jak w Pythonie czy innych językach wyższego poziomu. Zamiast tego możesz użyć bibliotek timerów, które działają poprzez mierzenie upływu czasu w funkcji loop
i wywoływanie funkcji, gdy czas się skończy.
Zadanie - wyślij tekst do funkcji serverless
-
Otwórz projekt
smart-timer
w VS Code, jeśli nie jest już otwarty. -
Otwórz plik nagłówkowy
config.h
i dodaj URL dla swojej aplikacji funkcji:const char *TEXT_TO_TIMER_FUNCTION_URL = "<URL>";
Zamień
<URL>
na URL dla swojej aplikacji funkcji, który uzyskałeś w ostatnim kroku poprzedniej lekcji, wskazując adres IP lokalnej maszyny, na której działa aplikacja funkcji. -
Utwórz nowy plik w folderze
src
o nazwielanguage_understanding.h
. Będzie on używany do zdefiniowania klasy, która wyśle rozpoznaną mowę do Twojej aplikacji funkcji, aby została przekształcona na sekundy za pomocą LUIS. -
Dodaj następujące elementy na początku tego pliku:
#pragma once #include <Arduino.h> #include <ArduinoJson.h> #include <HTTPClient.h> #include <WiFiClient.h> #include "config.h"
To zawiera potrzebne pliki nagłówkowe.
-
Zdefiniuj klasę o nazwie
LanguageUnderstanding
i zadeklaruj instancję tej klasy:class LanguageUnderstanding { public: private: }; LanguageUnderstanding languageUnderstanding;
-
Aby wywołać aplikację funkcji, musisz zadeklarować klienta WiFi. Dodaj następujące elementy do sekcji
private
klasy:WiFiClient _client;
-
W sekcji
public
zadeklaruj metodę o nazwieGetTimerDuration
, aby wywołać aplikację funkcji:int GetTimerDuration(String text) { }
-
W metodzie
GetTimerDuration
dodaj następujący kod, aby zbudować JSON, który zostanie wysłany do aplikacji funkcji:DynamicJsonDocument doc(1024); doc["text"] = text; String body; serializeJson(doc, body);
To konwertuje tekst przekazany do metody
GetTimerDuration
na następujący JSON:{ "text" : "<text>" }
gdzie
<text>
to tekst przekazany do funkcji. -
Poniżej tego dodaj następujący kod, aby wywołać aplikację funkcji:
HTTPClient httpClient; httpClient.begin(_client, TEXT_TO_TIMER_FUNCTION_URL); int httpResponseCode = httpClient.POST(body);
To wykonuje żądanie POST do aplikacji funkcji, przekazując ciało JSON i uzyskując kod odpowiedzi.
-
Dodaj następujący kod poniżej tego:
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); }
Ten kod sprawdza kod odpowiedzi. Jeśli wynosi 200 (sukces), liczba sekund dla timera jest pobierana z ciała odpowiedzi. W przeciwnym razie błąd jest wysyłany do monitora szeregowego, a liczba sekund jest ustawiana na 0.
-
Dodaj następujący kod na końcu tej metody, aby zamknąć połączenie HTTP i zwrócić liczbę sekund:
httpClient.end(); return seconds;
-
W pliku
main.cpp
dołącz ten nowy nagłówek:#include "speech_to_text.h"
-
Na końcu funkcji
processAudio
wywołaj metodęGetTimerDuration
, aby uzyskać czas trwania timera:int total_seconds = languageUnderstanding.GetTimerDuration(text);
To konwertuje tekst z wywołania klasy
SpeechToText
na liczbę sekund dla timera.
Zadanie - ustaw timer
Liczba sekund może być użyta do ustawienia timera.
-
Dodaj następującą zależność biblioteki do pliku
platformio.ini
, aby dodać bibliotekę do ustawienia timera:contrem/arduino-timer @ 2.3.0
-
Dodaj dyrektywę
include
dla tej biblioteki do plikumain.cpp
:#include <arduino-timer.h>
-
Nad funkcją
processAudio
dodaj następujący kod:auto timer = timer_create_default();
Ten kod deklaruje timer o nazwie
timer
. -
Poniżej tego dodaj następujący kod:
void say(String text) { Serial.print("Saying "); Serial.println(text); }
Ta funkcja
say
ostatecznie przekształci tekst na mowę, ale na razie będzie tylko zapisywać przekazany tekst do monitora szeregowego. -
Poniżej funkcji
say
dodaj następujący kod:bool timerExpired(void *announcement) { say((char *)announcement); return false; }
To jest funkcja zwrotna, która zostanie wywołana, gdy timer wygaśnie. Przekazywana jest wiadomość do wypowiedzenia, gdy timer wygaśnie. Timery mogą się powtarzać, a to może być kontrolowane przez wartość zwrotną tej funkcji zwrotnej - tutaj zwraca
false
, aby poinformować timer, że nie ma się uruchamiać ponownie. -
Dodaj następujący kod na końcu funkcji
processAudio
:if (total_seconds == 0) { return; } int minutes = total_seconds / 60; int seconds = total_seconds % 60;
Ten kod sprawdza całkowitą liczbę sekund, a jeśli wynosi 0, zwraca się z wywołania funkcji, aby nie ustawiać timerów. Następnie konwertuje całkowitą liczbę sekund na minuty i sekundy.
-
Poniżej tego kodu dodaj następujący kod, aby utworzyć wiadomość do wypowiedzenia, gdy timer zostanie uruchomiony:
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.";
-
Poniżej tego dodaj podobny kod, aby utworzyć wiadomość do wypowiedzenia, gdy timer wygaśnie:
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.";
-
Po tym wypowiedz wiadomość o uruchomieniu timera:
say(begin_message);
-
Na końcu tej funkcji uruchom timer:
timer.in(total_seconds * 1000, timerExpired, (void *)(end_message.c_str()));
To uruchamia timer. Timer jest ustawiany w milisekundach, więc całkowita liczba sekund jest mnożona przez 1,000, aby przekształcić ją na milisekundy. Funkcja
timerExpired
jest przekazywana jako funkcja zwrotna, aend_message
jest przekazywana jako argument do funkcji zwrotnej. Ta funkcja zwrotna przyjmuje tylko argumenty typuvoid *
, więc ciąg znaków jest odpowiednio konwertowany. -
Na koniec timer musi tykać, a to jest robione w funkcji
loop
. Dodaj następujący kod na końcu funkcjiloop
:timer.tick();
-
Zbuduj ten kod, wgraj go na swój Wio Terminal i przetestuj go przez monitor szeregowy. Gdy zobaczysz
Ready
w monitorze szeregowym, naciśnij przycisk C (ten po lewej stronie, najbliżej przełącznika zasilania) i mów. 4 sekundy dźwięku zostaną przechwycone, przekształcone na tekst, a następnie przesłane do Twojej aplikacji funkcji, a timer zostanie ustawiony. Upewnij się, że Twoja aplikacja funkcji działa lokalnie.Zobaczysz, kiedy timer się uruchomi i kiedy się zakończy.
--- 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.
💁 Ten kod znajdziesz w folderze code-timer/wio-terminal.
😀 Twój program timera zakończył się sukcesem!
Zastrzeżenie:
Ten dokument został przetłumaczony za pomocą usługi tłumaczenia AI Co-op Translator. Chociaż staramy się zapewnić dokładność, prosimy pamiętać, że automatyczne tłumaczenia mogą zawierać błędy lub nieścisłości. Oryginalny dokument w jego rodzimym języku powinien być uznawany za autorytatywne źródło. W przypadku informacji krytycznych zaleca się skorzystanie z profesjonalnego tłumaczenia przez człowieka. Nie ponosimy odpowiedzialności za jakiekolwiek nieporozumienia lub błędne interpretacje wynikające z użycia tego tłumaczenia.