ESP8266 阿里云物联网平台 (详细步骤)

#记录一些注意事项

  • 物联网平台必须先等数据点都上传过一次后,才开发公版APP页面,否则控件会不显示

  • SDK必须3.2

  • 工具链5.2

  • TLS使用mbedtls选项

  • 因为用到TLS,使用内存比较大,可以按照下面的任务栈大小设置
    设置好下面2个任务后,余下大约10K左右我们自己分配,别超了,否则TLS链接会连接出错

    //	注意必须大于4096
    xTaskCreate((void (*)(void *))start_conn_mgr, "conn_mgr", 4096, NULL, 5, aws_task_handle);/* 主循环	 */
    //注意必须大于6K
    xTaskCreate((void (*)(void *))linkkit_main, "lightbulb", 8092, NULL, 5, NULL);
    

一、平台设置

  1. 进入阿里云生活平台 https://iot.console.aliyun.com/

  2. 实力概况—>公共实例
    在这里插入图片描述

  3. 创建产品
    在这里插入图片描述

  4. 默认即可
    在这里插入图片描述

  5. 设备—>添加设备
    在这里插入图片描述

  6. 拿下 设备的 三元组,但实际上,我们连进去,需要的是四元组,还缺一个ProductSecret
    三元组在这里找到: 设备—>查看对应设备

在这里插入图片描述在这里插入图片描述
最后的ProductSecre在 产品—>查看对应产品
在这里插入图片描述在这里插入图片描述

二、获取SDK

这里就要参考一个徐大佬的文章了,这里带出链接
https://xuhong.blog.csdn.net/article/details/101448052

这里简短说一下流程

  1. 保证你的网络畅通…用手机流量,上飞机(我家那长城宽带,就算有飞机了,一样拿不下来,只能通过手机流量)------如果你网络贼好,当我没说---------

  2. 配置git代理

git config --global http.proxy http://172.20.10.4:1080
  1. 获取rots-sdk和阿里云sdk 这里注意sdk版本是3.2(可能3.0也行,没试)
git clone -b v3.2 https://github.com/espressif/ESP8266_RTOS_SDK.git
git clone --recursive https://github.com/espressif/esp-aliyun.git
  1. 获取工具链,在github的esp8266的sdk中就能找到
    特别注意超过3.0版本,我们使用的是8.4的工具链,否则会出现编译错误!
    https://github.com/espressif/ESP8266_RTOS_SDK
    在这里插入图片描述

  2. 设置IDF_PATH

export IDF_PATH=/mnt/hgfs/xuanzihao/ESP_ALIYUN/ESP8266_RTOS_SDK/
  1. 进入例子的目录
cd esp-aliyun\examples\solutions\smart_light
  1. 设置芯片为esp8266
make chip=esp8266 defconfig
  1. 编译
make all
  1. 出现错误
error: implicit declaration of function 'calloc' [-We

直接在对应文件中加入头文件

#include "stdlib.h"

若出现 mbedtls 错误,则要 make menuconfig 的SSL中选择mbedtls
在这里插入图片描述

  1. 再次make,成功
    在这里插入图片描述

  2. 编译四元组当然也可以直接代码里面去改,不通过烧录固件方式烧进去
    位于 esp-aliyun\config\mass_mfg ,烧录地址 0x100000

$IDF_PATH/components/nvs_flash/nvs_partition_generator/nvs_partition_gen.py --input single_mfg_config.csv --output my_single_mfg.bin --size 0x4000
  1. 烧录
    在这里插入图片描述

三、代码修改/解析

  1. 使用零配或者AP配网注意这里的零配和AP配网,必须要有对应的产品配网二维码,否则是没办法通过这2中方式去配网的(可能是我没找到其他方法),若想通过这2种方式配网,可以在 阿里云生活平台(飞燕)中来创建产品,具体可以参考我之前写的ESP32进入阿里生活来进行操作
    app_main.c中
#ifdef CONFIG_USE_SOFTAP_CONFIG
    conn_mgr_set_sc_mode(CONN_SOFTAP_MODE);
#else
    conn_mgr_set_sc_mode(CONN_SC_ZERO_MODE);
  1. 修改成smarconfig方式,主要修改
    app_main()中,丢掉2个设置模式
#if 0
#ifdef CONFIG_USE_SOFTAP_CONFIG
    conn_mgr_set_sc_mode(CONN_SOFTAP_MODE);
#else
    conn_mgr_set_sc_mode(CONN_SC_ZERO_MODE);
#endif
#endif

conn_mgr.c中
conn_mgr_start()中,改成smartconfig
增加smartconfig的CB

需要额外注意一个地方,对于一些平台来说,例如阿里云,华为Hilink等,对于这个进入发现模式,示有一个时间要求的,例如1分钟后,就停止了,这里我是直接将停止的逻辑丢掉了

1分钟后停止的逻辑在这里👇
在这里插入图片描述

//增加smartconfig逻辑
static void sc_callback(smartconfig_status_t status, void *pdata)
{
    switch (status) {
        case SC_STATUS_WAIT:
            ESP_LOGI(TAG, "SC_STATUS_WAIT");
            break;
        case SC_STATUS_FIND_CHANNEL:
            ESP_LOGI(TAG, "SC_STATUS_FINDING_CHANNEL");
            break;
        case SC_STATUS_GETTING_SSID_PSWD:
            ESP_LOGI(TAG, "SC_STATUS_GETTING_SSID_PSWD");
            break;
        case SC_STATUS_LINK:
            ESP_LOGI(TAG, "SC_STATUS_LINK");
            wifi_config_t *wifi_config = pdata;
            ESP_LOGI(TAG, "SSID:%s", wifi_config->sta.ssid);
            ESP_LOGI(TAG, "PASSWORD:%s", wifi_config->sta.password);
            ESP_ERROR_CHECK( esp_wifi_disconnect() );
            ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, wifi_config) );
            ESP_ERROR_CHECK( esp_wifi_connect() );
            conn_mgr_save_wifi_config();
            break;
        case SC_STATUS_LINK_OVER:
            ESP_LOGI(TAG, "SC_STATUS_LINK_OVER");
            if (pdata != NULL) {
                sc_callback_data_t *sc_callback_data = (sc_callback_data_t *)pdata;
                switch (sc_callback_data->type) {
                    case SC_ACK_TYPE_ESPTOUCH:
                        ESP_LOGI(TAG, "Phone ip: %d.%d.%d.%d", sc_callback_data->ip[0], sc_callback_data->ip[1], sc_callback_data->ip[2], sc_callback_data->ip[3]);
                        ESP_LOGI(TAG, "TYPE: ESPTOUCH");
                        break;
                    case SC_ACK_TYPE_AIRKISS:
                        ESP_LOGI(TAG, "TYPE: AIRKISS");
                        break;
                    default:
                        ESP_LOGE(TAG, "TYPE: ERROR");
                        break;
                }
            }
            break;
        default:
            break;
    }
}

esp_err_t conn_mgr_start(void)
{
    bool ret = true;
    bool configured = false;

	//替换成smartconfig
    #if 0
    uint8_t mode = 0;
    int mode_len = sizeof(uint8_t);
    conn_sc_mode_t awss_mode = CONN_SC_ZERO_MODE;

    // Let's find out if the device is configured.
    if (conn_mgr_is_configured(&configured) != ESP_OK) {
        return ESP_FAIL;
    }

    // Get SC mode and decide to start which awss service
    HAL_Kv_Get(SC_MODE, &mode, &mode_len);
    if (mode_len && mode == CONN_SOFTAP_MODE) {
        awss_mode = CONN_SOFTAP_MODE;
    }

    // If the device is not yet configured, start awss service.
    if (!configured) {
        do {
            if (awss_config_press() != 0) {
                ret = false;
                break;
            }
            if (awss_mode == CONN_SOFTAP_MODE) {
                if (awss_dev_ap_start() != 0) {
                    ret = false;
                    break;
                }
            } else {
                if (awss_start() != 0) {
                    ret = false;
                    break;
                }
            }
        } while (0);
    } else {
        if (conn_mgr_wifi_connect() != ESP_OK) {
            ret = false;
        }
    }
    #else 
    if (conn_mgr_is_configured(&configured) != ESP_OK) {
        return ESP_FAIL;
    }
    
    if (!configured) {
		ESP_ERROR_CHECK( esp_smartconfig_set_type(SC_TYPE_ESPTOUCH_AIRKISS) );
		ESP_ERROR_CHECK( esp_smartconfig_start(sc_callback) );
    }
    else{
        if (conn_mgr_wifi_connect() != ESP_OK) {
            ret = false;
        }

    }
    #endif
    return ret == true ? ESP_OK : ESP_FAIL;
}

  1. 增加串口的设置,将数据发送给阿里云
    通过 IOT_Linkkit_Report即可将数据发送过去,这里先通过g_user_example_ctx.cloud_connected来判断是否已经连平台成功了
//增加串口测试
void uart_init()
{
    /* Configure parameters of an UART driver,
     * communication pins and install the driver */
    uart_config_t uart_config = {
    	.baud_rate = 115200,
        .data_bits = UART_DATA_8_BITS,
        .parity    = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE
    };

    uart_param_config(UART_NUM_0, &uart_config);
    uart_driver_install(UART_NUM_0, 100 * 2, 100 * 2, 0, 0);
    
}

static void uart_task(void *pvParameters)
{
	ESP_LOGI(TAG," \r\n******* uart_task start ******* \r\n");
	uint8_t *data = (uint8_t *) malloc(256);
	for(;;)
	{
		uint8_t len = uart_read_bytes(UART_NUM_0, data, 100, 20 / portTICK_RATE_MS);/* 串口接收超时20ms */
		if(len>0)//接收到数据
		{
			extern user_example_ctx_t g_user_example_ctx;
			/* 若已经连上阿里云 */
			if (g_user_example_ctx.cloud_connected ==1 )
			{
				/* 数据透传到阿里云 */
				uint8_t res = IOT_Linkkit_Report(0, ITM_MSG_POST_PROPERTY,
										 (unsigned char *)data, len);
				ESP_LOGI(TAG,"Post Property Message ID: %d", res);

			}

		}
	}
}
  1. 对于重新进入配网模式,可以使用一个按键长按来实现
    这里额外增加了一个功能:长按时,重新配置设置一下四元组
    我们可以通过这几个函数进行操作
	HAL_SetProductSecret((char *)"");
	HAL_SetProductKey((char *)"");
	HAL_SetDeviceSecret((char *)"");		
	HAL_SetDeviceName((char *)"test1");

去掉配网设置

	HAL_Kv_Del(STA_SSID_KEY);
	HAL_Kv_Del(STA_PASSWORD_KEY);

完整的按键逻辑:

/增加按键处理
#define GPIO_INPUT_IO_0     0
#define GPIO_INPUT_PIN_SEL  ((1ULL<<GPIO_INPUT_IO_0))//GPIO0

static xQueueHandle gpio_evt_queue = NULL;

static void gpio_isr_handler(void *arg)
{
    uint32_t gpio_num = (uint32_t) arg;
    xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL);
}

static void gpio_task_example(void *arg)
{
    uint32_t io_num;
	uint8_t down_cont = 0;
    for (;;) 
    {

    	#if 0
        if (xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) {
            ESP_LOGI(TAG, "GPIO[%d] intr, val: %d\n", io_num, gpio_get_level(io_num));
		#else

		//暂时不用中断,直接扫io
		if(!gpio_get_level(GPIO_INPUT_IO_0))
		{
			ESP_LOGI(TAG, "key %d \r\n",down_cont);
			if(down_cont++ == 25)
			{
				HAL_Kv_Del(STA_SSID_KEY);
				HAL_Kv_Del(STA_PASSWORD_KEY);
				//system_restart();

				//配网重新设置一下4元组
				//这里直接设置
				/*
				{ "ProductKey": "a1Eo5MZSsw6", "DeviceName": "MLX90614", "DeviceSecret": "4bc5d4780a4cfe148267460336b29171" }
				productsecret:"yiYsgDadOTxB9jep"
				*/

				HAL_SetProductSecret((char *)"");
				HAL_SetProductKey((char *)"");
				HAL_SetDeviceSecret((char *)"");		
				HAL_SetDeviceName((char *)"test1");

				
				esp_restart();
			}
		}
		else
		{
			down_cont = 0;
		}
		vTaskDelay(200/portTICK_PERIOD_MS);
		#endif



            
        }
}

void gpio_init()
{
    gpio_config_t io_conf;

    //interrupt of rising edge
    //io_conf.intr_type = GPIO_INTR_NEGEDGE; 不需要中断
    //bit mask of the pins, use GPIO4/5 here
    io_conf.pin_bit_mask = GPIO_INPUT_PIN_SEL;
    //set as input mode
    io_conf.mode = GPIO_MODE_INPUT;
    //enable pull-up mode
    io_conf.pull_up_en = 1;
    gpio_config(&io_conf);

    //change gpio intrrupt type for one pin
    //gpio_set_intr_type(GPIO_INPUT_IO_0, GPIO_INTR_ANYEDGE);

    //create a queue to handle gpio event from isr
    gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t));
    //start gpio task
    xTaskCreate(gpio_task_example, "gpio_task_example", 2048, NULL, 3, NULL);
    //install gpio isr service
    //gpio_install_isr_service(0);
    //hook isr handler for specific gpio pin
    //gpio_isr_handler_add(GPIO_INPUT_IO_0, gpio_isr_handler, (void *) GPIO_INPUT_IO_0);

}
  1. 对于通过串口发送的JSON数据格式,可以通过官网的数据点观看,注意平台数据不会更新到页面上,要点击获取
    在这里插入图片描述

设备LOG

[0m[1;32;40muser_report_reply_event_handler.122: Message Post Reply Received, Message ID: 13, Code: 200, Reply: {}[0m

[1;33m[inf] iotx_mc_keepalive_sub(1699): send MQTT ping...

[0m[1;33m[inf] iotx_mc_cycle(1570): receive ping response!

[0m[1;33m[inf] dm_msg_request(205): DM Send Message, URI: /sys/a1zgJ61EEAf/test1/thing/event/property/post, Payload: {"id":"14","version":"1.0","params":{"ActivePower":10},"method":"thing.event.property.post"}

[0m[1;33m[inf] dm_client_publish(131): Publish Result: 0

[0m[0;32mI (9948476) app main: Post Property Message ID: 14[0m
[1;33m[inf] dm_msg_proc_thing_event_post_reply(318): Event Id: property

[0m[1;33m[inf] _iotx_linkkit_event_callback(246): Receive Message Type: 32

[0m[1;33m[inf] _iotx_linkkit_event_callback(248): Receive Message: {"id":14,"code":200,"devid":0,"payload":{}}

[0m[1;32;40muser_report_reply_event_handler.122: Message Post Reply Received, Message ID: 14, Code: 200, Reply: {}[0m

在这里插入图片描述

  1. 若下发数据,则可以在 linkkit_solo.cuser_property_set_event_handler中进行判断

平台点击
在这里插入图片描述
设备LOG

[1;33m[inf] dm_msg_proc_thing_service_property_set(144): thing/service/property/set

[0m[1;33m[inf] dm_msg_response(261): Send URI: /sys/a1zgJ61EEAf/test1/thing/service/property/set_reply, Payload: {"id":"693981989","code":200,"data":{}}

[0m[1;33m[inf] dm_client_publish(131): Publish Result: 0

[0m[1;33m[inf] _iotx_linkkit_event_callback(246): Receive Message Type: 15

[0m[1;33m[inf] _iotx_linkkit_event_callback(248): Receive Message: {"devid":0,"payload":{"LightAdjustLevel":55}}

[0m[0;32mI (10169946) linkkit_example_solo: Property Set Received, Devid: 0, Request: {"LightAdjustLevel":55}[0m
[0;32mI (10169946) lightbulb: lightbulb_set_brightness : 78[0m
[0;32mI (10169956) lightbulb: lightbulb_set_saturation : 100.000000[0m
[1;33m[inf] dm_msg_request(205): DM Send Message, URI: /sys/a1zgJ61EEAf/test1/thing/event/property/post, Payload: {"id":"15","version":"1.0","params":{"LightAdjustLevel":55},"method":"thing.event.property.post"}

[0m[1;33m[inf] dm_client_publish(131): Publish Result: 0

[0m[0;32mI (10169986) linkkit_example_solo: Post Property Message ID: 15[0m
[1;33m[inf] dm_msg_proc_thing_event_post_reply(318): Event Id: property

[0m[1;33m[inf] _iotx_linkkit_event_callback(246): Receive Message Type: 32

[0m[1;33m[inf] _iotx_linkkit_event_callback(248): Receive Message: {"id":15,"code":200,"devid":0,"payload":{}}

[0m[1;32;40muser_report_reply_event_handler.122: Message Post Reply Received, Message ID: 15, Code: 200, Reply: {}[0m

代码处理,我这里直接通过 ty_send_data(request); 将数据丢出去串口了,实际上收到的是一些json数据,用cjson来解析处理即可

static int user_property_set_event_handler(const int devid, const char *request, const int request_len)
{
    int res = 0;
    cJSON *root = NULL, *LightSwitch = NULL, *LightColor = NULL;
    ESP_LOGI(TAG,"Property Set Received, Devid: %d, Request: %s", devid, request);


	//app_uart_send(request,strlen(request));

	ty_send_data(request);
	
    #if 0
    lightbulb_set_brightness(78);
    lightbulb_set_saturation(100);
    
    if (!request) {
        return NULL_VALUE_ERROR;
    }

    /* Parse Root */
    root = cJSON_Parse(request);
    if (!root) {
        ESP_LOGI(TAG,"JSON Parse Error");
        return FAIL_RETURN;
    }

    /** Switch Lightbulb On/Off   */
    LightSwitch = cJSON_GetObjectItem(root, "LightSwitch");
    if (LightSwitch) {
        lightbulb_set_on(LightSwitch->valueint);
    } 

    /** Switch Lightbulb Hue */
    LightSwitch = cJSON_GetObjectItem(root, "RGBColor");
    if (LightSwitch) {
        LightColor = cJSON_GetObjectItem(LightSwitch, "Red");
        lightbulb_set_hue(LightColor ? LightColor->valueint : 0);
        LightColor = cJSON_GetObjectItem(LightSwitch, "Green");
        lightbulb_set_hue(LightColor ? LightColor->valueint : 120);
        LightColor = cJSON_GetObjectItem(LightSwitch, "Blue");
        lightbulb_set_hue(LightColor ? LightColor->valueint : 240);
    }
    
    cJSON_Delete(root);
    #endif

    res = IOT_Linkkit_Report(EXAMPLE_MASTER_DEVID, ITM_MSG_POST_PROPERTY,
                             (unsigned char *)request, request_len);
    ESP_LOGI(TAG,"Post Property Message ID: %d", res);

    return SUCCESS_RETURN;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值