11 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に置き換えます。この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);
これにより、JSONボディを渡してPOSTリクエストを送信し、レスポンスコードを取得します。
-
この下に以下のコードを追加します:
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
-
このライブラリをインクルードする指示を
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 *
型の引数しか受け取れないため、文字列を適切に変換します。 -
最後に、タイマーを「動作」させる必要があります。これは
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 を使用して翻訳されています。正確性を期すよう努めておりますが、自動翻訳には誤りや不正確さが含まれる可能性があります。元の言語で記載された原文が公式な情報源と見なされるべきです。重要な情報については、専門の人間による翻訳を推奨します。本翻訳の使用に起因する誤解や誤認について、当方は一切の責任を負いません。