通过WIFI或GPRS上传温度到云端
本篇博客将介绍如何使用WIFI或GPRS模块将温度数据上传到云端。我们将涵盖连接网络的过程、上传数据的过程以及相关代码。
准备工作
在开始之前,我们需要准备以下材料:
- STM32F4开发板
- 温度传感器(例如18B20)
- WIFI模块或GPRS模块
- 连接线
接下来,按照以下步骤进行准备:
- 将温度传感器连接到STM32F4开发板,确保传感器正常工作并能够读取温度数据。
- 将WIFI模块或GPRS模块连接到STM32F4开发板,并进行相应的配置。
完成上述准备后,我们可以开始编写代码。
实现过程
根据原理图,我们需要进行一下设置
- 配置串口1
- 配置AHB2
- DMA2
- APB2
1.串口初始化
首先,我们需要初始化串口以便与
ESP8266
进行通信。
在STM32F4上,我们可以使用UART来与ESP8266进行串口通信。以下是一个示例代码片段,用于初始化串口:
修改文件:usart.c
void USART1_Config(void)
{ NVIC_InitTypeDef NVIC_InitStructure;GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); //串口1时钟使能RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); // GPIOB时钟GPIO_PinAFConfig(GPIOB,GPIO_PinSource6,GPIO_AF_USART1); //PB10复用为USART1
GPIO_PinAFConfig(GPIOB,GPIO_PinSource7,GPIO_AF_USART1); //PA11复用为USART1GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //PA2-TXGPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化PB10//USART3_RX PB11GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化PB11USART_InitStructure.USART_BaudRate = 115200;//波特率一般设置为9600;USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式USART_Init(USART1, &USART_InitStructure); //初始化串口 1USART_Cmd(USART1, ENABLE); //使能串口 //使能接收中断//设置中断优先级NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;//抢占优先级3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启中断 TIM2_Init(1000-1,7200-1); //中断USART1_RX_STA=0; //清零TIM_Cmd(TIM2,ENABLE); //关闭定时器2}
2. 网络配置
- 连接服务器
- 配置网络
在连接WIFI之前,我们需要配置ESP8266的网络参数。以下是一个示例代码片段,用于配置ESP8266的网络参数:
#include "esp8266.h"
#include "string.h"
#include "usart.h"
#include "stm32f4xx.h"
#include "sys1.h"
#include "delay.h"
#include "stdlib.h"char flag = 0;
void esp8266_Init(){cs_init();esp8266_quit_trans();esp8266_start_trans(); //esp8266进行初始化wifigotcompleteflag=1;
}//ESP8266模块和PC进入透传模式
void esp8266_start_trans(void)
{u8 *str;//设置工作模式 1:station模式 2:AP模式 3:兼容 AP+station模式while(esp8266_send_cmd("AT+CWMODE=1","OK",50)){printf("AT+CWMODE_ERR\r\n");}printf("AT+CWMODE_OK\r\n");//让Wifi模块重启的命令while(esp8266_send_cmd("AT+RST","ready",50));{printf("AT+RST_ERR\r\n");}printf("AT+RST_OK\r\n");delay_ms(1000); //延时3S等待重启成功delay_ms(1000);printf("delay_OK\r\n");while(esp8266_send_cmd("AT+CWJAP=\"wifi名称\",\"WiFi密码\"","WIFI GOT IP",200)){printf("WIFI GOT IP_ERR\r\n");}//=0:单路连接模式 =1:多路连接模式while(esp8266_send_cmd("AT+CIPMUX=0","OK",30)){printf("AT+CIPMUX_ERR\r\n");}//建立TCP连接 这四项分别代表了 要连接的ID号0~4 连接类型 远程服务器IP地址 远程服务器端口号while(esp8266_send_cmd("AT+CIPSTART=\"TCP\",\"远程服务器ip\",远程服务器端口号","CONNECT",200)){printf("AT+CIPSTART_ERR\r\n");}//是否开启透传模式 0:表示关闭 1:表示开启透传while(esp8266_send_cmd("AT+CIPMODE=1","OK",200)){printf("AT+CIPMODE_ERR\r\n");}//透传模式下 开始发送数据的指令 这个指令之后就可以直接发数据了while(esp8266_send_cmd("AT+CIPSEND","OK",50)){printf("AT+CIPSEND_ERR\r\n");}
printf("连接服务器完成\r\n");
}u8 esp8266_quit_trans(void)
{u8 result=1;u1_printf("+++");delay_ms(1000); //等待500ms太少 要1000ms才可以退出result=esp8266_send_cmd("AT","OK",200);//退出透传判断.if(result)printf("quit_trans failed!");elseprintf("quit_trans success!");return result;
}//向ESP8266发送命令
//cmd:发送的命令字符串;ack:期待的应答结果,如果为空,则表示不需要等待应答;waittime:等待时间(单位:10ms)
//返回值:0,发送成功(得到了期待的应答结果);1,发送失败
u8 esp8266_send_cmd(u8 *cmd,u8 *ack,u16 waittime)
{u8 res=0; USART1_RX_STA=0;u1_printf("%s\r\n",cmd); //发送命令if(ack&&waittime) //需要等待应答{while(--waittime) //等待倒计时{delay_ms(20);if(USART1_RX_STA&0X8000)//接收到期待的应答结果{if(esp8266_check_cmd(ack)){printf("ack:%s\r\n",(u8*)ack);break;//得到有效数据 }USART1_RX_STA=0;} }if(waittime==0)res=1; }return res;
} //ESP8266发送命令后,检测接收到的应答
//str:期待的应答结果
//返回值:0,没有得到期待的应答结果;其他,期待应答结果的位置(str的位置)
u8* esp8266_check_cmd(u8 *str)
{char st[20];char *strx=0;if(USART1_RX_STA&0X8000) //接收到一次数据了{ USART1_RX_BUF[USART1_RX_STA&0X7FFF]=0;//添加结束符strx=strstr((const char*)USART1_RX_BUF,(const char*)str);} return (u8*)strx;
}//向ESP8266发送数据
//cmd:发送的命令字符串;waittime:等待时间(单位:10ms)
//返回值:发送数据后,服务器的返回验证码
u8* esp8266_send_data(u8 *cmd,u16 waittime)
{char temp[5];char *ack=temp;USART1_RX_STA=0;u1_printf("%s",cmd); //发送命令if(waittime) //需要等待应答{while(--waittime) //等待倒计时{delay_ms(10);if(USART1_RX_STA&0X8000)//接收到期待的应答结果{USART1_RX_BUF[USART1_RX_STA&0X7FFF]=0;//添加结束符ack=(char*)USART1_RX_BUF;//printf("ack:%s\r\n",(u8*)ack);USART1_RX_STA=0;break;//得到有效数据 } }}return (u8*)ack;
}
extern u8 wifigotcompleteflag;char stehttpbehind[500]=" HTTP/1.1\r\n\
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9\r\n\
Accept-Encoding: gzip, deflate\r\n\
Accept-Language: zh-CN,zh;q=0.9\r\n\
Connection: keep-alive\r\n\
Host: 192.168.0.109:8001\r\n\
Upgrade-Insecure-Requests: 1\r\n\
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36\r\n\r\n";void esp8266_http_send(char *sb){char stehttp[600]="GET /";strcat((char*)stehttp,sb);strcat((char*)stehttp,stehttpbehind);u1_printf("%s",stehttp);}
int fflag;
void Wifi_data(char *Wifi_data){char sp[20];char* Point=NULL;if(strstr((const char *)Wifi_data, (const char *)"ctrl=")!=NULL)//接收到设置阈值命令{Point = strstr((const char *)Wifi_data, (const char *)"ctrl=")+5;memcpy(sp, Point, 3);fflag=atoi(sp); }}
void cs_init(void){GPIO_InitTypeDef GPIO_InitStructure;RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);sys_gpio_set(GPIOE, SYS_GPIO_PIN7,SYS_GPIO_MODE_OUT, SYS_GPIO_OTYPE_OD, SYS_GPIO_SPEED_MID, SYS_GPIO_PUPD_PU);GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;/* 数据端口输出 */GPIO_Init(GPIOE, &GPIO_InitStructure);GPIO_SetBits(GPIOE, GPIO_Pin_7 );
}
3. 温度上传
温度上传的过程涉及到从温度传感器读取温度值,并将其发送到云端。
在你的已完成的温度获取模块中,可能有相应的函数来读取温度值。以下是一个示例代码片段,用于上传温度值到云端:
while (1){temperature = ds18b20_get_temperature();TEMP_SEND=(float)temperature/10;printf("temp:%f",TEMP_SEND);sprintf(send_string,"temp:%f",TEMP_SEND);printf("°´¼ü£º%d",KEYD6);u1_printf(send_string);}
4.打开网络助手
打开网络调试助手(NetAssist
软件)设置为TCP Server
数据将会被上传到这里