Steps to Prototype a Product

This guide outlines the steps to create an Alexa Connect Kit (ACK) product prototype. First, you create a virtual product in the ACK console to define the Alexa capabilities that your product will support. Then you provision an ACK module as your virtual product and run a sample application on your hardware and control it with the Alexa app. Finally, you learn how to edit your virtual product and application in order to customize your prototype.

Prerequisites

Step 1: Create a virtual product

Create a virtual product in your Amazon developer account. For step-by-step instructions, see Create a Virtual Product. Specify the Display Category as "LIGHT".

Step 2: Provision your ACK Module as a virtual product

Use the Module Utility command line interface (CLI) to provision your ACK module as your virtual product. See Steps to Provision a Module – ACK managed services.

For general information about provisioning, see Module Life Cycle Overview.

At this point, your USI development board and your Arduino Zero may still be physically connected. If they are, before provisioning, you need to physically disconnect the two boards. Once they are disconnected, plug the Micro-USB cable that came with the kit into the USI development kit debug port, and connect the other end to your computer. See USI MT7697H development board components to help you find the debug port.

Step 3: Generate a barcode for product registration

Prerequisites:

  • An ACK module that is product provisioned. This prerequisite should be fulfilled if you've completed steps 1 and 2 in this guide.

ACK supports Amazon's Wifi Simple Setup to make it easy for your users to register their devices with Amazon and Alexa services. In this step you’ll generate a barcode for your ACK module that enables registration through Wifi Simple Setup.

  1. Run the Module Utility CLI barcode command: barcode -p <port> --upc 12345678

  2. You'll use file DVC_XXXXXXXXXXXXXXXX.png when you register the module in step 5.

Step 4: Upload Device SDK sample application to your host microcontroller

The next step is to upload the ACK Device SDK AlexaConnectKit_HelloWorld sample application to your host microcontroller. This step explains the process using the Development Kit for ACK, but you can complete it with your own host microcontroller. For reference, see Step 4: Upload Code to the Arduino Zero, except upload AlexaConnectKit_HelloWorld not AlexaConnectKit_SmartLight.

Step 5: Register the ACK module with Alexa and ACK services

To register your ACK module with Alexa, you scan the barcode you generated in step 3. This registers the ACK module with ACK managed services, and allows the module to connect to Alexa.

Prerequisites:

  • You have completed the previous steps in this guide.
  • Your ACK module is not already registered to a user. If the module needs to be deregistered, see factory reset the module for instructions.
  • Your Alexa app has minimum version 2.2.314100.0 (Android) or 2.2.315327.0 (iOS).

Step 5.1. Restart the ACK development board

When the ACK module on the development board first receives power, it starts a beaconing process to make the device discoverable for barcode registration. After a full 5 minutes the module returns to an idle state, the beaconing process ceases, and the module is no longer discoverable until it returns again to an active beaconing state.

To restart your development board

  • If your development board is powered on for more than 5 minutes, manually disconnect the USB cable from the Arduino Programming Port, and then plug it back in. This restarts the beaconing process.

Step 5.2. Register your device

To register the development device with Alexa, use the Alexa app to scan the barcode you generated in step 3 in order to register the development device with Alexa.

For Alexa app installation instructions, see Download the Amazon Alexa App.

To register your device

  1. On your mobile device, open the Alexa app.

  2. Select the Devices, and then select the plus sign (+).

  3. Select Add Device.

  4. From the list, select Development Device.

    Don't have a barcode
  5. Under "What brand is your development device?" select ACK Module, and then click next.

  6. If prompted, enable access to your mobile devices' Bluetooth, camera, and location services on your mobile device and then select next.

  7. To register the development device with Alexa, use the Alexa app to scan the barcode you generated in step 3 (the DVC_XXXXXXXXXXXXXXXX.png file) in order to register the development device with Alexa. The default ACK test device is called Development Device. If you don't have a barcode, or aren't able to successfully register your device using the barcode, refer to user guided setup to complete device registration.

  8. Select the Wi-Fi network to connect to, and if necessary enter the Wi-Fi password.

  9. After the ACK setup utility connects your module, you should see a notification that tells you that development device is set up and ready to use.

    If you are unable to register your device using barcode registration, defer to user guided setup to complete device registration.

  10. You should see the status LED on your development board change from white to green. Congratulations, this means that your device is now connected to the Alexa service!

    If you run into issues, see the troubleshoot the development kit guide.

  11. Finally, verify that your test product is listed on the ACK Console > Modules page.

Step 6: Add functionality to your product

So far, the user can turn on or off the LED provided with your product. To demonstrate the process of adding functionality, the following examples show changes to make so that the user can brighten or dim the LED.

To get started:

  • Identify the functionality you want to offer. With the following example, the user can speak to Alexa or use the Alexa app to change the brightness of the LED.
  • Identify the Alexa interfaces that define the functionality. To change the brightness of an LED, the Alexa.BrightnessController Interface is appropriate because it supports utterances such as “Alexa, set the bedroom light to fifty percent” and provides a graphical interface in the Alexa app for adjusting the brightness. For a list of Alexa interfaces, see List of Capability Interfaces and Supported Locales.
  • Identify what needs to happen in the device hardware to support the functionality. For example, when the user gives a command to change the brightness level, the voltage level of a pin on the Arduino board needs to change.

Add support for relevant Alexa interfaces to your virtual product

  1. Add support for Alexa.BrightnessController to your virtual product by following the procedures at Customize a Virtual Product.

  2. Verify that the updated JSON looks similar to the following:

    [
      {
        "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
        }
      }
    ]
    

Set up your source code editor

Prepare for editing your source code by opening your preferred source code editor, for example Visual Studio, CLion, or Sublime Text.

To specify in the Arduino IDE that you are using an external editor

  1. Open the Arduino IDE.
  2. On the File menu, click Preferences.
  3. On the Settings tab, select the Use external editor check box.
  4. Click OK.

Locate the ACK Device SDK and the HelloWorld example application

  1. Identify the location where you unzipped the ACK Device SDK. For information about the steps that you followed when you ran the setup script, see Set up your Environment Step 3.6 Run the setup script

  2. Change directory to the location where the ACK Device SDK files were unzipped, for example /Users/<username>/<Downloads>/<ack-device-sdk>/.

  3. Locate the HelloWorld example application, which is at ./applications/HelloWorld.

Orient yourself to the next steps for adding new functionality

During the steps that follow, you'll first add support to your product for receiving voice commands and for manipulating the brightness-related controls in the Alexa app. Then, you'll add support in the device hardware so that your product handles commands and responds by changing the level of brightness in the LED. Finally, you'll consider extending the functionality that you've added.

The following steps reference the HelloWorld example. In the example, you'll be adding support for Alexa.BrightnessController to the embedded code of the host microcontroller for your device. In the example, the host microcontroller is the Arduino board included with your development kit.

While the following steps are specific to the brightness controller and specific to Arduino, consider applying the following steps generally for any functionality that you might want to add to your product.

Add support for the new functionality while not yet implementing handling in the device hardware

  1. To support the new functionality, in the ack_user_config.h file, on line 22, increase the memory allocation by changing ACK memory pool size to 1024:
    #define ACK_MEMORY_POOL_SIZE 1024
    
  2. Do the following to declare support for Alexa.BrightnessController.

    In ack_user_config.h, near line 30, insert the following:

    #define ACK_BRIGHTNESS_CONTROLLER
    

    In HelloWorld_Alexa.c, near line 18, insert the following:

    #include "ack_brightness_controller.h"
    

    For more information, in the ACK Device SDK, see section 2.1.4.

  3. Do the following to add handler code for the brightness controller properties.

    In HelloWorld_Alexa.c, after static bool AddPowerStateProperty(uint32_t propertyOrdinal, unsigned propertyFlags);, insert the following:

    static bool AddBrightnessProperty(uint32_t propertyOrdinal, unsigned propertyFlags);
    

    In HelloWorld_Alexa.c, after #define POWER_STATE_PROPERTY 1, insert the following:

    #define BRIGHTNESS_PROPERTY 2
    

    In HelloWorld_Alexa.c, after { POWER_STATE_PROPERTY, AddPowerStateProperty },, insert the following:

    { BRIGHTNESS_PROPERTY, AddBrightnessProperty },
    
  1. In HelloWorld_Alexa.c, create a function AddBrightnessProperty. To do so, copy and paste the function AddPowerStateProperty and rename it AddBrightnessProperty.
  2. Make the following changes to the AddBrightnessProperty function:

    In ACK_DEBUG_PRINT_E("Error %u adding power state property.", error);, replace power state with brightness.

    Replace the call to ACK_AddPowerControllerProperty with a call to ACK_AddBrightnessControllerProperty.

    In the call to ACK_AddBrightnessControllerProperty, replace Hardware_IsPowerOn() with 42. This temporary change allows for handling Alexa commands without needing to make any device hardware changes. The Alexa app responds to every change that it receives by setting the brightness to 42.

    The following shows an example implementation of the ACK_AddBrightnessControllerProperty function:

    static bool AddBrightnessProperty(uint32_t propertyOrdinal, unsigned propertyFlags)
    {
        ACKStateCommon_t propertyState = { 0, 0, propertyFlags };
        ACKError_t error;
    
        error = ACK_AddBrightnessControllerProperty(&propertyState, 42);
    
        if (ACK_NO_ERROR != error)
        {
            ACK_DEBUG_PRINT_E("Error %u adding brightness state property.", error);
            return false;
        }
    
        return true;
    }
    
  3. In HelloWorld_Alexa.c, create a function ACKUser_OnBrightnessControllerDirective to handle the brightness controller directives. To verify the handler signature, see the relevant file in the include directory, for example include/ack_brightness_controller.h. For more information, in the ACK Device SDK, see section 2.1.4, lines 192-194.

    The following shows an example implementation of the ACKUser_OnBrightnessControllerDirective function.

        void ACKUser_OnBrightnessControllerDirective(int32_t correlationId, bool isDelta, int32_t value)
        {
    
            ACK_DEBUG_PRINT_I("Received brightness controller directive; value %d.", value);
    
            ACK_CompleteDirectiveWithSuccess(
                    correlationId,
                    ACK_PROPERTY_BIT(BRIGHTNESS_PROPERTY),
                    0);
        }
    

Upload your code and test the new functionality

  1. Use the setup.py script provided in the ACK Device SDK to install your new application code in a way that Arduino can compile and upload. For information about using the script, see Set up your Environment Step 3.6 Run the setup script.

    As part of your development workflow, make sure to use the --force option so that the setup.py script overwrites the code you previously installed.

    python3 ./setup.py --force
    
  2. Compile and upload your code using the Arduino IDE. For more information, see Step 4: Upload Code to the Arduino Zero.
  3. Use the Arduino IDE to review logs generated by your host microcontroller application, for example methods such as ACK_DEBUG_PRINT_I(). In the Arduino IDE, on the Tools menu, click Serial Monitor. Set the baud rate to 115200.
  4. Experiment with your device by using the Alexa app. Use the slider control to alter the brightness. The brightness should reset to 42. Keep in mind that the behavior of the device LED is unchanged because you haven't made any changes yet to the device hardware.

Implement hardware-oriented logic to store the brightness level on your device, and set the LED brightness

The following steps show how to implement a function to set the brightness in hardware and a function to get the current brightness from hardware.

  1. In the header file HelloWorld_Hardware.h, declare the function signatures.

    In HelloWorld_Hardware.h, review lines 29-32 to see the corresponding function signatures for handling the state related to PowerController, which controls whether the LED is on or off.

    The example assumes the following function signatures:

    • void Hardware_SetBrightnessState(int32_t value);, which accepts the brightness value and sets it in hardware.
    • int32_t Hardware_GetBrightnessState(void);, which gets the brightness value from hardware.
  2. In HelloWord_Hardware.c, implement the following functions:

    Simplify the implementation by not reading the brightness value from hardware. Instead, create a global variable g_brightness and call the value as if reading from hardware. In HelloWorld_Hardware.c, below the #include lines, add int32_t g_brightness;.

    Implement the simplified Hardware_GetBrightnessState as follows:

        int32_t Hardware_GetBrightnessState(void)
        {
            return g_brightness;
        }
    
  3. In HelloWord_Hardware.c, do the following to implement Hardware_SetBrightnessState, which receives a value for the brightness level to set in hardware.

    Specify g_brightness = value; to set the brightness level in a global variable for later retrieval.

    Specify ACKPlatform_SetDigitalPinPWMLevel(ACK_HW_PIN_SAMPLE_APPLICATIONS_LED, (uint8_t)((255 * value) / 100) );. The ACK Device SDK provides the function ACKPlatform_SetDigitalPinPWMLevel as part of its Arduino support. The file .\user\platform\arduino\ack_arduino_platform.cpp shows all functions provided for Arduino. The example uses ACKPlatform_SetDigitalPinPWMLevel because setting a pin to a brightness value requires pulse width modulation (PWM). Alexa provides values for brightness between 0 and 100, while Arduino accepts PWM brightness levels 0 and 255, so the example multiplies the Alexa value by 2.55.

  4. Do the following to connect the hardware logic to the Alexa logic that handles directives from the user:

    In HelloWorld_Alexa.c, in the AddBrightnessProperty function where you previously set the value to 42, replace 42 with a call to Hardware_GetBrightnessState(), to get the brightness stored in the hardware. The line should look as follows:

    error = ACK_AddBrightnessControllerProperty(&propertyState, Hardware_GetBrightnessState());
    

    In HelloWorld_Alexa.c, to set the value in hardware as each Alexa command arrives. In ACKUser_OnBrightnessControllerDirective, before the call to ACK_CompleteDirectiveWithSuccess, add the line Hardware_SetBrightnessState(value);.

Extend the functionality that you've added

The implementation of brightness controller does not cover all user scenarios. For the brightness controller and also for other functionality that you add, make sure that you extend and improve the functionality by addressing issues similar to the following:

  • The implementation does not handle when power is off and the user, for example, changes the brightness from 0 to 50. The power controller commands stop working because the power controller and brightness controller affect the same pins and have a shared state.
  • The implementation assumes that all incoming brightness controller directives provide the absolute desired value for brightness, for example “Alexa, change brightness to 50”. However, a user can provide a relative instruction, for example “Alexa, increase brightness by 50”. To handle the relative instruction, see the delta value in the function signature for ACKUser_OnBrightnessControllerDirective.
  • Check for situations like a user increasing the brightness by 50 when brightness is already at 90. More generally, recognize all user situations for each controller.
  • Consider supporting a local mechanism such as a button press that turns the power on and off and maintains the state with Alexa. In HelloWorld_Hardware.c, see the stub function Hardware_IsPowerToggleButtonDown. For more information, in the ACK Device SDK, see section 5.3.1.