目录
通信模块选择
WiFi模块
WIFI模块选择ESP8266S01(MQTT固件库),选择MQTT固件库既支持MQTT指令也支持TCP指令,对于维护和开发有便利之处,模块大致在10元左右,建议选择安可信官网购买
蓝牙模块
蓝牙模块选择HC-08,可以满足基本的开发需求
基本框架
1、内网通信(近距离通信)
STM32与蓝牙模块进行连接,在不用远程通信的情况下,直接使用蓝牙透传模式,手机蓝牙上位机进行接收数据,用户可以直接通过APP观测数据
2、外网通信(远程通信)
WiFi模块先连接路由器或WiFi热点进行联网,通过MQTT协议连接上云平台,按照云平台协议规则将数据发送至平台,平台应用层对数据进行展示(应用APP,可视化界面等等)
3、关于WiFi配网以及云平台验证问题
①对于WiFi来说,我们需要将WiFi名称与密码送入WiFi模块进行配网,直接使用STM32写死程序不利于后期的维护与批量生产,所以采用蓝牙配网的模式较为合适,蓝牙先与STM32连接进行消息透传,我们通过APP输入WiFi名称与密码,STM32对数据进行解析,获取有用的数据段,再将WiFi名称与密码发送给WIFI模块进行配网
②MQTT协议需要设备ID进行连接,WiFi模块获取唯一ID较为复杂,这里我们获取STM32的设备ID作为连接云平台所需ID,我们只需要在云平台批量添加STM32设备ID,STM32烧录程序后就直接获取ID,通过ID去连接云平台,在开发的时候我们就不用因为ID问题重复修改代码
4、关于蓝牙名称问题
实际开发中,每一套设备都会装一套蓝牙模块,由于蓝牙模块初始化名称都为HC-08,连接会出现误连情况,所以在初次使用时,我们需要设置一个唯一的蓝牙名称,这里采用STM32的ID作为蓝牙名称,保证名称的唯一性,并且符合一机一密的规则
模块连接图示
STM32串口1作为调试,串口2连接蓝牙模块,串口3连接WiFi模块,WiFi模块的EN引脚直接连接3.3V,STM32定义3个引脚连接WiFi模块的RST,蓝牙模块的KEY引脚和STA引脚
重要驱动开发
STM32的ID获取
int Get_ChipID(void)
{
chipid.id[0] = *(__I uint32_t *)(0X1FFFF7F0 + 0x00);
chipid.id[1] = *(__I uint32_t *)(0X1FFFF7F0 + 0x04);
chipid.id[2] = *(__I uint32_t *)(0X1FFFF7F0 + 0x08);
sprintf((char *)(chipid.ID_buff),"%08X%08X",chipid.id[1],chipid.id[2]);
if((char *)chipid.ID_buff == NULL)
{
return 0;
}
return 1;
}
蓝牙修改名称
void HC08_AT_Init(void)
{
if(HC08_SetRole(HC08_SLAVE_ROLE) == HC08_ACK_OK)
{
printf("AT+ROLE OK\n");
delay_ms(500);
}
if(HC08_SetNAME((char *)chipid.ID_buff) == HC08_ACK_OK )
{
printf("AT+NAME OK\n");
delay_ms(500);
}
}
WIFI配网以及蓝牙通信协议解析
void HC08_RecvProcess(void)
{
char *local;
hc08_recv_complete = 0;
hc08_recv_len = hc08_rx_index;
hc08_rx_index = 0;
//´òÓ¡ÐÅÏ¢
printf((const char *)hc08_recv_buff);
printf("\n");
if((local = strstr((char *)hc08_recv_buff,"ID")) != NULL )
{
if(local[2] == '1')
{
strncpy(ID,local+4,((int)local[3] - 48));
printf("WIFI ID is %s\n",ID);
flag1 = 1;
}
if(local[2] == '2')
{
strncpy(ID,local+5,((int)local[3]-48)*10+((int)local[4]-48));
printf("WIFI ID is %s\n",ID);
flag1 = 1;
}
}
if((local = strstr((char *)hc08_recv_buff,"PS")) != NULL )
{
if(local[2] == '1')
{
strncpy(PASSWORD,local+4,((int)local[3] - 48));
printf("WIFI Password is %s\n",PASSWORD);
flag2 = 1;
}
if(local[2] == '2')
{
strncpy(PASSWORD,local+5,((int)local[3]-48)*10+((int)local[4]-48));
printf("WIFI Password %s\n",PASSWORD);
flag2 = 1;
}
}
printf("\r\n");
HC08_RecvBuff_Clear();
}
WiFi连接云平台
while(1)
{
if(esp_connect_ok != ESP_STA_CONNECTED)
{
ESP_Client_ConnectServer(0,(u8 *)"",(u8 *)"",(u8 *)ID,(u8 *)PASSWORD);
connect_ok = MQTT_IDLE;
}
else
{
if(connect_ok == MQTT_IDLE)
{
HF_Mqtt_Connect();
connect_ok = MQTT_WAIT;
}
}
MQTT_RecvProcess();
if(urc_update == 1)
{
urc_update = 0;
MQTT_PUB_Init();
if(connect_ok == MQTT_RUN)
{
Mqtt_Publish(mqtt_send.topic,2,0,(uint8_t *)mqtt_send.data,strlen(mqtt_send.data));
printf("MQTT is PUBing\n");
}
}
if(ping_start == 1)
{
ping_start = 0;
if(connect_ok == MQTT_RUN)
{
Mqtt_Ping();
printf("MQTT-PING\n");
}
}
}
实验效果
蓝牙已经连接(WiFi请求配网)
APP发送WiFi名称和密码信息
WIFI连接云平台
云端查看设备信息
蓝牙APP查看设备信息