智能环境采集
1. 智能环境采集
智能环境采集由WiFi模组和DHT11温湿度传感器组成:本实例中利用ESP8266模组作为一个TCP Server,通过STA模式将ESP8266连接到路由器中;PC或者手机连接到相同的路由器后,建立TCP客户端,通过发送相应的字符到TCP Server来读取当前温湿度数据,从而实现智能环境采集的功能
DHT11温湿度传感器的介绍:请参考DHT11温湿度传感器一文
2. 智能环境采集功能实现
硬件连接:采用GPIO5驱动DHT11;DHT11电源VCC连接到VIN,DHT11GND连接到GND
实验步骤如下:
–> 在ESP8266_RTOS_SDK目录下新建dht11文件夹,把tcpserver实验中的tcpserver目录下所有文件拷贝到该文件夹中
–> 在user目录下新建dht11.c文件,并添加如下代码
#define DHT11_PIN_NUM 5
#define DHT11_PIN_BIT GPIO_Pin_5
#define DHT11_SET 1
#define DHT11_RESET 0
//温湿度定义
uint8 ucharT_data_H=0,ucharT_data_L=0;
uint8 ucharRH_data_H=0,ucharRH_data_L=0;
uint8 ucharcheckdata=0;
//温湿传感启动
static void DHT11_TEST(void){
uint8 ucharT_data_H_temp,ucharT_data_L_temp;
uint8 ucharRH_data_H_humidity,ucharRH_data_L_humidity;
uint8 ucharcheckdata_temp;
uint8 ucharFLAG = 0,uchartemp=0;
uint8 ucharcomdata;
uint8 i;
taskENTER_CRITICAL();
{
//拉低18ms
GPIO_OUTPUT_SET(DHT11_PIN_NUM,DHT11_RESET);
os_delay_us(18*1000);
GPIO_OUTPUT_SET(DHT11_PIN_NUM,DHT11_SET);
//拉高40us
GPIO_AS_INPUT(DHT11_PIN_BIT);
os_delay_us(4*10);
}
//等待拉低80us应答
if(!GPIO_INPUT_GET(DHT11_PIN_NUM)){
//等待拉高应答
ucharFLAG=2;
while((!GPIO_INPUT_GET(DHT11_PIN_NUM))&&ucharFLAG++);
ucharFLAG=2;
//等待拉低传输数据
while(GPIO_INPUT_GET(DHT11_PIN_NUM)&&ucharFLAG++);
for(i=0;i<8;i++){
//等待拉高
ucharFLAG=2;
while((!GPIO_INPUT_GET(DHT11_PIN_NUM))&&ucharFLAG++);
//延时30us
os_delay_us(3*10);
//赋值当前bit为0
uchartemp=0;
//如果继续为高,则赋值为bit为1
if(GPIO_INPUT_GET(DHT11_PIN_NUM))uchartemp=1;
//判断是否超时
ucharFLAG=2;
while(GPIO_INPUT_GET(DHT11_PIN_NUM)&&ucharFLAG++);
//超时退出
if(ucharFLAG==1)break;
//左移1位。进行赋值
ucharcomdata<<=1;
ucharcomdata|=uchartemp;
}
ucharRH_data_H_humidity = ucharcomdata;
for(i=0;i<8;i++){
ucharFLAG=2;
while((!GPIO_INPUT_GET(DHT11_PIN_NUM))&&ucharFLAG++);
os_delay_us(3*10);
uchartemp=0;
if(GPIO_INPUT_GET(DHT11_PIN_NUM))uchartemp=1;
ucharFLAG=2;
while(GPIO_INPUT_GET(DHT11_PIN_NUM)&&ucharFLAG++);
if(ucharFLAG==1)break;
ucharcomdata<<=1;
ucharcomdata|=uchartemp;
}
ucharRH_data_L_humidity = ucharcomdata;
for(i=0;i<8;i++){
ucharFLAG=2;
while((!GPIO_INPUT_GET(DHT11_PIN_NUM))&&ucharFLAG++);
os_delay_us(3*10);
uchartemp=0;
if(GPIO_INPUT_GET(DHT11_PIN_NUM))uchartemp=1;
ucharFLAG=2;
while((GPIO_INPUT_GET(DHT11_PIN_NUM))&&ucharFLAG++);
if(ucharFLAG==1)break;
ucharcomdata<<=1;
ucharcomdata|=uchartemp;
}
ucharT_data_H_temp = ucharcomdata;
for(i=0;i<8;i++){
ucharFLAG=2;
while((!GPIO_INPUT_GET(DHT11_PIN_NUM))&&ucharFLAG++);
os_delay_us(3*10);
uchartemp=0;
if(GPIO_INPUT_GET(DHT11_PIN_NUM))uchartemp=1;
ucharFLAG=2;
while((GPIO_INPUT_GET(DHT11_PIN_NUM))&&ucharFLAG++);
if(ucharFLAG==1)break;
ucharcomdata<<=1;
ucharcomdata|=uchartemp;
}
ucharT_data_L_temp = ucharcomdata;
for(i=0;i<8;i++){
ucharFLAG=2;
while((!GPIO_INPUT_GET(DHT11_PIN_NUM))&&ucharFLAG++);
os_delay_us(3*10);
uchartemp=0;
if(GPIO_INPUT_GET(DHT11_PIN_NUM))uchartemp=1;
ucharFLAG=2;
while((GPIO_INPUT_GET(DHT11_PIN_NUM))&&ucharFLAG++);
if(ucharFLAG==1)break;
ucharcomdata<<=1;
ucharcomdata|=uchartemp;
}
ucharcheckdata_temp = ucharcomdata;
uchartemp=(ucharT_data_H_temp+ucharT_data_L_temp+ucharRH_data_H_humidity+ucharRH_data_L_humidity);
if(uchartemp==ucharcheckdata_temp){
ucharT_data_H = ucharT_data_H_temp;
ucharT_data_L = ucharT_data_L_temp;
ucharRH_data_H = ucharRH_data_H_humidity;
ucharRH_data_L = ucharRH_data_L_humidity;
ucharcheckdata = ucharcheckdata_temp;
}
}
else{ //没用成功读取,返回0
ucharT_data_H = 0;
ucharT_data_L = 0;
ucharRH_data_H = 0;
ucharRH_data_L = 0;
}
taskEXIT_CRITICAL();
}
//ATaskDht11 任务
void ATaskDht11( void *pvParameters ) {
for(;;){
vTaskDelay(500);
DHT11_TEST();
printf("ucharT_data_H = %d\n",ucharT_data_H);
printf("ucharRH_data_H = %d\n",ucharRH_data_H);
}
vTaskDelete( NULL );
}
//Dht11_init 初始化
void Dht11_init(void){
xTaskCreate(ATaskDht11, "ATaskDht11", 256, NULL, 4, NULL);
}
–> 在include目录下新建dht11.h文件,并添加声明
void DHT11_TEST(void);//用于温湿度数据采集
void ATaskDht11( void *pvParameters );//用于任务实现
void Dht11_init(void);//用于任务创建
–> 在tcpserver下完成readdata解析
void ATaskTcpServer( void *pvParameters ){
int iVariableExample = 0;
int fd = -1;
int cfd = -1;
int NetTimeOnt = 20000;
int ret;
struct sockaddr_in ServerAddr;
struct sockaddr ClientAddr;
socklen_t ClientAddrlen = sizeof(struct sockaddr);
char Tcpmsg[48];
char data[30];
STATION_STATUS StaStatus;
do{
StaStatus = wifi_station_get_connect_status();
vTaskDelay(100);
}while(StaStatus != STATION_GOT_IP);
fd = socket(PF_INET,SOCK_STREAM,0);
if(fd == -1){
printf("get socket fail!\n");
vTaskDelete(NULL);
return;
}
setsockopt(fd,SOL_SOCKET,SO_RCVTIMEO,&NetTimeOnt,sizeof(int));
memset(&ServerAddr,0,sizeof(ServerAddr));
ServerAddr.sin_family = AF_INET;
ServerAddr.sin_addr.s_addr = INADDR_ANY;
ServerAddr.sin_port = htons(SERVERPORT);
ServerAddr.sin_len = sizeof(ServerAddr);
if(bind(fd,(struct sockaddr*)&ServerAddr,ServerAddr.sin_len) != 0){
printf("bind socket fail!\n");
vTaskDelete(NULL);
return;
}
if(listen(fd,5) != 0){
printf("listen socket fail!\n");
vTaskDelete(NULL);
return;
}
for(;;){
cfd = accept(fd,&ClientAddr,&ClientAddrlen);
if(cfd != -1){
ret = recv(cfd,Tcpmsg,48,0);
if(ret > 0){
printf("TcpClient:%s\n",Tcpmsg);
if(strncmp(Tcpmsg,"readdata",8) == 0){
sprintf(data,"Temp=%d\nhum=%d",ucharT_data_H,ucharRH_data_H);
send(cfd,data,strlen(data),0);
}
else
send(cfd,"cmd is error!",sizeof("cmd is error!"),0);
}
else{
printf("TcpClient data is no!\n");
}
}
close(cfd);
}
vTaskDelete( NULL );
}
–> 在user_main.c文件中的user_init()函数下添加如下代码
#define SSID "Hotspot" //ESP8266要加入的无线网
#define PASSWORD "88888888"
void ICACHE_FLASH_ATTR
user_init(void){
printf("SDK version:%s\n", system_get_sdk_version());
Led_init();
wifi_set_opmode(STATION_MODE);
struct station_config *config = (struct station_config *)\
zalloc(sizeof(struct station_config));
sprintf(config->ssid,SSID);
sprintf(config->password,PASSWORD);
wifi_station_set_config(config);
free(config);
wifi_station_set_auto_connect(TRUE);
TcpServer_init();
Dht11_init();
xTaskCreate(ATaskLed, "LED", 256, NULL, 2, NULL);
}
–> 在ESP8266编译器中编译完成,烧写bin文件到ESP8266,模组复位后,打开串口助手,PC端建立TCP客户端,与ESP8266服务器连上后,发送readdata即可读取温湿度信息