WIFI模块(esp-01s)实现天气预报代码实现

news2024/12/23 10:49:21

目录

前言

实现图片

一、串口编程的实现

二、发送AT指令

esp01s.c

esp01s.h

三、数据处理

1、初始化

2、cjson处理函数

3、核心控制代码 

四、修改堆栈大小


前言

实现图片

 前面讲解了使用AT指令获取天气与cjson的解析数据,本章综合将时间显示到屏幕

一、串口编程的实现

uint8_t rx_dat;
char rxdata[1000];
int rx_p = 0,rx_ppre = 0;

 

int fputc(int ch,FILE *f)
{
  //采用轮询方式发送1字节数据,超时时间设置为无限等待
  
  HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,HAL_MAX_DELAY);
  
  return ch;
}
int fgetc(FILE *f)
{
  uint8_t ch;
  // 采用轮询方式接收 1字节数据,超时时间设置为无限等待
  HAL_UART_Receive( &huart1,(uint8_t*)&ch,1, HAL_MAX_DELAY );
  return ch;
}

// 串口中断接收数据
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart->Instance == USART1)
	{
        
        // if(rx_p >= sizeof(rxdata))  rx_p = 0;       //防止串口被刷爆
        rxdata[rx_p ++] = rx_dat;
		HAL_UART_Receive_IT(&huart1,&rx_dat,1);
	}
}

二、发送AT指令

esp01s.c

#include "esp01s.h"
#include "usart.h"

uint8_t rx_dat;
char rxdata[1000];
int rx_p = 0,rx_ppre = 0;

unsigned char Time_buff[1000];

int fputc(int ch,FILE *f)
{
  //采用轮询方式发送1字节数据,超时时间设置为无限等待
  
  HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,HAL_MAX_DELAY);
  
  return ch;
}
int fgetc(FILE *f)
{
  uint8_t ch;
  // 采用轮询方式接收 1字节数据,超时时间设置为无限等待
  HAL_UART_Receive( &huart1,(uint8_t*)&ch,1, HAL_MAX_DELAY );
  return ch;
}

// 串口中断接收数据
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart->Instance == USART1)
	{
        
        // if(rx_p >= sizeof(rxdata))  rx_p = 0;       //防止串口被刷爆
        rxdata[rx_p ++] = rx_dat;
		HAL_UART_Receive_IT(&huart1,&rx_dat,1);
	}
}


//清空缓存
void esp01s_clear(void)
{
    memset(rxdata,0,sizeof(rxdata));
    rx_p = 0;
}

//esp01s等待接收完成 0成功 1失败
int esp01s_waitrecive(void)
{
    if(rx_p == 0) 							//如果接收计数为0 则说明没有处于接收数据中,所以直接跳出,结束函数
        return 1;
 
    if(rx_p == rx_ppre)				//如果上一次的值和这次相同,则说明接收完毕
    {
        rx_p = 0;							//清0接收计数
 
        return 0;								//返回接收完成标志
    }
 
    rx_ppre = rx_p;					//置为相同
 
    return 1;								//返回接收未完成标志
}

//esp01s发送指令   0成功 1失败
int esp01s_sendcmd(char *cmd,char *res)
{
    unsigned char timeout = 250;

    printf(cmd);
    while(timeout --)
    {
        if(esp01s_waitrecive() == 0)            //如果收到数据
        {
            if(strstr(rxdata,res) != NULL)      //如果检索到关键词
            {
                esp01s_clear();
                return 0;
            }
        }
        HAL_Delay(10);
    }
    return 1;
}

//esp01s发送数据
void esp01s_senddata(char *data)
{
    esp01s_clear();								//清空接收缓存

    if(!esp01s_sendcmd("AT+CIPSEND\r\n",">"))				//收到‘>’时可以发送数据
    //printf(data);
    {
        /*发送请求数据*/
        printf(data);               	//发送设备连接请求数据
    }

}

unsigned char *ESP8266_GetIPD_GET(unsigned short timeOut, uint8_t *buff) //这里我用了一个全局变量将esp8266buf储存到这个全局变量里面
{
    do
    {
        HAL_Delay(5);
    }
    while(timeOut--);
 
    strcpy((char*)buff, (char*)rxdata);
    return buff;
}


esp01s.h

#ifndef __ESP01S_H
#define __ESP01S_H

#include "main.h"
#include "string.h"
#include "stdio.h"

extern uint8_t rx_dat;
extern char rxdata[1000];
extern int rx_p,rx_ppre;
extern unsigned char Time_buff[1000];

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);
void esp01s_clear(void);
int esp01s_waitrecive(void);
int esp01s_sendcmd(char *cmd,char *res);
void esp01s_senddata(char *data);
unsigned char *ESP8266_GetIPD_GET(unsigned short timeOut, uint8_t *buff);

#endif 

三、数据处理

1、初始化

esp01s_clear();
  while(esp01s_sendcmd("+++",""));
  while(esp01s_sendcmd("AT\r\n", "OK"));
  while(esp01s_sendcmd("AT+RST\r\n", "OK"));
  while(esp01s_sendcmd("AT+CWMODE=1\r\n", "OK"));
  while(esp01s_sendcmd("AT+CIPMUX=0\r\n", "OK"));
  while(esp01s_sendcmd("AT+CWJAP=\"meng\",\"20010131\"\r\n", "WIFI GOT IP"));
  while(esp01s_sendcmd("AT+CIPSTART=\"TCP\",\"api.seniverse.com\",80\r\n","CONNECT"));
  // while(esp01s_sendcmd("AT+CIPSTART=\"TCP\",\"api.pinduoduo.com\",80\r\n","CONNECT"));
  while(esp01s_sendcmd("AT+CIPMODE=1\r\n", "OK"));

  HAL_GPIO_WritePin(led_blue_GPIO_Port,led_blue_Pin,GPIO_PIN_RESET);

2、cjson处理函数

int test2_jiexi()
{
  char *data;
  cJSON *json=NULL,*arrayItem=NULL,*object=NULL,*subobject=NULL,*nowobject=NULL,*mingobject=NULL,*houobject=NULL,*nowtext=NULL,*nowhigh=NULL,*nowlow=NULL,*mingtext=NULL,*minghigh=NULL,*minglow=NULL,*houtext=NULL,*houhigh=NULL,*houlow=NULL;
  cJSON *nowdate = NULL,*mingdate = NULL,*houdate = NULL;
  data = (char*)te;
  json = cJSON_Parse(data);    //解析数据包
  // if(json == NULL)                           //解析失败
  // {
  //   sprintf(text,"Error:%s",cJSON_GetErrorPtr());
  //   lcd_showstr(0,0,(uint8 *)text,WHITE);
  //   return 1;
  // }
  if(json)
  { 
    HAL_GPIO_WritePin(led_red_GPIO_Port,led_red_Pin,GPIO_PIN_RESET);
    if((arrayItem = cJSON_GetObjectItem(json,"results")) != NULL)     //匹配字符串results,获取数组内容
    {
      HAL_GPIO_WritePin(led_red_GPIO_Port,led_red_Pin,GPIO_PIN_RESET);
      int size = cJSON_GetArraySize(arrayItem);
      // sprintf(text,"size is %d",size);
      // lcd_showstr(0,0,(uint8 *)text,WHITE);
      if((object = cJSON_GetArrayItem(arrayItem,0)) != NULL)         //results第0位
      {
        //if((subobject = cJSON_GetObjectItem(object,"location")) != NULL);   //位置信息
        if((subobject = cJSON_GetObjectItem(object,"daily")) != NULL)      //天气信息
        {
          int tianqi_size = cJSON_GetArraySize(subobject);
          // sprintf(text,"size is %d",tianqi_size);
          // lcd_showstr(0,1,(uint8 *)text,WHITE);
          if((nowobject = cJSON_GetArrayItem(subobject,0)) != NULL)        //今天
          {
            nowtext = cJSON_GetObjectItem(nowobject,"text_day");            //天气状况
            nowhigh = cJSON_GetObjectItem(nowobject,"high");                //高温
            nowlow = cJSON_GetObjectItem(nowobject,"low");                  //低温
            nowdate = cJSON_GetObjectItem(nowobject,"date");                //日期

            sprintf(text,"%s:",nowdate->valuestring);
            lcd_showstr(0,0,(uint8 *)text,WHITE);
            sprintf(text,"%s %sC/%sC",nowtext->valuestring,nowhigh->valuestring,nowlow->valuestring);
            lcd_showstr(20,1,(uint8 *)text,WHITE);
          }
          if((mingobject = cJSON_GetArrayItem(subobject,1)) != NULL)        //明天
          {
            mingtext = cJSON_GetObjectItem(mingobject,"text_day");            //天气状况
            minghigh = cJSON_GetObjectItem(mingobject,"high");                //高温
            minglow = cJSON_GetObjectItem(mingobject,"low");                  //低温
            mingdate = cJSON_GetObjectItem(mingobject,"date");                //日期

            sprintf(text,"%s:",mingdate->valuestring);
            lcd_showstr(0,3,(uint8 *)text,WHITE);
            sprintf(text,"%s %sC/%sC",mingtext->valuestring,minghigh->valuestring,minglow->valuestring);
            lcd_showstr(20,4,(uint8 *)text,WHITE);
          }
          if((houobject = cJSON_GetArrayItem(subobject,2)) != NULL)        //后天
          {
            houtext = cJSON_GetObjectItem(houobject,"text_day");            //天气状况
            houhigh = cJSON_GetObjectItem(houobject,"high");                //高温
            houlow = cJSON_GetObjectItem(houobject,"low");                  //低温
            houdate = cJSON_GetObjectItem(houobject,"date");                //日期

            sprintf(text,"%s:",houdate->valuestring);
            lcd_showstr(0,6,(uint8 *)text,WHITE);
            sprintf(text,"%s %sC/%sC",houtext->valuestring,houhigh->valuestring,houlow->valuestring);
            lcd_showstr(20,7,(uint8 *)text,WHITE);
          }
        }
        //if((subobject = cJSON_GetObjectItem(object,"last_update")) != NULL);      //更新信息
      }
    }
    
  } 
  cJSON_Delete(json);
  return 0;
}

3、核心控制代码 

u8g2_ClearBuffer(&u8g2);
    if(key[0].single_flag == 1)
    {
      key[0].single_flag = 0;
      // esp01s_senddata("GET http://api.pinduoduo.com/api/server/_stm\r\n");
      esp01s_senddata("GET https://api.seniverse.com/v3/weather/daily.json?key=S6H95GCCwULqmbSE8&location=weifang&language=en&unit=c&start=-1&days=4\r\n");
      
      te = ESP8266_GetIPD_GET(200, Time_buff); //将串口数据取出来

      esp01s_clear();//清除缓存数据
      HAL_Delay(500);
      while(esp01s_sendcmd("+++", ""));      /*退出透传模式,发送两次*/
      HAL_GPIO_WritePin(led_blue_GPIO_Port,led_blue_Pin,GPIO_PIN_SET);
    }
    
    // int num1 = strlen((char*) te);
    // sprintf(text,"%d",num1);
    // lcd_showstr(0,7,(uint8 *)text,WHITE);
    test2_jiexi();
    u8g2_SendBuffer(&u8g2);
    // lcd_clear(BLACK);

四、修改堆栈大小

在json处理长字符串时,需要修改堆栈大小(卡了好长时间)

将 Stack_Size与Heap_Size改大,程序正常运行

有需要的可以联系我,给工程代码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1263524.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python超级详细的变量命名规则

Python 需要使用标识符给变量命名,其实标识符就是用于给程序中变量、类、方法命名的符号(简单来说,标识符就是合法的名字)。 Python 语言的标识符必须以字母、下画线(_)开头,后面可以跟任意数目…

Python单元测试之道:从入门到精通的全面指南

在这篇文章中,我们会深入探讨Python单元测试的各个方面,包括它的基本概念、基础知识、实践方法、高级话题,如何在实际项目中进行单元测试,单元测试的最佳实践,以及一些有用的工具和资源 一、单元测试重要性 测试是软…

ELk部署,保姆级教学超详细!!!

Elk(Elasticsearch, Logstash, Kibana)是一套日志收集、存储和展示方案,是由Elastic公司开发的开源软件组合。 Elasticsearch:是一个分布式的搜索和分析引擎。它能够处理大量的数据,并提供快速、准确的搜索结果&#x…

在线 SQL 模拟器SQL Fiddle使用简介

在线 SQL 模拟器SQL Fiddle使用简介 有时候,我们想去验证 SQL语句,却缺少数据库环境,那该怎么办呢? 这时候在线 SQL 模拟器就有了用武之地。SQL 模拟器免安装,可以在网页直接运行 SQL 。 SQL Fiddle 支持 MySQL、Orac…

Stable Diffusion绘画系列【4】:可爱盲盒风人物

《博主简介》 小伙伴们好,我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源,可关注公-仲-hao:【阿旭算法与机器学习】,共同学习交流~ 👍感谢小伙伴们点赞、关注! 《------往期经典推…

数据结构——链式二叉树的实现(详解)

呀哈喽。我是结衣。 不知道大家的递归学到怎么样呢?如果大家的递归功底不是很好,那么我相信在学完这篇文章后大家一定会对递归有一个更深层次的了解的。 构造链式二叉树 在学习二叉树的基本操作前,需先要创建一棵二叉树,然后才能…

国标GB28181安防监控平台EasyCVR周界入侵AI算法检测方案

在城市管理和公共安全领域,安全视频监控的重要性日益凸显。AI视频智能分析平台基于深度学习和计算机视觉技术,利用AI入侵算法,能够实时、精准地监测周界入侵行为。 TSINGSEE青犀在视频监控及AI视频智能分析领域拥有深厚的技术积累和丰富的实…

2020年3月25日 Go生态洞察:Go、Go社区与疫情大流行

🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页——🐅🐾猫头虎的博客🎐 🐳 《面试题大全专栏》 🦕 文章图文…

2024年最受欢迎的项目管理工具盘点

十大项目管理系统包括:1.产品研发项目管理工具:PingCode;2.通用项目协作工具:Worktile;3.开源项目管理系统:Redmine;4.IT/敏捷项目管理系统:Jira;5.免费个人项目管理&…

java基础进阶-线程池

1、线程池 线程池就是一个可以复用线程的技术。 2、应用场景 用户每发起一个请求,后台就需要创建一个新线程来处理,下次新任务来了肯定又要创建新线程处理的,而创建新线程的开销是很大的,并且请求过多时,肯定会产生大…

2023年【起重机械指挥】考试题库及起重机械指挥考试资料

题库来源:安全生产模拟考试一点通公众号小程序 2023年【起重机械指挥】考试题库及起重机械指挥考试资料,包含起重机械指挥考试题库答案和解析及起重机械指挥考试资料练习。安全生产模拟考试一点通结合国家起重机械指挥考试最新大纲及起重机械指挥考试真…

OpenSSL 使用AES对文件加解密

AES(Advanced Encryption Standard)是一种对称加密算法,它是目前广泛使用的加密算法之一。AES算法是由美国国家标准与技术研究院(NIST)于2001年发布的,它取代了原先的DES(Data Encryption Stand…

设计师福利!2024在线图标设计网站推荐,不容错过的宝藏!

在当今竞争激烈的商业环境中,公司或个人品牌的视觉识别元素已经成为区分你和竞争对手的关键因素之一。一个独特而引人注目的标志可以深深扎根于人们的心中,并在消费者心中建立一个强烈的品牌印象。如果你正在寻找合适的工具来创建或改进你的标志&#xf…

Nginx系列-正向代理和反向代理

Nginx系列-正向代理和反向代理 文章目录 Nginx系列-正向代理和反向代理1. 三个对象2. 两种场景代理2.1. 正向代理2.2. 反向代理 3. 两种场景的对比3.1 为什么叫做反向代理3.2 正向代理和反向代理的作用 1. 三个对象 客户端:发出请求到代理,并接收代理的…

2019年11月20日 Go生态洞察:Go开发者调查启动

🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页——🐅🐾猫头虎的博客🎐 🐳 《面试题大全专栏》 🦕 文章图文…

1128. 等价多米诺骨牌对的数量

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/number-of-equivalent-domino-pa…

主机的具体权限规划:ACL的使用

目的:针对某一用户或某一组来设置特定权限需求,针对上,接着设置 ACL可以针对单一用户,文件,或者目录来进行rwx的权限设置,对于需要特殊权限的设置非常有帮助。 第一,查看文件系统是否支持&…

frida - 2.hook使用

frida hook 方法 下面是frida客户端命令行的参数帮助 Frida两种操作模式 1.attach 模式 将一个脚本注入到 Android 目标进程,即需要App处于启动状态, 这意味着只能从 当前时机往后hook。 frida -U -l myhook.js com.xxx.xxxx参数解释: -U 指定对USB设备操作 -l 指定…

08 木谷博客系统RBAC权限设计

这节内容说一下木谷博客系统的权限设计,采用现在主流的权限模型RBAC,对应关系如下: 以上5张表都在mugu_auth_server这个库中 该部分的服务单独定义在user-boot这个模块中。 将角色、权限对应关系加载到Redis 木谷博客系统在认证中心颁发令牌的时候是将用户的角色保存到令牌…

LabVIEW通过编程将图形类控件的X轴显示为时间戳

LabVIEW通过编程将图形类控件的X轴显示为时间戳 每个版本的LabVIEW中都有属性节点,可以以编程方式调整X轴和Y轴格式。对于不同版本的LabVIEW,这些属性节点无法在同一个位置找到。请参阅以下部分,了解特定版本LabVIEW的相关属性节点的位置。 …