前言
介绍8266如何连接到乐鑫云平台,以及如何与乐鑫云平台进行交互
在此之前我们已经在乐鑫云平台创建了云端设备,并且获取到了云端设备所对应的设备秘钥
云端设备和云下设备需要靠秘钥进行连接
我们将秘钥下载下来 秘钥就是个二进制文件,我们可以将这个二进制文件烧录到8266模组当中,这样的话8266就可以使用这个二进制秘钥来连接乐鑫云平台
那么8266如何连接这个云平台以及如何使用这个秘钥呢?
这里8266将使用不加密的tcp通讯来和乐鑫云平台进行交互,端口号是8000
云下设备与乐鑫云平台的交互,他使用的是json字符串,json字符串中有GET指令,“tock 000”设备秘钥,等等参数
当接收方接收到发送方发送的json报文后,接收方需要向发送方响应
注意程序当中会根据我们flash大小,决定系统扇区的起始位置
case FLASH_SIZE_32M_MAP_512_512:
rf_cal_sec = 1024 - 5;
priv_param_start_sec = 0x7C; // 【设备密钥】烧录到【0x7D】
break;
case FLASH_SIZE_32M_MAP_1024_1024:
rf_cal_sec = 1024 - 5;
priv_param_start_sec = 0xFC; // 【设备密钥】烧录到【0xFD】
break;
user_init
我们只关心这个函数
user_esp_platform_init(); // 查询复位状态、参数初始化
user_esp_platform_init
首先它读取0x7D扇区的数据,这里面有设备秘钥等参数,
system_param_load(priv_param_start_sec+1,0,&esp_param,sizeof(esp_param)); // 读取【0x7D(0x7C+1)扇区】的数据(KEY_BIN)
os_printf("esp_param.devkey = %sn",esp_param.devkey); // 串口打印【devkey】
os_printf("esp_param.token = %sn",esp_param.token); // 串口打印【token】
os_printf("esp_param.pad = %sn",esp_param.pad); // 串口打印【pad】
os_printf("esp_param.activeflag = %dn",esp_param.activeflag); // 串口打印【activeflag】
之后连接WiFi
// 判断ESP8266是否为SoftAP模式
//-------------------------------------------------------------------------------------------
if (wifi_get_opmode() != SOFTAP_MODE) // 不是SoftAP模式
{
// 设置定时器(定时查询ESP8266的IP情况)
//----------------------------------------
os_timer_disarm(&client_timer);
os_timer_setfn(&client_timer, (os_timer_func_t *)user_esp_platform_check_ip,(void *)1); // 参数3=1:表示当前是刚复位状态
os_timer_arm(&client_timer, 100, 0); // 使能毫秒定时器(100Ms定时)
}
user_esp_platform_check_ip
如果成功连接到WiFi的话
// ESP8266获取到IP地址
//---------------------------------------------------------------------------
if (wifi_station_get_connect_status()==STATION_GOT_IP && ipconfig.ip.addr!=0)
进行tcp连接设置
// TCP连接设置
//------------------------------------------------------------------
user_conn.proto.tcp = &user_tcp; // 开辟内存
user_conn.type = ESPCONN_TCP; // 设为TCP连接
user_conn.state = ESPCONN_NONE;
device_status = DEVICE_CONNECTING; // 设备(8266)状态设为【正在连接】
if (reset_flag) // 判断是否是刚复位
{ device_recon_count = 0;} // 系统复位后,ESP8266_TCP重连计数=0(reset_flag==1表示为系统复位)
#if (PLUG_DEVICE || LIGHT_DEVICE)
os_timer_disarm(&beacon_timer); // 设置心跳定时器定时器
os_timer_setfn(&beacon_timer, (os_timer_func_t *)user_esp_platform_sent_beacon, &user_conn);
并进行DNS域名解析
#ifdef USE_DNS
user_esp_platform_start_dns(&user_conn); // DNS设置
如果域名解析成功的话,那么就将8266作为tcp_client,连接到tcp_server也就是乐鑫云平台
espconn_regist_connectcb(pespconn, user_esp_platform_connect_cb); // TCP连接成功_回调函数
espconn_regist_disconcb(pespconn, user_esp_platform_discon_cb); // TCP断开成功_回调函数
espconn_regist_reconcb(pespconn, user_esp_platform_recon_cb); // TCP异常断开_回调函数
user_esp_platform_connect(pespconn); // ESP8266(Client)连接TCP Server
当tcp连接成功之后,我们向乐鑫云平台发送数据报
// TCP连接成功_回调函数
//==================================================================================================================
LOCAL void ICACHE_FLASH_ATTR user_esp_platform_connect_cb(void *arg)
{
struct espconn *pespconn = arg;
ESP_DBG("user_esp_platform_connect_cbn");
// 如果与服务器的TCP连接建立,那就关闭softAP模式
//-----------------------------------------------
if (wifi_get_opmode() == STATIONAP_MODE ) // 【开启AP模式使为了使用APP来向ESP8266发送路由器WIFI的SSID、PASS】
{
wifi_set_opmode(STATION_MODE); // 设为STA模式
}
#if (PLUG_DEVICE || SENSOR_DEVICE)
user_link_led_timer_done();
#endif
device_recon_count = 0; // ESP8266_TCP重连计数 = 0
espconn_regist_recvcb(pespconn, user_esp_platform_recv_cb); // 网络数据接收成功_回调函数
espconn_regist_sentcb(pespconn, user_esp_platform_sent_cb); // 网络数据发送成功_回调函数
user_esp_platform_sent(pespconn); // ESP8266发送TCP数据(设备向乐鑫云平台发送数据包)
}
8266会根据云端设备是否激活来选择向乐鑫云平台发送云端设备激活的json字符串还是标识身份的json字符串
if (pbuf != NULL)
{
//【云端设备】未激活
//----------------------------------------------------------
if (esp_param.activeflag == 0) // 【0】:云端设备未激活
{
uint8 token[token_size] = {0};
uint8 bssid[6];
active_nonce = os_random()&0x7FFFFFFF; // 第一次激活,获取随机的【激活加密码】
os_memcpy(token, esp_param.token, 40); // 获取esp_param.token值
wifi_get_macaddr(STATION_IF, bssid); // 获取STA的MAC地址
// 格式化【ACTIVE_FRAME】,激活云端设备。【参数见"ACTIVE_FRAME"定义】
//--------------------------------------------------------------------------------------
os_sprintf(pbuf, ACTIVE_FRAME, active_nonce, token, MAC2STR(bssid),iot_version, devkey);
}
//【云端设备】激活(类似于执行RESET操作)
//-------------------------------------------------------------------------------------------------------------
//【"nonce"可选参数:用于 MD5-NONCE,SHA1-NONCE,HMAC-SHA1-NONCE 加密算法,是一个随机的整数,用来混淆加密算法】
//【"encrypt_method"必要参数:激活方式(这里设为PLAIN方式)】
//【"token"可选参数:是40位随机字符,用于"拥有者授权",在实际情况中可能是出厂说明书里面的“二维码”】
//【"bssid"可选参数:设置该设备的MAC地址】
//【"rom_version"可选参数:版本信息】
//【"Authorization"必选参数:验证设备身份(Master Device Key)】
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#define ACTIVE_FRAME "{"nonce": %d,"path": "/v1/device/activate/", "method": "POST", "body": {"encrypt_method": "PLAIN", "token": "%s", "bssid": ""MACSTR"","rom_version":"%s"}, "meta": {"Authorization": "token %s"}}n"
//【云下设备】向云平台标识身份,表明是设备发出的连接(ESP8266与乐鑫云平台建立连接后需向云平台标识身份,建立连接之后使用一次即可)
//-------------------------------------------------------------------------------------------------------------------------------
//【"nonce"可选参数:用于 MD5-NONCE,SHA1-NONCE,HMAC-SHA1-NONCE 加密算法,是一个随机的整数,用来混淆加密算法】
//【"Authorization"必选参数:验证设备身份(Master Device Key)】
//-----------------------------------------------------------------------------------------------------------------------------------------------
#define FIRST_FRAME "{"nonce": %d, "path": "/v1/device/identify", "method": "GET","meta": {"Authorization": "token %s"}}n"
关于创建数据点,修改数据点,定时等等的许多功能先不细讲
RPC(Remote Procedure Call Protocol)远程过程调用协议。一个通俗的描述是:客户端在不知道调用细节的情况下,调用存在于远程计算机上的某个对象,就像调用本地应用程序中的对象一样
最后看一下8266接收乐鑫云平台向它发送的RPC请求,他会作何处理,当8266接收乐鑫云平台向它发送的RPC请求请求内容是LED_ON时8266会将led点亮,LED_OFF时,8266将会把led熄灭
if( ((char *)os_strstr(pbuffer, "{"deliver_to_device": true, "get": {"action": "LED_ON"}")) != NULL )
{
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO4_U, FUNC_GPIO4);
GPIO_OUTPUT_SET(GPIO_ID_PIN(4),0); // LED亮
}
else if( ((char *)os_strstr(pbuffer, "{"deliver_to_device": true, "get": {"action": "LED_OFF"}")) != NULL )
{
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO4_U, FUNC_GPIO4);
GPIO_OUTPUT_SET(GPIO_ID_PIN(4),1); // LED灭
}
所谓的设备接入云平台,实际上就是设备与云平台建立网络连接,之后按照云平台规定的数据格式,来收发网络数据,设备就能与云平台进行交互,实现设备接入云平台
本文章来源于互联网,如有侵权,请联系删除!原文地址:ESP8266连接乐鑫云平台IOT_Demo