Demo project for alink SDS
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
docs/readme_image
driver
esp8266-rtos-sdk-alink
include
platforms
user
Makefile
README.md
gen_misc.sh

README.md

本工程为阿里云 ESP8266 ALINK SDS 接口使用示例,你可以通过本示例了解 ALINK 配网、升级及数据传输等

1 ALINK 概述

1.1 是什么 ALINK

智能硬件模组、阿里智能云、阿里智能 APP,阿里智能生活事业部为厂商提供一站式设备智能化解决方案。alink 到目前已经过了多次的版本迭代,各版本的区别如下:

  1. alink v1.0:为阿里提供最基础的版本,支持一键配网,设备热点配网技术,ota 升级等功能
  2. alink v1.1:增强设备身份安全
  3. alink embed:增加支持零配发现模式,默认配网激活模式,手机热点配网模式,但需要占更多的内存空间
  4. alink sds:APP和服务端允许客户定制化,但是需要收取服务收费

1.2 为什么要使用 ALINK

阿里智能开发平台的提供强大的智能平台,极大的简化的智能家居开发的高难度和复杂性,主要有以下六个特点:低成本、短时间、大安全、大数据、标准化和定制化等。

1.3 怎么使用 ALINK

我们已经完成 ALINK EMBED SDK 在模组上的适配工作,您在 产品开发时,只需基于模组基础上进行二次开发。

2 前置条件

2.1 知识储备

2.2 硬件准备

  • 开发板:一块以上 ESP_WROOM_02 开发板
  • 路由器:关闭 5G 网络,且可以连接外网(所有的数据交互必需通过阿里云服务器)
  • 手机:内置有 SIM 卡,可连接 4G 移动网络(测试热点配网功能时,设备需要通过手机热点连接阿里云服务器完成的注册、绑定等过程)

3 开发板介绍

标号 1 开关拨下(拨下为断电状态,拨上为上电状态);
标号 2 开关拨下(拨下为下载模式,拨上为运行模式);
标号 3 开关拨上(CHIP_EN PIN,默认拨上即可);
标号 4 跳线帽插入上方的两个针脚;
标号 5 插入跳线帽;
标号 6 配网开关,短按(<3s)激活设备,长按(>=3s)设备进入配网模式;
标号 9 设置开关,短按(<3s)高频压测模式,长按(>=3s)设备端会解绑并恢复出厂设置;
标号 10 焊接 GPIO4 与 SW2 旁边的小圆孔,使能 SW2 按键,即出厂设置开关。

4 文件结构

esp8266-alink-embed
├── bin                                     // 存放生成的 bin 文件
├── docs
├── driver
├── esp8266-rtos-sdk-alink                  // ESP8266 SDK
├── gen_misc.sh                             // 编译脚本
├── include
├── Makefile                                // 通过 Makefile 来配置 alink 选项
├── platforms
│   ├── alink-embed
│   │   ├── adaptation                      // ALINK 的底层适配
│   │   ├── application                     // ALINK 应用层API的封装
│   │   │   ├── esp_alink_data_transport.c  // ALINK 数据传传输
│   │   │   ├── esp_alink_main.c            // 连接ap、恢复出厂设置、事件回调函数
│   │   │   ├── esp_info_store.c            // FLASH 的读写操作
│   │   │   ├── esp_json_parser.c           // JSON 字符串的生成与解析
│   │   │   └── Makefile
│   │   ├── include
│   │   │   ├── alink_export.h              // ALINK 官方提供的原生应用层 API
│   │   │   ├── alink_json_parser.h         // ALINK 官方提供的原生JSON API
│   │   │   ├── esp_alink.h                 // 封装的应用层API使用说明及配置
│   │   │   ├── esp_alink_log.h             // 定义了打印等级
│   │   │   ├── esp_info_store.h            // 信息存储API详解及EXAMPLE
│   │   │   └── esp_json_parser.h           // JSON API详解及EXAMPLE
│   │   ├── lib                             // 库文件
│   │   ├── Makefile
│   │   └── README.md
│   └── Makefile
├── README.md
└── user
    ├── alink_key_trigger.c                 // 按键触发函数
    ├── Makefile
    └── sample_json.c                       // ALINK 非透传示例

5 编译环境的搭建

您可以使用 xcc 和 gcc 来编译项目,建议使用 gcc。对于 gcc,请参考esp-open-sdk

6 配置

您可以通过修改本工程下的 Makefile 来配置。

/*!< 打开 json 调试,您可以查看任务的栈空间使用情况判断是事出现栈溢出 */
CCFLAGS += -D SAMPLE_JSON_DEBUG

/*!< 修改模组名称,在修改模组名称前,请确认设备已经解绑 */
CCFLAGS += -D CONFIG_ALINK_MODULE_NAME=\"ESP-WROOM-02\"

/*!< 如果开发时内存空间不足可以参考如下配置,内存将增大4k左右,但此配置不支持超长数据包测试 */
CCFLAGS += -D ALINK_WRITE_NOT_BUFFER
CCFLAGS += -D CONFIG_DOWN_CMD_QUEUE_NUM=1
CCFLAGS += -D CONFIG_EVENT_HANDLER_CB_STACK=384
CCFLAGS += -D CONFIG_READ_TASK_STACK=768
CCFLAGS += -D CONFIG_ALINK_DATA_LEN=512
CCFLAGS += -D CONFIG_SSL_READ_BUFFER_LEN=2048

7 编译

如果您是在 ubuntu 的平台下开发只需运行脚本 gen_misc.sh,其他平台的参见:https://github.com/pfalcon/esp-open-sdk

8 固件烧录(windows)

  1. 安装串口驱动

  2. 安装烧写工具

  3. 烧录相关 bin 文件 将 GPIO0 开关(GPIO0 Control)拨到内侧开发板置为下载模式,按照如下所示,配置串口号、串口波特率等,按 START 即可开始下载程序

     boot.bin------------------->0x000000    // 启动程序
     user1.2048.new.5.bin------->0x01000     // 主程序
     device_id.bin-------------->0x1F7000    // 设备ID
     blank_12k.bin-------------->0x1F8000    // 初始化用户参数区
     blank.bin------------------>0x1FB000    // 初始化 RF_CAL 参数区。
     esp_init_data_default.bin-->0x1FC000    // 初始化其他射频参数区
     blank.bin------------------>0x1FE000    // 初始化系统参数区
    

    注:ESP-LAUNCHER 上的 J82 跳针需要用跳线帽短接,否则无法下载

  4. 启动设备 下载完毕后将 GPIO0 开关 (GPIO0 Control) 拨到外侧将 ESP-LAUNCHER 开发板置为工作模式,出现“ENTER SAMARTCONFIG MODE”信息,即表示 ALINK 程序正常运行,进入配网模式

9 运行与调试

  1. 下载阿里独立开发者-DemoApp
  2. 登陆淘宝账号
  3. 设备配网
  4. 按键说明:
    • 激活设备:短按(<3s)配网开关
    • 重新配网:长按(>=3s)配网开关
    • 高频压测:短按(<3s)设置开关
    • 出厂设置:长按(>=3s)设置开关

10 开发流程

10.1 签约入驻

使用淘宝账号签约入驻阿里平台,并完成账号授权

10.2 产品注册

产品注册是设备上云的必要过程,任何一款产品在上云之前必须完成在平台的注册

10.3 申请设备ID

  1. 购买设备ID:使用 ALINK SDS 的每一个设备都需要一个唯一的设备ID,设备ID需要向阿里官方购买。
  2. 烧录设备ID:设备ID需要在产品生产时烧录到设备的eFuse中,为方便您的修改,在产品开发时,您可以先设备的ID直接烧录 FLASH 中,我们为您提供了生成设备ID固件脚本,请按照如下说明操作:
    • 填写设备ID列表:打开device_id_secret.txt,填入设备的ID
    num       device_id                   device_secret
    0    3XezoNYjjnkJyslLEEGm    kfU2rROY5s8ffg0kNVotykZNdfn7ZD5X
    
    • 烧录设备ID固件:运行gen_misc.sh脚本,将会在device_id文件夹下生成设备ID的固件,您可以选烧录工具上的'DeviceMasterKey Folder Path',进行批量设备的烧录,烧录后的固件将自动从文件夹中移到"device_id/used"。

10.4 产品开发

注:1. 除非您有特殊需求,否则您在开发时只需修改 user 下的代码,无需关心其内部实现细节   2. 您需要先开发手机APP,alink embed 版本需要单独的开发的APP,除demo外使用阿里小智将无法进行设备的配网,控制等操作

  1. 初始化

    阿里服务器后台导出设备 TRD 表格,调用alink_init()传入产品注册的信息,注册事件回调函数

    const alink_product_t product_info = {
    const alink_product_t product_info = {
        .name           = "alink_product",
        /*!< Product version number, ota upgrade need to be modified */
        .version        = "1.0.0",
        .model          = "OPENALINK_LIVING_LIGHT_SDS_TEST",
        .key            = "1L6ueddLqnRORAQ2sGOL",
        .secret         = "qfxCLoc1yXEk9aLdx5F74tl1pdxl0W0q7eYOvvuo",
        .key_sandbox    = "",
        .secret_sandbox = "",
    };
    ESP_ERROR_CHECK( alink_init(&product_info, alink_event_handler) );
  2. 配网

    • 事件回调函数:
      • 设备配网过程中的所有动作,都会传入事件回调函数中,您可以根据实际需求事件回调函数相应的做相应处理,如在当设备进入配置配网模式灯慢闪,等待激活时灯快闪等
      typedef enum {
          ALINK_EVENT_CLOUD_CONNECTED = 0,/*!< ESP8266 connected from alink cloude */
          ALINK_EVENT_CLOUD_DISCONNECTED, /*!< ESP8266 disconnected from alink cloude */
          ALINK_EVENT_GET_DEVICE_DATA,    /*!< Alink cloud requests data from the device */
          ALINK_EVENT_SET_DEVICE_DATA,    /*!< Alink cloud to send data to the device */
          ALINK_EVENT_POST_CLOUD_DATA,    /*!< The device sends data to alink cloud  */
          ALINK_EVENT_WIFI_CONNECTED,     /*!< ESP8266 station got IP from connected AP */
          ALINK_EVENT_WIFI_DISCONNECTED,  /*!< ESP8266 station disconnected from AP */
          ALINK_EVENT_CONFIG_NETWORK,     /*!< The equipment enters the distribution mode */
          ALINK_EVENT_UPDATE_ROUTER,      /*!< Request to configure the router */
          ALINK_EVENT_FACTORY_RESET,      /*!< Request to restore factory settings */
          ALINK_EVENT_ACTIVATE_DEVICE,    /*!< Request activation device */
          ALINK_EVENT_HIGH_FREQUENCY_TEST,/*!< Enter the high frequency data transceiver test */
      } alink_event_t;
      • 如果您需要传入自己定义的事件,可以通过调用 alink_event_send() 发送自定义事件
      • 事件回调函数的栈默认大小为 1KB, 请避免在事件回调函数使用较大的栈空间,如需修改请使用 Makefile
    • 激活设备:在配网过程中设备需求很服务发送激活指令(具体指令内容由实际产品决定)
    • 主动上报:当设备成功连接到阿里云服务器时需要主动上报设备的状态,以保证云端数据与设备端同步,否则将无法配网成功
  3. 修改触发方式

    您需要根据实际产品,确定以何种方式触发出厂设置、重新配网、激活等操作,本示例使用的是按键触发方式,如果设备没有按键,您可以通过反复开关电源、通过蓝牙等方式触发,具体修改参见 alink_key_trigger.c

    static void key_13_short_press(void)
    {
        ALINK_LOGD("short press..");
        alink_event_send(ALINK_EVENT_ACTIVATE_DEVICE);
    }
    
    static void key_13_long_press(void)
    {
        ALINK_LOGD("long press..");
        alink_event_send(ALINK_EVENT_UPDATE_ROUTER);
    }
    
    static void key_sw2_short_press(void)
    {
        ALINK_LOGD("short press..");
        alink_event_send(ALINK_EVENT_HIGH_FREQUENCY_TEST);
    }
    
    static void key_sw2_long_press(void)
    {
        ALINK_LOGD("long press..");
        alink_event_send(ALINK_EVENT_FACTORY_RESET);
    }
  4. 数据通信

    • 数据格式:确认设备通信时的数据格式(透传/非透传),目前 ALINK EMBED 只支持非透传
      • 透传:设备端收到的二进制格式的数据。由阿里云端服务器的 lua 脚本完成 json 格式与二进制数据的转换
      • 非透传:设备端收到的 JSON 格式的数据,JSON 格式的转换由设备端完成,阿里云端服务器的 lua 脚本是空实现
    • 数据长度:由于esp8266内存有限,因此数据长度调整为上报1KB,下发2KB
    • 数据上报:主动上报是由设备端主动发起
    • 数据下发:设备端收的到的数据有设置设备状态和获取设备状态组成
  5. 日志等级

    本工程的日志分为:alink 官方日志和 esp8266 适配层日志。日志共分为了七个级别,每一级别的日志在输出时均有颜色和相应的标识以区分,日志前带有"<>"的为alink 官方日志,设置日志后比当前级别低的日志均输出。

    • 配置

      # 日志等级列表
      # default 0 if LOG_ALINK_LEVEL_NONE
      # default 1 if LOG_ALINK_LEVEL_FATAL
      # default 2 if LOG_ALINK_LEVEL_ERROR
      # default 3 if LOG_ALINK_LEVEL_WARN
      # default 4 if LOG_ALINK_LEVEL_INFO
      # default 5 if LOG_ALINK_LEVEL_DEBUG
      # default 6 if LOG_ALINK_LEVEL_VERBOSE
      # esp8266 适配层日志等级配置
      CCFLAGS += -D CONFIG_LOG_ALINK_LEVEL=4
      # alink 官方日志等级配置
      CCFLAGS += -D CONFIG_ALINK_SDK_LOG_LEVEL=5
    • 示例 alink 日志的使用方法与printf一致

      /* 定义日志文件标识 */
      static const char *TAG = "sample_json";
      
      ALINK_LOGI("compile time : %s %s", __DATE__, __TIME__);

注:1. 模组认证时,需将 alink 官方日志等级设置为 bebug 模式;   2. 在进行高频测试时,需将日志等级都设置成 info 模式,以免过多的日志信息高频测试。

  1. 信息存储

    为了方便您的使用,我们将flash的读写操作进行了封装,您可以通过 key_value 的方式进行数据存储,无需关心 flash 的擦写,4字节对齐等问题。

    • 配置

      # 存储flash的位置
      CCFLAGS += -D CONFIG_INFO_STORE_MANAGER_ADDR=0x1f8000
      # 标识信息字符串 key 的最大长度
      CCFLAGS += -D CONFIG_INFO_STORE_KEY_LEN=16
      # 存储信息的个数,每多一条信息记录需要多占用 60B
      CCFLAGS += -D CONFIG_INFO_STORE_KEY_NUM=5
    • 示例

      /*!< 初始化存储信息管理列表 */
      char buf[16] = "12345678910";
      esp_info_init();
      
      /*!< 数据保存 */
      esp_info_save("test_buf", buf, sizeof(buf));
      
      /*!< 数据加载 */
      memset(buf, 0, sizeof(buf));
      esp_info_load("test_buf", buf, sizeof(buf));
      printf("buf: %s\n", buf);
      
      /*!< 数据擦除 */
      esp_info_erase("test_buf");

    注:总存储信息量不能超过4KB。为了保证在写 flash 时出现突然断电,对数据的破坏,我们采用了12k的空间来存储4KB的数据, 第一个4KB来记录存储的位置,另两个4KB的空间用于对数据进行存储备份。

  2. json 解析

    为了方便您快速使用 json 格式数据的解析与生成,我们对 CJson 进行了封装,esp_json_packesp_json_parse支持泛类,字符,整类,浮点类型只需要通过一个API就可以完成。

    • 示例

      int ret = 0;
      char *json_root = (char *)calloc(1, 512);
      char *json_sub = (char *)calloc(1, 64);
      int valueint = 0;
      char valuestring[20];
      double valuedouble = 0;
      /*
      {
          "key0": 0,
          "key1": "tmp1",
          "key4": {
              "key2": {
                  "name": "json test"
              },
              "key3": 1
          },
          "key5": 99.00000,
          "key6": 99.23456
      }
       */
      ret = esp_json_pack(json_root, "key0", valueint++);
      ret = esp_json_pack(json_root, "key1", "tmp1");
      ret = esp_json_pack(json_sub, "key2", "{\"name\":\"json test\"}");
      ret = esp_json_pack(json_sub, "key3", valueint++);
      ret = esp_json_pack(json_root, "key4", json_sub);
      ret = esp_json_pack(json_root, "key5", 99.23456);
      ret = esp_json_pack_double(json_root, "key6", 99.23456);
      printf("json_len: %d, json: %s\n", ret, json_root);
      
      printf("------------- json parse -----------\n");
      
      esp_json_parse(json_root, "key0", &valueint);
      printf("key0: %d\n", valueint);
      esp_json_parse(json_root, "key1", valuestring);
      printf("key1: %s\n", valuestring);
      esp_json_parse(json_root, "key4", json_sub);
      printf("key4: %s\n", json_sub);
      
      esp_json_parse(json_sub, "key2", valuestring);
      printf("key2: %s\n", valuestring);
      esp_json_parse(json_sub, "key3", &valueint);
      printf("key3: %d\n", valueint);
      esp_json_parse(json_root, "key5", &valueint);
      printf("key5: %d\n", valueint);
      /*!< CJson floating point type handling problems, later will be fixed */
      esp_json_parse(json_root, "key6", &valuedouble);
      
      /*!< printf can not output double type */
      char double_char[16] = {0};
      sprintf(double_char, "%lf", valuedouble);
      printf("key6: %s\n", double_char);
      
      free(json_root);
      free(json_sub);

11 注意事项

  • 请定期更新本项目工程,后期将有持续对本工程进行优化改进
  • 模组不支持 5G 网络,请确认已关闭路由器 5G 网络功能
  • 测试热点配网时,请确认 4G 网络处于开启状态
  • 本次更新修改了 chip_id,在烧录之前请先进行设备的解绑
  • ALINK 受网络环境影响极大,进行测试时,请保证网络环境良好,否则将无法通过高频压测和稳定性测试。
  • alink sds版本,目前不支持数据透传

12 Related links