最近尝试用ESP8266模块实现网络日历功能,通过免费的API接口NOW-API 获取网络时间与天气,大致思路是通过ESP8266连接服务器并通过HTTP GET的方式获取所需信息,以下是串口驱动ESP8266的代码及获取Demo。
ESP8266驱动esp8266.c
#include "stm32f10x.h"
#include "esp8266.h"
#include "delay.h"
#include "usart.h"
#include <stdarg.h>
#include <string.h>
#include <stdio.h>
//这里修改WIFI名称和密码
#define ESP8266_WIFI_INFO "AT+CWJAP=\"TP-LINK_302\",\"330022AABBCCDD\"\r\n"
#define ESP8266_TIME_INFO "AT+CIPSTART=\"TCP\",\"api.k780.com\",80\r\n"
char get_time0[] = "GET http://api.k780.com/?app=life.time&appkey=35488&sign=5138e2ad3378313fb818787e185054ae&format=json\r\n";
//阅读API接口说明后修改下面数据中的城市代码
char get_weather0[] = "GET http://api.k780.com/?app=weather.today&weaid=151&appkey=35488&sign=5138e2ad3378313fb818787e185054ae&format=json\r\n";
int i;
unsigned char esp8266_buf[1024];
unsigned short esp8266_cnt = 0, esp8266_cntPre = 0;
extern clock localTime;//时间结构体
extern weather WEA;//天气结构体
#define REV_OK 0
#define REV_WAIT 1
void Usart2_Init(unsigned int baud)
{
GPIO_InitTypeDef gpioInitStruct;
USART_InitTypeDef usartInitStruct;
NVIC_InitTypeDef nvicInitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
//PA2 TXD
gpioInitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
gpioInitStruct.GPIO_Pin = GPIO_Pin_2;
gpioInitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &gpioInitStruct);
//PA3 RXD
gpioInitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
gpioInitStruct.GPIO_Pin = GPIO_Pin_3;
gpioInitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &gpioInitStruct);
usartInitStruct.USART_BaudRate = baud;
usartInitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
usartInitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
usartInitStruct.USART_Parity = USART_Parity_No;
usartInitStruct.USART_StopBits = USART_StopBits_1;
usartInitStruct.USART_WordLength = USART_WordLength_8b;
USART_Init(USART2, &usartInitStruct);
USART_Cmd(USART2, ENABLE);
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
nvicInitStruct.NVIC_IRQChannel = USART2_IRQn;
nvicInitStruct.NVIC_IRQChannelCmd = ENABLE;
nvicInitStruct.NVIC_IRQChannelPreemptionPriority = 0;
nvicInitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_Init(&nvicInitStruct);
}
void ESP8266_Clear(void)
{
memset(esp8266_buf, 0, sizeof(esp8266_buf));
esp8266_cnt = 0;
}
_Bool ESP8266_WaitRecive(void)
{
if(esp8266_cnt == 0)
return REV_WAIT;
if(esp8266_cnt == esp8266_cntPre)
{
esp8266_cnt = 0;
return REV_OK;
}
esp8266_cntPre = esp8266_cnt;
return REV_WAIT;
}
_Bool ESP8266_SendCmd(char *cmd, char *res)
{
unsigned char timeOut = 200;
Usart_SendString(USART2, (unsigned char *)cmd, strlen((const char *)cmd));
while(timeOut--)
{
if(ESP8266_WaitRecive() == REV_OK)
{
if(strstr((const char *)esp8266_buf, res) != NULL)
{
ESP8266_Clear();
return 0;
}
}
DelayXms(10);
}
return 1;
}
void ESP8266_SendData(unsigned char *data, unsigned short len)
{
char cmdBuf[32];
ESP8266_Clear();
sprintf(cmdBuf, "AT+CIPSEND=%d\r\n", len);
if(!ESP8266_SendCmd(cmdBuf, ">"))
{
Usart_SendString(USART2, data, len);
}
}
unsigned char *ESP8266_GetIPD(unsigned short timeOut)
{
char *ptrIPD = NULL;
do
{
if(ESP8266_WaitRecive() == REV_OK)
{
ptrIPD = strstr((char *)esp8266_buf, "IPD,");//IPD为ESP8266设备返回接收数据前的标志
if(ptrIPD == NULL)
{
}
else
{
ptrIPD = strchr(ptrIPD, ':');
if(ptrIPD != NULL)
{
ptrIPD++;
return (unsigned char *)(ptrIPD);
}
else
return NULL;
}
}
DelayXms(5);
} while(timeOut--);
return NULL;
}
void ESP8266_Init(void)
{
GPIO_InitTypeDef GPIO_Initure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_Initure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Initure.GPIO_Pin = GPIO_Pin_0;
GPIO_Initure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_Initure);
GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_RESET);
DelayXms(250);
GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_SET);
DelayXms(500);
ESP8266_Clear();
while(ESP8266_SendCmd("AT\r\n", "OK"))
DelayXms(500);
while(ESP8266_SendCmd(ESP8266_WIFI_INFO, "GOT IP"))
DelayXms(500);
ESP8266_Clear();
}
void ESP8266_Init_TIME(void)
{
GPIO_InitTypeDef GPIO_Initure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//ESP8266重启
GPIO_Initure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Initure.GPIO_Pin = GPIO_Pin_0;
GPIO_Initure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_Initure);
GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_RESET);
DelayXms(250);
GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_SET);
DelayXms(500);
ESP8266_Clear();
while(ESP8266_SendCmd("AT\r\n", "OK"))
DelayXms(500);
while(ESP8266_SendCmd(ESP8266_WIFI_INFO, "GOT IP"))
DelayXms(500);
while(ESP8266_SendCmd(ESP8266_TIME_INFO, "CONNECT"))
DelayXms(500);
ESP8266_Clear();
}
void ESP8266_GETTIME(char *buff,int timeOut)
{
char *ptrIPD = NULL;
ESP8266_Init_TIME();
ESP8266_SendData((unsigned char *)buff, strlen(buff));
do
{
//检查HTTP GET 后返回的数据是否正常
ptrIPD = strstr((const char*)esp8266_buf, "datetime_2");
if(ptrIPD == NULL)
{
}
else
{
localTime.month =10*(*(ptrIPD-95+109-31)-0x30)+*(ptrIPD-95+110-31)-0x30;
localTime.day =10*(*(ptrIPD-95+112-31)-0x30)+*(ptrIPD-95+113-31)-0x30;
for(j=0;j<15;j++)
{
localTime.date[j] =*(ptrIPD-95+236-31+j);
}
if(strstr((char *)localTime.date, "Sun")!=NULL){localTime.dateTemp=0;}
else if(strstr((char *)localTime.date, "Mon")!=NULL){localTime.dateTemp=1;}
else if(strstr((char *)localTime.date, "Tue")!=NULL){localTime.dateTemp=2;}
else if(strstr((char *)localTime.date, "Wed")!=NULL){localTime.dateTemp=3;}
else if(strstr((char *)localTime.date, "Thu")!=NULL){localTime.dateTemp=4;}
else if(strstr((char *)localTime.date, "Fri")!=NULL){localTime.dateTemp=5;}
else if(strstr((char *)localTime.date, "Sat")!=NULL){localTime.dateTemp=6;}
localTime.hour =10*(*(ptrIPD-95+115-31)-0x30)+*(ptrIPD-95+116-31)-0x30;
localTime.min =10*(*(ptrIPD-95+118-31)-0x30)+*(ptrIPD-95+119-31)-0x30;
localTime.sec =10*(*(ptrIPD-95+121-31)-0x30)+*(ptrIPD-95+122-31)-0x30+1;//延时补偿,可自行调整
if(localTime.sec>=60)
{
localTime.sec=localTime.sec-60;
localTime.min=localTime.min+1;
if(localTime.min==60)
{
localTime.min=0;
localTime.hour++;
}
}
}
DelayXms(10);
} while(timeOut--);
//检查接收是否成功,不成功重新再来
if(localTime.date[0]==0x00)
{
ESP8266_Clear();
ESP8266_GETTIME(get_time0,500);
}
ESP8266_Clear();
}
void ESP8266_GETWEATHER(char *buff,int timeOut)
{
char *IPD,*aqi,*daywea,*id,*gif= NULL;
ESP8266_Init_TIME();
ESP8266_SendData((unsigned char *)buff, strlen(buff));
do
{
IPD = strstr((char *)esp8266_buf, "IPD,");
if(IPD == NULL)
{
}
else
{
}
DelayXms(1);
} while(timeOut--);
aqi = strstr((char *)esp8266_buf, "aqi");
if(*(aqi+8)==0x22)
{
WEA.aqi=10*(*(aqi+6)-0x30)+*(aqi+7)-0x30;
}
else if(*(aqi+8)==0x22)
{
WEA.aqi=100*(*(aqi+6)-0x30)+10*(*(aqi+7)-0x30)+*(aqi+8)-0x30;
}
daywea = strstr((char *)esp8266_buf, "weather");
for(i=0;i<32;i++)
{
WEA.dayweather[i]=*(daywea+10+i);
}
id = strstr((char *)esp8266_buf, "weatid");
if(*(id+10)==0x22)
{
WEA.weatid=(*(id+9)-0x30);
}
else if(*(id+10)!=0x22)
{
WEA.weatid=10*(*(id+9)-0x30)+*(id+10)-0x30;
}
gif = strstr((char *)esp8266_buf, "weather_iconid");
if(*(gif+18)==0x22)
{
WEA.weagif=(*(gif+17)-0x30);
}
else if(*(gif+18)!=0x22)
{
WEA.weagif=10*(*(gif+17)-0x30)+*(gif+18)-0x30;
}
if(WEA.dayweather[0]==0x00)
{
ESP8266_Clear();
ESP8266_GETWEATHER(get_weather0,500);
}
ESP8266_Clear();
}
void USART2_IRQHandler(void)
{
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
{
if(esp8266_cnt >= sizeof(esp8266_buf)) esp8266_cnt = 0;
esp8266_buf[esp8266_cnt++] = USART2->DR;
USART_ClearFlag(USART2, USART_FLAG_RXNE);
}
}
头文件esp8266.h
#ifndef ESP8266_h
#define ESP8266_h
typedef struct
{
unsigned char sec;
unsigned char min;
unsigned char hour;
unsigned char day;
unsigned char date[4];
unsigned char month;
unsigned char year;
unsigned char dateTemp;
}clock;
typedef struct
{
u16 aqi;
unsigned char dayweather[32];
unsigned char weatid;
u16 weagif;
}weather;
void Usart2_Init(unsigned int baud)£»
void esp8266_init(void);
void esp8266_get_tianqi(void);
void esp8266_get_shijian(void);
void esp8266_get_time(void);
void dispose_time_data(void);
void ESP8266_Init(void);
void ESP8266_Init_TIME(void);
void ESP8266_GETTIME(char *buff,int timeOut);
void ESP8266_GETWEATHER(char *buff,int timeOut);
void ESP8266_Clear(void);
void ESP8266_SendData(unsigned char *data, unsigned short len);
unsigned char *ESP8266_GetIPD(unsigned short timeOut);
#endif
其余的延时函数delay.c,delay.h参考我的博客基于STM32F103与MY2480-16P语音模块的时钟兼闹钟设计(第一部分)
下面是测试程序main.c
//单片机头文件
#include "stm32f10x.h"
//网络设备
#include "esp8266.h"
//硬件驱动
#include "delay.h"
#include "usart.h"
//C库
#include <string.h>
#include <stdio.h>
clock localTime;
weather WEA;
char get_time[] = "GET http://api.k780.com/?app=life.time&appkey=35488&sign=5138e2ad3378313fb818787e185054ae&format=json\r\n";
//阅读API接口说明后修改下面数据中的城市代码
char get_weather[] = "GET http://api.k780.com/?app=weather.today&weaid=151&appkey=35488&sign=5138e2ad3378313fb818787e185054ae&format=json\r\n";
u8 time[6];
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断控制器分组设置
Delay_Init(); //systick初始化
Usart2_Init(115200); //串口2,驱动ESP8266用
ESP8266_GETTIME(get_time,500); //获取时间
ESP8266_GETWEATHER(get_weather,500); //获取天气
DelayXms(250);
}
文章浏览阅读213次。Java详解剑指offer面试题18——删除链表的结点题目一——O(1)删除链表结点给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间内删除该结点。假设要删除的结点确实在链表中。常规思路:删除某个结点需要找到该结点的前一个结点,由于单向链表没有指向前一个结点的指针,所以不得不从头指针开始遍历链表。显然时间复杂度为O(n)。实现如下:package Chap3;public class DeleteNode { private class Node { _java创建一个单项循环链表,每经过三个结点,就删除第三个结点 → 找到最后遗留的一
文章浏览阅读3.2k次,点赞8次,收藏20次。一:Ray射线定义:射线是一条从原点出发,沿某一方向运动的无限直线。//创建一条初始位置为startPos,方向为dir的一条射线Ray ray = new Ray (startPos, dir);//创建一条从摄像机通过屏幕点的光线。//得到的光线在世界空间中,从相机的近平面开始,经过屏幕上的(x,y)像素坐标(位置)。z是忽略。Ray camerRay = Camera.main..._overlapspherenonalloc
文章浏览阅读203次。我们通过配置STM32CubeMX来初始化I2C外设,并编写代码来实现传感器的初始化和数据读取。在实际应用中,可以将读取到的甲醛浓度数据与预设的阈值进行比较,以便及时采取相应的措施来改善室内空气质量。因此,在许多应用中,监测室内空气中甲醛浓度的传感器变得越来越重要。通过以上步骤,我们可以使用硬件I2C在嵌入式系统中读取甲醛传感器SGP30的数据。打开Keil MDK,创建一个新的工程,并将生成的初始化代码添加到该工程中。最后,我们需要在main函数中调用这些函数,并添加必要的延时以进行周期性的数据读取。_sgp30 不模拟i2c
文章浏览阅读605次。else { //如果不是,则恢复滑动。_ios tableview 滑动手势冲突
文章浏览阅读1.2w次,点赞13次,收藏19次。IDEA中微服务在service窗口以配置方式启动网上千篇一律的在 workspace.xml中配置Run Dashboard,但是只有在旧版本中才有这个节点的配置。但是新版的该怎么办呢?压根就没有这个节点,硬着头皮添加进去你会发现,问题依然存在。纠结的我捣鼓一个夜晚终于搞明白了,赶紧激动的记录下来,和小伙伴们分享我的成果!1.idea版本我使用的版本是2020.1.1,service窗口中可以以配置方式启动微服务,一般是配置不同端口号启动。如下图。(但是在旧版本中,对应的窗口叫做Run Dash_idea的service
文章浏览阅读1.1w次,点赞16次,收藏33次。三个文件搞定YOLOv8【训练】【验证】【推理】_yolov8推理
文章浏览阅读709次。XXX.crt private.key_nginx 证书 转换为pkcs12 证书
文章浏览阅读642次,点赞14次,收藏14次。主要知识点有:IP地址填写检查方法、读取写入方法、西门子PLC变量地址与类型的关系文章提供测试代码讲解、参数效果贴出、整体工程下载
文章浏览阅读373次,点赞18次,收藏19次。中级架构,分布式应用,中间层分布式+数据库分布式,是单体架构的并发扩展,将一个大的系统划分为多个业务模块,业务模块分别部署在不同的服务器上,各个业务模块之间通过接口进行数据交互。**2.微服务架构:**其实和 SOA 架构类似,微服务是在 SOA 上做的升华,微服务架构强调的一个重点是“业务需要彻底的组件化和服务化”,原有的单个业务系统会拆分为多个可以独立开发、设计、运行的小应用。而且,它可以标准化,同样的容器不管在哪里运行,结果都是一样的,所以市场上有很多 SaaS 产品,提供标准化的微服务。
文章浏览阅读626次。点击下方卡片,关注“自动驾驶之心”公众号ADAS巨卷干货,即可获取点击进入→自动驾驶之心【AIGC】技术交流群摘要近年来,深度学习领域取得了重大进展,特别是在计算机视觉(CV)、自然语言处理(NLP)和语音等领域。根据大量数据训练的大规模模型的使用为实际应用、提高工业生产力和促进社会发展带来了巨大的希望。然而,它极易受到不稳定的训练过程和对计算资源的严格要求的影响。随着对计算能力自适应的要求越来越..._深度学习增量训练的训练过程
文章浏览阅读1.3k次,点赞44次,收藏29次。随着Web2.0、社交网络、微博等等一系列新型的互联网产品的诞生,基于Web环境的互联网应用越来越广泛,企业信息化的过程中各种应用都架设在Web平台上,Web业务的迅速发展也引起黑客们的强烈关注,接踵而至的就是Web安全威胁的凸显,黑客利用网站操作系统的漏洞和Web服务程序的SQL注入漏洞等得到Web服务器的控制权限,轻则篡改网页内容,重则窃取重要内部数据,更为严重的则是在网页中植入恶意代码,使得网站访问者受到侵害。这也使得越来越多的用户关注应用层的安全问题,对Web应用安全的关注度也逐渐升温。_漏洞利用场景ctf
文章浏览阅读5.8k次。Mac 卸载 隐蔽软件 Core_Sync 的步骤_core sync