当前位置: 首页 > news >正文

物联网中的ESP8266该这么用!

🙌秋名山码民的主页
😂oi退役选手,Java、大数据、单片机、IoT均有所涉猎,热爱技术,技术无罪
🎉欢迎关注🔎点赞👍收藏⭐️留言📝
获取源码,添加WX

目录

  • 1. 前言
  • 2. 概述esp8266
  • 3. AT命令来控制模块
  • 4. MQTT协议的概述
  • 5. 示例
  • 最后


1. 前言

在学习物联网的过程中,大家首先想到的通信应该就是蓝牙和wifi了,而wifi中又属esp8266比较出名,包括esp32的快速崛起也离不开起本身内置wife和蓝牙,这个模块本身可以连接路由器,也可以作为热点让你的手机来连接他。
本文主要从以下几个方面来进行讲解:

  1. 简单概述esp8266
  2. 搞定其AT指令集
  3. MQTT协议的概述
  4. 示例

2. 概述esp8266

ESP8266是一款以太网控制器芯片,由乐鑫科技(Espressif Systems)推出。它是一种低成本、高性能的Wi-Fi模块,广泛应用于物联网和嵌入式系统领域。
在这里插入图片描述

  1. 完整的WIFE网络解决方案,可独立运行,也可作为模块从动装置搭载到其他soc
  2. ESP8266模块内部集成了Wi-Fi无线通信功能,支持802.11b/g/n标准,可以连接到无线网络并进行数据传输。它通过串口与主控设备通信,并提供了AT指令集,简化了与主控设备的交互
  3. 可以采用Arduino IDE、MicroPython、NodeMCU等多种开发环境
  4. ESP8266具有良好的可扩展性,可以通过外部Flash存储器扩展其储存容量,支持OTA(Over-The-Air)固件升级
  5. ESP8266 RTOS SDK,支持FreeRTOS操作系统

具体参数:
在这里插入图片描述
在这里插入图片描述

硬件接口介绍:
在这里插入图片描述

  • UART接口:UART(通用异步收发传输器)接口是ESP8266与其他设备进行串行通信的主要接口,它可通过RX和TX引脚连接到其他设备。通过UART接口,可以实现与计算机、传感器、其他微控制器等设备的数据收发和控制。

  • GPIO口:ESP8266具有多个GPIO(通用输入/输出)口,用于与其他外围设备进行交互。GPIO口支持数字输入输出和PWM功能,可以通过编程来控制各种外设,如LED灯、继电器、开关等。

  • I2C接口:I2C(Inter-Integrated Circuit)接口是一种串行通信接口,可以连接多个设备,使用两根线(SDA和SCL)实现数据传输。ESP8266通过I2C接口可以与其他I2C设备通信,如传感器、显示屏等。

  • SPI接口:SPI(Serial Peripheral Interface)接口也是一种串行通信接口,可以连接多个设备,使用四根线(MISO、MOSI、SCK和SS)实现数据传输。ESP8266通过SPI接口可以与其他SPI设备通信,如Flash存储器、LCD显示屏等。

  • ADC接口:ESP8266内部集成了一个ADC(模数转换器),用于将模拟信号转换为数字信号。ADC接口可以连接到传感器等模拟设备,读取模拟值并将其转换为数字数据。

  • PWM接口:ESP8266的GPIO口支持PWM(脉冲宽度调制)功能,可用于控制电机、灯光等外设的亮度和速度。

  • SDIO接口:SDIO(Secure Digital Input Output)接口是一种高速的串行数据接口,常用于SD卡和MMC卡的读写操作。ESP8266通过SDIO接口可以连接到SD卡或MMC卡,实现数据存储和读取。

3. AT命令来控制模块

esp8266按照乐鑫官方的指令有上百条,但是常用的就10来条,下面我列举一些,其他的读者若需要可以下载乐鑫的用户手册查看。

  1. AT:测试ESP8266模块是否在线,并返回“OK”表示模块正常工作。
  2. AT+RST:重置ESP8266模块,并返回“ready”表示模块已经准备好。
  3. AT+CWMODE=:设置ESP8266的工作模式,其中参数取值为1、2或3,分别对应STA模式、AP模式和STA+AP模式。
  4. AT+CWJAP=,:连接到指定的Wi-Fi网络,其中和分别为需要连接的Wi-Fi网络名称和密码。该指令执行成功后,ESP8266会自动获取IP地址。
  5. AT+CIFSR:获取ESP8266当前IP地址。
  6. AT+CIPMUX=:设置ESP8266的多连接模式,其中参数取值为0或1,分别表示单连接模式和多连接模式。
  7. AT+CIPSTART=,,:建立TCP或UDP连接,其中参数为“TCP”或“UDP”,参数为连接目标IP地址,参数为连接目标端口号。
  8. AT+CIPSEND=:设置ESP8266发送数据的长度,其中参数为待发送数据的长度,发送数据时需先执行该指令。
  9. AT+CIPCLOSE:关闭ESP8266当前连接。

记得把端口打开:Windows打开特定端口

使用的调试助手为野火多功能调试助手
在这里插入图片描述

AT参考

4. MQTT协议的概述

MQTT(Message Queuing Telemetry Transport)是一种轻量级的、基于发布/订阅模型的消息传输协议,适用于物联网和移动应用等场景,他们之间的关系大概就像下面这张图一样:
在这里插入图片描述
具体协议介绍,后续有机会,单独开一篇来讲解。

5. 示例

代码取自野火,完整代码在野火论坛,公开资料

通用代码:

  1. 初始化函数
void ESP8266_Init ( void )
{ESP8266_GPIO_Config (); ESP8266_USART_Config (); macESP8266_RST_HIGH_LEVEL();macESP8266_CH_ENABLE();}
  1. 初始化GPIO
static void ESP8266_GPIO_Config ( void )
{/*定义一个GPIO_InitTypeDef类型的结构体*/GPIO_InitTypeDef GPIO_InitStructure;/* 配置 CH_PD 引脚*/macESP8266_CH_PD_APBxClock_FUN ( macESP8266_CH_PD_CLK, ENABLE ); GPIO_InitStructure.GPIO_Pin = macESP8266_CH_PD_PIN;	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init ( macESP8266_CH_PD_PORT, & GPIO_InitStructure );	 /* 配置 RST 引脚*/macESP8266_RST_APBxClock_FUN ( macESP8266_RST_CLK, ENABLE ); GPIO_InitStructure.GPIO_Pin = macESP8266_RST_PIN;	GPIO_Init ( macESP8266_RST_PORT, & GPIO_InitStructure );	 }
  1. 初始化串口
static void ESP8266_USART_Config ( void )
{GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;/* config USART clock */macESP8266_USART_APBxClock_FUN ( macESP8266_USART_CLK, ENABLE );macESP8266_USART_GPIO_APBxClock_FUN ( macESP8266_USART_GPIO_CLK, ENABLE );/* USART GPIO config *//* Configure USART Tx as alternate function push-pull */GPIO_InitStructure.GPIO_Pin =  macESP8266_USART_TX_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(macESP8266_USART_TX_PORT, &GPIO_InitStructure);  /* Configure USART Rx as input floating */GPIO_InitStructure.GPIO_Pin = macESP8266_USART_RX_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(macESP8266_USART_RX_PORT, &GPIO_InitStructure);/* USART1 mode config */USART_InitStructure.USART_BaudRate = macESP8266_USART_BAUD_RATE;USART_InitStructure.USART_WordLength = USART_WordLength_8b;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(macESP8266_USARTx, &USART_InitStructure);/* 中断配置 */USART_ITConfig ( macESP8266_USARTx, USART_IT_RXNE, ENABLE ); //使能串口接收中断 USART_ITConfig ( macESP8266_USARTx, USART_IT_IDLE, ENABLE ); //使能串口总线空闲中断 	ESP8266_USART_NVIC_Configuration ();USART_Cmd(macESP8266_USARTx, ENABLE);}
  1. 配置中断
static void ESP8266_USART_NVIC_Configuration ( void )
{NVIC_InitTypeDef NVIC_InitStructure; /* Configure the NVIC Preemption Priority Bits */  NVIC_PriorityGroupConfig ( macNVIC_PriorityGroup_x );/* Enable the USART2 Interrupt */NVIC_InitStructure.NVIC_IRQChannel = macESP8266_USART_IRQ;	 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);}

常规的结束,接下来就是移植代码,ESP8266,接收发送模块化代码


/** 函数名:ESP8266_Rst* 描述  :重启WF-ESP8266模块* 输入  :无* 返回  : 无* 调用  :被 ESP8266_AT_Test 调用*/
void ESP8266_Rst ( void )
{#if 0ESP8266_Cmd ( "AT+RST", "OK", "ready", 2500 );   	#elsemacESP8266_RST_LOW_LEVEL();Delay_ms ( 500 ); macESP8266_RST_HIGH_LEVEL();#endif}/** 函数名:ESP8266_Cmd* 描述  :对WF-ESP8266模块发送AT指令* 输入  :cmd,待发送的指令*         reply1,reply2,期待的响应,为NULL表不需响应,两者为或逻辑关系*         waittime,等待响应的时间* 返回  : 1,指令发送成功*         0,指令发送失败* 调用  :被外部调用*/
bool ESP8266_Cmd ( char * cmd, char * reply1, char * reply2, u32 waittime )
{    strEsp8266_Fram_Record .InfBit .FramLength = 0;               //从新开始接收新的数据包macESP8266_Usart ( "%s\r\n", cmd );if ( ( reply1 == 0 ) && ( reply2 == 0 ) )                      //不需要接收数据return true;Delay_ms ( waittime );                 //延时strEsp8266_Fram_Record .Data_RX_BUF [ strEsp8266_Fram_Record .InfBit .FramLength ]  = '\0';macPC_Usart ( "%s", strEsp8266_Fram_Record .Data_RX_BUF );if ( ( reply1 != 0 ) && ( reply2 != 0 ) )return ( ( bool ) strstr ( strEsp8266_Fram_Record .Data_RX_BUF, reply1 ) || ( bool ) strstr ( strEsp8266_Fram_Record .Data_RX_BUF, reply2 ) ); else if ( reply1 != 0 )return ( ( bool ) strstr ( strEsp8266_Fram_Record .Data_RX_BUF, reply1 ) );elsereturn ( ( bool ) strstr ( strEsp8266_Fram_Record .Data_RX_BUF, reply2 ) );}/** 函数名:ESP8266_AT_Test* 描述  :对WF-ESP8266模块进行AT测试启动* 输入  :无* 返回  : 无* 调用  :被外部调用*/
//void ESP8266_AT_Test ( void )
//{
//	macESP8266_RST_HIGH_LEVEL();
//	
//	Delay_ms ( 1000 ); 
//	
//	while ( ! ESP8266_Cmd ( "AT", "OK", NULL, 500 ) ) ESP8266_Rst ();  	//}
void ESP8266_AT_Test ( void )
{char count=0;macESP8266_RST_HIGH_LEVEL();	Delay_ms ( 1000 );while ( count < 10 ){if( ESP8266_Cmd ( "AT", "OK", NULL, 500 ) ) return;ESP8266_Rst();++ count;}
}/** 函数名:ESP8266_Net_Mode_Choose* 描述  :选择WF-ESP8266模块的工作模式* 输入  :enumMode,工作模式* 返回  : 1,选择成功*         0,选择失败* 调用  :被外部调用*/
bool ESP8266_Net_Mode_Choose ( ENUM_Net_ModeTypeDef enumMode )
{switch ( enumMode ){case STA:return ESP8266_Cmd ( "AT+CWMODE=1", "OK", "no change", 2500 ); case AP:return ESP8266_Cmd ( "AT+CWMODE=2", "OK", "no change", 2500 ); case STA_AP:return ESP8266_Cmd ( "AT+CWMODE=3", "OK", "no change", 2500 ); default:return false;}}/** 函数名:ESP8266_JoinAP* 描述  :WF-ESP8266模块连接外部WiFi* 输入  :pSSID,WiFi名称字符串*       :pPassWord,WiFi密码字符串* 返回  : 1,连接成功*         0,连接失败* 调用  :被外部调用*/
bool ESP8266_JoinAP ( char * pSSID, char * pPassWord )
{char cCmd [120];sprintf ( cCmd, "AT+CWJAP=\"%s\",\"%s\"", pSSID, pPassWord );return ESP8266_Cmd ( cCmd, "OK", NULL, 5000 );}/** 函数名:ESP8266_BuildAP* 描述  :WF-ESP8266模块创建WiFi热点* 输入  :pSSID,WiFi名称字符串*       :pPassWord,WiFi密码字符串*       :enunPsdMode,WiFi加密方式代号字符串* 返回  : 1,创建成功*         0,创建失败* 调用  :被外部调用*/
bool ESP8266_BuildAP ( char * pSSID, char * pPassWord, ENUM_AP_PsdMode_TypeDef enunPsdMode )
{char cCmd [120];sprintf ( cCmd, "AT+CWSAP=\"%s\",\"%s\",1,%d", pSSID, pPassWord, enunPsdMode );return ESP8266_Cmd ( cCmd, "OK", 0, 1000 );}/** 函数名:ESP8266_Enable_MultipleId* 描述  :WF-ESP8266模块启动多连接* 输入  :enumEnUnvarnishTx,配置是否多连接* 返回  : 1,配置成功*         0,配置失败* 调用  :被外部调用*/
bool ESP8266_Enable_MultipleId ( FunctionalState enumEnUnvarnishTx )
{char cStr [20];sprintf ( cStr, "AT+CIPMUX=%d", ( enumEnUnvarnishTx ? 1 : 0 ) );return ESP8266_Cmd ( cStr, "OK", 0, 500 );}/** 函数名:ESP8266_Link_Server* 描述  :WF-ESP8266模块连接外部服务器* 输入  :enumE,网络协议*       :ip,服务器IP字符串*       :ComNum,服务器端口字符串*       :id,模块连接服务器的ID* 返回  : 1,连接成功*         0,连接失败* 调用  :被外部调用*/
bool ESP8266_Link_Server ( ENUM_NetPro_TypeDef enumE, char * ip, char * ComNum, ENUM_ID_NO_TypeDef id)
{char cStr [100] = { 0 }, cCmd [120];switch (  enumE ){case enumTCP:sprintf ( cStr, "\"%s\",\"%s\",%s", "TCP", ip, ComNum );break;case enumUDP:sprintf ( cStr, "\"%s\",\"%s\",%s", "UDP", ip, ComNum );break;default:break;}if ( id < 5 )sprintf ( cCmd, "AT+CIPSTART=%d,%s", id, cStr);elsesprintf ( cCmd, "AT+CIPSTART=%s", cStr );return ESP8266_Cmd ( cCmd, "OK", "ALREAY CONNECT", 4000 );}/** 函数名:ESP8266_StartOrShutServer* 描述  :WF-ESP8266模块开启或关闭服务器模式* 输入  :enumMode,开启/关闭*       :pPortNum,服务器端口号字符串*       :pTimeOver,服务器超时时间字符串,单位:秒* 返回  : 1,操作成功*         0,操作失败* 调用  :被外部调用*/
bool ESP8266_StartOrShutServer ( FunctionalState enumMode, char * pPortNum, char * pTimeOver )
{char cCmd1 [120], cCmd2 [120];if ( enumMode ){sprintf ( cCmd1, "AT+CIPSERVER=%d,%s", 1, pPortNum );sprintf ( cCmd2, "AT+CIPSTO=%s", pTimeOver );return ( ESP8266_Cmd ( cCmd1, "OK", 0, 500 ) &&ESP8266_Cmd ( cCmd2, "OK", 0, 500 ) );}else{sprintf ( cCmd1, "AT+CIPSERVER=%d,%s", 0, pPortNum );return ESP8266_Cmd ( cCmd1, "OK", 0, 500 );}}/** 函数名:ESP8266_Get_LinkStatus* 描述  :获取 WF-ESP8266 的连接状态,较适合单端口时使用* 输入  :无* 返回  : 2,获得ip*         3,建立连接*         3,失去连接*         0,获取状态失败* 调用  :被外部调用*/
uint8_t ESP8266_Get_LinkStatus ( void )
{if ( ESP8266_Cmd ( "AT+CIPSTATUS", "OK", 0, 500 ) ){if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "STATUS:2\r\n" ) )return 2;else if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "STATUS:3\r\n" ) )return 3;else if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "STATUS:4\r\n" ) )return 4;		}return 0;}/** 函数名:ESP8266_Get_IdLinkStatus* 描述  :获取 WF-ESP8266 的端口(Id)连接状态,较适合多端口时使用* 输入  :无* 返回  : 端口(Id)的连接状态,低5位为有效位,分别对应Id5~0,某位若置1表该Id建立了连接,若被清0表该Id未建立连接* 调用  :被外部调用*/
uint8_t ESP8266_Get_IdLinkStatus ( void )
{uint8_t ucIdLinkStatus = 0x00;if ( ESP8266_Cmd ( "AT+CIPSTATUS", "OK", 0, 500 ) ){if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "+CIPSTATUS:0," ) )ucIdLinkStatus |= 0x01;else ucIdLinkStatus &= ~ 0x01;if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "+CIPSTATUS:1," ) )ucIdLinkStatus |= 0x02;else ucIdLinkStatus &= ~ 0x02;if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "+CIPSTATUS:2," ) )ucIdLinkStatus |= 0x04;else ucIdLinkStatus &= ~ 0x04;if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "+CIPSTATUS:3," ) )ucIdLinkStatus |= 0x08;else ucIdLinkStatus &= ~ 0x08;if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "+CIPSTATUS:4," ) )ucIdLinkStatus |= 0x10;else ucIdLinkStatus &= ~ 0x10;	}return ucIdLinkStatus;}/** 函数名:ESP8266_Inquire_ApIp* 描述  :获取 F-ESP8266 的 AP IP* 输入  :pApIp,存放 AP IP 的数组的首地址*         ucArrayLength,存放 AP IP 的数组的长度* 返回  : 0,获取失败*         1,获取成功* 调用  :被外部调用*/
uint8_t ESP8266_Inquire_ApIp ( char * pApIp, uint8_t ucArrayLength )
{char uc;char * pCh;ESP8266_Cmd ( "AT+CIFSR", "OK", 0, 500 );pCh = strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "APIP,\"" );if ( pCh )pCh += 6;elsereturn 0;for ( uc = 0; uc < ucArrayLength; uc ++ ){pApIp [ uc ] = * ( pCh + uc);if ( pApIp [ uc ] == '\"' ){pApIp [ uc ] = '\0';break;}}return 1;}/** 函数名:ESP8266_UnvarnishSend* 描述  :配置WF-ESP8266模块进入透传发送* 输入  :无* 返回  : 1,配置成功*         0,配置失败* 调用  :被外部调用*/
bool ESP8266_UnvarnishSend ( void )
{if ( ! ESP8266_Cmd ( "AT+CIPMODE=1", "OK", 0, 500 ) )return false;return ESP8266_Cmd ( "AT+CIPSEND", "OK", ">", 500 );}/** 函数名:ESP8266_ExitUnvarnishSend* 描述  :配置WF-ESP8266模块退出透传模式* 输入  :无* 返回  : 无* 调用  :被外部调用*/
void ESP8266_ExitUnvarnishSend ( void )
{Delay_ms ( 1000 );macESP8266_Usart ( "+++" );Delay_ms ( 500 ); }/** 函数名:ESP8266_SendString* 描述  :WF-ESP8266模块发送字符串* 输入  :enumEnUnvarnishTx,声明是否已使能了透传模式*       :pStr,要发送的字符串*       :ulStrLength,要发送的字符串的字节数*       :ucId,哪个ID发送的字符串* 返回  : 1,发送成功*         0,发送失败* 调用  :被外部调用*/
bool ESP8266_SendString ( FunctionalState enumEnUnvarnishTx, char * pStr, u32 ulStrLength, ENUM_ID_NO_TypeDef ucId )
{char cStr [20];bool bRet = false;if ( enumEnUnvarnishTx ){macESP8266_Usart ( "%s", pStr );bRet = true;}else{if ( ucId < 5 )sprintf ( cStr, "AT+CIPSEND=%d,%d", ucId, ulStrLength + 2 );elsesprintf ( cStr, "AT+CIPSEND=%d", ulStrLength + 2 );ESP8266_Cmd ( cStr, "> ", 0, 1000 );bRet = ESP8266_Cmd ( pStr, "SEND OK", 0, 1000 );}return bRet;}/** 函数名:ESP8266_ReceiveString* 描述  :WF-ESP8266模块接收字符串* 输入  :enumEnUnvarnishTx,声明是否已使能了透传模式* 返回  : 接收到的字符串首地址* 调用  :被外部调用*/
char * ESP8266_ReceiveString ( FunctionalState enumEnUnvarnishTx )
{char * pRecStr = 0;strEsp8266_Fram_Record .InfBit .FramLength = 0;strEsp8266_Fram_Record .InfBit .FramFinishFlag = 0;while ( ! strEsp8266_Fram_Record .InfBit .FramFinishFlag );strEsp8266_Fram_Record .Data_RX_BUF [ strEsp8266_Fram_Record .InfBit .FramLength ] = '\0';if ( enumEnUnvarnishTx )pRecStr = strEsp8266_Fram_Record .Data_RX_BUF;else {if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "+IPD" ) )pRecStr = strEsp8266_Fram_Record .Data_RX_BUF;}return pRecStr;}

最后

参考资料:
《乐鑫ESP8266用户手册》
《ESP8266作为TCP服务器端使用心得》
《野火ESP8266部分例程》

如果本文对你有所帮助,还请三连支持一下博主!
请添加图片描述

相关文章:

物联网中的ESP8266该这么用!

&#x1f64c;秋名山码民的主页 &#x1f602;oi退役选手&#xff0c;Java、大数据、单片机、IoT均有所涉猎&#xff0c;热爱技术&#xff0c;技术无罪 &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; 获取源码&#xff0c;添加WX 目录 1. 前言…...

django中循环生成的多个btn,只有第一个btn会弹出模态框

django中循环生成的多个btn&#xff0c;只有第一个btn会弹出模态框 需求&#xff1a;为每个button按钮都绑定同一点击事件&#xff0c;点击每个btn都可弹出模态框 原因 问题代码 <button idbtnDel type"button" class"btn btn-primary btn-lg" > […...

JVM第二十三讲:Java动态调试技术原理

Java动态调试技术原理 本文是JVM第二十三讲&#xff0c;Java动态调试技术原理。转载自 美团技术团队胡健的Java 动态调试技术原理及实践&#xff0c;通过学习java agent方式进行动态调试&#xff0c;了解目前很多大厂开源的一些基于此的调试工具 (例如来自阿里开源的Arthas)。 …...

制造企业如何三步实现进销存管理?

制造企业如何三步实现进销存管理&#xff1f; 一、什么是进销存软件&#xff1f; 进销存软件是一种针对制造业企业设计的管理软件系统&#xff0c;旨在协调和优化企业的生产、采购、销售以及库存管理等方面的活动。该系统的主要目标是提高企业的生产效率、降低库存成本、优化…...

封装localstorage为对象 js

export const LocalStorageManager {recordKey: "Record",// 获取本地存储中的值get(key) {try {const value localStorage.getItem(key);if (value null || value undefined || value "") {return null;}return JSON.parse(localStorage.getItem(key…...

算法通关村第五关|白银|队栈和Hash的经典算法题【持续更新】

1.用栈实现队列 用两个栈实现队列。 class MyQueue {Deque<Integer> inStack;Deque<Integer> outStack;public MyQueue() {inStack new LinkedList<Integer>();outStack new LinkedList<Integer>();}public void push(int x) {inStack.push(x);}pu…...

java--构造器

1.构造器是什么样子 构造器分为无参构造(就相当于你有车子&#xff0c;但是里面是空的)和带参构造(就相当于你有车子&#xff0c;里面还有几个妹纸&#xff0c;你真该死啊) 2.构造器有什么特点 创建对象时&#xff0c;对象会去调用构造器。 3.构造器的常见应用场景 创建对象…...

纪念基于JavaScript 实现的后台桌面 UI 设计

目录 前言 C/S 到 B/S ASP Builder 的诞生 关于 Craneoffice.net 开发环境配置 后台界面的 UI 区域要素 桌面系统的想法和设计 搜索引擎 导航面板 快捷访问 二级导航 小组件及其它 设置桌面壁纸 小时钟 附件小程序 计算器界面设计 日历与任务 系统设置 天气小…...

C++11 auto限制

限制&#xff1a; auto 不能用于函数参数auto 不能用于非静态成员变量auto 无法定义数组auto 无法推导出模板参数 推荐一个零声学院项目课&#xff0c;个人觉得老师讲得不错&#xff0c;分享给大家&#xff1a; 零声白金学习卡&#xff08;含基础架构/高性能存储/golang云原生…...

公司老项目springmvc jsp 自定义多数据源 转到springboot 整理

真实完整步骤&#xff0c;踩坑整理 有同样的坑&#xff0c;欢迎补充整理 网上的案例老是少了很多配置&#xff0c;本案例涉及到 spring-mvc&#xff0c;自定义多数据源&#xff0c;统一前缀&#xff0c;事务&#xff0c;mybatis&#xff0c;jsp访问异常&#xff0c;静态文件。…...

Java之SpringCloud Alibaba【七】【Spring Cloud微服务网关Gateway组件】

一、网关简介 大家都都知道在微服务架构中&#xff0c;一个系统会被拆分为很多个微服务。那么作为客户端要如何去调用这么多的微服务呢?如果没有网关的存在&#xff0c;我们只能在客户端记录每个微服务的地址&#xff0c;然后分别去用。 这样的架构&#xff0c;会存在着诸多…...

探讨jdk源码中的二分查找算法返回值巧妙之处

文章目录 1.什么是二分查找算法1.1 简介1.2 实现思路 2.二分查找的示例3.jdk 中的 Arrays.binarySearch()4.jdk 中核心二分查找方法解析4.1 为什么 low 是插入点4.2 为什么要进行取反&#xff1a;-&#xff08;low 1&#xff09;4.3 为什么不直接返回 插入点 low 的相反数&…...

深度学习实战:基于TensorFlow与OpenCV的手语识别系统

文章目录 写在前面基于TensorFlow与OpenCV的手语识别系统安装环境一、导入工具库二、导入数据集三、数据预处理四、训练模型基于CNN基于LeNet5基于ResNet50 五、模型预测基于OpenCV 写在后面 写在前面 本期内容&#xff1a;基于TensorFlow与OpenCV的手语识别系统 实验环境&…...

学习整理nginx常用屏蔽规则,让网站更安全

学习整理nginx常用屏蔽规则&#xff0c;让网站更安全 注意一、防止文件被下载二、屏蔽非常见蜘蛛&#xff08;爬虫&#xff09;三、禁止某个目录执行脚本四、屏蔽某个IP或IP段 注意 在开始之前&#xff0c;希望您已经熟悉的Nginx常用命令&#xff08;如停止&#xff0c;重启等…...

四十一、【进阶】索引使用SQL提示

1、SQL提示使用情景 在使用MySQL时&#xff0c;当一个字段参在于多个索引中时&#xff0c;默认情况下&#xff0c;MySQL会自动选择一个索引&#xff0c;但我们可以指定索引吗&#xff1f;可以忽略某一种索引吗&#xff1f; 答案是可以的。 前提&#xff1a;profession字段已经…...

AI智能分析网关高空抛物算法如何实时检测高楼外立面剥落?

高楼外立面剥落是一种十分危险的行为&#xff0c;会造成严重的人身伤害和财产损失。TSINGSEE青犀智能分析网关利用高楼外立面剥落的信息&#xff0c;结合高空抛物算法来进行处理就可很好解决此问题。 1. 数据收集 首先&#xff0c;需要收集关于高楼外立面剥落的数据。这可以通…...

微信小程序 - 页面继承(非完美解决方案)

微信小程序 - 面页继承&#xff08;非完美解决方案&#xff09; 废话思路首页 indexindex.jsindex.jsonindex.wxml 父页面 page-basepage-base.jspage-base.wxml 子页面 page-apage-a.jspage-a.wxml 子页面 page-bpage-b.jspage-b.wxml 其它app.jsapp.jsonapp.wxss 参考资料 废…...

智能配件管理系统有什么用?企业如何实现管理数字化转型?

在当今高度信息化的时代&#xff0c;企业运营的各个环节都离不开准确及时的数据支持。特别是在制造业中&#xff0c;生产数据的记录和管理对于提高生产效率、降低成本、优化资源配置等方面具有至关重要的作用。然而&#xff0c;许多企业仍在采用纸质流转卡来记录生产数据&#…...

@SuppressWarnings注解使用说明

在Java编程中&#xff0c;我们常常会遇到一些警告&#xff08;warnings&#xff09;&#xff0c;这些警告通常是对某些潜在问题的提示&#xff0c;虽然这些问题可能不会立即影响程序的运行&#xff0c;但可能会在将来引发问题。为了消除这些警告&#xff0c;我们可以使用Suppre…...

算法从入门到入土cpp版

1. 排序 1. 快速排序 # include<iostream> using namespace std;const int N 100010;int q[N];void quick_sort(int q[], int l, int r) {if(l>r) return;int il-1,jr1,tempq[l];while(i<j){do i;while(q[i]<temp);do j--;while(q[j]>temp);if(i<j)swa…...

VSCode无法转到定义python源码(ctrl加单击不跳转)

已经尝试的方案&#xff1a; 1.确保对应python环境正确激活 在 VSCode 中&#xff0c;打开命令面板&#xff08;CtrlShiftP&#xff09;&#xff0c;输入并选择 Python: Select Interpreter&#xff0c;然后从列表中选择正确的 Python 解释器。 2.重新卸载Python插件再重新安装…...

Kotlin-特殊类型

文章目录 数据类型枚举类型匿名类和伴生对象单例类伴生对象 数据类型 声明一个数据类非常简单: //在class前面添加data关键字表示为一个数据类 data class Student(var name: String, var age: Int)数据类声明后,编译器会根据主构造函数中声明的所有属性自动为其生成以下函数…...

【Net】TCP粘包与半包

文章目录 TCP粘包与半包1 背景2 粘包&#xff08;packet stick&#xff09;3 半包&#xff08;packet split&#xff09;4 为什么会出现粘包/半包&#xff1f;5 如何解决&#xff1f;6 示例7 总结 TCP粘包与半包 在网络编程中&#xff0c;粘包和半包问题是常见的 TCP 协议特有…...

JavaScript性能优化:实战技巧提升10倍速度

JavaScript 性能优化实战技术文章大纲 基础优化策略 减少 DOM 操作&#xff1a;频繁的 DOM 操作会导致重绘和回流&#xff0c;影响性能。使用文档片段&#xff08;DocumentFragment&#xff09;或虚拟 DOM 技术优化批量操作。 避免全局变量污染&#xff1a;全局变量会增加内…...

「Java教案」算术运算符与表达式

课程目标 1&#xff0e;知识目标 能够区分Java运算符的种类&#xff0c;例如&#xff0c;算术、赋值、关系、逻辑、位运算等。能够区分Java各类运算符的功能和使用场景。能够根据表达式的构成和计算规则&#xff0c;写出正确的表达式。能够根据运算符优先级与结合性&#xff…...

java对接bacnet ip协议(跨网段方式)

1、环境准备 #maven环境<repositories><repository><id>ias-releases</id><url>https://maven.mangoautomation.net/repository/ias-release/</url></repository></repositories><dependencies><dependency><…...

windows11安装编译QtMvvm

windows11安装编译QtMvvm 1 从github下载代码2 官方的Download/Installtion3 自行构建编译QtMvvm遇到的问题3.1 `qmake`问题执行命令报错原因分析qmake报错:找不到编译器 cl解决方案3.2 `make qmake_all`问题执行命令报错原因分析make命令未识别解决方案3.3 缺少`perl`问题执行…...

RAG理论基础总结

目录 概念 流程 文档收集和切割 读取文档 转换文档 写入文档 向量转换和存储 搜索请求构建 向量存储工作原理 向量数据库 文档过滤和检索 检索前 检索 检索后 查询增强和关联 QuestionAnswerAdvisor查询增强 高级RAG架构 自纠错 RAG&#xff08;C-RAG&#xf…...

解决:输入SSH后,仍无法通过网址登录以及紧接着的新问题Permission denied(publickey,password).

现象&#xff1a; 管理员: Windows PowerShell输入SSH后&#xff0c;仍无法通过网址登录 例如输入你的ssh命令&#xff1a;ssh -CNg -L xxxx:127.0.0.1:xxxx rootaaaaaaaaa.com -p yyyyy 得到终端提示&#xff1a;ssh无法识别为 cmdlet、函数、脚本文件或可运行程序的名称。 解…...

容器化革命:告别传统Dockerfile,拥抱现代构建最佳实践

前言 还记得我第一次自信满满地写Dockerfile时,感觉自己像个DevOps天才👑。但很快我就发现,管理这些文件变成了噩梦——安全问题、意外的构建问题、臃肿的镜像层出不穷。如果你一直在手动编写Dockerfile,让我告诉你:有更好的方法! 本文将揭示传统Dockerfile编写方式的…...