最新资讯

  • 基于I.MX6ULL的Linux C多线程物联网网关+STM32+Qt上位机+Linux C++多线程服务器(含web)的多种无线通信系统的智慧农场

基于I.MX6ULL的Linux C多线程物联网网关+STM32+Qt上位机+Linux C++多线程服务器(含web)的多种无线通信系统的智慧农场

2026-01-30 23:02:33 栏目:最新资讯 3 阅读

前言

我国是农业大国,而非农业强国。近30年来农业高产量主要依靠农药化肥的大量投入,大部分化肥和水资源没有被有效利用而随地弃置,导致大量养分损失并造成环境污染。我国农业生产仍然以传统生产模式为主,传统耕种只能凭经验施肥灌溉,不仅浪费大量的人力物力,也对环境保护与水土保持构成严重威胁,对农业可持续性发展带来严峻挑战

基于I.MX6ULL的Linux C多线程物联网网关+STM32+Qt上位机+Linux C++多线程服务器(含web服务)的多种无线通信系统的智慧农场项目

技术栈+硬件选型

Linux c++应用编程(JS,WEB,HTML什么的我只知道一点点皮毛,只用了其一两个函数);

Linux socket编程,多线程编程,内核驱动编程,文件I/O

Qt/C++ 客户端开发;

Mysql 数据存储;

C语言下位机开发;

I.MX6ULL    挺贵,不建议买,我脑抽买了:

光敏模块   模拟天黑天亮;

水泵          抽水;

电机         散热

电机驱动模块 *2

土壤湿度检测传感器;

ZigBee DL_22 *2  45r;

HC-06 *2    蓝牙模块;

stm32c8t6 *4 下位机(便宜,够用,市面价格10r);

RC522(RFID模块 SPI协议) 与白卡通信 获取卡号;

DTH11 温湿度采集模块(单总线协议,市面价格 4r);

sg90 舵机模块(PWM协议 市面价9r );

8226 01-s WIFI模块*2   (uart协议 市面价格5r) 连接 C++ 服务器 和做热点;

蜂鸣器  RFID注册提示音

总设计流程

本系统一共有四个单片机,四个单片机上分别挂载了的不同传感器结点和一个通信模块,通过三种无线通信协议向物联网网关发送结点数据,物联网网关收到数据将数据上传至Linux C++云服务器,服务器监听了5个端口,分别是用于监听物联网网关的消息,web服务的80端口用与发送HTML给浏览器,与JavaScript通信更新HTML网页的端口,还有物联网网关终端Qt界面,用与对物联网网关的下结点的整体控制与显示,最后一个端口给一个Qt移动端的端口,用于智慧农场的一系列数据显示,整个物联网系统服务于智慧农场。两两单片机可以说毫无联系,但经过网关和服务器的连接,又显得联系紧密恰巧凸显一个完整的物联网控制系统。

STM32C8T6:

除了使用8266模块的单片机不需要编号因为8266会自动为其局域网下的用户编号,其他都需要编号,同一个无线传感器上编号必须不一样,还有就上传服务器的设备名字不能一样,Mysql将设备名字设为主键了,唯一。单片机需要每隔2s左右上传一次传感器结点数据,上传格式为 “ ID+传感器设备名字+#+value+操作符”  例如 ,002舵机#false0 , 001电机#true#LED3#false0   这样为一个数据包可一直延申,按格式写就好了,服务器按格式拆包。因为存在设备控制,所以需要预留控制接口,比如对收到的数据拆包,如果收到id与自身id相同,再判断传感器设备名字,如果传感器设备名字相同,在根据value去改变设备状态。操作符什么的在服务器介绍那边会讲诉清楚,知道有这个事情就可以了。RFID模块上传数据都很特殊,所以自己写了几个操作符专门服务于RFID设备的注册,与门禁比对。

I.MX6ULL Linux C 多线程物联网网关:

一共有四个通信模块,物联网网关通过三种无线通信模块接收数据MCU传来的数据,然后通过一个无线通信模块(8266 -01s Sation模式)连接Linux云服务器上传数据,所以可以通过三种协议向物联网网关发送数据,无线通信为块为ESP 8266-01s,HC-06,ZigBee,其中只有HC-06是一对一通信,其他都是可以一对多,三种通信模块都是串口(UART)驱动,其中一个ESP 8266-01s配置成AP 模式,AP 模式是指 ESP8266 模块自身作为一个热点,然后监听一个8888端口,单片机即可直接与其连接,从而实现物联网网关获取整个局域网的结点信息,另外一个ESP 8266-01s 配置成Sation 模式,Sation 模式是 ESP8266 模块通过路由器连接Linux云服务器,对设备的远程控制功就能通过互联网实现,用于将其他三个模块收到的消息上传Linux云服务器。ZigBee是硬件上按钮配置,配置成相同信道,广播模式就可以接收同信道的数据了。三种都是串口协议,所以我们需要编写I.MX6ULL的Linux驱动程序,这里I.MX6ULL的恩智浦官方已经写好了,但是我不会搞设备树那些,好不容易修改的设备树去编译驱动然后Uboot启动I.MX6ULL时,内核启动报错,我也不知道什么原因,用的是原子的的设备树和内核文件,当时搞不出来,我就中直接用配置寄存器的方式自己写4个串口驱动就行了,串口驱动还是简单的,照着裸机历程去配置寄存器就好了,有一些细微的区别就是定义寄存器地址需要映射出寄存器虚拟地址指针,读取寄存器修改寄存器的方式也不同。

驱动程序编写,最重要的就是文件操作结构体,用户与内核空间信息交互的桥梁,学过STM32都知道串口接收函数的编写吧,接收寄存读到的数据一直追加在一个BUF里面,直到当收到 时,代表接收完毕,立一个标志位,用户空间一直通过read函数读取驱动文件,如果驱动文件中的标志位为一,则代表收到了一个完整的数据包,将数据包发给用户空间,然后清除标志位。这样用户空间获取到了该通信模块接收到的数据,这里不同的是8266的消息接收函数不一样!   !   !  当时因为接收函数都写一样的这个8266的一直收不到,这个8266收到的消息有前有多个 所以需要对其过滤。

   一共3模块,所以需要开启三个线程,三个线程打开各自的通信模块的UART驱动模块文件然后按照AT指令集用write函数将用户空间的数据发送到内核空间然后去发送AT指令配置模块,配置完成后就轮询获取接收标志位,如果收到数据,就通过一个 ESP 8266-01s 发送给Linux云服务器,所以思路就有了,我们创建三个线程,6个全局变量,其中三个为各自的接收数据BUF,另外三个为各自的标志位,子线程循环读取内核模块传给用户空间的消息,当read函数>0,说明内核模块中的标志位被置一,说明接收到了一个完整的数据包,然后将用户空间的对应标志位置一,主线程循环判断三个标志位,当其中一个标志位为一,就将对应的buf写入 上传Linux云服务器的那个8266的UART内核驱动文件,内核驱动文件就将其写入寄存器上传Linux云服务器,最后标志位赋值为0,一直轮询下去,然后需要将打开的文件的文件描述符置为全局变量方便主线程收到服务器的消息需要对特定的文件进行操作(写入寄存器给指定的无线通信模块发送数据)。

一共有三个对外接收消息的模块嘛,在网关我们可以知道该数据是哪个无线传感器来的数据,但是上传服务器器后,服务器不知道,所以我们将经过 8266-01s结点的消息都加1000 ,ZigBee加2000,HC-06加3000 ,这样其中单片机id为001经过ZigBee发过来就成了2001,同理蓝牙,但是8266不一样,他热点模式自动分配IP号,可以直接实现该局域网下点对点通信,所以8266的单片机不需要发送带id的数据包,这样就根据单片机的id值大小范围我们就知道了他所在结点区域,这样就可以实现服务器对其的控制,同样收到服务器传下来的控制数据包时,我们需要根据范围去判断该值的是哪个结点的数据包,然后减去该增加的数,最后传到指定单片机上。

主循环

while(1)				
	{	
		if(WiFi8266Server_Flag==1)
		{
			WiFi8266Server_handle();
			WiFi8266Server_Flag=0;
		}
		if(UARTServer_Flag==1)
		{
			TCP_Server_handle();
			UARTServer_Flag=0;	
		}
		if(ZigBee_Flag==1)

		{
    	ZigBee_handle();
		ZigBee_Flag=0;
		}
		if(HC06_Flag==1)
		{
			HC06_handle();
			HC06_Flag=0;  
		}

		if(UART_Flag==1)
		{
		  UART_handle();
		  UART_Flag=0;
        }
}
串口3文件驱动编写,按照可以去写其他几个
#define NEWCHRIOBEE_CNT			1		  	/* 设备号个数 */

#define NEWCHRIOBEE_NAME		"newchriobee"	/* 名字 */


/* 寄存器物理地址 */
#define CCM_CGPR1_BASE  (0x020C406C)  //uart3 ,uart4
#define CCM_CGPR0_BASE  (0x020C4068)  //uart2
//3
#define IOMUXC_UART3_TX_DATA_UART3_TX_BASE   (0x020E00A4)   
#define IOMUXC_UART3_RX_DATA_UART3_RX_BASE   (0x020E00A8)
#define PAD_CTL_PAD_UART3_TX_DATA_BASE       (0x020E0330)
#define PAD_CTL_PAD_UART3_RX_DATA_BASE       (0x020E0334)



#define UART3_UFCR_BASE    (0x021EC090)
#define UART3_UBIR_BASE    (0x021EC0A4) 
#define UART3_UBMR_BASE    (0x021EC0A8)
#define UART3_UCR1_BASE    (0x021EC080)
#define UART3_UCR2_BASE    (0x021EC084)
#define UART3_UCR3_BASE    (0x021EC088)
#define UART3_USR2_BASE    (0x021EC098)
#define UART3_URXD_BASE    (0x021EC000)
#define UART3_UTXD_BASE    (0x021EC040)



/* 映射后的寄存器虚拟地址指针 */

static void __iomem * CCM_CGPR1;
static void __iomem * CCM_CGPR0;

static void __iomem *IOMUXC_UART3_TX_DATA_UART3_TX;
static void __iomem *IOMUXC_UART3_RX_DATA_UART3_RX;
static void __iomem *PAD_CTL_PAD_UART3_TX_DATA;
static void __iomem *PAD_CTL_PAD_UART3_RX_DATA;
static void __iomem *UART3_UFCR;
static void __iomem *UART3_UBIR;
static void __iomem *UART3_UBMR;
static void __iomem *UART3_UCR1;
static void __iomem *UART3_UCR2;
static void __iomem *UART3_UCR3;
static void __iomem *UART3_USR2;
static void __iomem *UART3_URXD;
static void __iomem *UART3_UTXD;
 void register_init(void);
 void uart_init(void);
 void uart_io_init(void);
 void uart_disable(void);
 void uart_enable(void);
 void uart_softreset(void);
 int  getc(void);
 void myexit(void);


unsigned char i;  
char RECS[100];

void register_init(void)
{
    printk("register_init
");
    CCM_CGPR1=ioremap(CCM_CGPR1_BASE,4);
    CCM_CGPR0=ioremap(CCM_CGPR0_BASE,4);
	IOMUXC_UART3_TX_DATA_UART3_TX=ioremap(IOMUXC_UART3_TX_DATA_UART3_TX_BASE, 4);
	IOMUXC_UART3_RX_DATA_UART3_RX=ioremap(IOMUXC_UART3_RX_DATA_UART3_RX_BASE,4);
	PAD_CTL_PAD_UART3_TX_DATA=ioremap(PAD_CTL_PAD_UART3_TX_DATA_BASE,4);
	PAD_CTL_PAD_UART3_RX_DATA=ioremap(PAD_CTL_PAD_UART3_RX_DATA_BASE,4);

	UART3_UFCR=ioremap(UART3_UFCR_BASE,4);
	UART3_UBIR=ioremap(UART3_UBIR_BASE,4);
	UART3_UBMR=ioremap(UART3_UBMR_BASE,4);
	UART3_UCR1=ioremap(UART3_UCR1_BASE,4);
	UART3_UCR2=ioremap(UART3_UCR2_BASE,4);
	UART3_UCR3=ioremap(UART3_UCR3_BASE,4);
	UART3_USR2=ioremap(UART3_USR2_BASE,4);
	UART3_URXD=ioremap(UART3_URXD_BASE,4);
	UART3_UTXD=ioremap(UART3_UTXD_BASE,4);
}

void uart_init(void)
{
	__u32 ret;
	uart_io_init();

  writel(0XFFFFFFFF,CCM_CGPR1);

	writel(0XFFFFFFFF,CCM_CGPR0);

	uart_disable();
	uart_softreset();
	writel(0,UART3_UCR1);
	
  ret=readl(UART3_UCR2);
	ret|= (1<<14) | (1<<5) | (1<<2) | (1<<1);
	writel(ret,UART3_UCR2);


  ret=readl(UART3_UCR3);
	ret|= 1<<2; 
  writel(ret,UART3_UCR3);

  ret=readl(UART3_UCR1);
	ret &= ~(1<<14);
  writel(ret,UART3_UCR1);
	writel(5<<7,UART3_UFCR);
	writel(71,UART3_UBIR);
	writel(3124,UART3_UBMR);

	uart_enable();
}

void uart_io_init(void)
{
	writel(0,IOMUXC_UART3_TX_DATA_UART3_TX);	
	writel(0,IOMUXC_UART3_RX_DATA_UART3_RX);	
	writel(0x10B0,PAD_CTL_PAD_UART3_TX_DATA);
	writel(0x10B0,PAD_CTL_PAD_UART3_TX_DATA);
}

void uart_disable()

{
	__u32 ret;
	ret=readl(UART3_UCR1);
	ret &= ~(1<<0);
  writel(ret,UART3_UCR1);
}

void uart_enable()
{
	__u32 ret;
	ret=readl(UART3_UCR1);
	ret |= (1<<0);	
  writel(ret,UART3_UCR1);
}
void uart_softreset()
{	
	__u32 ret;
	ret=readl(UART3_UCR2);
	ret  &= ~(1<<0); 			/* UCR2的bit0为0,复位UART  	  	*/
   writel(ret,UART3_UCR2);
	
while((readl(UART3_UCR2) & 0x1) == 0); /* 等待复位完成 					*/
}
void send_c(unsigned char c)
{
   while(((readl(UART3_USR2)>> 3) & 0X01) == 0); /*等待上一次发送完成*/
   writel(c & 0XFF, UART3_UTXD);         /*写入寄存器*/
}
void send_str(char *str)
{
	char *p = str;
	while(*p)
   send_c(*p++);
}

int read_c(void)
{
   while((readl(UART3_USR2) & 0x1) == 0);/*等待接收完成*/	
		RECS[i++]=readl(UART3_URXD);
		if((RECS[i-2]=='
')|(RECS[i-1]=='
'))  
		{
			RECS[i-2]='';
			i = 0;		
			return 1; 
		}
    return 0;
}

void myexit(void)
{
	iounmap(CCM_CGPR1);
	iounmap(IOMUXC_UART3_TX_DATA_UART3_TX);
	iounmap(IOMUXC_UART3_RX_DATA_UART3_RX);
	iounmap(PAD_CTL_PAD_UART3_TX_DATA);
	iounmap(PAD_CTL_PAD_UART3_RX_DATA);
	iounmap(UART3_UFCR);
	iounmap(UART3_UBIR);
	iounmap(UART3_UBMR);
	iounmap(UART3_UCR1);
	iounmap(UART3_UCR2);
	iounmap(UART3_UCR3);
	iounmap(UART3_USR2);
	iounmap(UART3_URXD);
	iounmap(UART3_UTXD);

}


struct newchriobee_dev{
	dev_t devid;			/* 设备号 	 */
	struct cdev cdev;		/* cdev 	*/
	struct class *class;	/* 类 		*/
	struct device *device;	/* 设备 	 */
	int major;				/* 主设备号	  */
	int minor;				/* 次设备号   */
};

struct newchriobee_dev newchriobee;	


static int iobee_open(struct inode *inode, struct file *filp)
{
	register_init();     /*初始化寄存器*/
    uart_init();        /*初始化uart*/
	printk("kernel  open!
");
	filp->private_data = &newchriobee; /* 设置私有数据 */
return 0;
}



static ssize_t iobee_read(struct file *filp, char __user *buf, size_t cnt, loff_t *offt)
{ 
	 int ret;
    if(!read_c())   /*判断是否接收到数据*/
	return 0;	
	
    printk("kernel recvdata:%s@
",RECS);  /*调试用途,可删除*/
    ret=copy_to_user(buf,RECS,cnt);  /*内核到用户空间*/
    if(ret<0)
	{
     printk("kernel read error!
");
	}	
	return 0;
}

	
static ssize_t iobee_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offt)
{
     char sendbuf[1024]={0};
     int ret;
	 ret=copy_from_user(sendbuf,buf,cnt);
	 if(ret< 0) {
	 printk("write error !
");
     return 0;
     }
    printk("kernel sendstring:%s@
",sendbuf);  /*调试用途,可删除*/
	send_str(sendbuf);
	return 0;
}

static int iobee_release(struct inode *inode, struct file *filp)
{
	return 0;
}

/* 设备操作函数 */

static struct file_operations newchriobee_fops = {

	.owner = THIS_MODULE,
	.open = iobee_open,
	.read = iobee_read,
	.write = iobee_write,
	.release = iobee_release,
};

static int __init iobee_init(void)
{
	/* 注册字符设备驱动 */
	/* 1、创建设备号 */
	if (newchriobee.major) {		/*  定义了设备号 */
		newchriobee.devid = MKDEV(newchriobee.major, 0);
		register_chrdev_region(newchriobee.devid, NEWCHRIOBEE_CNT, NEWCHRIOBEE_NAME);
	} else {						/* 没有定义设备号 */

		alloc_chrdev_region(&newchriobee.devid, 0, NEWCHRIOBEE_CNT, NEWCHRIOBEE_NAME);	/* 申请设备号 */
		newchriobee.major = MAJOR(newchriobee.devid);	/* 获取分配号的主设备号 */
		newchriobee.minor = MINOR(newchriobee.devid);	/* 获取分配号的次设备号 */
	}
	printk("newcheiobee major=%d,minor=%d
",newchriobee.major, newchriobee.minor);	

	/* 2、初始化cdev */
	newchriobee.cdev.owner = THIS_MODULE;
	cdev_init(&newchriobee.cdev, &newchriobee_fops);
	/* 3、添加一个cdev */
	cdev_add(&newchriobee.cdev, newchriobee.devid,NEWCHRIOBEE_CNT);
	/* 4、创建类 */
	newchriobee.class = class_create(THIS_MODULE,NEWCHRIOBEE_NAME);

	if (IS_ERR(newchriobee.class)) {
		return PTR_ERR(newchriobee.class);
	}
	/* 5、创建设备 */
	newchriobee.device = device_create(newchriobee.class, NULL, newchriobee.devid, NULL,NEWCHRIOBEE_NAME);
	if (IS_ERR(newchriobee.device)) {
		return PTR_ERR(newchriobee.device);
	}
	return 0;
}

static void __exit iobee_exit(void)
{
    myexit();
	/* 注销字符设备驱动 */
	cdev_del(&newchriobee.cdev);/*  删除cdev */
	unregister_chrdev_region(newchriobee.devid, NEWCHRIOBEE_CNT); /* 注销设备号 */
	device_destroy(newchriobee.class, newchriobee.devid);
	class_destroy(newchriobee.class);
	printk("iobee clear !
");

}

module_init(iobee_init);
module_exit(iobee_exit);

MODULE_LICENSE("GPL");

MODULE_AUTHOR("YZM very Good");
Linux C++服务器:

咱们物联网系统一共有五个设备需要接入云服务,分别是web,MCU,QT,QT APP,JS。所以创建五个套接字,绑定五个不同端口,实现不同的服务。访问80端口服务器向客户发送一个HTML文件,HTML文件里面有JS,JS连接服务器的另外一个端口,每2秒向服务器拿一次结点数据更新,响应JS数据需要自己发送响应头和json格式的数据模拟WEB服务器。同理其他都差不多,MCU的端口服务是工程量最大的,首先介绍服务器的自动判断单片机结点是否连接断开功能,我规定单片机每2秒上传一次传感器个结点数据并且给每个单片机都固定一个IP,当上传数据时包头都是ID,我们拆包拿出ID,将IP数字作为键放入一个map容器。初始化键的值为true。然后给这个ID开一个线程让一直while循环每sleep 5秒判断一次键的值是否为true,如果为true则置为false继续循环,如果为false则删除该数据退出线程清理线程。所以单片机每次上传数据都判断map容器是否存在ID如果存在则让它置为true,不存在则添加,就像STM32的看门狗一样没有及时喂狗就没有及时将false置为true,线程判断到时如果还为false就删除ID当作断开连接处理,所以需要单片机每一段时间更新一次数据去将map容器的值置true。接下来多线程操作数据库的问题,数据库的性能瓶颈往往出现在并发读写上。我对Mysql的查询优化性能什么的挺薄弱的,我想了一个办法,每次收到单片机的数据时我们对数据库库插入更改后,立马进行一次查询,然后将查询到的数据包保存起来,web网页呀Qt程序呀他们那边都是定时器定时拿数据,避免其他线程频繁对数据库查询,直接让他们定时去访问这个保存起来的数据包,因为每来一次单片机数据都会更新数据库和数据包所以数据包时刻都是最新状态。

  接下来就是各个单片机之间的控制系统的熟实现,单片机上传过来的数据包最后一为代表他需要的服务器进行的操作,0代表更新数据,1代表需要控制其他单片机结点,2代表RFID注册,3代表RFID卡号与数据库比对,打个比如:我的数据包是  1000name#value0  这个数据包是id1000 设备名字name 值为value    0为操作符 所以该数据是更新服务器数据,服务器收到此数据就去数据库更新数据, 如果数据包为 1000 LED3#true1   这个1就是代表该id:1000 的单片机需要服务器将设备为 LED3的值修改为true 就是开灯的意思,然后服务器就去数据库或者那个数据包找到包涵LED3设备的ID 知道了ID 我们直接组包发给网关,网关根据ID范围就知道该ID属于哪个结点,然后就向该无线通信结点发送数据包控制该结点下的单片机的结点,对应广播形式的无线传感器结点我们单片机需要判断收到的数据包的ID是不是跟本设备ID匹配,不同则代表不属于该单片机消息,直接丢包。

通过内模板创建线程


int main(void)
{
       //数据库初始化
       SQLifconfig *sql_typ_MCU=new SQLifconfig;     
       sql_typ_MCU->SQL_init(host,user,pwd,dbname);  /*数据库连接*/

       SQLifconfig *sql_typ_MID=new SQLifconfig;     
       sql_typ_MID->SQL_init(host,user,pwd,dbname);  /*数据库连接*/

       SQLifconfig *sql_typ_APP=new SQLifconfig;     
       sql_typ_APP->SQL_init(host,user,pwd,dbname);  /*数据库连接*/

       SQLifconfig *sql_typ_Web=new SQLifconfig;     
       sql_typ_Web->SQL_init(host,user,pwd,dbname);  /*数据库连接*/

       SQLifconfig *sql_typ_JS=new SQLifconfig;     
       sql_typ_JS->SQL_init(host,user,pwd,dbname);  /*数据库连接*/


       cout<<"sql select :"<Dql_sql("SELECT *  FROM node")<Dml_sql("DELETE  FROM node");
   
   //server初始化
      Myserver    MCU_server(AF_INET,SOCK_STREAM,0,sql_typ_MCU);
      MCU_server.server_start(MY_IP,MY_MCUPORT,AF_INET);

      Myserver    APP_server(AF_INET,SOCK_STREAM,0,sql_typ_APP);
      APP_server.server_start(MY_IP,MY_APPPORT,AF_INET);

      Myserver     Web_server(AF_INET,SOCK_STREAM,0,sql_typ_Web);
      Web_server.server_start(MY_IP,MY_WEBPORT,AF_INET);

      Myserver     js_server(AF_INET,SOCK_STREAM,0,sql_typ_JS);
      js_server.server_start(MY_IP,MY_JSPORT,AF_INET);


      Myserver    MEE_server(AF_INET,SOCK_STREAM,0,sql_typ_MID);
      MEE_server.server_start(MY_IP,MY_MMEPORT,AF_INET);

   while (1)
   {
     //std::cout<<"new connect !!"<
Qt物联网网关终端:

终端开一个定时器,定时去服务器拿数据显示,根据ID范围判断哪个无线模块结点下的数据,显示在特定的容器控件下,首先因为存在不同类型的传感器节点所以有不同的操作,比如温湿度只需要显示,RFID需要信息显示和清空注册,温度阈值需要设置阈值,电机需要开关,所以传过来的数据我对器其ID进行子串匹配,存在TH(threshold)代表设备关于阈值 (温度TH),然后给他创建一共自己封装好的类,然后在根据id把这个对象放入特定容器布局,同理设备名字存在RFID,value值等于true或者false的都格外判断为启动电机,LED等设备的标志,这些规则都需要单片机去遵循。

特殊功能:服务器那边以STM32看门狗的方式判断是否断开连接,我们客户端也同样需要。首先一共有四种容器,分别转四个自定义类,每一个设备类都有两个槽函数,一个为接收主窗口的信号,一个为数据比对函数,每次收到数据包都需要根据上面的分类将其id,name,value与早就存在特定的容器的相同对象进行比对(封装了一个槽函数),如果比对成功该类的标志位置一,全部比对完成后,发送一个所以对象都绑定了的信号,所有对象判断自身标志位,如果为一则将置0,如果为0,则代表没有及时喂狗,代表新的数据包没有上次存储的数据,代表该结点以不存在,需要delete清除该自己,同时发送信号到主窗口,删除容器中的数据,这样可以一直保持最新的数据显示。(这个思路真的复杂,想了好久)

挺乱这算法哈哈


void Widget::Data_Analysis(QStringList Data)
{
            bool asd;

    if(Data.at(1).contains("TH"))
    {
            asd=true;
         for (int i=0;iData_compare(Data)){
           asd=false;
           return ;
           }
        }
         if(asd)
         {
             setWidget_layout(Data,1);
         }
    }
    else if(Data.at(2)=="true" || Data.at(2)=="false"){
          asd=true;
        for (int i=0;iData_compare(Data))
          {
              asd=false;
              return ;
          }
       }
        if(asd)
        {
             setWidget_layout(Data,0);
        }
    }
    else if(Data.at(1).contains("RFID")){
          asd=true;
        for (int i=0;iData_compare(Data))
          {
              asd=false;
              return ;
          }
       }
        if(asd)
        {
             setWidget_layout(Data,3);
        }
    }
    else
    {
               asd=true;
        for (int i=0;iData_compare(Data))
          {
              asd=false;
              return ;
          }
        }
        if(asd)
        {
             setWidget_layout(Data,2);
        }
    }

}



void Widget::setWidget_layout(QStringList Data,int x)
{
        int id=Data.at(0).toInt();
        if(id>=1000 && id<2000)
        {
            if(x==0)
            {
                MyIsbtn* isbtn=new MyIsbtn(this,Data,socket);
                connect(this,&Widget::Delete_SING,isbtn,&MyIsbtn::Delete_MyIsbtn);
                connect(isbtn,&MyIsbtn::sendindex,this,&Widget::Delete_index);
                layout8266->insertWidget(0,isbtn);
                mlist_isbtn.append(isbtn);
             }else  if(x==1){
                MySetTH* setTh=new MySetTH(this,Data,socket);
                connect(this,&Widget::Delete_SING,setTh,&MySetTH::Delete_MySetTH);
                connect(setTh,&MySetTH::sendindex,this,&Widget::Delete_index);
                layout8266->insertWidget(0,setTh);
                mlist_setth.append(setTh);
            }
            else  if(x==2){
                MyShowData* showdata=new MyShowData(this,Data);
                connect(this,&Widget::Delete_SING,showdata,&MyShowData::Delete_MyShowData);
                connect(showdata,&MyShowData::sendindex,this,&Widget::Delete_index);
                layout8266->insertWidget(0,showdata);
                mlist_showdata.append(showdata);
             }
            else  if(x==3){
                MyRFID* rfid=new MyRFID(this,Data,socket);
                connect(this,&Widget::Delete_SING,rfid,&MyRFID::Delete_MyRFID);
                connect(rfid,&MyRFID::sendindex,this,&Widget::Delete_index);
                layout8266->insertWidget(0,rfid);
                mlist_rfid.append(rfid);
             }

        }
        else if(id>=2000 && id<3000)
        {
            if(x==0)
            {
                MyIsbtn* isbtn=new MyIsbtn(this,Data,socket);
                connect(this,&Widget::Delete_SING,isbtn,&MyIsbtn::Delete_MyIsbtn);
                connect(isbtn,&MyIsbtn::sendindex,this,&Widget::Delete_index);
                layouthc06->insertWidget(0,isbtn);
                mlist_isbtn.append(isbtn);
             }else  if(x==1){
                MySetTH* setTh=new MySetTH(this,Data,socket);
                connect(this,&Widget::Delete_SING,setTh,&MySetTH::Delete_MySetTH);
                connect(setTh,&MySetTH::sendindex,this,&Widget::Delete_index);
                layouthc06->insertWidget(0,setTh);
                mlist_setth.append(setTh);
            }
            else  if(x==2){
                MyShowData* showdata=new MyShowData(this,Data);
                connect(this,&Widget::Delete_SING,showdata,&MyShowData::Delete_MyShowData);
                connect(showdata,&MyShowData::sendindex,this,&Widget::Delete_index);
                layouthc06->insertWidget(0,showdata);
                mlist_showdata.append(showdata);
             }
            else  if(x==3){
                MyRFID* rfid=new MyRFID(this,Data,socket);
                connect(this,&Widget::Delete_SING,rfid,&MyRFID::Delete_MyRFID);
                connect(rfid,&MyRFID::sendindex,this,&Widget::Delete_index);
                layouthc06->insertWidget(0,rfid);
                mlist_rfid.append(rfid);
             }

        }
        else if(id>=3000 && id<4000)
        {
            if(x==0)
            {
                MyIsbtn* isbtn=new MyIsbtn(this,Data,socket);
                connect(this,&Widget::Delete_SING,isbtn,&MyIsbtn::Delete_MyIsbtn);
                connect(isbtn,&MyIsbtn::sendindex,this,&Widget::Delete_index);
                layoutzibge->insertWidget(0,isbtn);
                mlist_isbtn.append(isbtn);
             }else  if(x==1){
                MySetTH* setTh=new MySetTH(this,Data,socket);
                connect(this,&Widget::Delete_SING,setTh,&MySetTH::Delete_MySetTH);
                connect(setTh,&MySetTH::sendindex,this,&Widget::Delete_index);
                layoutzibge->insertWidget(0,setTh);
                mlist_setth.append(setTh);
            }
            else  if(x==2){
                MyShowData* showdata=new MyShowData(this,Data);
                connect(this,&Widget::Delete_SING,showdata,&MyShowData::Delete_MyShowData);
                connect(showdata,&MyShowData::sendindex,this,&Widget::Delete_index);
                layoutzibge->insertWidget(0,showdata);
                mlist_showdata.append(showdata);
             }
            else  if(x==3){
                MyRFID* rfid=new MyRFID(this,Data,socket);
                connect(this,&Widget::Delete_SING,rfid,&MyRFID::Delete_MyRFID);
                connect(rfid,&MyRFID::sendindex,this,&Widget::Delete_index);
                layoutzibge->insertWidget(0,rfid);
                mlist_rfid.append(rfid);
             }

        }

}

void Widget::Delete_index(int i,QString name)
{
    //ui->textEdit->append("销毁"+QString ::number(i)+":"+name);
    if(i==0)   //isbtn
    {
     for (int i=0;iIsname(name))
          {
            mlist_isbtn.removeAt(i);
            return ;
          }

    }

    }
    else if(i==1){
        for (int i=0;iIsname(name))
             {
               mlist_setth.removeAt(i);
               return ;
             }
        }
    }
    else if(i==2){
        for (int i=0;iIsname(name))
             {
               mlist_showdata.removeAt(i);
               return ;
             }
        }
    }
    else if(i==3){
        for (int i=0;iIsname(name))
             {
               mlist_rfid.removeAt(i);
               return ;
             }
        }
    }

}
Qt  APP:

本项目是服务于智慧农场,所以开发一个app 只显示一个农场的特定的数据和特定的操作,使其一些操作和数据固化。

JS,WEB,HTML:





    
    智慧农场
    





温------------度:

温--度--阈--值:


湿------------度:


土--壤--湿--度:

土壤湿度阈值:


光------------敏:

光--敏--阈--值:


本人hello word的水平,不多说  (面向人工智障编程,cv工程师)

总结

本项目是我写过最麻烦的项目,调试花了一周,总时长25天,各种BUG,每个设备之间的数据传递问题巨多,先局部后则整体,代码看了百遍不止,调麻了,但也只有调试BUG才能成长和磨练自己,学习阶段还是好好自己学扎实。

本文地址:https://www.yitenyun.com/3648.html

搜索文章

Tags

#ios面试 #ios弱网 #断点续传 #ios开发 #objective-c #ios #ios缓存 #服务器 #python #pip #conda #远程工作 香港站群服务器 多IP服务器 香港站群 站群服务器 #kubernetes #笔记 #平面 #容器 #linux #学习方法 #运维 #进程控制 #fastapi #html #css #docker #后端 #数据库 #MobaXterm #ubuntu #Conda # 私有索引 # 包管理 #Trae #IDE #AI 原生集成开发环境 #Trae AI #低代码 #爬虫 #音视频 #开发语言 #云原生 #iventoy #VmWare #OpenEuler #人工智能 #node.js #cpolar #物联网 #websocket #内网穿透 #网络 #github #git #vscode #mobaxterm #深度学习 #计算机视觉 #开源 #RTP over RTSP #RTP over TCP #RTSP服务器 #RTP #TCP发送RTP #学习 #android #腾讯云 #c# #算法 #大数据 #unity #游戏引擎 #数信院生信服务器 #Rstudio #生信入门 #生信云服务器 #安全 #nginx #tcp/ip #缓存 #云计算 #windows #web安全 #kylin #qt #c++ #vllm #大模型 #Streamlit #Qwen #本地部署 #AI聊天机器人 #我的世界 #C++ #我的世界服务器搭建 #minecraft #udp #ssh #todesk #java #jar #Dell #PowerEdge620 #内存 #硬盘 #RAID5 #架构 #面试 #http #cpp #项目 #高并发 #claude #gemini #gemini国内访问 #gemini api #gemini中转搭建 #Cloudflare #多个客户端访问 #IO多路复用 #回显服务器 #TCP相关API #金融 #mcp #金融投资Agent #Agent #n8n #hadoop #hbase #hive #zookeeper #spark #kafka #flink #vue.js #前端 #django #flask #web3.py #ollama #ai #llm #性能优化 #swagger #oracle #mamba #Android #Bluedroid #智能手机 #电气工程 #C# #PLC #压力测试 #gpu算力 #MCP #jmeter #功能测试 #软件测试 #自动化测试 #职场和发展 #openlayers #bmap #tile #server #vue #单片机 #嵌入式硬件 #TCP #客户端 #嵌入式 #DIY机器人工房 #jenkins #自动化 #maven #gitlab #c语言 #网络协议 #ide #需求分析 #scala #测试用例 #测试工具 #mcu #asp.net #sqlserver #MCP服务器 #apache #企业开发 #ERP #项目实践 #.NET开发 #C#编程 #编程与数学 #NPU #CANN #screen 命令 #阿里云 #华为 #ModelEngine #JumpServer #堡垒机 #mvp #个人开发 #设计模式 #振镜 #振镜焊接 #1024程序员节 #单元测试 #集成测试 #php #网络安全 #DisM++ # GLM-4.6V # 系统维护 #京东云 #SRS #流媒体 #直播 #AIGC #ida #深度优先 #DFS #守护进程 #复用 #screen #unity3d #游戏 #服务器框架 #Fantasy #elasticsearch #umeditor粘贴word #ueditor粘贴word #ueditor复制word #ueditor上传word图片 #国产化 #SPA #单页应用 #stm32 #spring cloud #spring #jvm #spring boot #nfs #iscsi #RustDesk #IndexTTS 2.0 #本地化部署 #麒麟OS #jetty #信息与通信 #信号处理 #tcpdump #centos #毕业设计 #车辆排放 #凤希AI伴侣 #SA-PEKS # 关键词猜测攻击 # 盲签名 # 限速机制 #pycharm #ms-swift # 大模型 # 模型训练 #PyTorch # Triton # 高并发部署 #transformer #javascript #银河麒麟高级服务器操作系统安装 #银河麒麟高级服务器V11配置 #设置基础软件仓库时出错 #银河麒高级服务器系统的实操教程 #生产级部署银河麒麟服务系统教程 #Linux系统的快速上手教程 #sqlite #Ansible #Playbook #AI服务器 #openEuler #欧拉 #epoll #AI #大模型学习 #java-ee #负载均衡 #mysql #sql #json #golang #rdp #科技 #自然语言处理 #神经网络 #libosinfo #Dify #ARM架构 #鲲鹏 #EMC存储 #存储维护 #NetApp存储 #SSH反向隧道 # Miniconda # Jupyter远程访问 #chatgpt #codex #高级IO #select #计算机网络 #微服务 #NAS #Termux #Samba #Linux #react.js #CVE-2025-61686 #漏洞 #路径遍历高危漏洞 #macos #idm #万悟 #联通元景 #智能体 #镜像 #程序员 #大模型教程 #AI大模型 #微信小程序 #小程序 #微信 #健身房预约系统 #健身房管理系统 #健身管理系统 #web服务器 #flutter #数码相机 #debian #鸭科夫 #逃离鸭科夫 #鸭科夫联机 #鸭科夫异地联机 #开服 #北京百思可瑞教育 #百思可瑞教育 #北京百思教育 #散列表 #数据结构 #哈希算法 #risc-v #部署 #GPU服务器 #8U #硬件架构 #fiddler #redis #搜索引擎 #智能路由器 #5G #AI编程 #运维开发 #pytorch #C2000 #TI #实时控制MCU #AI服务器电源 #leetcode #黑群晖 #虚拟机 #无U盘 #纯小白 #支付 #银河麒麟 #系统升级 #信创 #远程桌面 #远程控制 #东方仙盟 #UDP的API使用 #bash #蓝湖 #Axure原型发布 #编辑器 #SAP #ebs #metaerp #oracle ebs #DeepSeek #蓝耘智算 #分布式 #个人博客 #Anaconda配置云虚拟环境 #系统架构 #openHiTLS #TLCP #DTLCP #密码学 #商用密码算法 #Clawdbot #个人助理 #数字员工 #CPU #华为云 #测评 #CCE #Dify-LLM #Flexus #课程设计 #Nacos #web #RAID #RAID技术 #磁盘 #存储 #cursor #rustdesk #p2p #YOLOFuse # Base64编码 # 多模态检测 #进程 #操作系统 #进程创建与终止 #shell #翻译 #C #Spring AI #STDIO传输 #SSE传输 #WebMVC #WebFlux #bootstrap #YOLOv8 # 目标检测 # Docker镜像 #文件IO #输入输出流 #文件管理 #文件服务器 #经验分享 #机器学习 #kmeans #聚类 #prompt #harmonyos #小艺 #鸿蒙 #搜索 #mariadb #视频去字幕 #代理模式 #Spring AOP #树莓派4b安装系统 #scanf #printf #getchar #putchar #cin #cout #Java #paddleocr #STDIO协议 #Streamable-HTTP #McpTool注解 #服务器能力 #pve #wsl #时序数据库 #电脑 #LangGraph #CLI #Python #JavaScript #langgraph.json #分阶段策略 #模型协议 #ddos #工具集 #大模型应用 #API调用 #PyInstaller打包运行 #服务端部署 #KMS激活 #大语言模型 #排序算法 #jdk #排序 #numpy #CSDN #aiohttp #asyncio #异步 #数据仓库 #算力一体机 #ai算力服务器 #.netcore #https #openresty #lua #wordpress #雨云 #LobeChat #vLLM #GPU加速 #海外服务器安装宝塔面板 #开源工具 #tomcat #intellij-idea #910B #ansible #YOLO #目标检测 #大模型部署 #mindie #大模型推理 #创业创新 #业界资讯 #Go并发 #高并发架构 #Goroutine #系统设计 #Tracker 服务器 #响应最快 #torrent 下载 #2026年 #Aria2 可用 #迅雷可用 #BT工具通用 #milvus #langchain #大模型开发 #ssl #VMware #简单数论 #埃氏筛法 #prometheus #grafana #vuejs #CosyVoice3 # 语音合成 #eBPF #数据分析 #Puppet # IndexTTS2 # TTS #语音识别 #说话人验证 #声纹识别 #CAM++ #云服务器 #个人电脑 #C语言 #Harbor #x86_64 #数字人系统 #yum #windows11 #microsoft #系统修复 #三维 #3D #三维重建 #信令服务器 #Janus #MediaSoup #其他 #PTP_1588 #gPTP #rtsp #转发 #unix #CS2 #debian13 #Windows #fpga开发 #信创国产化 #达梦数据库 #gitea #FTP服务器 #rust #webrtc #网站 #截图工具 #批量处理图片 #图片格式转换 #图片裁剪 #ping通服务器 #读不了内网数据库 #bug菌问答团队 #GPU #AutoDL ##租显卡 #进程等待 #wait #waitpid #结构体 #制造 #Kylin-Server #国产操作系统 #服务器安装 #Android16 #音频性能实战 #音频进阶 #LangFlow # 智能运维 # 性能瓶颈分析 # GPU租赁 # 自建服务器 #推荐算法 #devops #渗透测试 #黑客技术 #计算机 #文件上传漏洞 #CTF #deepseek #postgresql #A2A #GenAI #遛狗 #SSE # AI翻译机 # 实时翻译 #bug #VMWare Tool #聊天小程序 #心理健康服务平台 #心理健康系统 #心理服务平台 #心理健康小程序 #无人机 #Deepoc #具身模型 #开发板 #未来 # 一锤定音 # 大模型微调 #adb #nodejs #tdengine #涛思数据 #ffmpeg #数据挖掘 #CUDA #Triton #交互 #SSH密钥 # PyTorch # CUDA #SSH公钥认证 # 安全加固 #练习 #基础练习 #数组 #循环 #九九乘法表 #计算机实现 #dynadot #域名 #ETL管道 #RAG #向量存储 #数据预处理 #DocumentReader #esb接口 #走处理类报异常 #dify #arm开发 #语言模型 #昇腾300I DUO #PowerBI #企业 #银河麒麟部署 #银河麒麟部署文档 #银河麒麟linux #银河麒麟linux部署教程 #idea #intellij idea #serverless #ui #opencv #cosmic #Qwen3-14B # 大模型部署 # 私有化AI #vnstat #监控 #AI 推理 #NV #文心一言 #AI智能体 #vp9 #攻防演练 #Java web #红队 #Llama-Factory # 树莓派 # ARM架构 #SSH跳板机 # Python3.11 #LVDS #高速ADC #DDR #游戏机 #银河麒麟操作系统 #openssh #华为交换机 #信创终端 #API限流 # 频率限制 # 令牌桶算法 #驱动开发 #chrome #处理器 #iBMC #UltraISO #screen命令 #notepad++ #Gunicorn #WSGI #Flask #并发模型 #容器化 #性能调优 #智能体来了 #智能体对传统行业冲击 #行业转型 #AI赋能 #teamviewer #Emby #视频 #llama #门禁 #梯控 #智能一卡通 #门禁一卡通 #消费一卡通 #智能梯控 #一卡通 #超时设置 #客户端/服务器 #网络编程 #sql注入 #管道Pipe #system V #ai编程 #LLM #chat #机器人 #YOLO26 #muduo #TcpServer #accept #高并发服务器 #Miniconda #SSH #远程开发 #muduo库 #uv #uvx #uv pip #npx #Ruff #pytest #aws #web server #请求处理流程 #框架搭建 #状态模式 #AI-native #dba #Tokio #springboot #知识库 #react native #昇腾 #vivado license #CVE-2025-68143 #CVE-2025-68144 #CVE-2025-68145 #html5 #WinSCP 下载安装教程 #SFTP #FTP工具 #服务器文件传输 # 批量管理 #ASR #SenseVoice #星图GPU #媒体 #中间件 #远程连接 #交通物流 #laravel #node #政务 #uni-app #H5 #手机h5网页浏览器 #安卓app #苹果ios APP #手机电脑开启摄像头并排查 #rocketmq #selenium #svn #证书 #scrapy #fabric #可信计算技术 #winscp #ONLYOFFICE #MCP 服务器 #嵌入式编译 #ccache #distcc #参数估计 #矩估计 #概率论 # 双因素认证 # TensorFlow #毕设 #蓝牙 #LE Audio #BAP #连接数据库报错 #链表 #puppeteer #KMS #slmgr #scikit-learn #随机森林 #安全威胁分析 #源码 #闲置物品交易系统 #仙盟创梦IDE #硬件工程 #智能家居 #POC #问答 #交付 #动态规划 #pyqt #xlwings #Excel #dlms #dlms协议 #逻辑设备 #逻辑设置间权限 #mybatis #AI Agent #开发者工具 #企业微信 #3d #服务器IO模型 #非阻塞轮询模型 #多任务并发模型 #异步信号模型 #多路复用模型 #系统安全 #Minecraft #Minecraft服务器 #PaperMC #我的世界服务器 #ipmitool #BMC # 黑屏模式 # TTS服务器 #前端开发 #EN4FE #领域驱动 #自由表达演说平台 #演说 #程序员创富 #程序人生 #移动端h5网页 #调用浏览器摄像头并拍照 #开启摄像头权限 #拍照后查看与上传服务器端 #摄像头黑屏打不开问题 #流程图 #论文阅读 #论文笔记 #图论 #国产开源制品管理工具 #Hadess #一文上手 #蓝桥杯 #串口服务器 #工业级串口服务器 #串口转以太网 #串口设备联网通讯模块 #串口服务器选型 #okhttp #embedding #IndexTTS2 # 阿里云安骑士 # 木马查杀 #kong #Kong Audio #Kong Audio3 #KongAudio3 #空音3 #空音 #中国民乐 #visual studio code #范式 #前端框架 #计算机外设 #入侵 #日志排查 #Karalon #AI Test #Reactor #ET模式 #非阻塞 #健康医疗 #图像识别 #多进程 #python技巧 #高考 #企业级存储 #网络设备 #iot #软件工程 #生信 #word #pdf #Smokeping #工程实践 #策略模式 #租显卡 #训练推理 #产品经理 #就业 #AI应用 #wps #Linux多线程 #ambari #bigtop #hdp #hue #kerberos #pencil #pencil.dev #设计 #vps #zotero #WebDAV #同步失败 #轻量化 #低配服务器 #Beidou #北斗 #SSR #Anything-LLM #IDC服务器 #私有化部署 #麒麟 #V11 #kylinos #raid #raid阵列 #esp32教程 #信息可视化 #gpt #API #AI写作 #taro #java大文件上传 #java大文件秒传 #java大文件上传下载 #java文件传输解决方案 #poll #PyCharm # 远程调试 # YOLOFuse #通信 #simulink #matlab #journalctl #docker安装seata #信息安全 #信息收集 #Langchain-Chatchat # 国产化服务器 # 信创 #软件 #本地生活 #电商系统 #商城 #Syslog #系统日志 #日志分析 #日志监控 #生产服务器问题查询 #日志过滤 #Autodl私有云 #深度服务器配置 # 水冷服务器 # 风冷服务器 # IndexTTS 2.0 # 自动化运维 #VoxCPM-1.5-TTS # 云端GPU # PyCharm宕机 #全链路优化 #实战教程 #database #儿童AI #图像生成 #pjsip #LoRA # lora-scripts # 模型微调 #AI论文写作工具 #学术写作辅助 #论文创作效率提升 #AI写论文实测 #传统行业 #stl #漏洞修复 #IIS Crypto #blender #warp #SSH保活 #数字化转型 #实体经济 #商业模式 #软件开发 #数智红包 #商业变革 #创业干货 #微PE # GLM-4.6V-Flash-WEB # AI部署 #everything #材料工程 #智能电视 #能源 #AB包 #人脸识别sdk #视频编解码 #人脸识别 #VMware创建虚拟机 #远程更新 #缓存更新 #多指令适配 #物料关联计划 #AI生成 # outputs目录 # 自动化 #挖漏洞 #攻击溯源 #编程 #决策树 #Zabbix #语音合成 #HistoryServer #Spark #YARN #jobhistory #二值化 #Canny边缘检测 #轮廓检测 #透视变换 #DooTask #ZooKeeper #ZooKeeper面试题 #面试宝典 #深入解析 #ComfyUI # 推理服务器 #飞牛NAS #NVR #EasyNVR #防毒面罩 #防尘面罩 #编程助手 #.net #net core #kestrel #web-server #asp.net-core #MC #elk #rabbitmq #m3u8 #HLS #移动端H5网页 #APP安卓苹果ios #监控画面 直播视频流 #Prometheus #计算机毕业设计 #程序定制 #毕设代做 #课设 #Hadoop #高斯溅射 #postman #UEFI #BIOS #Legacy BIOS #内存接口 # 澜起科技 # 服务器主板 # 显卡驱动备份 #Socket #模拟退火算法 #集成学习 #开关电源 #热敏电阻 #PTC热敏电阻 #文件传输 #电脑文件传输 #电脑传输文件 #电脑怎么传输文件到另一台电脑 #电脑传输文件到另一台电脑 #身体实验室 #健康认知重构 #系统思维 #微行动 #NEAT效应 #亚健康自救 #ICT人 #云开发 #eureka #性能 #优化 #RAM #KMS 激活 #mongodb #AI智能棋盘 #Rock Pi S #边缘计算 #wireshark #广播 #组播 #并发服务器 #nacos #银河麒麟aarch64 #MC群组服务器 #uvicorn #uvloop #asgi #event # 服务器迁移 # 回滚方案 #大模型入门 #homelab #Lattepanda #Jellyfin #Plex #Kodi #企业存储 #RustFS #对象存储 #高可用 #es安装 #Docker #云计算运维 #asp.net大文件上传 #asp.net大文件上传下载 #asp.net大文件上传源码 #ASP.NET断点续传 #asp.net上传文件夹 #asp.net上传大文件 #excel #gpu #nvcc #cuda #nvidia #ceph #漏洞挖掘 #TensorRT # 推理优化 #C/C++ #c++高并发 #百万并发 #SSH别名 #zabbix #BoringSSL #log4j #Jetty # CosyVoice3 # 嵌入式服务器 #模块 #STUN #turn #ICE #RXT4090显卡 #RTX4090 #深度学习服务器 #硬件选型 #群晖 #音乐 # ARM服务器 # 鲲鹏 #IntelliJ IDEA #Spring Boot #SQL注入主机 #neo4j #NoSQL #SQL #http头信息 #uip #Coturn #TURN #ci/cd #k8s #部署上线 #动静分离 #Nginx #新人首发 # 代理转发 # 跳板机 #echarts #鸿蒙PC #树莓派 #温湿度监控 #WhatsApp通知 #IoT #MySQL # HiChatBox # 离线AI #建筑缺陷 #红外 #数据集 #TCP服务器 #开发实战 #SMARC #ARM #全文检索 #银河麒麟服务器系统 # 公钥认证 #短剧 #短剧小程序 #短剧系统 #微剧 #空间计算 #原型模式 #hibernate #nosql #VibeVoice # 云服务器 #戴尔服务器 #戴尔730 #装系统 #SMTP # 内容安全 # Qwen3Guard #汽车 #X11转发 #ThingsBoard MCP #可撤销IBE #服务器辅助 #私钥更新 #安全性证明 #双线性Diffie-Hellman #I/O模型 #并发 #水平触发、边缘触发 #多路复用 #MinIO服务器启动与配置详解 #clickhouse #改行学it #代理 #平板 #零售 #智能硬件 #数据访问 #vncdotool #链接VNC服务器 #如何隐藏光标 #HeyGem # 服务器IP访问 # 端口映射 #gateway #Comate #agent #ai大模型 #FHSS #eclipse #servlet #arm64 #CNAS #CMA #程序文件 #SSH复用 # 远程开发 #磁盘配额 #存储管理 #形考作业 #国家开放大学 #系统运维 #自动化运维 #IO #插件 #开源软件 #DHCP #网络安全大赛 #C++ UA Server #SDK #跨平台开发 #云服务器选购 #Saas #线程 #机器视觉 #6D位姿 #UOS #海光K100 #统信 #NFC #智能公交 #服务器计费 #FP-增长 #outlook #错误代码2603 #无网络连接 #2603 #mssql #数据安全 #注入漏洞 #wpf #实时检测 #卷积神经网络 #Modbus #MOXA #GATT服务器 #蓝牙低功耗 #googlecloud #lucene #DAG #firefox #safari # RTX 3090 #b树 #具身智能 # ControlMaster #Proxmox VE #虚拟化 #硬件 #bond #服务器链路聚合 #网卡绑定 #Fun-ASR # 语音识别 # WebUI #HarmonyOS APP #密码 #windbg分析蓝屏教程 #AI电商客服 #spring ai #oauth2 #memory mcp #Cursor #数据可视化 #网路编程 #nmodbus4类库使用教程 #docker-compose #目标跟踪 #rtmp #smtp #smtp服务器 #PHP #声源定位 #MUSIC #c++20 # 远程连接 #fs7TF #Buck #NVIDIA #算力 #交错并联 #DGX #ROS # 局域网访问 # 批量处理 #内存治理 #IFix # 高温监控 #跨域 #发布上线后跨域报错 #请求接口跨域问题解决 #跨域请求代理配置 #request浏览器跨域 #gerrit #opc ua #opc #npu #memcache # 环境迁移 #大剑师 #nodejs面试题 #matplotlib #安全架构 #ansys #ansys问题解决办法 # 网络延迟 #指针 #anaconda #虚拟环境 #ranger #MySQL8.0 #远程软件 #WT-2026-0001 #QVD-2026-4572 #smartermail # GLM-TTS # 数据安全 #TTS私有化 # IndexTTS # 音色克隆 #ESP32 # OTA升级 # 黄山派 #内网 #飞牛nas #fnos #ip #设计师 #图像处理 #游戏美术 #技术美术 # 大模型推理 #分布式数据库 #集中式数据库 #业务需求 #选型误 # Connection refused #系统管理 #服务 #代理服务器 #rsync # 数据同步 #azure #Apple AI #Apple 人工智能 #FoundationModel #Summarize #SwiftUI #arm #多线程 #claudeCode #content7 #源代码管理 #Socket网络编程 #跳槽 #工作 #挖矿 #Linux病毒 #网安应急响应 #统信UOS #服务器操作系统 #win10 #qemu #odoo # GLM # 服务连通性 #HarmonyOS # 服务器配置 # GPU # 高并发 # 串口服务器 # NPort5630 #appche #数据恢复 #视频恢复 #视频修复 #RAID5恢复 #流媒体服务器恢复 #Ubuntu #SSH跳转 #TTS #go # GPU集群 #Gateway #认证服务器集成详解 #服务器开启 TLS v1.2 #IISCrypto 使用教程 #TLS 协议配置 #IIS 安全设置 #服务器运维工具 #ftp #sftp #uniapp #合法域名校验出错 #服务器域名配置不生效 #request域名配置 #已经配置好了但还是报错 #uniapp微信小程序 #YOLO识别 #YOLO环境搭建Windows #YOLO环境搭建Ubuntu # 轻量化镜像 # 边缘计算 #国产化OS #华为od #华为机试 #OpenHarmony #Python办公自动化 #Python办公 #版本控制 #Git入门 #开发工具 #代码托管 #jupyter #cpu #套接字 #I/O多路复用 #字节序 #工程设计 #预混 #扩散 #燃烧知识 #层流 #湍流 #weston #x11 #x11显示服务器 #量子计算 #研发管理 #禅道 #禅道云端部署 #计算几何 #斜率 #方向归一化 #叉积 # 批量部署 #samba #copilot #RSO #机器人操作系统 #硬盘克隆 #DiskGenius # 键鼠锁定 #glibc #MQTT协议 #服务器线程 # SSL通信 # 动态结构体 #RWK35xx #语音流 #实时传输 #超算中心 #PBS #lsf #报表制作 #职场 #用数据讲故事 #语音生成 #AI部署 # ms-swift #PN 结 #后端框架 #JNI #pxe #lvs # 数字人系统 # 远程部署 #adobe # TURN # NAT穿透 #MCP服务器注解 #异步支持 #方法筛选 #声明式编程 #自动筛选机制 #服务器繁忙 #powerbi #麦克风权限 #访问麦克风并录制音频 #麦克风录制音频后在线播放 #用户拒绝访问麦克风权限怎么办 #uniapp 安卓 苹果ios #将音频保存本地或上传服务器 #express #cherry studio #Node.js # child_process #gmssh #宝塔 #1panel #free #vmstat #sar #宝塔面板部署RustDesk #RustDesk远程控制手机 #手机远程控制 #铁路桥梁 #DIC技术 #箱梁试验 #裂纹监测 #四点弯曲 #可再生能源 #绿色算力 #风电 #若依 #TRO #TRO侵权 #TRO和解 #运维工具 #GLM-4.6V-Flash-WEB # AI视觉 # 本地部署 #DNS #Discord机器人 #云部署 #程序那些事 #AI应用编程 #r语言 #分类 #边缘AI # Kontron # SMARC-sAMX8 #remote-ssh #人大金仓 #Kingbase #OpenAI #故障 #多模态 #微调 #超参 #LLamafactory #CMake #Make #Java程序员 #Java面试 #后端开发 #Spring源码 #Spring #SpringBoot #webpack #cesium #可视化 #esp32 arduino #FASTMCP #sglang #n8n解惑 #交换机 #三层交换机 #SSH Agent Forwarding # 容器化 #reactjs #web3 #产品运营 #Aluminium #Google #联机教程 #局域网联机 #局域网联机教程 #局域网游戏 #AI技术 #yolov12 #研究生life #vmware # 权限修复 #模型上下文协议 #MultiServerMCPC #load_mcp_tools #load_mcp_prompt # 服务器IP # 端口7860 #ShaderGraph #图形 #VMware Workstation16 #junit #H5网页 #网页白屏 #H5页面空白 #资源加载问题 #打包部署后网页打不开 #HBuilderX #r-tree #扩展屏应用开发 #android runtime #服务器解析漏洞 #算力建设 #le audio #低功耗音频 #连接 # 远程访问 #tensorflow #ServBay #claude code #code cli #ccusage #GB28181 #SIP信令 #视频监控 #xshell #host key #Modbus-TCP #雨云服务器 #教程 #MCSM面板 #RK3576 #瑞芯微 #硬件设计 #win11 #c #mtgsig #美团医药 #美团医药mtgsig #美团医药mtgsig1.2 #opc模拟服务器 #ArkUI #ArkTS #鸿蒙开发 #反向代理 #实时音视频 #Host #SSRF #数据迁移 #MinIO #Exchange #sentinel #系统安装 #测速 #iperf #iperf3 #静脉曲张 #腿部健康 #运动 #spine #IPv6 #网络攻击模型