Alexa Connect Kitを使ってAlexa対応フルカラーLEDを作ってみた

2022.07.07

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは。CX事業本部Delivery部のakkyです。

最近、Alexa Connect Kit Dev board with RP2040という個人製作ハードウェアを発見し、Alexa対応デバイスを簡単に開発することができるAlexa Connect Kitという製品があることを知りました。

今回は、私もESP32-PICO-V3-ZEROとRaspberry Pi Picoを使用してフルカラーLEDを制御するAlexa対応デバイスを製作してみましたので、ご紹介します。 ハードウェアを製作し、ソフトウェアは公式チュートリアルの内容に加えて、サービスの追加まで行ってみました。

Alexa Connect Kitの概要

公式ページ

Alexa Connect Kit(以下ACK)は、Amazonからリリースされている、Alexa対応デバイスを少ない工数で開発することができるフルマネージドのWi-Fiモジュールです。 ACKはAlexa対応のスマートスピーカーを作るものではありません。あくまでAlexaから制御されるデバイスを開発するための製品です。

ACKのファームウェアはAmazonが管理しており、開発者が変更することはできません。開発者は、外部に接続したマイコン(以下HMCU)からUART経由でACKを制御します。つまり、必ずWi-Fiモジュールと制御用マイコンを組み合わせて使用するものになります。HMCUで使用するC言語用SDKもAmazonから提供されています。

デバイスの登録管理を行うためのサーバもAmazonから提供されるため、開発者が用意するものはACKのみで済みます。

ACKはEspressif ESP32-PICO-V3-ZERO版とUSI MT7697H版がありますが、MT7697Hは入手が困難なので(US Amazonにも在庫なし)、ESP32-PICO-V3-ZEROを使用します。1万円程度でArduinoシールドがありますが、今回は秋月電子で販売されている単体モジュールを使用しました。こちらはわずか430円です!

HMCUに使用するマイコンとして、公式チュートリアルにはArduino Zeroが紹介されていますが、国内では入手困難です。しかし、1組のUARTと2本のGPIOがあり、ROMが128KB、RAMが32KB程度あればおおよそどんなマイコンでも使用することができます。SDKにはESP32とArduinoのサンプルコードが付属しています。Arduino対応マイコンであれば、サンプルコードをそのまま(またはピン番号の変更程度で)動かすことができます。

今回は、Alexa Connect Kit Dev board with RP2040を参考にさせていただき、Raspberry Pi Picoを使用しました。

ハードウェアの製作

メインパーツはESP32-PICO-V3-ZEROとRaspberry Pi Picoです。そのほかに、FT232などのUSB-UARTコンバータ(ACKのセットアップに必要です)とLED、コンデンサなどを用意しました。

ESP32-PICO-V3-ZEROはすべての端子が底面パッドに出ているので、あきらかにPCBを製作したほうが良いのですが、今回は直接ブレッドボード用ワイヤをはんだ付けしました。ひとまずこれで動作していますが、このままではすごく取れやすいので、ユニバーサル基板に接着剤で取り付けるなどするのがおすすめです。

デバッグポートが取れてしまいました?

Raspberry Pi PicoおよびUSB-UARTとは、以下のように接続しました。また、ESP32-PICO-V3-ZEROの電源には100uFの電解コンデンサを接続しました。

その他の注意事項

  • USB-UARTは3.3V品を使ってください。
  • フルカラーLEDはカソードコモン品を使い、電流制限抵抗は適宜調整してください。
  • Arduino対応のその他のマイコンを使う場合は、Serial1をACKのU1RXDとU1TXDへ、D2をINT_Bへ、D3をENへ接続してください。
RPiPico 接続先 USB-UART
1(GP0) ACK U1RXD/IO22
2(GP1) ACK U1TXD/IO19
4(GP2) ACK INT_B/IO27
5(GP3) ACK EN
11(GP8) LED RED
12(GP9) LED GREEN
14(GP10) LED BLUE
36(3V3OUT) VDD33
GND GND GND
ACK DBG_RXD/IO3 TXD
ACK DBG_TXD/IO1 RXD

ソフトウェアの準備

Raspberry Pi Picoの開発にはArduinoを使用しました。Arduino IDEにArduino-Picoをインストールしてください。

ESP32用のファームウェアは事前に書き込まれているので、準備は不要です。アップデートも自動的に行われます。

HMCU用のSDKはAlexa Connect Kit Developer ConsoleのResourcesからダウンロードできます。コンソールへのログインには、Amazon developer accountが必要です。

Show ResourcesからDevelopment Kitを選択し、ACK Module with Espressif Chipsetを選択すると、ACK Device SDKが出てきますのでダウンロードしてください。また、Module Utilityも使用しますので、ダウンロードしてください。 今回は、ACK Device SDK 4.2、Module Utility 5.1.43.0を使用しました。なお、Module Utility CLIの実行にはJava JREが必要です。 スマートフォン用のAlexaアプリも必要です。

プロダクトの作成

Alexa Connect Kit Developer ConsoleのProductsを開き、右上のCreate Productをクリックします。

以下の項目をそれぞれ入力します。今回はSmartLEDという名前にしてみました。

  • Product Name
    • プロダクトの名前
  • Description
    • プロダクトの説明(何か入力しないとエラーになります)
  • Manufacturer Name
    • 製造者名
  • Display Category
    • Alexaアプリで表示されるカテゴリー名。LIGHTを選択しました。
  • Region Support
    • 製品をリリースする地域。Region 3(AU, JP)を選択しました。
  • Do you intend to distribute this product commercially?
    • 商用製品ではないのでNo
  • Is this a children’s product or is it otherwise directed to children younger than 13 years old?
    • 子供向けではないのでNo

Create productをクリックすると、プロファイルの生成が始まります。1時間程度かかりますので、この間にハードウェアの製作をしてもいいかもしれません。

ACKのプロビジョニング

プロファイルの生成が完了したら、Download provisioning fileからプロビジョニングファイルをダウンロードします。gz形式なので、対応するアーカイバで解凍してください。

Module Utility CLIに含まれるackmoduleutility.jarを使用し、ACKに情報をプロビジョニングします。PCにRaspberry Pi PicoとACK、USB-UARTを接続します。この際、ACKを起動させるためにENピンをVCCに接続してください。

コンソールを起動し、以下のコマンドでプロビジョニングします。-pで指定するシリアルポート名とプロビジョニング情報ファイルは正しいものに変更してください。

java -jar ackmoduleutility.jar provision -p <シリアルポート> --provisionconfigfile ProvisioningInfo_xxxxxxxx.conf

実行すると、Webブラウザが開き、認証画面が表示されますので、許可してください。

次に、Alexaアプリへの登録用バーコードを生成します。upcは実験ですのでインストアコードを指定しました。

java -jar ackmoduleutility.jar barcode -p <シリアルポート> --upc 412345678903

実行すると、同じディレクトリにいくつかファイルが生成されますが、使用するのはこのうちDVC_*.pngファイルです。 作業がおわったら、ENピンをACKに戻しておきます。

SDKのインストール

HMCU用のSDKをArduinoにインストールします。ACK_Device_SDK_4.2~のディレクトリにある、user/platform/arduino/setup.pyを実行してください。

python3 setup.py

実行すると、ArduinoのLibraryディレクトリ(Windowsの場合はC:\Users\<ユーザー名>\Documents\Arduino\libraries、Macの場合は/Users/<ユーザー名>/Documents/Arduino/libraries)にライブラリがコピーされます。

動作確認

Arduino IDEを開き、スケッチ例→AlexaConnectKit_SmartLight→SmartLightをRaspberry Pi Picoに書き込んでください。 シリアルコンソールに以下のようなログが表示されれば動作しています。

63607 [INF ACK_GetStatus] Approximate epoch: 60 seconds
3116 [INF ProcessEventIfAvailable] HOSTINT asserted; processing inbound event.
3116 [INF SetSize_] Heaplet high-water consumption: 12 bytes
3156 [WRN ProcessEventState_ReceiveNextEvent_] Event of acp_response type 1 not handled.
3156 [INF ProcessEventIfAvailable] HOSTINT asserted; processing inbound event.
3217 [INF ProcessEventState_ReceiveNextEvent_] Received connectivity module booted event.
3217 [INF LifecycleModuleBooted] Connectivity Module finished booting or rebooting.
3217 [INF ACKUser_OnLifecycleStateChange] ACK lifecycle state: BOOTED
3217 [INF SatisfySendHostConfig] Sending host config to ACK Connectivity Module...
3217 [INF ACKModule_HostConfigWrite] Sending write host config command
3217 [INF SetSize_] Heaplet high-water consumption: 16 bytes
3521 [INF SatisfySendHostConfig] Sent host config to ACK Connectivity Module.
3521 [INF ACKModule_GetDeviceType] Sending get-device-type command.
3556 [INF SetSize_] Heaplet high-water consumption: 32 bytes

次にスマートフォンのAlexaアプリを開き、デバイスタブ右上の⊕をタップし、「デバイスを追加」をタップしてください。

「開発デバイス」をタップします。

「ACK」をタップします。

アプリに必要な許可を与えます。

「バーコードをスキャン」をタップし、カメラで先ほど生成したDVC_*.pngをスキャンします。

Wi-Fiに接続されますので、しばらく待ちます。ここで何もしなくてよいフラストレーションフリーセットアップは素晴らしい!

セットアップが成功すると、ライトの制御ができるようになります!(画面はこのあとのモノなので、少し違います)

カラーLED制御化する

ここまででライトの制御ができるようになったのですが、このままでは赤しか点灯しません。ここからはチュートリアルの内容を超えて、カラーLEDを制御できるようにしましょう。

Alexa Connect Kit Consoleを開き、Products→SmartLEDのAlexa smart home capabilitiesのEditをクリックします。メニューからBrightness Controllerを選択してAddしてください。同様にColor ControllerもAddします。JSONは以下のようになります。

[
  {
    "type": "AlexaInterface",
    "interface": "Alexa.PowerController",
    "version": "3",
    "properties": {
      "proactivelyReported": true,
      "retrievable": true,
      "supported": [
        {
          "name": "powerState"
        }
      ]
    }
  },
  {
    "type": "AlexaInterface",
    "interface": "Alexa.BrightnessController",
    "version": "3",
    "properties": {
      "supported": [
        {
          "name": "brightness"
        }
      ],
      "proactivelyReported": true,
      "retrievable": true
    }
  },
  {
    "type": "AlexaInterface",
    "interface": "Alexa.ColorController",
    "version": "3",
    "properties": {
      "supported": [
        {
          "name": "color"
        }
      ],
      "proactivelyReported": true,
      "retrievable": true
    }
  }
]

この状態でSaveしてください。

次に、HMCUのコードを変更します。Arduinoのサンプルをそのまま別位置に保存して新たなプロジェクトを作りたいのですが、ACKのSDKはライブラリ化がきちんとされておらず、exampleのディレクトリにすべてのコードが突っ込まれる構造になっています。このため、ArduinoのLibraryディレクトリ(Windowsの場合はC:\Users\<ユーザー名>\Documents\Arduino\libraries、Macの場合は/Users/<ユーザー名>/Documents/Arduino/libraries)に存在するAlexaConnectKit_SmartLight/example/SmartLightディレクトリを適当な位置にコピーして、こちらを編集します。

SDKに付属しているack_color_controllerライブラリを追加する作業を行います。

SmartLight.ino

ヘッダに以下のコードを追加します

#include "src/ack_color_controller.h"
#include <ColorConverterLib.h>

各種宣言を追加します。

bool AddLightColorProperty(uint32_t propertyOrdinal, unsigned propertyFlags);
#define PROPERTY_COLOR_MODE 4
double g_hue = 0.0, g_saturation = 1.0;

ACKUser_PropertyTableを編集し、{ 0, NULL }の前に以下のコードを追加します。

 { PROPERTY_COLOR_MODE, AddLightColorProperty },

c_lightPropertiesBitsを編集し、以下のコードを付け加えます。

 | ACK_PROPERTY_BIT(PROPERTY_COLOR_MODE);

Hardware_TurnLightOnおよびHardware_TurnLightOffは以下のコードに置き換えます。

void Hardware_TurnLightOn(void)
{
    uint8_t r,g,b;
    ColorConverter::HsvToRgb(g_hue, g_saturation, (double)g_brightness / MAXIMUM_BRIGHTNESS, r, g, b);
    
    ACKPlatform_SetDigitalPinPWMLevel(ACK_HW_PIN_SAMPLE_APPLICATIONS_LED, r);
    ACKPlatform_SetDigitalPinPWMLevel(ACK_HW_PIN_SAMPLE_APPLICATIONS_GPIO_1, g);
    ACKPlatform_SetDigitalPinPWMLevel(ACK_HW_PIN_SAMPLE_APPLICATIONS_GPIO_2, b);
}

void Hardware_TurnLightOff(void)
{
    ACKPlatform_SetDigitalPinPWMLevel(ACK_HW_PIN_SAMPLE_APPLICATIONS_LED, 0);
    ACKPlatform_SetDigitalPinPWMLevel(ACK_HW_PIN_SAMPLE_APPLICATIONS_GPIO_1, 0);
    ACKPlatform_SetDigitalPinPWMLevel(ACK_HW_PIN_SAMPLE_APPLICATIONS_GPIO_2, 0);
}

コードを追加します。

bool AddLightColorProperty(uint32_t propertyOrdinal, unsigned propertyFlags)
{
    // Populate metadata about the property. 
    // Leave the time-of-sample-field 0 to cause the current time to be sent. 
    // Set the error margin to 10 milliseconds for illustrative purposes.
    ACKStateCommon_t common = { 0, 10, propertyFlags };
    ACKError_t error;

    error = ACK_AddColorControllerProperty(&common, g_hue, g_saturation, (double)g_brightness / MAXIMUM_BRIGHTNESS);

    if (ACK_NO_ERROR != error)
    {
        ACK_DEBUG_PRINT_E("Error %u adding color property to event", error);
        return false;
    }

    return true;
}

void Hardware_ChangeColor(void)
{
  if(g_power)
  {
    Hardware_TurnLightOn();
  }
}

void ACKUser_OnColorControllerDirective(int32_t correlationId, double hue, double saturation, double brightness) 
{  
    ACKPropertiesBits_t changedPropertiesBits = 0;

#ifdef ACK_LOGGING
    ACK_WriteLogFormatted(
        acp_log_level_info,
        LOG_COMPONENT_NAME,
        "Handling Set Color directive hue: %lf saturation: %lf brightness: %lf",
        hue,
        saturation,
        brightness);
#endif
    changedPropertiesBits |= ACK_PROPERTY_BIT(PROPERTY_COLOR_MODE);

    g_hue = hue / 360.0;
    g_saturation = saturation;

    Hardware_ChangeColor();
    
    ACK_CompleteDirectiveWithSuccess(
        correlationId,
        c_lightPropertiesBits,
        changedPropertiesBits);
}

ack_user_config.h

以下のコードを追加します。

#define ACK_COLOR_CONTROLLER
#define ACK_SAMPLE_APPLICATIONS_GPIO_PIN_1
#define ACK_SAMPLE_APPLICATIONS_GPIO_PIN_2

HSV変換ライブラリにArduino-ColorConverterを使用しますので、Code→Download ZIPからダウンロードし、Arduino IDEにインストールしてください(パッケージマネージャからではうまく動きませんでした)

編集が完了したら、Raspberry Pi Picoにアップロードしてください。 次に、Alexaアプリから先ほど追加したライトを削除し、もう一度同じ手順で追加してください。正しく動作すると、ライトの明るさ変更と色変更ができるようになっていると思います。お疲れ様でした!

おわりに

ACKを使用すると、非常に簡単にAlexa対応ハードウェアが開発できることがわかりました。対応しているサービスが限られているなどの制限はあるものの、基本的なサービスは実装できるようです。

フルマネージドサービスなので、ACK自体の管理がいらないのは製品化する際にとても良さそうです。また、詳細は未確認ですが、STM32のサンプルを見ると、HMCU自体のOTAもできてしまうようです。至れり尽くせり。

開発はとても簡単なので、自分で電子工作するハードウェアのAlexa対応はすぐできると思います。ぜひお試しください!