本帖最后由 龙鳞铁碎牙 于 2025-6-2 08:22 编辑
#每日话题# #技术资源# #申请开发板# #申请原创#
拿到STM32C092RC 开发板有一段时间了,也写了几篇帖子,发现目前还没有人用STM32C092RC 和ESP8266发过帖子,那我就来做第一个吃螃蟹的人,来给网友展示下
ESP8266连接远程云服务器的魅力操作,现在的社会是个万物互联的时代,任何电子产品都在加入物联网云,方便用户通过智能手机和PC电脑来远程操作智能家居。实现一机在手,世界我有的操作体验!!!
首先查看原理图
可以知道PB6和PB7对应的是USART1
对应STM32C092RC 开发板上的CN10座子右下角的两个引脚。
我们对照着连接号ESP8266
左上角是ESP8266,左下角是ESP8266的VCC,GND和RST引脚,右边的是ESP8266的RX和TX引脚
整个连接如上图所示
CubeMX上主要配置这个两个串口USART1和USART2就可以了,USART2是板载的USB串口。
下面为了进行MQTT远程LED点灯,我们还需要配置好LED1和LED2两个引脚,查看原理图
配置好PA5和PC9两个输出引脚。
下面的重点就是ESP8266的MQTT连接了。
MQTT是一个基于客户端-服务器的消息发布/订阅传输协议。MQTT协议是轻量、简单、开放和易于实现的,这些特点使它适用范围非常广泛。在很多情况下,包括受限的环境中,如:机器与机器(M2M)通信和物联网(IoT)。其在,通过卫星链路通信传感器、偶尔拨号的医疗设备、智能家居、及一些小型化设备中已广泛使用。
使用MQTT协议,需要有一个云服务器,比如华为云,百度云,阿里云,AWS云,涂鸦云等等,我们的STM32板子就是一个客户端,电脑上的MQTTfx软件也是客户端。这些个客户端接入了共同的云服务器,多个客户端就可以互相收发信息通信了,原理就这么简单。
MQTT(Message Queuing Telemetry Transport) 消息队列遥测传输协议,是一个基于客户端-服务器的消息发布/订阅传输协议。
主要的概念有5个:
Broker 代理:MQTT 服务器
Publish 发布者:客户端
Subscribe 订阅者:客户端,可订阅多个 topic Topic
主题:消息的类型,订阅主题之后就可以收到该 topic 的消息内容即 payload Payload
消息内容:具体的内容。
本次我就直接使用ESP8266自带的MQTT指令来连接进入云端,收发数据,不用走TCP服务,还需要自己实现复杂的接口,移植paho MQTT库,太复杂了!
添加ESP8266初始化代码
void ESP8266_Init(void)
{
char str[256] = {0};
ESP8266_Clear();
HAL_UART_Receive_IT(UART_ESP8266, &rx_data, 1);
ESP8266_SendCmd("AT+RST\r\n", "OK");
DelayXms(3000);
printf("ESP8266 重启\r\n");
while(ESP8266_SendCmd("AT\r\n", "OK"))
DelayXms(200);
printf("ESP8266 测试\r\n");
while(ESP8266_SendCmd("AT+CWMODE=1\r\n", "OK"))//设置工作模式为STA
DelayXms(200);
while(ESP8266_SendCmd("AT+CWDHCP=1,1\r\n", "OK"))
DelayXms(200);
ESP8266_SendCmd(ESP8266_WIFI_INFO, "OK");
DelayXms(5000);
/*网络设备接入Broker*/
while(ESP8266_SendCmd("AT+MQTTUSERCFG=0,1,\"ALICLIENTLD\",\""ALI_USERNAME"\",\""ALI_PASSWD"\",0,0,\"\"\r\n","OK")){}
DelayXms(1000);
while(ESP8266_SendCmd("AT+MQTTCONN=0,\""ALI_MQTT_HOSTURL"\",1883,1\r\n","OK")){}
DelayXms(1000);
MQTT_Sub(MQTT_TOPIC_DEVICE_RECV, 0);
}
中断接收函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart == UART_ESP8266) {
ESP8266_RxCallBack();
}
}
//==========================================================
// 函数名称: USART2_IRQHandler
//
// 函数功能: 串口2收发中断
//
// 入口参数: 无
//
// 返回参数: 无
//
// 说明:
//==========================================================
void ESP8266_RxCallBack(void)
{
if(esp8266_cnt >= sizeof(esp8266_buf)) esp8266_cnt = 0; //防止串口被刷爆
esp8266_buf[esp8266_cnt++] = rx_data;
HAL_UART_Receive_IT(UART_ESP8266, &rx_data, 1);
}
MQTT功能函数
char str_send[1024];
//Publish MQTT message in string
void MQTT_Pub(char *topic, char *payload)
{
sprintf(str_send, "AT+MQTTPUB=0,\"%s\",\"%s\",0,0\r\n", topic, payload);
WIFI_Send_Bytes((uint8_t *)str_send, strlen(str_send));
//HAL_Delay(500);
printf("publish %s end\r\n", str_send);
}
void MQTT_PubUint8(char *topic, uint8_t payload)
{
char str[32] = {0};
sprintf(str, "%u", payload);
MQTT_Pub(topic, str);
}
void MQTT_PubUint16(char *topic, uint16_t payload)
{
char str[32] = {0};
sprintf(str, "%u", payload);
MQTT_Pub(topic, str);
}
void MQTT_PubUint32(char *topic, uint32_t payload)
{
char str[32] = {0};
sprintf(str, "%lu", payload);
MQTT_Pub(topic, str);
}
void MQTT_PubFloat(char *topic, float payload)
{
char str[32] = {0};
sprintf(str, "%f", payload);
MQTT_Pub(topic, str);
}
void MQTT_PubDouble(char *topic, double payload)
{
char str[32] = {0};
sprintf(str, "%f", payload);
MQTT_Pub(topic, str);
}
void MQTT_Sub(char *topic, uint8_t Qos)
{
char str[256];
sprintf(str, "AT+MQTTSUB=0,\"%s\",%d\r\n", topic, Qos);
//printf("\r\nsubscribe topic: %s\r\n", topic);
WIFI_Send_Bytes((uint8_t *)str, strlen(str));
}
void MQTT_UnSub(char *topic)
{
char str[256];
sprintf(str, "AT+MQTTUNSUB=0,\"%s\"\r\n", topic);
WIFI_Send_Bytes((uint8_t *)str, strlen(str));
}
//Close the MQTT Connection
void MQTT_Close(char *topic)
{
WIFI_Send_Bytes((uint8_t *)"AT+MQTTCLEAN=0\r\n", 16);
}
mqtt_recv_t mqtt_recv = {
.len = 0,
.json = {0},
};
1.打开 MQTT.fx,点击齿轮状的设置按钮,填写 Broker Address,Port 等,再到 User Credentials 里填写用户名和密码,OK,Connect
可以看到,在MQTT.fx软件上收到了ESP8266发布的STM32/string和STM32/uint8两个消息
同样的,可以在MQTT.fx上发送
void sys_data_recv(void)
{
printf("recv :%s\r\n", esp8266_buf);
if (strstr((const char *)esp8266_buf, MQTT_TOPIC_DEVICE_RECV))
{
printf("recv :%s\r\n", esp8266_buf);
/*获取发来的信息*/
char msg[256];
/*获取json字符串*/
sscanf((const char *)esp8266_buf, "+MQTTSUBRECV:0,\"iotled\",%d,%s", \
&mqtt_recv.len, mqtt_recv.json);
printf("mqtt_recv.len :%d\r\n", mqtt_recv.len);
if (strstr(mqtt_recv.json, "led1=1"))
{
HAL_GPIO_WritePin(LD1_GPIO_Port, LD1_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_SET);
printf("led1 on\r\n");
return ;
}
if (strstr(mqtt_recv.json, "led1=0"))
{
HAL_GPIO_WritePin(LD1_GPIO_Port, LD1_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_SET);
printf("led1 off\r\n");
return ;
}
if (strstr(mqtt_recv.json, "led2=1"))
{
HAL_GPIO_WritePin(LD1_GPIO_Port, LD1_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET);
printf("led2 on\r\n");
return ;
}
if (strstr(mqtt_recv.json, "led2=0"))
{
HAL_GPIO_WritePin(LD1_GPIO_Port, LD1_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_SET);
printf("led2 off\r\n");
return ;
}
if (strstr(mqtt_recv.json, "led=1"))
{
HAL_GPIO_WritePin(LD1_GPIO_Port, LD1_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET);
printf("led1 led2 on\r\n");
return ;
}
if (strstr(mqtt_recv.json, "led=0"))
{
HAL_GPIO_WritePin(LD1_GPIO_Port, LD1_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_SET);
printf("led1 led2 off\r\n");
return ;
}
}
}
1.只点亮LED1,只需发送led1=1
满足实验要求
2.熄灭LED1,发送led1=0
可以看到LED1已经熄灭
3,只点亮LED2,发送led2=1
可以看到LED2点亮
4,熄灭LED2,发送led2=0
可以看到LED2熄灭
5.同时点亮LED1和LED2,发送led=1
可以看到LED1和LED2同时点亮
这样就完成了ESP8266通过MQTT协议上传数据,同时通过电脑端的MQTTfx软件来远程点灯!MQTTfx软件已经放到附件里了,直接下载使用
我比较喜欢用手机MQTT工具来操作,因为手机无法展示效果,只能录屏,除非有两个手机
这是我用手机端接受的数据,和电脑短的MQTTfx软件效果一模一样,还更便捷方便!人在任何地方都能控制,比电脑更好
|