基于STM32与ESP8266的太空人WiFi天气时钟(代码开源)

news2024/11/20 9:21:07

        前言:本文为手把手教学ESP8266著名开源项目——太空人WiFi天气时钟,不同的是本次项目采用的是STM32作为MCU。两者开发过程中有因为各自芯片的特点时钟频率,内存大小等),导致开发程序大不相同,很多地方需要特殊设计一下。而作者使用STM32开发的原因很简单,ESP8266虽然计算能力等方面优于STM32F1xx,但是弊端也很明显。其所具备的引脚和外设太少,扩展性一般(ESP32算是二者优点兼备)。加之网上ESP8266的太空人WiFi天气时钟已经开源的很完善了,所以尝试用STM32实现一下,也方便后续利用STM32拓展开发。(文末有代码开源!

        实验硬件:STM32F103ZET6;7针1.3寸TFT-LCD(240×240);ESP8266

        硬件实物图:

        效果图:

引脚连接:

LCD显示引脚:

VCC --> 3.3V

GND --> GND

CLK --> PA5

DIN --> PA7

RES --> PB0

DC --> PB1

CS --> PA4

ESP8266模块引脚:

VCC --> 3.3V

GND --> GND

RX--> PB10

TX --> PB11

RST --> PB9

EN --> PB7

一、ESP8266简介与使用

1.1 ESP8266简介

        ESP8266是一款超低功耗的UART-WiFi透传模块,拥有业内极富竞争力的封装尺寸和超低能耗技术,专为移动设备物联网应用设计,可将用户的物理设备连接到Wi-Fi无线网络上,进行互联网或局域网通信,实现联网功能。

        ESP8266上海乐鑫信息科技(国产设计的低功耗WiFi芯片,集成完整的TCP/IP协议栈和MCU网上ESP8266型号很多,基本都具备联网功能,部分型号可以直接作为MCU使用)。而ESP8266模块是深圳安信可公司基于ESP8266芯片研发(增加必要外围电路、串口flash、板载天线等)的串口WiFi模块,成本低、使用简便、功能强大。

一般是模块固件损坏或者买回来里面可能被别人刷过固件需要擦除或者增加固件才用,作者的ESP8266是因为烧写了Arduino IDE的例程进去,不能识别AT指令,后来用不到了才想到刷回AT固件刷固件有风险!!!如果大家买的是ESP8266 nodeMCU可能就需要刷AT固件

1.2 硬件与网络的桥梁——ESP8266

        ESP8266模块和串口蓝牙JDY-31模块一样,串口WiFi模块也是扩展单片机功能的又一神器。小巧的 ESP8266 WiFi模块通过串口AT指令与单片机通讯,实现串口透传,非常好上手(部分型号ESP8266可以直接当MCU,无需再通过串口与其他MCU通讯)。

 透传,又称透明传输,具体来说就是“输入即输出(如从WiFi模块串口输入的字符会透传到服务器端)”,数据不改变不同协议之间的转换(如串口到WiFi、蓝牙等)由模块完成。使用者无需关心内部具体实现,因此模块对于使用者是“透明的”、似乎不存在的(因为可无视中间的实现原理)。一个高度封装的模块,应该隐藏内部实现细节,仅对外提供使用接口。

        把硬件联网之后,就再也不是“玩单机”了。配合服务器端的Socket网络编程,可以玩许多东西。所以我觉得WiFi模块是连接软件(网络编程)与硬件(单片机)的桥梁,把所学的单片机(MCU)Web知识联系起来了。

如今大火的物联网等概念都属于“智能硬件",ESP8266等模块的出现大大减少了网络开发的难度系数,也进一步促进了技术下放。而且,通过学习ESP8266/ESP32等模块,可以熟悉大量TCP/IP等网络协议,对后续Linux系统板网络开发也是极具意义的。

1.3 ESP8266使用——AT指令

        AT指令最早在蓝牙模块上接触过,所谓AT指令实质上就是一些起控制作用的特殊字符串。模块可以通过AT指令控制搭配使用源代码API函数开发,总体开发速度快,难度较低。

说明:下面仅列举一些最常用的AT指令及用法,指令的详细参数及使用说明请参考官方文档:ESP8266 AT指令集。

基础AT指令

指令描述
AT测试AT启动
AT+RST重启模块
AT+GMR查看版本信息

AT 是最常用的指令,用于测试模块能否正常接受指令。在sscom中向串口发送指令 AT ,若收到模块返回的 OK 则说明模块的AT指令可正常工作。发送 AT+GMR 可查看AT指令及SDK的版本号,一般最新版指令会增加一些新功能,可随时关注官方的更新。

WiFi功能AT指令

WiFi是让硬件联网的基础,和其他功能一样,这里仅列举所需的常用指令,更详细指令说明还得查阅文档。

指令描述
AT+CWMODE设置WiFi模式(sta/AP/sta+AP)
AT+CWLAP扫描附近的AP信息
AT+CWJAP连接AP
AT+CWQAP与AP断开连接
AT+CWSAP设置ESP8266 softAP配置
AT+CWLIF获取连接到 ESP8266 softAP 的 station 的信息

关于WiFi模式这里要说明一下,sta模式下模块相当于客户端,像我们手机平板一样是要去连接路由器的,而AP模式下模块相当于路由器,是发射WiFi被别人连的。ESP8266支持两种模式并存(模块出厂默认的是AP模式) 。另外,扫描WiFi指令 AT+CWLAP 只能在sta模式下使用,否则会报ERRO错误, AT+CWJAPAT+CWQAP 指令也同理。

sta模式连接WiFi演示

  1. 发送 AT+CWMODE=1 指令配置模块为sta模式(参数1,2,3分别对应模式sta,AP和sta/AP)。

  2. 发送 AT+CWLAP 指令扫描当前附近WiFi,模块会返回可用AP列表。

  3. 使用 AT+CWJAP="WiFi名称","WiFi密码" 连接到指定的路由器,比如我在图书馆的WiFi是 “Wang”,密码是“123456”,实际连接WiFi发送的指令就是 AT+CWJAP="Wang","123456" 。

  4. 返回的“WIFI CONNECTED”说明连接成功,“WIFI GOT IP”代表模块分配到了IP。

  5. 最后可使用 AT+CWQAP 断开当前连接的WiFi。

TCP/IP相关AT指令

传输控制协议(英语:Transmission Control Protocol,缩写为 TCP)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793定义。在简化的计算机网络OSI模型中,它完成第四层传输层所指定的功能,用户数据报协议(UDP)是同一层内另一个重要的传输协议。在因特网协议族(Internet protocol suite)中,TCP层是位于IP层之上,应用层之下的中间层。不同主机的应用层之间经常需要可靠的、像管道一样的连接,但是IP层不提供这样的流机制,而是提供不可靠的包交换。

我们常说互联网互联网,那两个连接到互联网的设备该如何相互“交流”呢?TCP连接就是其中一种最常用的方式。TCP是面向连接的传输层协议,通信双方都要实现TCP协议,其中一方只需目标ip地址和端口号就能发起连接,连接一旦建立,就像在双方之间拉了一条管子,管子两端可进行全双工(双向同时收发)通信。

TCP是传输层协议,是在网络层IP协议的基础上封装而来。而这些封装的实现细节也是与我们无关,我们只需使用系统所提供的相关接口“拿来即用”,比如网络编程中的Socket。ESP8266模块中也实现了TCP/IP协议栈,模块作为客户端可轻松使用AT指令向服务端发起TCP连接。连接TCP服务器并开启透传模式后,模块串口收到的数据就会通过TCP连接透传到服务端,这样就完成了数据从硬件串口通过网络到程序进程的传输,实现软硬结合。

指令描述
AT+CIPSTATUS查询网络连接信息
AT+CIPMUX设置多连接模式
AT+CIPSTART建立TCP连接UDP传输或者SSL连接
AT+CIPCLOSE关闭TCP/UDP/SSL传输
AT+CIPMODE设置透传模式
AT+CIPSEND发送数据

把WiFi模块和电脑连接,在sscom确定AT指令能正常使用后,就可以开始配置TCP连接了,具体步骤如下:

  1. 根据上面“sta模式连接WiFi演示”一节把模块连上WiFi

  2. 输入指令 AT+CIPMUX=0 设置单连接

  3. 从“网络调试助手”得知本机IP和端口,输入指令 AT+CIPSTART="TCP","192.168.43.140",1234 (指令参数分别为连接类型、目标IP地址和端口号)向服务器发起TCP连接请求,握手成功并建立连接后,服务器端的“网络调试助手”就会显示客户端IP和端口信息,此时双方已做好收发数据的准备(根据实际需要连接的IP地址来

  4. 输入指令 AT+CIPMODE=1 开启透传模式

  5. 输入命令 AT+CIPSEND 进入透传模式,此时模块会把所有串口收到的数据都从TCP端口发送至服务器,同样的,从服务器收到的数据也会从模块串口发送出去打印到sscom上。这样WiFi模块就真正成为了连接硬件与网络的桥梁,实现了串口到TCP的协议转换

以上其实就是大概本次项目需要使用到的指令,ESP8266配置代码如下:

void esp8266_config(void)
{
		char str[200];
		sprintf(str, "AT+CWJAP=\"%s\",\"%s\"\r\n", WIFI_NAME, WIFI_PSW);
//		SendATCmd("+++", 500);				// 退出透传模式
		SendATCmd("AT\r\n", 2000);			// 测试ESP01模块是否存在
//		SendATCmd("AT+GMR\r\n",3000);	// 查看模块版本信息
		SendATCmd("AT+CWMODE=1\r\n", 2000);	// 开启STA+AP模式 ==================		
		SendATCmd("AT+RST\r\n", 3000);	
		SendATCmd(str, 10000);	// 连接无线路由器或者手机热点,等待10秒 ============
		SendATCmd("AT+CIPMUX=0\r\n", 2000);	// 关闭多连接
		SendATCmd("AT+CIPSTART=\"TCP\",\"api.seniverse.com\",80\r\n", 2000);	// 连接心知  天气TCP服务器
		SendATCmd("AT+CIPMODE=1\r\n", 500);	// 开启透传模式
		SendATCmd("AT+CIPSEND\r\n", 500);		// 开始透传
}

二、知心天气API使用

        本项目为WiFi天气时钟,自然离不开需要从网页上读取天气信息。这里我们使用业内比较著名的知心天气

2.1 登陆心知天气官网,注册

没有账号的朋友可以自己去注册一下,流程很简单。不商用的话,知心天气是免费的,还是比较良心的(网站响应率也很高)。

点击“立即免费试用”

点击免费版的“免费申请”

申请后可查看到自己的私钥(自行保存后面需要用到)

2.1 API函数的使用

         目前,大部分网络数据调用都是习惯性的调用数据提供商的API接口函数

重新点击“产品”—>“天气数据”,点击“查看API文档” 

点击"天气实况",打开对应的API接口文档 

查看天气实况的接口地址,以及返回的数据结果示例(自行保存后面需要用到)

(1)上述知心天气API接口函数的寻找和使用通用性很高,大部分网络数据读取的流程与之类似。

(2)嵌入式开发大部分情况下一般都是C语言进行开发的,由于C语言的局限性,没有直接的字典类型处理(python),所以,对于服务器返回给ESP8266的JSON数据一般是无法直接解码读取的。目前有2种方法处理:①、移植CJSON去解码②取巧去比对字符串(本次使用的方法)

        项目使用过程中直接使用知心天气自带的API函数,项目大致流程:开启STA模式后,成功连上WiFi后,通过TCP协议去访问执行天气网站的服务器,在发送特定的API接口函数,服务器响应后返回需要的结果信息。

三、UART串口通讯

        STM32作为MCU与ESP8266直接的通讯就是简单的UART(串口)通信,这一点依旧与蓝牙模块很类似。使用方法:通过串口UARTx_TX连接ESP8266的UART_RX,然后单片机通过串口发送AT指令集。ESP8266后续从服务器接受的数据信息也从ESP8266的UART_TX传输给单片机UARTx_RX。后续只需要使用自己的方法去解析串口接收到的数据,即可得到自己想要的数据信息。

可以初步使用电脑串口去读取MCU接收到ESP8266返回的信息:

四、CubeMX配置

1、RCC配置外部高速晶振(精度更高)——HSE;

2、SYS配置:Debug设置成Serial Wire否则可能导致芯片自锁);

3、GPIO配置:此处模拟使用SPI通信,并且设置ESP8266的EN和RST;

4、RTC配置:年月日,时分秒;

5、UART1和UART3配置:MCU分别与电脑和ESP8266通讯(记得开启串口通信中断);

6、时钟树配置 

7、工程配置

五、代码与解析

5.1 TFT-LCD显示代码

LCD显示部分其实都是非常基础的操作,不熟悉的可以去看看笔者另一篇文章了解一下。作者这里主要把工程中不一样的地方指出来一下。【强烈推荐】基于STM32的TFT-LCD各种显示实现(内容详尽含代码)_混分巨兽龙某某的博客-CSDN博客_lcd显示屏显示代码

5.1.1 UI设计

        WiFi天气时钟中最要的点——UI设计,需要去设计很多界面图标,作者这里耗费了超级多的时间,翻遍了GitHub视觉中国。最后找到了差不多符合作者要求的UI库(有需要的可以评论区留下邮箱),如下:

 5.1.2 GIF动图实现

        目前,由于STM32自身内存的缘故,其实STM32是不太适合实现GIF动图的。所以,网上这方面的资料和代码都很少。目前,较为主流的方法:(1)enWin或者Lvgl库实现GIF动图;(2)从SD卡读取数据去显示

        作者这里用了一直笨方法去实现了GIF显示,就是去循环遍历GIF动图的每一帧。

使用GIF分离器去分离GIF动图的每一帧

再利用Image2Lcd 2.9(破解版)去提前图模;

将取模代码变为2维数组第一维度为帧数第二维度为每帧图片的取模

之后循环显示该GIF数组的每一帧,即可实现GIF动图显示。

代码:

void showimage4(const unsigned char *p) 
{
  int i; 
	unsigned char picH,picL;

	Address_set(180,146,228,195);
	for(i=0;i<49*50;i++)
		{	
			picL=*(p+i*2);	
			picH=*(p+i*2+1);				
			LCD_WR_DATA(picH<<8|picL); 				
		}	
}


for(int a=0;a<11;a++)
{
    showimage4(gImage_1[a]);
}

5.2 ESP8266代码

EPS8266部分代码主要是配置后负责和目标服务器去实现通讯,当然还有需要解码服务器返回信息。

5.2.1 ESP8266配置代码(含UART处理)

UART回调处理函数:

/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(huart);
  /* NOTE: This function Should not be modified, when the callback is needed,
           the HAL_UART_TxCpltCallback could be implemented in the user file
   */
	if(huart == &huart1)
	{
		g_uart1_rx.buf[g_uart1_rx.size++] = aRxBuffer_rx1;   									
		if((g_uart1_rx.buf[g_uart1_rx.size-1] == 0x0A)&&(g_uart1_rx.buf[g_uart1_rx.size-2] == 0x0D))	
		{
			HAL_UART_Transmit(&huart1, (uint8_t *)&g_uart1_rx.buf, g_uart1_rx.size,0xFFFF);	
					while(HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX);			
			g_uart1_rx.size = 0;
			memset(g_uart1_rx.buf,0x00,sizeof(g_uart1_rx.buf));									
		}
		HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer_rx1, 1);						
	}
	if(huart == &huart3)
	{
		g_uart3_rx.buf[g_uart3_rx.size++] = aRxBuffer_rx3;   									
	
		if((g_uart3_rx.buf[g_uart3_rx.size-1] == 'K')&&(g_uart3_rx.buf[g_uart3_rx.size-2] == 'O'))	
		{
			HAL_UART_Transmit(&huart1, (uint8_t *)&g_uart3_rx.buf, g_uart3_rx.size,0xFFFF);	
				while(HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX);			
			g_uart3_rx.size = 0;
			memset(g_uart3_rx.buf,0x00,sizeof(g_uart3_rx.buf));									
		}
		else if((g_uart3_rx.buf[g_uart3_rx.size-2] == ']')&&(g_uart3_rx.buf[g_uart3_rx.size-1] == '}')
			&&(g_uart3_rx.buf[g_uart3_rx.size-3] == '}'))
		{
			HAL_UART_Transmit(&huart1, (uint8_t *)&g_uart3_rx.buf, g_uart3_rx.size,0xFFFF);	
			while(HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX);			//				
			strcpy(Data_buff,(char *)g_uart3_rx.buf);
			temp = 1;
			g_uart3_rx.size = 0;				
			memset(g_uart3_rx.buf,0x00,sizeof(g_uart3_rx.buf));									

		}
		HAL_UART_Receive_IT(&huart3, (uint8_t *)&aRxBuffer_rx3, 1);						
	}
	
}
/* USER CODE END 4 */

ESP8266.h(AT控制):

#ifndef __ESP8266_H
#define __ESP8266_H

//#include "stdint.h"

//uint8_t aRxBuffer_rx1;			//接收中断缓冲
//uint8_t aRxBuffer_rx3;			//接收中断缓冲

//typedef struct {
//	uint16_t size;
//	uint8_t buf[1022]; // 接收缓冲数组
//} UART_RXDATA;

//UART_RXDATA g_uart1_rx;
//UART_RXDATA g_uart3_rx;

//char Data_buff[1022];

//char weather[10];				//存储天气

//uint8_t temperature[2]={0,0}; 		//储存最高气温和最低气温
//uint8_t temp = 0;

//需要连接的wifi账号和密码,需要修改,且WiFi频段不支持5GHz
#define WIFI_NAME "Wang"
#define WIFI_PSW    "123456"
 
心知天气api,注意key=后面需要替换成自己账号的密钥
//char *get="GET https://api.seniverse.com/v3/weather/daily.json?key=SkV9zIBpwJAOixrJZ&location=chongqing&language=en&unit=c\r\n";

//void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);
void SendATCmd(char *cmd, int waitms); 
void esp8266_config(void);


#endif

ESP8266.c:

#include "esp8266.h"
#include "usart.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "lcd.h"


void SendATCmd(char *cmd, int waitms) 
{ // 发送AT指令给串口3
	if (NULL != cmd)
	{
		HAL_UART_Transmit(&huart3, (uint8_t *)cmd, strlen(cmd), 0xFFFF);	
		if (waitms > 0)
			HAL_Delay(waitms);  // 延时等待ESP01模块应答时间
	}
}

void esp8266_config(void)
{
		char str[200];
		sprintf(str, "AT+CWJAP=\"%s\",\"%s\"\r\n", WIFI_NAME, WIFI_PSW);
//		SendATCmd("+++", 500);				// 退出透传模式
		SendATCmd("AT\r\n", 2000);			// 测试ESP01模块是否存在
//		SendATCmd("AT+GMR\r\n",3000);	// 查看模块版本信息
		SendATCmd("AT+CWMODE=1\r\n", 2000);	// 开启STA+AP模式 ==================		
		SendATCmd("AT+RST\r\n", 3000);	
		SendATCmd(str, 10000);	// 连接无线路由器或者手机热点,等待10秒 ============
		SendATCmd("AT+CIPMUX=0\r\n", 2000);	// 关闭多连接
		SendATCmd("AT+CIPSTART=\"TCP\",\"api.seniverse.com\",80\r\n", 2000);	// 连接心知天气TCP服务器
		SendATCmd("AT+CIPMODE=1\r\n", 500);	// 开启透传模式
		SendATCmd("AT+CIPSEND\r\n", 500);		// 开始透传
	
		SendATCmd("GET https://api.seniverse.com/v3/weather/daily.json?key=SkV9zIBpwJAOixrJZ&location=zhenjiang&language=en&unit=c\r\n", 2000);
}

注意,key=后面尽量换成自己的密钥,location=后面也可以换成自己所在城市的字母。

5.2.2 ESP8266信息解码

        这部分作者取巧,使用了字符串对比和指针取值的操作。

strstr()函数:

atoi()函数:

代码:

			char *p;
			p =	strstr(Data_buff,"text_day");				//查找天气		
			sscanf(p+11,"%[^\"]",weather);	
//			LCD_ShowString(40,80,(uint8_t*)weather);			
			p = strstr(Data_buff,"high");								//查找气温
			temperature[0]=atoi(p+7);
			p = strstr(Data_buff,"low");
			temperature[1]=atoi(p+6);
//			LCD_ShowxNum2(45,40,temperature[1],2,24,0);
			LCD_ShowxNum2(160,207,temperature[0],2,24,0);

			//温度
			value = (temperature[1]+temperature[0])/2;
			LCD_ShowxNum2(52,160,value,2,24,0); 			

			//湿度
			p = strstr(Data_buff,"humidity");
			humidity=atoi(p+11);
			LCD_ShowxNum2(132,160,humidity,2,24,0);
			LCD_ShowNew(161,160,'%',24,0);
			
			if((strstr(weather,"Overcast")) || (strstr(weather,"Mostly Cloudy")) || (strstr(weather,"Partly Cloudy")) || strstr(weather,"Cloudy"))	
			{
				Overcast();
			}
			if((strstr(weather,"Sunny")) || (strstr(weather,"Clear")) || (strstr(weather,"Fair")))			//ÇçÌì
			{
				Sunny();
			}
			if((strstr(weather,"Shower")))				
			{
				Shower();
			}
			if((strstr(weather,"Thundershower")) || (strstr(weather,"Thundershower with Hail")))		
			{
				Thundershower();
			}
			if((strstr(weather,"Light rain")) || (strstr(weather,"Moderate Rain")))			
			{
				smallrain();
			}
			if((strstr(weather,"Heavy Rain")) || (strstr(weather,"Storm")) || (strstr(weather,"Heavy Storm")) || (strstr(weather,"Severe Storm")))		
			{
				Bigrain();
			}
			if((strstr(weather,"Ice Rain")) || (strstr(weather,"Sleet")) || (strstr(weather,"Snow Flurry")) || (strstr(weather,"Light Snow")) || (strstr(weather,"Moderate Snow")) || (strstr(weather,"Heavy Snow")) || (strstr(weather,"Snowstorm")))		
			{
				snow();
			}			

5.3 RTC代码

rtcdisplay.h:

#ifndef __RTCDISPLAY_H
#define __RTCDISPLAY_H

void RTC_display();

#endif

rtcdisplay.c:

#include "rtcdisplay.h"
#include "rtc.h"
#include "lcd.h"

RTC_DateTypeDef GetData;  //获取日期结构体
RTC_TimeTypeDef GetTime;   //获取时间结构体

void RTC_display()				//RTC DISPLAY
{
	
	  /* Get the RTC current Time */
	  HAL_RTC_GetTime(&hrtc, &GetTime, RTC_FORMAT_BIN);
    /* Get the RTC current Date */
    HAL_RTC_GetDate(&hrtc, &GetData, RTC_FORMAT_BIN);
	
		/* Display date Format : yy/mm/dd */
//		OLED_ShowNum(0,0,2000+GetData.Year,4,16);			//year
//		OLED_ShowStr(35,30,".",2);
//		OLED_ShowNum(45,0,GetData.Month,2,16);				//month
//		OLED_ShowStr(60,30,".",2);
//		OLED_ShowNum(70,0,GetData.Date,2,16);			    //date
	
    /* Display time Format : hh:mm:ss */
		LCD_ShowxNum2(15,75,GetTime.Hours,2,60,0);				//hour
//		LCD_ShowNew(75,65,':',60,0);
		LCD_ShowxNum2(105,75,GetTime.Minutes,2,60,0);			//min
		LCD_ShowxNum2(180,105,GetTime.Seconds,2,32,0);			//seconds

}

这里RTC的时钟显示,作者也去网上找了专门的LED数字字体,如果需要LED数字字体库的也可以评论留言,作者把安装脚本发你。

六、项目效果

太空人WIFI天气时钟

七、项目代码

代码地址: 基于STM32与ESP8266的太空人WiFi天气时钟(TFT-LCD)-嵌入式文档类资源-CSDN文库

如果积分不够的朋友,点波关注评论区留下邮箱,作者无偿提供源码和后续问题解答。求求啦关注一波吧 !!!

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

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

相关文章

Redis 持久化配置,RDB和AOF方式配置说明

文章目录 一、概述二、RDB 持久化方式配置三、AOF 持久化方式配置 如果您对Redis的了解不够深入请关注本栏目&#xff0c;本栏目包括Redis安装&#xff0c;Redis配置文件说明&#xff0c;Redis命令和数据类型说明。 一、概述 Redis 持久化是指将 Redis 数据存储到磁盘上&#x…

KVM实验之动态迁移

前言 一台NFS&#xff08;192.168.184.132&#xff09; 一台KVM-a&#xff08;192.168.184.133&#xff09; 一台KVM-b&#xff08;192.168.184.134&#xff09; NFS配置&#xff1a; [rootlocalhost ~]# setenforce 0 //关闭selinux [rootlocalhost ~]# service iptables st…

python re 匹配所有字段名称相同的值

import retext {"code": 200,"message": "success","traceId": "da0b668c-4d67-44bf-907f-c072fc63839a","data": {"list": [{"articleId": 121862102,"title": "python 目录…

k8s 金丝雀发布与声明式管理

Deployment控制器支持自定义控制更新过程中的滚动节奏&#xff0c;如“暂停(pause)”或“继续(resume)”更新操作。比如等待第一批新的Pod资源创建完成后立即暂停更新过程&#xff0c;此时&#xff0c;仅存在一部分新版本的应用&#xff0c;主体部分还是旧的版本。然后&#xf…

用图说话——流程图进阶

目录 一、基本流程图 二、时序流程图 一、基本流程图 经常阅读歪果仁绘制的流程图&#xff0c;感觉比较规范&#xff0c;自己在工作中也尝试用他们思维来绘图&#xff0c;这是一个小栗子&#xff1a; 二、时序流程图 在进行Detail设计过程中&#xff0c;一般的绘图软件显得…

微信小程序笔记功能(富文本editor功能)开发

一、效果图展示 模拟器及pc 端效果图 手机端就不贴了 二、把官方示例copy到自己的项目传送门 三、改一改上传图片功能 insertImage() {const that thiswx.chooseImage({// count:1 一次选择图片的个数success: function (response) {// 多张图片上传response.tempFilePaths…

基于opencv的selenium滑动验证码的实现

这篇文章主要介绍了基于opencv的selenium滑动验证码的实现&#xff0c;文中通过示例代码介绍的非常详细&#xff0c;对大家的学习或者工作具有一定的参考学习价值&#xff0c;需要的朋友们下面随着小编来一起学习学习吧 基于selenium进行动作链 由于最近很多人聊到滑动验证码…

Python通过pyecharts对爬虫房地产数据进行数据可视化分析(一)

一、背景 对Python通过代理使用多线程爬取安居客二手房数据&#xff08;二&#xff09;中爬取的房地产数据进行数据分析与可视化展示 我们爬取到的房产数据&#xff0c;主要是武汉二手房的房源信息&#xff0c;主要包括了待售房源的户型、面积、朝向、楼层、建筑年份、小区名称…

图像去噪滤波算法汇总(Python)

前言 上篇文章&#xff1a;图像数据噪音种类以及Python生成对应噪音&#xff0c;汇总了常见的图片噪音以及噪音生成方法&#xff0c;主要用在数据增强上面&#xff0c;作为数据集填充的方式&#xff0c;可以避免模型过拟合。想要了解图像数据增强算法的可以去看本人所撰这篇文…

IO,库-10.24.25

库-10.24.25 一、概念 头文件&#xff1a;.h&#xff1a;函数声明&#xff0c;结构体定义&#xff0c;宏定义&#xff0c;外部引用&#xff0c;重定义&#xff0c;条件编译 #include <>:从系统路径&#xff08;/usr/include&#xff09;下查找 #include " "&am…

如何将Mysql数据库的表导出并导入到另外的架构

如何将Mysql数据库的表导出并导入到另外的架构 准备一、解决方法1.右键->导出->用mysqldump导出2.注意路径一般为&#xff1a;C:/Program Files/MySQL/MySQL Server 8.0/bin/mysqldump.exe和导出的sql文件位置3.右键->SQL脚本->运行SQL脚本4.找到SQL脚本并点击确定…

[moeCTF 2023] REV

逆向这东西&#xff0c;不太好说。 base64 这是个pyc文件&#xff08;python编译后的字节码文件&#xff09;&#xff0c;这东西可以直接用各种方法反编译。也可以不弄&#xff0c;必竟这应该签到级别的。用notepad打开&#xff0c;可以看到base64的编译和两个码表。显然猜是…

mac系统u盘启动盘制作教程,更新至macOS Sonoma 14

mac系统怎么制作装系统的u盘,如果您要在多台电脑上安装 macOS&#xff0c;而又不想每次都下载安装器&#xff0c;这时可引导安装器就会很有用。一起来看苹果电脑u盘启动盘制作教程吧。 Macos系统安装包合集包揽macos 10.15&#xff0c;macos 11和苹果最新系统等多个版本 1、A…

Windows 和 Linux 这2个系统在进行编程实现的时候的一些区别:

很惭愧&#xff0c;学了很多年才意识到&#xff0c;噢&#xff0c;原来这两个系统实现一些功能的时候会使用到不同的库&#xff0c;使用不同的函数。 那么&#xff0c;也会延伸出一些问题&#xff1a; 比如&#xff0c;如何实现版本的迁移。一个在Linux上运行的代码如何可以比…

Instant-NGP中的多分辨率哈希编码

Instant-NGP的出现&#xff0c;无疑给神经表达领域带来了新的生命力。可认为是NeRF诞生以来的关键里程碑了。首次让我们看到了秒级的重建、毫秒级的渲染的NeRF工作。 作为如此顶到爆的工作&#xff0c;Instant-NGP毫无疑问斩获SIGGRAPH 2022的最佳论文。虽然只是五篇最佳论文之…

微信公众号推送封面图制作:专业技巧大揭秘

在微信公众号推送中&#xff0c;一个吸引人的封面设计是吸引读者点击的重要因素。本文将指导你如何使用免费在线海报制作工具&#xff0c;如乔拓云&#xff0c;来制作一个适合节日的海报模板&#xff0c;并编辑文本、图片以及调整字体、颜色、布局等&#xff0c;最后导出并保存…

【Linux前篇 】VMWare虚拟机安装与环境配置及远程连接 —— windows版

目录 一、操作系统 1.1 什么是操作系统 1.2 常见操作系统 1.3 个人版本和服务器版本的区别 1.4 Linux的各个版本 二、VMWare 虚拟机安装配置流程 2.1 安装 2.2 配置虚拟网络编辑器 三、安装配置 Windows Server 2012 R2 3.1 创建虚拟机 3.2 安装 Windows Server 2012…

Linux文件I/O

下面的内容需要了解系统调用&#xff0c;可看下面的链接&#xff1a; 系统调用来龙去脉-CSDN博客 1.底层文件IO和标准IO 这里指的是操作系统提供的IO服务&#xff0c;不同于ANSI建立的标准IO。 底层IO和标准IO各自所使用的函数&#xff1a; 区别&#xff1a; 1.底层文件IO不…

TDesign设计系统全方位解析

随着互联网的发展和技术的不断更新和迭代&#xff0c;互联网产品类别的周期越来越短&#xff0c;用户需求也在不断提高。对于生产、设计和研究团队来说&#xff0c;有必要进行高效和持续的设计创新。腾讯“腾讯设计云”的研发帮助企业完成高效协作&#xff0c;提高设计开发效率…

SpringCloud学习:一【详细】

目录 服务架构演变 单体架构 分布式架构 分布式架构需要考虑的问题 微服务 架构比较 微服务技术对比 服务拆分注意事项 案例 服务远程调用 RestTemplate Eureka注册中心 RestTemplate存在的问题 服务调用考虑的问题 Eureka的作用 搭建EurekaServer 服务注册 …