一、平台设置
- 进入阿里云生活平台 https://iot.console.aliyun.com/
- 实力概况—>公共实例
文章图片
- 创建产品
文章图片
- 默认即可
文章图片
- 设备—>添加设备
文章图片
- 拿下 设备的 三元组,但实际上,我们连进去,需要的是四元组,还缺一个ProductSecret
三元组在这里找到: 设备—>查看对应设备
文章图片
文章图片
最后的ProductSecre在 产品—>查看对应产品
文章图片
文章图片
二、获取SDK 这里就要参考一个徐大佬的文章了,这里带出链接
https://xuhong.blog.csdn.net/article/details/101448052
【ESP8266 阿里云物联网平台 (详细步骤)】这里简短说一下流程
- 保证你的网络畅通…用手机流量,上飞机(我家那长城宽带,就算有飞机了,一样拿不下来,只能通过手机流量)------如果你网络贼好,当我没说---------
- 配置git代理
git config --global http.proxy http://172.20.10.4:1080
- 获取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
- 获取工具链,在github的esp8266的sdk中就能找到
特别注意超过3.0版本,我们使用的是8.4的工具链,否则会出现编译错误!
https://github.com/espressif/ESP8266_RTOS_SDK
文章图片
- 设置IDF_PATH
export IDF_PATH=/mnt/hgfs/xuanzihao/ESP_ALIYUN/ESP8266_RTOS_SDK/
- 进入例子的目录
cd esp-aliyun\examples\solutions\smart_light
- 设置芯片为esp8266
make chip=esp8266 defconfig
- 编译
make all
- 出现错误
error: implicit declaration of function 'calloc' [-We
直接在对应文件中加入头文件
#include "stdlib.h"
- 再次make,成功
文章图片
- 编译四元组当然也可以直接代码里面去改,不通过烧录固件方式烧进去
位于 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
- 烧录
文章图片
- 使用零配或者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);
- 修改成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 = https://www.it610.com/article/(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;
}
- 增加串口的设置,将数据发送给阿里云
通过 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 = https://www.it610.com/article/(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);
}}
}
}
- 对于重新进入配网模式,可以使用一个按键长按来实现
这里额外增加了一个功能:长按时,重新配置设置一下四元组
我们可以通过这几个函数进行操作
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_00
#define GPIO_INPUT_PIN_SEL((1ULL<
- 对于通过串口发送的JSON数据格式,可以通过官网的数据点观看,注意平台数据不会更新到页面上,要点击获取
文章图片
[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
文章图片
- 若下发数据,则可以在 linkkit_solo.c的user_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);
#endifres = 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;
}
推荐阅读
- ESP8266|ESP 保姆级教程 疯狂传感器篇 —— 案例(ESP8266 + DHT11 +WebServer页面(检测温湿度、网页显示)更新完)
- 开源一个安卓四轴上位机+配套ESP8266 UDP串口通信源码
- Arduino|VsCode Arduino生成[Error] Exit with code=1的解决方法
- 使用VsCode代替Arduino IDE编译
- 乐鑫 ESP8266 IDF RTOS3.1 Docker开发环境 win10
- Nodemcu freertos 学习之路 -- 环境搭建
- 乐鑫ESP8266烧录固件、升级最新固件、刷MQTT固件
- 学习类|第一期关于ESP8266EX模块固件库的烧写问题
- ESP8266|NodeMCU介绍