基于STM32F103最小系统板和DL-LN33 2.4G通信 ZigBee无线串口自组网采集温湿度

news2024/11/26 2:29:01

文章目录

  • 前言
    • 一、组网概述
    • 二、产品特性
    • 三、电气特性
    • 四、引脚配置
    • 五、UART通信协议
      • 5.1 UART参数
      • 5.2 包分割
      • 5.3 端口
      • 5.4 举例通信
        • 5.4.1 一个节点给另一个节点发送数据
        • 5.4.2 一个节点给另一个节点的内部端口发送数据
        • 5.4.3 一个节点给自己的内部端口发送数据
        • 5.4.4 不推荐的数据传输情况
      • 5.5 内部端口
        • 5.5.1 红灯闪烁控制端口
        • 5.5.2 基本信息管理端口
        • 5.5.3 错误报告端口
    • 六 参考示例
  • 总结


前言

  DL-LN3X 系列模块是新晋推出的无线通信模块,该模块专为需要自动组网多跳传输的应用场合设计。相对于其他常见的自组网无线通信解决方案,本方案更加灵活、可靠,可长期稳定工作;用户可以抛开复杂的协议栈和芯片手册,只需要掌握简单的串口通讯便可驾驭无线多跳传输。

一、组网概述

  DL-LN3X 模块是一种自组网多跳无线通信模块。模块无线频率为 2.4GHz~2.45GHz,属于全球免费的无线频段。该模块工作时,会与周围的模块自动组成一个无线多跳网络,此网络为对等网络,不需要中心节点,网络包含以下可配置参数:
  将多个 DL-LN3X 模块配置成地址不相同,信道和网络 ID 相同的状态,模块将组成一个网络。微控制器(MCU)或者电脑通过 Uart 告诉模块目标地址和待发送的数据,模块会通过网络选择最优的路径,将信息传输给目标模块,而目标模块将通过Uart 输出源地址和上述的数据。

  DL-LN3X 模块使用定向扩散协议寻找路由,这种路由算法会记录网络的状态,每个节点平均可记录 190 个目标节点的路由,在网络建立后传输速度和传输延时可到达最优。但这种算法网络建立较慢,在节点刚刚启动时,网络需要 1~5 分钟的时间重新生成路由,在这段时间内网络使用洪泛路由进行数据通信,此时网络的传输速度较慢。

二、产品特性

  1. 定向扩散型自组网协议
     模块上电后会自动组成多跳网状网络,完全不需要用户干预。
     每个模块都可以给网络中任意一个节点发送数据。
     带有确认传输功能,无线传输使用 CRC 校验,最多重传 15 次。
     网络中任何节点故障不影响整个网络的运行,具有很强的抗毁性。
     最大可支持 190 个模块组成网络,模块地址可通过 Uart 进行修改。
     单个包长可达 63 字节,带有数据包缓冲机制。
  2. 用户接口简单易学
     使用 uart 作为交互接口。
     波特率可调。
     使用长度可变的包传输数据,使用安全的数据分包协议。
     支持端口分割机制。
  3. 程序工作稳定
     操作系统基于线程切片,工作稳定。
     使用内存池代替堆完成动态内存分配,长期工作不产生内存碎片。
  4. 带有指示灯
     模块带有收/发包指示灯。
     模块带有定位指示灯,可以远程点亮,方便寻找。

三、电气特性

参数
工作电压 / 电流2.5~3.6V / 小于30mA
无线发送功率4.5dBm
工作频率2400~2450MHz
传输速率因为发送包的路由信息会占用一定的带宽,每个包的长度越长,发送效率越高。每个包包含 3Byte 数据时,2400Bit/s。每个包包含 30Byte 数据时,10KBit/s。
天线接口板载 PCB 天线
工作信道符合 IEEE802.15.4 协议的 16 个信道划分
通信接口UART 通信(支持 8 种波特率:2400/4800/9600/14400/19200/28800/38400/57600/115200/230400/125000/250000/500000)
接收灵敏度-97dBm
组网最大跳数 / 节点数 / 包长度15 跳 / 典型值为 190 个点 / 63Byte
丢包重传次数最多 15 次,网络负载高时,最少 5 次。
空中速率 / 延时250KBit/s / 节点间单挑,小于 10ms。
工作温度-40°C~85°C
模块尺寸18*23.5mm
传输距离70 米(空旷无遮挡)

四、引脚配置


五、UART通信协议

5.1 UART参数

DL-LN3X 模块使用 Uart 接口作为数据交互接口,接口的参数如下:
数据位    8 位
起始位    1 位
停止位    1 位
校验位    无校验
Uart 接口的波特率可以被用户设置为以下值:UART
  2400 4800 9600 14400 19200 28800 38400 57600 115200 230400 125000 250000 500000
几乎任何单片机的 Uart 输出都可以和 DL-LN3X 模块的 UART 进行通讯,电脑串口则可以使用 MAX3232 芯片转换为 UART 与 DL-LN3X 进行通信。

5.2 包分割

在通信过程中,最常见的场合是单片机通过UART告诉模块这样的信息:
“将数据 00 AE 13 33 发往地址为 0003 的模块,目标端口为 90,源端口为 91。”
对于单片机,需要将这些信息整理成一个包,通过UART发给模块:FE 08 91 90 03 00 00 AE 13 33 FF
此包的说明如下表:
  远程地址长度为 2byte,使用小端模式进行传输,即先传输低 8 位,再传输高 8 位。
  传输过程中如果遇到数据部分、地址或者端口号中出现 FF,则使用 FE FD 来代替;如果出现 FE,则用 FE FC 来代替。以免传输过程中出现的包头和包尾,使接收方误判断。在传输中这种替换称为“转义”。
  包长度不会受到转义的影响,例如发送的数据为 09 FF 时,替换为 09 FE FD,但包头中的数据长度仍然按照 2+4来计算,这样,发送的包如下:FE 06 91 90 03 00 09 FE FD FF
  虽然一共传输了 7 个字节,但包长为 6。如果地址、端口号中出现了 FF、FE 也需要进行转义。

5.3 端口

  DL-LN3X 模块设计了端口的概念,接收方收到一个包时,会根据包的端口号,选择对应的程序处理包。端口号的取值范围是0x00 ~ 0xFF,其中 0x00 ~ 0x7F端口由模块内部程序占用,用于调试设计, 0x80~0xFF 端口开放给 UART 连接的 MCU 或者电脑。
  当 MCU 给一个模块发送数据时,如果源端口号填写了小于 0x80 的值,则包无法发出;如果目的端口号填写了小于 0x80 的值,接收方模块的内部程序将处理这个包并执行相关的动作,而不是从 UART 发出这个包。
  例如发送这个包:FE 05 91 20 03 00 0A FF
  则会让地址为 03 00 的模块自带的红灯点亮 1 秒,而他的 UART 不会输出数据。

5.4 举例通信

5.4.1 一个节点给另一个节点发送数据

  例如将多个节点组成如下网络,在本文中节点特指 PC 或 MCU 和 DL-LN3X 模块组成的硬件设备。MCU 采集到温湿度为温度 23℃,湿度 60%,则无线传输的数据是 0x17,0x3C。节点和电脑都使用 A0 端口传输温度,A1 端口传输湿度,MCU 已知连接电脑的模块地址为 0x000F,则 MCU 发给模块的数据为:
  FE 05 A0 A0 0F 00 17 FF FE 05 A1 A1 0F 00 3C FF
则电脑串口收到的数据为:
  FE 05 A0 A0 01 00 17 FF FE 05 A1 A1 01 00 3C FF
电脑串口收到的数据中远程地址被替换为了源节点的地址。

5.4.2 一个节点给另一个节点的内部端口发送数据

寻找当前网络地址节点,如寻找地址为 0x0002 的节点时,PC 命令此模块的红灯点亮 5 秒,则 PC 发送:
  FE 05 A3 20 02 00 32 FF
可以看到地址为 0x0002 的模块红灯点亮 5 秒。

5.4.3 一个节点给自己的内部端口发送数据

  模块可以给自己的端口发送数据。详细说明看后面介绍。

5.4.4 不推荐的数据传输情况

使用当前节点网络,不推荐的传输情况有以下两种。

  1. 模块使用小于 80 的端口号作为源端口号,例如模块发送 FE 05 20 20 02 00 32 FF 则模块会收到一个端口号错误报告包:FE 06 22 20 02 00 E0 20 FF,实际上,模块不会传送任何数据,所以这样的传输是不推荐的。
  2. 模块给自己的某个端口传输数据。例如地址为 0x000F 的节点,传输数据给自己的 80 端口,模块发送FE 05 81 80 0F 00 32 FF,则自己会收到 FE 05 81 80 0F 00 32 FF,节点的单片机自己给自己传输了一条数据,这显然是不必要的,所以这样的传输是不推荐的。

5.5 内部端口

  模块内部已经规定的端口,包括这些端口可以接受的包,以及这些这些端口会发出的包。在对包进行说明时,仅对数据部分进行说明。例如:

  此包是一个端口 21 可以接受的包,则实际通过UART 发出的数据是:FE 07 91 21 00 00 12 98 88 FF,其中 91 可以是任意端口号,00 00 是目标地址,12 为命令,98 99 为新网络 ID。

5.5.1 红灯闪烁控制端口

  端口 0x20 用于控制模块的红色 LED 点亮,发送此包可以使模块的红色 LED 点亮一定时间。发出数据是: FE 05 80 20 00 00 01 FF,其中 20 是控制LED的端口号,00 00 是目标地址,01 为点亮时间。
此端口可接收以下包:

  发送这个数据给此模块可以点亮红色 LED,用户既可以给本地模块发送这个包,也可以给远程模块发送这个包。
这一功能用于测试一个指定地址的模块是否包含在网络中,如果想从许多节点中迅速找到某个特定地址的节点,也可以使用此功能。

5.5.2 基本信息管理端口

  端口 0x21 用于配置模块的基本参数,包括 地址,网络 ID,信道和波特率。此端口只接受远程地址填写 0x0000 的包,因此,这些信息的读取和修改只能通过本模块的 UART进行,不能远程操作。
  如果不知道模块配置的波特率,可以将 BaudReset 引脚连接到 GND,这样便可以使用 115200 波特率对模块进
行配置。
  注意: 只有使用 0x0000 作为目标地址才能与 21 端口进行通信,0x0000 即模块的本地地址。

  向模块发送配置命令后,模块会返回 FE 05 21 90 00 00 00 FF,表示配置完成,返回信息会指示发包的错误,错误信息详见响应包 。
  最后如果配置信息确认无误,向模块发送 FE 05 90 21 00 00 10 FF,模块会进行重启,然后使用新的参数进行工作。

5.5.3 错误报告端口

  端口 0x22 用于报告通信错误,用户不能向这个端口发送数据,当用户发送数据使用不合法的地址时,这个端口会发送错误报告包:

  当用户发送源地址小于 0x80 的包时,将会收到来自这个端口的错误报告

六 参考示例

  1.准备工作:两个以上DL-LN33组网模块(一主多从),两个个USB转TTL,一个DHT11温湿度传感器、STM32F103C8T6最小系统板。
  2.引脚接线

DL-LN33、DHT11USB-TTL、STM32最小系统板
LN33 / DHT11-VCC3.3V
LN33 / DHT11-GNDGND
LN33-TXUSB-TTL:RX,PB11
LN33-RXUSB-TTL:TX,PB10
DHT11-DPB8

  3.两个USB转TTL分别连接两个组网模块,通过拓扑软件观察组网情况和收发包数据,(红色节点为主节点)

   注: 组网测试拓扑,1. 拓扑软件会占用网络资源传输组网信息,会让网络传输速度变慢,适合用于检测网络连接情况,不适合长期使用;2. 拓扑软件会自动避让正常通信,让通信先进行,在网络较大时会出现拓扑获取失败,但不意味网络出现异常
  4.获取主节点地址(接USB转TTL为主节点,接最小系统板为从节点)
  5.参考例程

/** main.c **/
#include "led.h"
#include "lee.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "dht11.h" 	
#include "package.h"
#include "DL_LN3X.h"
#include "usart3.h"			 	 
#include "string.h"	  
#include <stdio.h>  
//温湿度采集实验
void recievePkg(sPkg* pkg);
void loopReceive(void);
void loopAll(void);
void initAll(void);
extern void uartRevieveByte(u8 data);

	u8 temperature;  	    
	u8 humidity;  
//newPkg(num)是一个宏,这个宏展开后是一个包结构体,包的数据部分长度是num
//使用下面的语句可以在RAM中生成一个带有3个数据的包
//newPkg(3) redPkg={	
//	.length = 7,
//	.src_port = 0x90,
//	.dis_port = 0x32,
//	.remote_addr = 0x0000,
//	.data = {0,10,20}
//};

newPkg(3) redPkg={7,0x90,0x32,0x00,0x00,{0,10,20}};

char buf1[7]={0x05,0x90,0x21,0x00,0x00,0x01,0xFF};//读取模块的地址指令,注意最前面的0xFE不加到数组里面,因为sendPkg函数里面自动会发0xfe
char buf2[7]={0x05,0x90,0x21,0x00,0x00,0x02,0xFF};//读取模块的网络ID指令
char buf3[7]={0x05,0x90,0x21,0x00,0x00,0x03,0xFF};//读取模块的信道指令
char buf4[7]={0x05,0x90,0x21,0x00,0x00,0x04,0xFF};//读取模块的波特率指令

newPkg(1) THPkg={5,0x90,0x32,0xCB,0x36,{0}};//注意包格式,0xCB,0x36为主节点地址

void loopAll()
{ 
	u16 i;
	u8 reclen=0;  
	u8 m=0;

	while (1)
	{
		DHT11_Read_Data(&temperature,&humidity);//读取温湿度值	
		THPkg.dis_port = 0xa0;
		THPkg.data[0] = temperature;
		sendPkg((sPkg*)(&THPkg));

		for(i = 0;i<100;i++)
		{
			delay_ms(10);
			loopReceive();
		}		
		THPkg.dis_port = 0xa1;
		THPkg.data[0] = humidity;
		sendPkg((sPkg*)(&THPkg));

		if(USART3_RX_STA&0X8000)			//接收到一次数据了
		 {

		   reclen=USART3_RX_STA&0X7FFF;	//得到数据长度
			 
			 for(i=0;i<reclen;i++)
			 uartRevieveByte(USART3_RX_BUF[i]);

			 USART3_RX_STA=0;	 
		 }

		for(i = 0;i<100;i++)
			{
				delay_ms(10);
				loopReceive();
			}		 							
	}
}

//这个函数需要在工作中不断被调用,它会尝试一次接收包,
//如果接收成功就交给recievePkg处理,并再次尝试,直到收不到新的包
void loopReceive(void)
{
	sPkg* pkg;
	pkg = getNextPkg();
	while(pkg != NULL)
	{
		recievePkg(pkg);
		pkg = getNextPkg();
	}
}

//收到一个包后会调用这个函数,这个函数根据包的目的端口选择相应的程序进行处理
void recievePkg(sPkg* pkg)
{
	//printf((char*) pkg);//通过串口1发送给电脑,用于测试
	switch(pkg->dis_port)
	{
		case 0xb0:		
		if(pkg->data[0] == 0x01)
		{
		//	greenTog();
		LED0=!LED0;//闪烁LED,提示系统正在运行.
		}
		break;
		default:
		break;		
	}
}

void initAll()
{
	delay_init();	    	 //延时函数初始化	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2
	uart_init(115200);	 //串口1初始化为9600
	usart3_init(115200);//串口3初始化为9600
	LED_Init();		  	 //初始化与LED连接的硬件接口 
}

 int main(void)
 {	
	initAll();
	loopAll();
}


/** DL_LN3X.c **/ 

#include "lee.h"
#include "led.h"
#include "package.h"
#include "usart.h"
#include "sys.h"

//接收包使用的结构体,将端口和地址都融入了data中
typedef struct sPkgBase__
{
	u8 length;
	u8 data[63];
}sPkgBase;

//收到包头函数
static void recvHead(u8 totle);
//收到包尾0xff
static void recvTerminal(void);
//收到数据函数
static void recvData(u8 data);
//这个标志在上一个收到了0xfe时赋值为yes,否则为0
static u8 escape = no;

//串口收到1byte数据时,中断中调用此函数
void uartRevieveByte(u8 data)
{
	switch(data)
	{
		case 0xff://收到结束符
		recvTerminal();
		break;
		case 0xfe://收到转义字符
		escape = yes;
		break;
		default://收到一般数据
		if(escape == yes)
		{//如果前一个是转义字符
			escape = no;
			if(data <=63)
			{
				recvHead(data);
			}
			else
			{//收到转义数据的规律是0xfe后面的数据+2还原数据
				recvData(data+2);
			}
		}
		else
		{//前一个不是转义字符,直接收到一个数据
			recvData(data);
		}
		break;
	}
}

//接收包使用的双缓冲,其中一个供程序使用,另一个用来装入下一个包.
static sPkgBase recv_temp[2];
//确定双缓冲中哪个用于接收,哪个程序分析的变量
static volatile  u8 Loading = 0;
//用于接收装入数据的缓冲
#define Load_pkg recv_temp[Loading]
//用于程序分析的缓冲
#define User_pkg recv_temp[(Loading+1)&1]

//接收计数器,表示一个包收到了多少个数据
#define RS_IDLE 0XFF//表示包还没有收到包头和长度
#define RS_DONE 0xA0//表示包已经完成了接收
static volatile u8 Recv_counter = RS_IDLE;

//如果User_pkg装有一个未处理的包,此变量为 yes
static volatile u8 Received = no;
//如果用户正在分析User_pkg中的数据此变量为 yes
static volatile u8 Locked = no;


//调用这个函数说明上一个包已经处理完了,并尝试接收一个包,
//如果已经收到包,则返回一个指向包的指针,否则返回null
sPkg* getNextPkg(void)
{
//	cli();
	sPkg* rev;
	
	Locked = no;

	if(Received == yes)
	{//两个缓冲区交换过,receive就是yes进入这里
		Received =no;
		Locked = yes;
		rev = (sPkg*)(&User_pkg);
	}
	else
	{//还没有交换,那么是否应该交换呢?
		if(Recv_counter == RS_DONE)
		{//如果另一个缓冲已经收完了就应该交换
			Loading++;
			Loading&=1;
			Recv_counter = RS_IDLE;	
			Locked = yes;
			rev = (sPkg*)(&User_pkg);			
		}
		else
		{//否则返回空,说明没有包待处理
			rev = NULL;
		}		
	}	
	//sei();
	return rev;
}

static void recvHead(u8 totle)
{
	if(Recv_counter == RS_IDLE)
	{
		Load_pkg.length = totle;
		Recv_counter = 0;
	}
}

static void recvData(u8 data)
{	
	if(Recv_counter < Load_pkg.length)
	{		
		Load_pkg.data[Recv_counter] = data;
		Recv_counter++;
	}
	else
	{
		Recv_counter = RS_IDLE;
	}
}

static void recvTerminal(void)
{
	if(Recv_counter == Load_pkg.length)
	{//收到完成的包
		if(Locked == no)
		{//调换缓冲区
			Loading++;
			Loading&=1;
			Received = yes;
			Recv_counter = RS_IDLE;
		} 
		else
		{//不调换缓冲区
			Recv_counter = RS_DONE;
		}
	}
	else
	{	//收到不完成的包,需要重新收	
		Recv_counter = RS_IDLE;
	}
}

  6.测试结果

总结

  1. 网络ID和信道相同可以组成网络互相通信
  2. 两个网络信道相同,网络ID不同,则不能相互通信,如果两个网络距离较近,则两个网络共享信道,传输速率下降
  3. 两个网络信道不同,则不能相互通信、互不干扰
  4. 网络ID不可以是0x0000和0xFFFF
  5. 信道必须是0x0B到0x1A之间的一个

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

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

相关文章

【单片机毕业设计选题24033】-基于STM32的智能饮水机设计

系统功能: 系统上电后显示“欢迎使用智能饮水系统请稍后”两秒后进入正常显示页面。 第一页面第一行显示“系统状态信息”&#xff0c;第二行显示温湿度信息&#xff0c;第三行显示 水温&水位值&#xff0c;第四行显示系统状态&#xff08;锁定或解锁状态&#xff09;。…

World of Warcraft [CLASSIC] Level 70 Dire Maul (DM)

[月牙钥匙] [大型爆盐炸弹] World of Warcraft [CLASSIC] Level 70 厄运之槌&#xff0c;完美贡品&#xff0c;Dire Maul &#xff08;DM&#xff09; Foror‘s Compendium of Dragon Slaying 佛洛尔的屠龙技术纲要 因为不是兽王宝宝&#xff0c;而且开始位置放的不对&am…

【python011】经纬度点位可视化html生成(有效方案)

1.熟悉、梳理、总结项目研发实战中的Python开发日常使用中的问题、知识点等&#xff0c;如获取省市等边界区域经纬度进行可视化&#xff0c;从而辅助判断、决策。 2.欢迎点赞、关注、批评、指正&#xff0c;互三走起来&#xff0c;小手动起来&#xff01; 3.欢迎点赞、关注、批…

输出100以内的质数

质数&#xff1a;只能被1和自身整除的数 let count; for(let i2; i<100; i){for(let j1; j<i; j){if(i % j 0){// 只要能被整除&#xff0c;count就加1count;}} if(count 2) {// 从1到自身被整除完之后&#xff0c;如果count只有两次&#xff0c;则说明i为质数co…

应急响应靶机-Linux(1)

前言 本次应急响应靶机采用的是知攻善防实验室的Linux-1应急响应靶机 靶机下载地址为&#xff1a; https://pan.quark.cn/s/4b6dffd0c51a 相关账户密码&#xff1a; defend/defend root/defend 解题 第一题-攻击者的IP地址 先找到的三个flag&#xff0c;最后才找的ip地址 所…

等保必须要做?不做等保可行吗?

网络安全等级保护&#xff08;简称“等保”&#xff09;是中国国家网络安全的基本制度&#xff0c;对网络运营者提出了明确的法律义务和责任。根据《中华人民共和国网络安全法》第二十一条规定&#xff1a;“国家实行网络安全等级保护制度。网络运营者应当按照网络安全等级保护…

枫清科技创始人高雪峰:不取侥幸之利,做难而正确的事!丨数据猿专访

大数据产业创新服务媒体 ——聚焦数据 改变商业 金庸有一本著作叫做《侠客行》&#xff0c;这部武侠小说的主角叫做石破天&#xff0c;他从小的时候便跟随少林弟子习武。长大后&#xff0c;随着自己获得的感悟越来越多&#xff0c;最终选择开宗立派&#xff0c;独创一门武功行…

深度学习论文: Separable Self-attention for Mobile Vision Transformers

深度学习论文: Separable Self-attention for Mobile Vision Transformers Separable Self-attention for Mobile Vision Transformers PDF:https://arxiv.org/pdf/2206.02680 PyTorch: https://github.com/shanglianlm0525/PyTorch-Networks 1 概述 MobileViT是一种融合了CN…

Linux基础 - 使用 vsftpd 服务传输文件

零. 简介 文件传输协议&#xff08;File Transfer Protocol&#xff0c;FTP&#xff09;是用于在网络上进行文件传输的标准网络协议。 FTP 允许客户端和服务器之间进行文件的上传、下载、删除、重命名等操作。它基于客户端 - 服务器模型工作&#xff0c;通常使用 TCP 协议进行…

Web渗透:文件包含漏洞

Ⅱ.远程文件包含 远程文件包含漏洞&#xff08;Remote File Inclusion, RFI&#xff09;是一种Web应用程序漏洞&#xff0c;允许攻击者通过URL从远程服务器包含并执行文件&#xff1b;RFI漏洞通常出现在动态包含文件的功能中&#xff0c;且用户输入未经适当验证和过滤。接着我…

信息系统项目管理师(项目立项管理)

项目建议书的主要内容包括项目的必要性、项目建设所必须的条件、项目的市场预测、产品方案或服务的市场预测项目评估的依据主要包括&#xff1a;项目建议书及其批准文件、项目可行性研究报告、报送组织的申请报告及主管部门的初审意见、项目关键建设条件和工程等的协议文件、必…

编译VTK静态库

编译VTK静态库遇到问题 vtkCommonCore-9.3d.lib(vtkSMPToolsAPI.obj) : error LNK2019: unresolved external symbol "public: bool __cdecl vtk::detail::smp::vtkSMPToolsImpl<1>::IsParallelScope(void)" (?IsParallelScope?$vtkSMPToolsImpl$00smpdetai…

未来已来,如何打造智慧养殖场?

近年来&#xff0c;国家出台了一系列扶持政策&#xff0c;以促进养殖行业高质量发展&#xff0c;推动行业转型升级。在国家政策和市场需求的双重驱动下&#xff0c;养殖行业正迎来前所未有的发展机遇。智慧养殖以其高效、智能和可持续的特点&#xff0c;正逐步取代传统养殖方式…

公司内部培训资料!制氢变换器技术汇总 最新制氢技术方案

网盘 https://pan.baidu.com/s/1UE_d_dGcxxltII2lMg3I4w?pwdyyt3 制氢的电源系统、制氢的装置及制氢的方法.pdf 功率变换器及控制方法.pdf 单级隔离双向AC-DC变换器拓扑结构及其控制方法.pdf 基于耦合电感的高增益变换器.pdf 多端口输入非隔离型直流变换器及其控制方法.pdf 大…

Stream Lua Nginx Module 插件一键安装

文章目录 一、场景说明二、脚本职责三、参数说明四、操作示例五、注意事项 一、场景说明 本自动化脚本旨在为提高研发、测试、运维快速部署应用环境而编写。 脚本遵循拿来即用的原则快速完成 CentOS 系统各应用环境部署工作。 统一研发、测试、生产环境的部署模式、部署结构、…

程序的调试技术,设置断点

断点&#xff08;break point&#xff09;是指在代码中指定位置&#xff0c;当程序运行到此位置时变中断下来&#xff0c;并让开发者可查看此时各变量的值。因断点中断的程序并没有结束&#xff0c;可以选择继续执行。 在程序的调试过程中&#xff0c;设置断点是一个很有用的分…

ElasticSearch中的BM25算法实现原理及应用分析

文章目录 一、引言二、BM25算法实现原理BM25算法的实现原理1. 词频&#xff08;TF&#xff09;&#xff1a;2. 逆文档频率&#xff08;IDF&#xff09;&#xff1a;3. 长度归一化&#xff1a;4. BM25评分公式&#xff1a; BM25算法示例 三、BM25算法在ElasticSearch中的应用分析…

时序分析基本概念介绍——min period 最小时钟周期

文章目录 前言一、什么是 min period&#xff1f;二、为什么检查 min period&#xff1f;三、如何设置 min period&#xff1f;四、如何检查 min period&#xff1f;五、如何修复 min period&#xff1f;总结 前言 我们在实际设计中可能会碰到这种情况&#xff0c;如果我们的m…

投标书制作

一、投标书的基本要求l . 帮助与你的标书读者沟通。从这个角度上来讲&#xff0c;标书是一篇针对用户需求的论文&#xff0c;逻辑结构和语言一定要清晰、可读。考虑到评标专家一般都具有较好的学术经验&#xff0c;其中很多还是教授、博导&#xff0c;投标的语言要针对读者的阅…

Redis安装与使用

目录 1、介绍 1、redis的特点: 2、缓存 2、安装Redis 1、安装单机版redis 2、redis-cli命令参数 3、清空数据库的两种方式和作用域&#xff1a; 4、redis的增删查改命令 5、redis的查看所有分类命令 6、redis过期时间与控制键的行为 7、redis的相关工具 1、介绍 r…