STM32+ESP-01对接阿里飞燕平台

STM32+ESP-01对接阿里飞燕平台


近年来,伴随着微电子技术和计算机信息技术的高速发展,物联网技术也就应运而生,万物互联成为可能。目前大部分消费类电子产品以及家电产品都已装载上了WIFI模块或者蓝牙模块,让它们都能连接入网,实现互联互通,远程控制、智能控制成为众多消费电子产品的卖点。因此WIFI模块的应用也随之成为嵌入式工程师必不可少的技能。
由于IPv4地址资源的紧缺,在局域网中的设备一般不能通过本地IP与外部网络直接建立连接,需要通过NAT网关进行IP映射,所以远程控制局域网中的物联网设备最好的解决方案就是通过外网服务器进行消息转发。目前各大互联网公司都推出了自己的物联网平台。比如阿里巴巴的飞燕平台,腾讯的微信硬件平台,机智云推出的机智云平台等等。
鉴于阿里巴巴集团的强大影响力,我们就以飞燕平台为例来讨论一下如何通过物联网平台进行WIFI设备到服务器再到手机终端的连接方案,开发我们的物联网产品。关于飞燕平台的细节信息请参考它的帮助文档https://help.aliyun.com/product/93051.html?spm=a2c4g.750001.list.264.36f87b13MRwU2W
由于采用硬件平台的不同相对应的对接程序也存在很大差异,对接前我们要先确定需要采用哪种硬件平台,例如今天我们的讨论是基于STM32MCU+ESP-01S WIFI模组的硬件配置,由于ESP-01S原始固件只支持TCP但不支持MQTT,所以业务逻辑控制以及MQTT协议要运行在MCU之上。连接框图如下:
在这里插入图片描述
阿里飞燕平台是基于MQTT协议的,所以这里我们先来了解一下MQTT协议,根据网络协议分层如下图:
在这里插入图片描述
MQTT(消息队列遥测传输)是ISO 标准(ISO/IEC PRF 20922)下基于发布/订阅范式的消息协议。它是基于 TCP/IP的协议簇的应用层协议,是为硬件性能低下的远程设备以及网络状况糟糕的情况下而设计的发布/订阅型消息协议 。MQTT是一个基于客户端-服务器的消息发布/订阅传输协议。MQTT协议是轻量、简单、开放和易于实现的,这些特点使它适用范围非常广泛。在很多情况下,包括受限的环境中,如:机器与机器(M2M)通信和物联网(IoT)。其在,通过卫星链路通信传感器、偶尔拨号的医疗设备、智能家居、及一些小型化设备中已广泛使用。
关于MQTT协议的具体内容请移步https://www.cnblogs.com/dongkuo/p/11360419.html
这位博主进行了协议的详细介绍。
阿里飞燕平台为了方便用户使用,简化对接平台时的繁琐底层程序,其提供了各类开发语言的SDK,下载地址如下:
https://code.aliyun.com/linkkit/c-sdk/repository/archive.zip?spm=a2c4g.11186623.2.36.63fb4e1eEOB1mz&ref=v3.0.1
SDK的应用方法细节请参考帮助文档
https://help.aliyun.com/product/93051.html?spm=a2c4g.750001.list.264.36f87b13MRwU2W
下载完SDK后解压,双击打开config.bat文件,会弹出一个选择模块的配置界面如下:
在这里插入图片描述
通过上下左右方向键移动光标,空格键选择和取消选择,我们选择以下选项

  1. PLATFORM_HAS_STDINT
  2. PLATFORM_HAS_DYNMEM
  3. FEATURE_MQTT_COMM_ENABLED
    3.1 FEATURE_MQTT_DEFAULT_IMPL
    3.2 FEATURE_MQTT_DIRECT
  4. FEATURE_ATM_ENABLED
    4.1 FEATURE_AT_TCP_ENABLED
    由于不同模块AT指令的差异,我们这里不采用SDK自带的AT指令解析模块,所以在FEATURE_ATM_ENABLED下只选择FEATURE_AT_TCP_ENABLED选项。选择完毕后保存退出。然后双击打开extract.bat,便会在output文件夹中生成所需文件,将\output\eng下所有文件以及\output\examples\ mqtt_example_at.c(mqtt_example_at.c文件是MQTT客户端API的应用实例)拷贝至KEIL或者IAR中的STM32工程目录下,并添加进工程。而后我们需要修改\output\eng\wrappers\wrapper.c中的相关函数,来实现对接,需要修改的函数如下:
    在这里插入图片描述
    在这里插入图片描述
    由于我们没有在MCU上运行OS所以其实以上函数并不需要,但SDK还是生成了上述函数实体,我们只需要将函数返回正确的值就可以,比如HAL_MutexCreate返回(void*)1,其他返回0。
    在这里插入图片描述在这里插入图片描述
    以上函数是MCU与ESP-01S通过串口进行AT指令通信的主要实现函数。
  5. HAL_AT_CONN_Init
#define LINK_ID_MAX 5
typedef struct link_s
{
int fd;
} link_t;
static link_t g_link[LINK_ID_MAX];
int HAL_AT_CONN_Init(void)
{
	int link;
	memset(g_link, 0, sizeof(g_link));
	for (link = 0; link < LINK_ID_MAX; link++)
	{
		g_link[link].fd = -1;
	}
	
	char cmd0[64] = {0};
	char out0[64] = {0};
         //选择模式1.Station 2.AP 3.AP+Station	
	HAL_Snprintf(cmd0, sizeof(cmd0), "AT+CWMODE=%d\r\n",3);
	if(at_send_cmd_wait_reply(cmd0,sizeof(cmd0),out0,sizeof(out0),"\r\n","OK\r\n",6000) < 0)
	{
		at_conn_hal_debug("%s %d failed", __func__, __LINE__);
		return -1;
	}
	//选择模式断开WIFI连接
	HAL_Snprintf(cmd0, sizeof(cmd0), "AT+CWQAP\r\n");
	if(at_send_cmd_wait_reply(cmd0,sizeof(cmd0),out0,sizeof(out0),"\r\n","OK\r\n",6000) < 0)
	{
		at_conn_hal_debug("%s %d failed", __func__, __LINE__);
		return -1;
	}
	//选择模式连接WIFI,SSID:WIFISSID Password:WIFIPassword
	HAL_Snprintf(cmd0, sizeof(cmd0), "AT+CWJAP=\"%s\",\"%s\"\r\n","WIFISSID","WIFIPassword");
	if(at_send_cmd_wait_reply(cmd0,sizeof(cmd0),out0,sizeof(out0),"\r\n","OK\r\n",6000) < 0)
	{
		at_conn_hal_debug("%s %d failed", __func__, __LINE__);
		return -1;
	}
	
	inited = true;
	return 0;
}
  1. HAL_AT_CONN_Deinit
int HAL_AT_CONN_Deinit(void)
{
if (!inited)
{
        return 0;
    }
    inited = false;
    return 0;
}
  1. HAL_AT_CONN_Start
int HAL_AT_CONN_Start(at_conn_t *c)
{
	char cmd0[128] = {0};
	char out0[128] = {0};
         //选择TCP连接模式为多连接
	HAL_Snprintf(cmd0, sizeof(cmd0), "AT+CIPMUX=%d\r\n",1);
	if(at_send_cmd_wait_reply(cmd0,sizeof(cmd0),out0,sizeof(out0),"\r\n","OK\r\n",6000) < 0)
	{
		at_conn_hal_debug("%s %d failed", __func__, __LINE__);
		return -1;
	}
	
	int link_id;
	for (link_id = 0; link_id < LINK_ID_MAX; link_id++)
	{
		if (g_link[link_id].fd >= 0)
		{
			continue;
		}
		else
		{
			g_link[link_id].fd = conn->fd;
			break;
		}
	}
	//建立TCP连接
	HAL_Snprintf(cmd0, sizeof(cmd0), "AT+CIPSTART=%d,\"%s\",\"%s\",%d\r\n",link_id,"TCP",conn->addr,conn->r_port);
	if(at_send_cmd_wait_reply(cmd0,sizeof(cmd0),out0,sizeof(out0),"\r\n","OK\r\n",300) < 0)
	{
		at_conn_hal_debug("%s %d failed", __func__, __LINE__);
		return -1;
	}
	return (int)0; 
}
  1. HAL_AT_CONN_Close
int HAL_AT_CONN_Close(int fd, int32_t remote_port)
{
	int link_id;
	link_id = fd_to_linkid(fd);
	if(link_id < 0 || link_id >= LINK_ID_MAX)
	{
at_conn_hal_debug("No connection found for fd (%d) in %s in %s", fd, __func__, __LINE__);
		return -1;
	}
	
	char cmd0[64] = {0};
	char out0[64] = {0};
         //关闭TCP连接
	HAL_Snprintf(cmd0, sizeof(cmd0), "AT+CIPCLOSE=%d\r\n",link_id);
	if(at_send_cmd_wait_reply(cmd0,sizeof(cmd0),out0,sizeof(out0),"\r\n","OK\r\n",6000) < 0)
	{
		//at_conn_hal_debug("%s %d failed", __func__, __LINE__);
		//return -1;
	}	
	g_link[link_id].fd = -1;
	
	return 0; 
}
  1. HAL_AT_CONN_Send
int HAL_AT_CONN_Send(int fd,
                     uint8_t *data,
                     uint32_t len,
                     char remote_ip[16],
                     int32_t remote_port,
                     int32_t timeout)
{
    	int link_id;
	if (!data)
	{
		return -1;
	}
	link_id = fd_to_linkid(fd);
	if (link_id < 0 || link_id >= LINK_ID_MAX)
	{
		at_conn_hal_debug("No connection found for fd (%d) in %s in %s", fd, __func__, __LINE__);
		return -1;
	}
	char cmd0[64] = {0};
	char out0[64] = {0};
        //设置发送数据到连接link_id,数据长度为len
	HAL_Snprintf(cmd0, sizeof(cmd0), "AT+CIPSEND=%d,%d\r\n",link_id,len);
	if(at_send_cmd_wait_reply(cmd0,sizeof(cmd0),out0,sizeof(out0),"\r\n","OK\r\n",300) < 0)
	{
		at_conn_hal_debug("%s %d failed", __func__, __LINE__);
		return -1;
	}
         //开始发送数据
	if(at_send_data_wait_reply(data,len,out0,sizeof(out0),">","OK\r\n",6000) < 0)
	{
		at_conn_hal_debug("%s %d failed", __func__, __LINE__);
		return -1;
	}
	
	HAL_SleepMs(5000);
	char Prefix[64] = {0};
	HAL_Snprintf(Prefix, sizeof(Prefix), "+IPD,%d,",link_id);
         //等待回复
	if (at_yield(out0, sizeof(out0), Prefix, ":", AT_UART_TIMEOUT_MS) <  0)
	{
		return -1;
	}	
	
	char mqtt_reply[256] = {0};
	char c = NULL;
	int num = atoi(out0);
	for(int i=0;i < num;i++)
	{
                 //抓取回复到mqtt_reply
		if (at_getc(&c,timeout) != 0)
		{
			return -1;
		}
		mqtt_reply[i] = c;
	}
	struct at_conn_input param;
	if (g_link[link_id].fd >= 0)
	{
		param.fd = g_link[link_id].fd;
		param.data = mqtt_reply;
		param.datalen = num;
		param.remote_ip = NULL;
		param.remote_port = 0;
		//将接收到的数据上传给MQTT协议上层
		if (IOT_ATM_Input(&param) != 0)
		{
			at_conn_hal_debug(" %s socket %d get data len %d fail to post to at_conn, drop it\n",__func__, g_link[link_id].fd, len);
		}
  }
	return (int)0; }
  1. HAL_AT_CONN_DomainToIp
int HAL_AT_CONN_DomainToIp(char *domain, char ip[16])
{
	char cmd0[128] = {0};
	char out0[128] = {0};
         //根据域名获取IP地址
	HAL_Snprintf(cmd0, sizeof(cmd0), "AT+CIPDOMAIN=\"%s\"\r\n",domain);
	if(at_send_cmd_wait_reply(cmd0,sizeof(cmd0),out0,sizeof(out0),"+CIPDOMAIN:","\r\n",6000) < 0)
	{
at_conn_hal_debug("%s %d failed", __func__, __LINE__);
return -1;
	}
	
	for(int i=0;i < 16;i++)
	{
ip[i] = out0[i];
	}
	at_conn_hal_debug("IP->%s", ip);
	return 0; 
}

以上程序都是在测试阶段编写,比较随意,有不足之处希望批评指正。
设备端程序完善后我们可以在阿里飞燕平台的控制台上中的物联网平台上进行调试,首先我们修改自定义Topic中的get类为发布和订阅,因为在mqtt_example_at.c的调试例子中采用订阅发布这个Topic来实现。

最后我们就可以启动程序来进行飞燕平台的连接了。如果应用mqtt_example_at.c调试例子,我们需把mqtt_example_at.c中main函数修改一个名字如mqtt_example,以免与我们自己的main函数冲突,并在我们定义的main函数中调用mqtt_example。
后续还将讨论如何用微信小程序与阿里飞燕平台对接,实现微信->阿里飞燕平台->WIFI模组的整套连接方案。

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
STM32 ESP8266平台是一种物联网开发平台,结合了STM32微控制器和ESP8266无线通信模块。该平台是为了方便人们在物联网应用领域快速开发和部署项目而设计的。 首先,STM32是意法半导体公司(ST Microelectronics)开发的一种低功耗、高性能的微控制器。它具有较强的处理能力和丰富的外设接口,可以广泛应用于各种嵌入式系统中。搭配ESP8266无线通信模块,可以实现微控制器与互联网之间的无线通信功能。 其次,ESP8266是一款集成了WiFi模块的芯片,由乐鑫科技公司(Espressif Systems)开发。它能够实现无线网络连接功能,并提供了丰富的AT指令集,方便对芯片进行控制和配置。搭配STM32微控制器,可以实现无线数据传输、远程监控等应用。 平台综合了STM32和ESP8266的优势,为物联网应用的开发提供了便利。该平台使用了开放式的开发环境,支持多种编程语言,如C语言、Python等,使开发者可以根据自己的需求,选择适合自己的编程语言进行开发。平台还提供了丰富的软件库和开发工具,帮助开发者快速实现各种功能和应用。 总之,STM32 ESP8266平台是一种结合STM32微控制器和ESP8266无线通信模块的物联网开发平台,具有较强的处理能力和丰富的通信功能。它为物联网应用的开发者提供了方便和效率,使得物联网应用的开发和部署变得更加容易和快捷。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值