SenseCAPプラットフォームは正式にSenseCraft Data Platform
に名称変更されました!
XIAO ESP32C3を使用してSenseCraft Data Platformに接続し、栽培アドバイスを取得する

この期間中、Seeed StudioのSenseCraft DataプラットフォームはAI機能を新たに開発・リリースしました。現在、SenseCraft Data PlatformのAI Advisorの主な機能は栽培者に建設的な栽培アドバイスを提供することに焦点を当てており、近い将来、より豊富なAI機能でアップデートされる予定です!
このチュートリアルでは、XIAO ESP32シリーズとSenseCraft Data platform
を橋渡しし、XIAOとGroveシリーズセンサーを使用してプラットフォームにデータをアップロードし、これらのセンサー値に基づいてAIから建設的な提案を得る方法を詳しく説明します。
はじめに
ハードウェアの準備
このチュートリアルで使用する3つのハードウェアは、XIAO ESP32C3、Grove Base for XIAO、およびGrove SHT40温湿度センサーです。配線の便宜上、XIAO拡張ボードを使用しますが、実際のニーズに応じて購入してください。
Seeed Studio XIAO ESP32C3 | Grove Base for XIAO | Grove - Temperature & Humidity Sensor(SHT40) |
---|---|---|
![]() | ![]() | ![]() |
ソフトウェア準備
XIAO ESP32C3を初めて使用する場合は、まずこのWikiを読んでArduinoで良好な開発環境を設定する方法を学ぶ必要があります。
また、このチュートリアルはXIAO ESP32S3とも互換性があり、XIAO ESP32S3を使用してこのチュートリアルの内容を完了することもできます。
SHT40センサーを使用するため、プログラムがスムーズに実行されるように、Arduinoに以下の2つのライブラリを追加する必要があります。
XIAO ESP32C3で温度と湿度データを取得する
下図に示すように、Grove SHT40温度湿度センサーをXIAOのIICインターフェースに接続してください。

次に、XIAO ESP32C3用の以下のプログラムをアップロードして、SHT40センサーを駆動して動作させ、空気中の温度と湿度の値を取得し始めます。
#include <Arduino.h>
#include <SensirionI2CSht4x.h>
#include <Wire.h>
SensirionI2CSht4x sht4x;
void setup() {
Serial.begin(115200);
while (!Serial) {
delay(100);
}
Wire.begin();
uint16_t error;
char errorMessage[256];
sht4x.begin(Wire);
uint32_t serialNumber;
error = sht4x.serialNumber(serialNumber);
if (error) {
Serial.print("Error trying to execute serialNumber(): ");
errorToString(error, errorMessage, 256);
Serial.println(errorMessage);
} else {
Serial.print("Serial Number: ");
Serial.println(serialNumber);
}
}
void loop() {
uint16_t error;
char errorMessage[256];
delay(1000);
float temperature;
float humidity;
error = sht4x.measureHighPrecision(temperature, humidity);
if (error) {
Serial.print("Error trying to execute measureHighPrecision(): ");
errorToString(error, errorMessage, 256);
Serial.println(errorMessage);
} else {
Serial.print("Temperature:");
Serial.print(temperature);
Serial.print("\t");
Serial.print("Humidity:");
Serial.println(humidity);
}
}
Arduino IDEのシリアルモニターを開き、ボーレートを115200に設定して結果を確認してください。

SenseCraft Data Platform HTTPS API入門 -- センサーデータのアップロード
SHT40センサーからデータを取得する方法がわかったので、次にSenseCraft Data Platform
の以下のAPI呼び出しルールを学習しましょう。下のボタンをクリックしてSenseCraftドキュメントセンターに直接ジャンプすることで、SenseCraft Data Platform
のAPIの使用方法について読むことができます。
SenseCraft Data Platformがセンサーデータを受信する基本原理は、EUI、Keyを認証情報として使用し、POSTによってデバイスデータを報告することです。
HTTPSサーバーアドレス:
https://sensecap.seeed.cc/deviceapi
ヘッダーについて
POSTでは、ヘッダーに認証情報を追加する必要があります。これは、デバイスのEUIとKeyをbase64で暗号化したデータで、以下の基本形式になります。
authorization = Device base64(EUI:Key)
インターフェースについて
デバイスがセンサーデータを報告するために使用するサーバーパスは:/kit/message_uplink
、モードはPOSTで、以下のリクエストパラメータが利用可能で許可されています。
名前 | タイプ | 説明 |
---|---|---|
- requestId | string | データが報告されるたびにデバイス側で生成されるuuidv4で、各メッセージで値が異なることを保証します。 |
- timestamp | string | メッセージが送信された時のミリ秒タイムスタンプ。 |
- intent | string | 現在は「event」に固定されています。 |
- deviceEui | string | デバイスEUI。 |
- deviceKey | string | デバイスキー。 |
- events | [object] | データ収集とデバイス状態が報告されるイベントの配列。 |
-- name | string | イベント名。 |
-- value | [object] | イベント値。 |
-- timestamp | string | データ収集時のミリ秒タイムスタンプ。 |
以下は、センサーアップロードデータの送信例です。
{
"requestId": "aaaa-aaaa-aaaa-aaaa",
"timestamp": "1691026791405",
"intent": "event",
"deviceEui": "2CF7xxxxxxx00002",
"deviceKey": "38xxxxxxxxxxxxxxxxxxxxC0EE76C3CD",
"events": [
{
"name": "measure-sensor",
"value": [
{
"channel": "1",
"measurements": {
"4097": "31.38",
"4098": "59.60"
},
"measureTime": "1691026791405"
}
]
},
{
"name": "update-channel-info",
"value": [
{
"channel": "1",
"sensorType": "1001",
"status": "normal"
}
],
"timestamp": "1691026791405"
}
]
}
SenseCraft Data Platform に温湿度データをアップロードする
上記のルールを理解したら、SHT40の温湿度データをSenseCraft Data PlatformにアップロードするためのHTTPSプログラムの作成を開始できます。
ステップ1. SenseCraft Data Platformに登録してログインする
以下のリンクをクリックして、SenseCraft Data Platform国際サイトに直接アクセスできます。SenseCraftのサービスを初めて使用する場合は、アカウントを登録する必要があります。
SenseCraft Data Platformにログインすると、コンソール画面が表示されます。独自のキットを追加する必要があるので、左側のメニューバーのDevelopKitをクリックしてください。

次に、左上のCreate DevelopKitをクリックします。

MIG Develop Kitを選択し、Confirmボタンをクリックするだけです。

次に、ダッシュボードで作成したデバイスを確認できます。通常は最初のものです。そのデバイスの「Connect」ボタンをクリックすると、そのデバイスのEUIとKEY情報が表示されます。これらを保存してください。次のステップで使用します。

ステップ2. 認証情報の取得
SenseCraftの認証情報用インターフェースには、Base64ベースのEUI:KEY暗号化が必要です。
例えば、あなたのEUIが2CF7F11003900000
でKeyが06C42483D7155E7006C42483D7155E70
の場合、ターミナルで以下のコマンドによってBase64暗号化された認証情報を取得できます。
echo -n 2CF7F11003900000:06C42483D7155E7006C42483D7155E70 |base64
>>> MkNGN0YxMTAwMzkwMDAwMDowNkM0MjQ4M0Q3MTU1RTcwMDZDNDI0ODNENzE1NUU3MA==
認証情報を保持してください。後でプログラムでapiKeyとして使用します。
ステップ3. センサータイプの番号を取得する
アップロードには、報告するセンサータイプの番号とセンサー名が含まれています。これにより、SenseCraftはどのセンサーからデータをアップロードしているか、データがどの単位であるかを知ることができます。
このセクションについては、SenseCraft Documentation Centerで提供されているセンサーと値の番号付きクロスリファレンステーブルを参照してください。
これら2つの文書の使用方法について、この記事で使用されているSHT40センサーを例として、説明を行います。SHT40センサーは温度と湿度の両方のデータを測定できるセンサーです。そのため、センサータイプのコードと(温度、湿度)値の2つのコードがあります。
センサータイプのコードはセンサータイプリストで調べる必要があります。コード1001の温度・湿度センサーを見つけました。

私たちが話しているセンサー値のコードは、実際には図の測定ID、4097と4098です。これらは測定IDリストでも見つけることができ、これらの値の単位がお使いのセンサーと一致するかどうかを確認できます。

テーブルで適切なセンサータイプが見つからない場合は、センサー番号4165から4174のカスタムタイプを使用する必要があるかもしれません。センサー値は単位なしの場合があります。
ステップ4. 必要なライブラリをインストールする
まずNTPClientライブラリです。これはXIAOネットワーキングを使用して現在のタイムスタンプを取得できます。

次にArduinoJsonライブラリです。これはSenseCraftから返されるデータの解析を簡単にしてくれます。

ステップ5. プログラムを通じてセンサーデータをアップロードする
以下はSHT40データをアップロードするプロシージャです。以下のマクロ定義は、お客様の状況に合わせて修正した場合にのみ使用してください。
const char* ssid = "YOUR-WIFI-NAME";
const char* password = "YOUR-WIFI-PASSWORD";
const char* apiKey = "YOUR-DEVICE-EUI&KEY-BASE64";
const char* deviceEUI = "YOUR-DEVICE-EUI";
const char* deviceKey = "YOUR-DEVICE-KEY";
const char* dataNum_1 = "4097"; // Air temperature
const char* dataNum_2 = "4098"; // Air humidity
const char* sensorType = "1001"; // Air temperature and humidity sensors
ssidとpasswordはあなたのネットワーク名とパスワードを指します。apiKeyはステップ2で取得したフォレンジック情報を指します。deviceEUIとdeviceKeyはあなたのデバイスEUIとキーで、これらもステップ2で取得したものです。
#include <Arduino.h>
#include <SensirionI2CSht4x.h>
#include <Wire.h>
#include "WiFi.h"
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <WiFiUdp.h>
#include <NTPClient.h>
// Replace with your devive content
const char* ssid = "YOUR-WIFI-NAME";
const char* password = "YOUR-WIFI-PASSWORD";
const char* apiKey = "YOUR-DEVICE-EUI&KEY-BASE64";
const char* deviceEUI = "YOUR-DEVICE-EUI";
const char* deviceKey = "YOUR-DEVICE-KEY";
const char* dataNum_1 = "4097"; // Air temperature
const char* dataNum_2 = "4098"; // Air humidity
const char* sensorType = "1001"; // Air temperature and humidity sensors
const char* ntpServer = "pool.ntp.org";
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, ntpServer);
char sensecapServer[] = "https://sensecap.seeed.cc/deviceapi/kit/message_uplink";
SensirionI2CSht4x sht4x;
void wifiConnect(){
WiFi.begin(ssid, password);
Serial.print("Connecting to ");
Serial.println(ssid);
while(WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("WiFi connected!");
Serial.println(WiFi.localIP());
}
void setup() {
Serial.begin(115200);
while (!Serial) {
delay(100);
}
Wire.begin();
uint16_t error;
char errorMessage[256];
sht4x.begin(Wire);
uint32_t serialNumber;
error = sht4x.serialNumber(serialNumber);
if (error) {
Serial.print("Error trying to execute serialNumber(): ");
errorToString(error, errorMessage, 256);
Serial.println(errorMessage);
} else {
Serial.print("Serial Number: ");
Serial.println(serialNumber);
}
wifiConnect();
timeClient.begin(); // Initialize the NTP client
timeClient.update(); // update timestamp
}
void loop() {
uint16_t error;
char errorMessage[256];
delay(1000);
float temperature;
float humidity;
error = sht4x.measureHighPrecision(temperature, humidity);
if (error) {
Serial.print("Error trying to execute measureHighPrecision(): ");
errorToString(error, errorMessage, 256);
Serial.println(errorMessage);
} else {
Serial.print("Temperature:");
Serial.print(temperature);
Serial.print("\t");
Serial.print("Humidity:");
Serial.println(humidity);
}
HTTPClient https;
if (https.begin(sensecapServer)) { // HTTPS
https.addHeader("Content-Type", "application/json");
String author = String("Device ") + apiKey;
https.addHeader("authorization", author);
String payload = String("{\"requestId\": \"aaaa-aaaa-aaaa-aaaa\", \"timestamp\": \"");
timeClient.update(); // update timestamp
uint64_t timestamp = timeClient.getEpochTime() * 1000ULL; // GET timestamp
payload += String(timestamp);
payload += String("\", \"intent\": \"event\", \"deviceEui\": \"");
payload += deviceEUI;
payload += String("\", \"deviceKey\": \"");
payload += deviceKey;
payload += String("\", \"events\": [{\"name\": \"measure-sensor\", \"value\": [{\"channel\": \"1\", \"measurements\": {\"");
payload += dataNum_1;
payload += String("\": \"");
payload += String(temperature);
payload += String("\", \"");
payload += dataNum_2;
payload += String("\": \"");
payload += String(humidity);
payload += String("\"}, \"measureTime\": \"");
payload += String(timestamp);
payload += String("\"}]}, {\"name\": \"update-channel-info\", \"value\": [{\"channel\": \"1\", \"sensorType\": \"");
payload += sensorType;
payload += String("\", \"status\": \"normal\"}], \"timestamp\": \"");
payload += String(timestamp);
payload += String("\"}]}");
Serial.println(payload);
int httpCode = https.POST(payload); // start connection and send HTTP header
if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
String payload = https.getString();
Serial.println(payload);
}
else{
Serial.print("[HTTP] ERROR: ");
Serial.println(httpCode);
}
}
else{
Serial.println("[HTTPS] Unable to connect");
delay(1000);
}
delay(300000);
}
シリアルモニターをオンにすると、プログラムの実行が開始されます。図に示されているような応答を受信した場合、SenseCraftがあなたのデータアップロードの1つを正常に受信したことを意味します。

SenseCraftがデータアップロードを受信する最小時間間隔は5分です。
SenseCraft Data Platform
のHTTP API紹介 -- AIアドバイスの取得
次に、以下でSenseCraft Data Platform
のAPIの使用方法を学びましょう。時間の経過に伴うセンサーデータを参考として使用し、AIから提案を取得します。
SenseCraft AIのインターフェース呼び出しプロセスは大まかに以下の通りです。
- インターフェースIを介して、AIGCでの使用がサポートされているアカウント下のデバイスと測定値IDを取得します。
- インターフェースIで取得した結果をパラメータの1つとして使用し、インターフェースIIを呼び出してAIGC結果を取得します。
- AIGC生成時間が長い場合があるため、インターフェースIは初回呼び出し時にresource_idを返し、その後フロントエンドはresource_idを使用して応答結果をポーリングします。応答のコードが11338の場合、AIGCがまだ推論処理中であることを意味し、最終結果が返されるまでresource_idを使用してインターフェースIIを再度呼び出す必要があります。
- インターフェースIIには、同一アカウントに対して5分以内に最大10回のリクエストというフロー制限があります。
HTTPSサーバーアドレス:
https://sensecap.seeed.cc/openapi
Interface I について
デバイスがセンサーデータを報告するために使用するサーバーパスは:/ai/view_suggestion_by_measurements
、モードはPOSTで、以下のリクエストパラメータが利用可能で許可されています。
名前 | 説明 | 備考 |
---|---|---|
- lang | 言語選択 | 1:中国語、2:英語。デフォルトは中国語。 |
- location | 場所 | 場所、例:"深圳"。 |
- crop | 作物または動物 | 相談する作物または動物、例:"りんご"。 |
- time_range | デバイスデータ照会時間 | 1: 30日 2: 180日 3: 360日。デフォルトは30日 |
- measurements | デバイス測定タイプ | 最大6つ |
-- dev_eui | デバイスEUI | |
-- channel_measurement | ||
--- channel_index | チャンネル番号 | この値は現在1に固定されています。 |
--- measurement_ids | 測定値番号 |
以下はInterface Iを呼び出す例です。
{
"lang": "2",
"crop": "apple",
"location": "Shenzhen",
"time_range": "1",
"measurements": [
{
"dev_eui": "2CF7F18215100010",
"channel_measurement": [
{
"channel_index": "1",
"measurement_ids": [
"4097",
"4098"
]
}
]
},
{
"dev_eui": "2CF7F1C043400103",
"channel_measurement": [
{
"channel_index": "1",
"measurement_ids": [
"4097"
]
}
]
}
]
}
Interface II について
Interface I の構造とフレームワークは Interface II とほぼ同じですが、唯一の違いは末尾に追加の resource_id があることです。以下のリクエストパラメータが利用可能で許可されています。
Name | Description | Note |
---|---|---|
- lang | 言語選択 | 1:中国語、2:英語。デフォルトは中国語。 |
- location | 場所 | 場所、例:"深圳"。 |
- crop | 作物または動物 | 相談する作物または動物、例:"りんご"。 |
- time_range | デバイスデータ照会時間 | 1: 30日 2: 180日 3: 360日。デフォルトは30日 |
- measurements | デバイス測定タイプ | 最大6つまで |
-- dev_eui | デバイス EUI | |
-- channel_measurement | ||
--- channel_index | チャンネル番号 | この値は現在1に固定されています。 |
--- measurement_ids | 測定値番号 | |
- resource_id | キャッシュされた認証情報 | 質問が行われ、返された結果が取得された場合、このパラメータを持参してバックエンドをポーリングし、AIの結果が返されるまで待機します。 |
以下は AI アドバイスを取得する例です。
{
"lang": "2",
"crop": "apple",
"location": "Shenzhen",
"time_range": "1",
"measurements": [
{
"dev_eui": "2CF7F18215100010",
"channel_measurement": [
{
"channel_index": "1",
"measurement_ids": [
"4097",
"4098"
]
}
]
},
{
"dev_eui": "2CF7F1C043400103",
"channel_measurement": [
{
"channel_index": "1",
"measurement_ids": [
"4097"
]
}
]
}
],
"resource_id": "openAi:ask:424326279298784:1691053698953"
}
XIAO ESP32C3 Getting SenseCraft AI Advisor
ステップ 6. API アクセスの作成
SenseCraft の AIGC インターフェースを呼び出したい場合は、SenseCraft で API ID と API Access Key を準備する必要があります。ダッシュボードの左側メニューバーで Access API keys を選択します。次に、上部の Create Access Key をクリックします。

作成された Access Key ID と Access API Key をコピーします。これらを安全に保管してください。以下のステップで使用します。

ステップ 7. プログラムの作成とアップロード
上記のインターフェースガイドラインに従って、SenseCraft が SHT40 からの温度と湿度データを使用して栽培の推奨事項を返すプログラムを作成できます。
#include <Arduino.h>
#include <Wire.h>
#include "WiFi.h"
#include <HTTPClient.h>
#include <base64.h>
#include <ArduinoJson.h>
//#define DEBUG 1
// Replace with your devive content
const char* ssid = "YOUR-WIFI-NAME";
const char* password = "YOUR-WIFI-PASSWORD";
const char* username = "YOUR-API-ID";
const char* accesskey = "YOUR-ACCESS-API-KEY";
const char* deviceEUI = "YOUR-DEVICE-EUI";
const char* crop = "apple";
const char* location = "Shenzhen";
const char* timerange = "1";
const char* dataNum_1 = "4097"; //Air temperature
const char* dataNum_2 = "4098"; //Air humidity
char sensecapAIServer[] = "https://sensecap.seeed.cc/openapi/ai/view_suggestion_by_measurements";
void wifiConnect(){
WiFi.begin(ssid, password);
Serial.print("Connecting to ");
Serial.println(ssid);
while(WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("WiFi connected!");
Serial.println(WiFi.localIP());
}
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
while (!Serial) {
delay(100);
}
wifiConnect();
}
String splicePayload(int mode, String resource_id = ""){
String payload = String("{\"lang\": \"2\", \"crop\": \""); // 1:Chinese 2:English
payload += crop;
payload += String("\", \"location\": \"");
payload += location;
payload += String("\", \"time_range\": \""); // 1:30 days, 2:180 days, 3:360 days
payload += timerange;
payload += String("\", \"measurements\": [{\"dev_eui\": \"");
payload += deviceEUI;
payload += String("\", \"channel_measurement\": [{\"channel_index\": \"1\", \"measurement_ids\": [\"");
payload += dataNum_1;
payload += String("\", \"");
payload += dataNum_2;
payload += String("\"]}]}");
//If you need values for other sensors
// payload += String(", {\"dev_eui\": \"");
// payload += deviceEUI_2;
// payload += String("\", \"channel_measurement\": [{\"channel_index\": \"1\", \"measurement_ids\": [\"");
// payload += dataNum_3;
// payload += String("\"]}]}");
if(mode == 1){
payload += String("]}");
}
else if(mode == 2){
// If a query code has been obtained. mode = 2
payload += String("], \"resource_id\": \"");
payload += resource_id;
payload += String("\"}");
}
Serial.println(payload);
return payload;
}
void loop() {
// put your main code here, to run repeatedly:
HTTPClient https;
if (https.begin(sensecapAIServer)) { // HTTPS
https.addHeader("Content-Type", "application/json");
String base64Credentials = base64::encode("YOUR-API-ID:YOUR-ACCESS-API-KEY");
https.addHeader("Authorization", "Basic " + base64Credentials);
String payload = splicePayload(1);
int httpCode = https.POST(payload); // start connection and send HTTP header
if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
String response = https.getString();
#ifdef DEBUG
Serial.println(response);
#endif
// get resource_id
DynamicJsonDocument doc(1024);
deserializeJson(doc, response);
String resource_id = doc["data"]["resource_id"].as<String>();
Serial.println("resource_id: " + resource_id);
String payload = splicePayload(2, resource_id);
do{
delay(2000);
https.addHeader("Content-Type", "application/json");
String base64Credentials = base64::encode("YOUR-API-ID:YOUR-ACCESS-API-KEY");
https.addHeader("Authorization", "Basic " + base64Credentials);
int httpCode = https.POST(payload); // start connection and send HTTP header
if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
String response = https.getString();
#ifdef DEBUG
Serial.println(response);
#endif
// Parsing JSON Responses
DynamicJsonDocument doc(1024);
deserializeJson(doc, response);
String code = doc["code"].as<String>();
Serial.println("status: " + code);
if(code == "0"){
DynamicJsonDocument doc(1024);
deserializeJson(doc, response);
String suggest = doc["data"].as<String>();
Serial.println("SenseCraft AI gives the following planting advice: ");
Serial.println(suggest);
break;
}
else if(code == "11396"){
Serial.println("Timeout. Please wait five minutes.");
break;
}
else Serial.println("Waiting for a reply...");
}
}while(1);
}
else{
Serial.print("[HTTP] ERROR: ");
Serial.println(httpCode);
}
}
else{
Serial.println("[HTTPS] Unable to connect");
delay(1000);
}
Serial.println("The next query will be in five minutes, so please do not query too often to avoid having your account restricted from use!");
delay(300000);
}
ここで、注意すべきいくつかのパラメータがあります。コードの冒頭で、マクロ定義 DEBUG
がコメントアウトされています。この行のコメントを外すと、プログラムを実行してSenseCraftが毎回返すメッセージを印刷することができます。
DEBUG
の下には、あなたのアカウントとデバイスに応じて変更する必要がある情報があります。例えば、リンゴを栽培しておらず、場所が深圳でない場合は、あなたの状況に合わせて変更する必要があります。
// Replace with your devive content
const char* ssid = "YOUR-WIFI-NAME";
const char* password = "YOUR-WIFI-PASSWORD";
const char* deviceEUI = "YOUR-DEVICE-EUI";
const char* crop = "apple";
const char* location = "Shenzhen";
const char* timerange = "1";
const char* dataNum_1 = "4097"; //Air temperature
const char* dataNum_2 = "4098"; //Air humidity
これに加えて、Access APIを解析するコードが2行あります。
String base64Credentials = base64::encode("YOUR-API-ID:YOUR-ACCESS-API-KEY");
例えば、ステップ6で取得したAPI IDとAPI KeyがそれぞれN0AV094KBPH1J9PX
と5DFA8167D23C499C86F61BDEFB901D4995B896A267054D7DAD590BF67FB9A219
である場合、このコード行を次のように変更する必要があります:
String base64Credentials = base64::encode("N0AV094KBPH1J9PX:5DFA8167D23C499C86F61BDEFB901D4995B896A267054D7DAD590BF67FB9A219");
このプログラムをアップロードすると、アップロードメッセージが表示され、AIから返される回答の結果を結果が返されるまでループし続けます。

この時点で、おめでとうございます!XIAOをSenseCraftに接続するすべての知識と内容をマスターしました。私たちのXIAOとSenseCraftを使用して、より多くの創造性を発揮していただくことを心から歓迎いたします!
トラブルシューティング
Q1: AI回答を取得した後、なぜnullの結果が返されるのですか?
これはインターフェースのタイムアウトが原因である可能性があります。次のクエリが送信されるまで待ってから結果を確認してください。この結果は一度だけ取得でき、その後結果は即座に消去され、再度クエリすることはできませんのでご注意ください。
技術サポート & 製品ディスカッション
私たちの製品をお選びいただき、ありがとうございます!私たちの製品での体験が可能な限りスムーズになるよう、さまざまなサポートを提供しています。異なる好みやニーズに対応するため、複数のコミュニケーションチャンネルを提供しています。