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

基于STM32的农业病虫害检测检测系统:OpenCV、MQTT、Flask框架、MySQL(代码示例)

一、项目概述

随着全球农业现代化的不断推进,智能农业监测系统应运而生。此项目旨在通过实时监测土壤湿度、温度等环境数据,结合作物生长状态的分析,提高农业生产效率和作物质量。通过引入STM32单片机、OpenCV图像处理技术和后端数据分析系统,项目能够有效解决农业生产中的以下问题:

  • 实时监测:传统农业依赖人工监测,效率低,且易受主观因素影响。本项目通过自动化监测,提供实时数据。

  • 病虫害检测:利用图像处理技术,及时识别作物病虫害,减少损失。

  • 数据分析与决策支持:后端系统分析历史数据,提供科学的农业管理建议。

通过上述功能,本项目为农民提供了一种高效、可靠的农业管理工具,推动农业生产智能化。

二、系统架构

系统架构设计需满足数据采集、处理和分析的需求。整体架构可分为以下几个主要部分:

  1. 数据采集模块:使用STM32单片机连接土壤湿度传感器和温度传感器,定时采集土壤和气候数据。

  2. 数据处理模块:通过OpenCV对作物生长状态进行图像分析,检测病虫害。

  3. 后端系统:服务器端处理分析数据,提供决策支持,并通过API将数据传递给前端应用。

  4. 数据库系统:存储历史数据,便于后续的趋势分析和决策支持。

系统架构图

采集数据
分析结果
存储数据
历史数据
数据采集模块
数据处理模块
后端系统
数据库
前端应用

选型与技术栈

  • 单片机:STM32系列,具备丰富的IO接口和低功耗特性。

  • 传感器:土壤湿度传感器、温度传感器(如DHT11)。

  • 图像处理:OpenCV库,用于图像采集和处理。

  • 通信协议:使用MQTT或HTTP协议进行数据传输。

  • 后端框架:Python Flask框架,便于快速开发RESTful API。

  • 数据库:MySQL或SQLite,用于存储历史数据。

三、环境搭建

硬件环境

  • STM32开发板

  • 土壤湿度传感器

  • 温度传感器(DHT11)

  • 摄像头模块(如USB摄像头)

  • 路由器(用于网络连接)

软件环境

  • 开发工具:Keil uVision或STM32CubeIDE

  • 编程语言:C/C++(STM32部分),Python(后端部分)

  • 数据库管理系统:MySQL或SQLite

  • 图像处理库:OpenCV

安装步骤

  1. STM32开发环境配置:
  • 下载并安装STM32CubeIDE。

  • 配置开发板的连接,安装对应的驱动程序。

  1. Python环境配置:
  • 安装Python:

    sudo apt-get install python3 python3-pip
    
  • 安装Flask和OpenCV:

    pip install Flask opencv-python
    
  1. 数据库配置:
  • 安装MySQL:

    sudo apt-get install mysql-server
    
  • 创建数据库和表:

    CREATE DATABASE smart_agriculture;
    USE smart_agriculture;
    CREATE TABLE sensor_data (id INT AUTO_INCREMENT PRIMARY KEY,moisture FLOAT,temperature FLOAT,timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
    );
    

注意事项

  • 确保STM32开发板与PC的连接正常,避免串口配置错误。

  • 在安装OpenCV时,可能需要安装额外的依赖库,确保图像处理功能正常。

四、代码实现

数据采集模块(STM32)

在智能农业监测系统中,数据采集模块是系统的核心部分,负责实时采集土壤湿度和温度数据。这里我们使用STM32单片机,通过连接DHT11温度传感器和土壤湿度传感器,定期进行数据采集。以下是STM32的数据采集代码示例及详细说明。

代码示例
#include "stm32f4xx_hal.h"
#include "dht11.h"  // 包含DHT11传感器的库
#include "soil_moisture.h"  // 自定义土壤湿度传感器库// 定义传感器引脚
#define DHT11_PIN GPIO_PIN_1
#define SOIL_MOISTURE_PIN GPIO_PIN_2// 定义采集周期
#define SAMPLE_PERIOD 5000  // 5秒采样一次// 函数原型
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
void collectSensorData(void);int main(void) {// 初始化HAL库HAL_Init();// 配置系统时钟SystemClock_Config();// 初始化GPIOMX_GPIO_Init();// 主循环while (1) {collectSensorData();  // 采集传感器数据HAL_Delay(SAMPLE_PERIOD);  // 延时5秒}
}void collectSensorData(void) {float humidity, temperature, soilMoisture;// 读取DHT11传感器数据if (DHT11_Read(DHT11_PIN, &humidity, &temperature) == HAL_OK) {// 成功读取温度和湿度printf("Temperature: %.2f °C, Humidity: %.2f %%\n", temperature, humidity);} else {// 读取失败printf("Failed to read from DHT11\n");}// 读取土壤湿度传感器数据soilMoisture = SoilMoisture_Read(SOIL_MOISTURE_PIN);printf("Soil Moisture: %.2f\n", soilMoisture);
}// 系统时钟配置函数
void SystemClock_Config(void) {// 这里配置系统时钟,具体内容根据使用的STM32型号进行调整
}// GPIO初始化函数
static void MX_GPIO_Init(void) {GPIO_InitTypeDef GPIO_InitStruct = {0};// 开启GPIO时钟__HAL_RCC_GPIOA_CLK_ENABLE();// 配置DHT11引脚GPIO_InitStruct.Pin = DHT11_PIN;GPIO_InitStruct.Mode = GPIO_MODE_INPUT;  // DHT11为输入引脚GPIO_InitStruct.Pull = GPIO_NOPULL;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);// 配置土壤湿度传感器引脚GPIO_InitStruct.Pin = SOIL_MOISTURE_PIN;GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;  // 模拟输入HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
代码说明
  1. 库引用:

    • #include "stm32f4xx_hal.h":包含STM32硬件抽象层库,提供对硬件的抽象接口。

    • #include "dht11.h":包含DHT11传感器的驱动库,负责读取温度和湿度数据。

    • #include "soil_moisture.h":自定义的土壤湿度传感器库,用于读取土壤湿度值。

  2. 宏定义:

    • DHT11_PINSOIL_MOISTURE_PIN:定义DHT11和土壤湿度传感器的连接引脚。

    • SAMPLE_PERIOD:定义数据采集的时间间隔,这里设置为5秒。

  3. 主函数:

    • HAL_Init():初始化HAL库。

    • SystemClock_Config():配置系统时钟,具体实现根据所选STM32型号设置。

    • MX_GPIO_Init():初始化GPIO引脚。

  4. 数据采集函数 collectSensorData

    • 使用DHT11_Read函数读取DHT11传感器的温度和湿度数据,返回成功与否的状态。

    • 使用SoilMoisture_Read函数读取土壤湿度数据,并打印到控制台。

  5. GPIO引脚配置:

    • GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;:将引脚设置为模拟输入模式,以便读取土壤湿度传感器的模拟信号。

    • GPIO_InitStruct.Pin = DHT11_PIN;:选择用于DHT11的GPIO引脚。

    • GPIO_InitStruct.Mode = GPIO_MODE_INPUT;:将该引脚设置为输入模式,因为DHT11传感器需要读取数据。

    • GPIO_InitStruct.Pull = GPIO_NOPULL;:设置引脚不使用上拉或下拉电阻,以确保DHT11传感器正常工作。

    • HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);:初始化GPIO引脚。

    • 对土壤湿度传感器引脚进行类似的配置:

数据处理模块(OpenCV)

在数据处理模块中,我们利用OpenCV库对作物的生长状态进行分析,特别是对病虫害的检测。以下是一个基本的使用OpenCV进行图像处理的代码示例。

代码示例
import cv2
import numpy as npdef detect_pests(image_path):# 读取输入图像image = cv2.imread(image_path)# 转换为灰度图gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 使用高斯模糊去噪声blurred = cv2.GaussianBlur(gray, (5, 5), 0)# 边缘检测edges = cv2.Canny(blurred, 100, 200)# 寻找轮廓contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)# 在原图上绘制轮廓for contour in contours:if cv2.contourArea(contour) > 100:  # 过滤小轮廓cv2.drawContours(image, [contour], -1, (0, 255, 0), 2)  # 绘制绿色轮廓# 显示结果cv2.imshow('Detected Pests', image)cv2.waitKey(0)cv2.destroyAllWindows()if __name__ == "__main__":detect_pests('crop_image.jpg')  # 替换为实际的作物图像路径
代码说明
  1. 库引用:

    • import cv2:导入OpenCV库。

    • import numpy as np:导入NumPy库,用于数值计算。

  2. 函数 detect_pests

    • def detect_pests(image_path):定义一个函数,接收图像路径作为参数。

    • cv2.imread(image_path):读取指定路径的图像。

    • cv2.cvtColor(image, cv2.COLOR_BGR2GRAY):将图像转换为灰度图,以便于后续处理。

  3. 图像处理步骤:

    • cv2.GaussianBlur(gray, (5, 5), 0):对灰度图应用高斯模糊,以减少噪声。

    • cv2.Canny(blurred, 100, 200):使用Canny边缘检测算法提取边缘。

    • cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE):寻找图像中的轮廓。

  4. 轮廓绘制:

    • 遍历所有轮廓,使用cv2.drawContours在原图上绘制超过100个像素的轮廓。
  5. 结果显示:

    • cv2.imshow('Detected Pests', image):显示处理后的图像。

    • cv2.waitKey(0)cv2.destroyAllWindows():等待用户

后端系统

在后端系统中,我们将使用Flask框架处理前端发来的请求,提供数据接口,并将处理后的数据存储到数据库中。以下是一个简单的后端实现示例。

代码示例
from flask import Flask, request, jsonify
import mysql.connectorapp = Flask(__name__)# 数据库连接配置
db_config = {'user': 'your_username','password': 'your_password','host': 'localhost','database': 'smart_agriculture'
}@app.route('/submit_data', methods=['POST'])
def submit_data():"""接收传感器数据并存储到数据库"""data = request.jsonmoisture = data.get('moisture')temperature = data.get('temperature')try:# 连接数据库connection = mysql.connector.connect(**db_config)cursor = connection.cursor()# 插入数据insert_query = "INSERT INTO sensor_data (moisture, temperature) VALUES (%s, %s)"cursor.execute(insert_query, (moisture, temperature))connection.commit()return jsonify({"message": "Data inserted successfully!"}), 201except mysql.connector.Error as err:return jsonify({"error": str(err)}), 500finally:cursor.close()connection.close()@app.route('/get_data', methods=['GET'])
def get_data():"""获取历史传感器数据"""try:connection = mysql.connector.connect(**db_config)cursor = connection.cursor()# 查询数据cursor.execute("SELECT * FROM sensor_data ORDER BY timestamp DESC")results = cursor.fetchall()# 转换为字典列表data = [{"id": row[0], "moisture": row[1], "temperature": row[2], "timestamp": row[3]} for row in results]return jsonify(data), 200except mysql.connector.Error as err:return jsonify({"error": str(err)}), 500finally:cursor.close()connection.close()if __name__ == "__main__":app.run(debug=True)
代码说明
  1. 库引用:

    • from flask import Flask, request, jsonify:导入Flask相关模块,用于创建Web应用和处理HTTP请求。

    • import mysql.connector:导入MySQL连接器,用于连接和操作MySQL数据库。

  2. Flask应用配置:

    • app = Flask(__name__):创建Flask应用实例。
  3. 数据库连接配置:

    • db_config字典中包含数据库的连接信息,包括用户名、密码、主机和数据库名称。
  4. 数据提交接口:

    • @app.route('/submit_data', methods=['POST']):定义一个POST请求的路由,用于接收传感器数据。

    • data = request.json:获取请求中的JSON数据。

    • 通过mysql.connector.connect(**db_config)连接数据库。

    • 使用SQL INSERT语句将传感器数据插入数据库。

  5. 数据获取接口:

    • @app.route('/get_data', methods=['GET']):定义一个GET请求的路由,用于返回历史传感器数据。

    • 执行SQL SELECT语句查询所有传感器数据,并将结果转换为字典列表。

    • 返回JSON格式的响应。

  6. 启动Flask应用:

    • if __name__ == "__main__": app.run(debug=True):在调试模式下启动Flask应用。

数据库设计

为了支持智能农业监测系统的功能,我们需要设计合适的数据库结构。以下是数据库表的简单设计:

数据库表结构
CREATE TABLE sensor_data (id INT AUTO_INCREMENT PRIMARY KEY,moisture FLOAT NOT NULL,temperature FLOAT NOT NULL,timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
);
表结构说明
  • id:主键,自增字段,用于唯一标识每条记录。

  • moisture:土壤湿度值,浮点型,表示当前的土壤湿度。

  • temperature:温度值,浮点型,表示当前环境温度。

五、项目总结

在本项目中,我们设计并实现了一个智能农业监测系统,主要功能包括实时监测土壤湿度和温度,利用图像处理技术检测作物生长状态(如病虫害),并将数据存储到数据库中以供后续分析。系统架构明确,模块分工合理,具体实现步骤如下:

  1. 数据采集模块:
  • 使用STM32单片机和传感器(DHT11和土壤湿度传感器)进行实时数据采集。

  • 定期将采集到的数据通过后端接口发送到服务器。

  1. 图像处理模块:
  • 利用OpenCV进行作物图像处理,通过边缘检测和轮廓提取分析作物的健康状况。

  • 针对检测到的病虫害,生成相应的分析结果。

  1. 后端系统:
  • 使用Flask框架搭建RESTful API,接收前端提交的传感器数据,并将其存储到MySQL数据库中。

  • 提供获取历史数据的接口,方便用户查看历史记录并进行数据分析。

  1. 数据库管理:
  • 设计合理的数据库表结构,以存储传感器数据及其时间戳,支持数据的高效存取和查询。

相关文章:

基于STM32的农业病虫害检测检测系统:OpenCV、MQTT、Flask框架、MySQL(代码示例)

一、项目概述 随着全球农业现代化的不断推进,智能农业监测系统应运而生。此项目旨在通过实时监测土壤湿度、温度等环境数据,结合作物生长状态的分析,提高农业生产效率和作物质量。通过引入STM32单片机、OpenCV图像处理技术和后端数据分析系统…...

算法日记day 39(动归之打家劫舍)

一、打家劫舍1 题目: 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。…...

Vue 生命周期详解含demo、面试常问问题案例

Vue 生命周期详解、面试常问问题案例 含 demo 文章目录 Vue 生命周期详解、面试常问问题案例 含 demo一、Vue 生命周期是什么二、Vue 中如何使用生命周期钩子1. **beforeCreate**2. **created**3. **beforeMount**4. **mounted**5. **beforeUpdate**6. **updated**7. **beforeD…...

表单自定义规则的校验

在 Vue 3 中使用 Element Plus 的表单组件进行自定义规则的校验非常方便。Element Plus 提供了 ElForm 和 ElFormItem 组件,它们内置了表单验证的功能。下面我将详细介绍如何使用 Element Plus 进行自定义规则的校验。 创建表单及规则 首先,你需要创建…...

JVM 有哪些垃圾回收算法(回收机制)?

JVM 有哪些垃圾回收算法(回收机制)? 标记-清除算法 在Java虚拟机中,标记-清除算法是一种用于垃圾回收的算法。它分为两个阶段:标记阶段和清除阶段。 在标记阶段,垃圾收集器会遍历堆内存中的所有对象&…...

2024年高教社杯数学建模国赛A题思路解析+代码+论文

2024年高教社杯全国大学生数学建模竞赛(以下简称国赛)将于9月5日晚6时正式开始。 下文包含:2024国赛思路解析​、国赛参赛时间及规则信息说明、好用的数模技巧及如何备战数学建模竞赛 C君将会第一时间发布选题建议、所有题目的思路解析、相…...

Linux中yum、vim、gcc/g++的使用

目录 一、Linux 软件包管理器 yum 什么是软件包 关于 rzsz 查看软件包★ 如何安装软件★ 如何卸载软件★ Linux 开发工具 二、Linux编译器-vim使用 vim的基本概念 vim的基本操作 vim正常模式命令集 vim末行模式命令集 vim操作总结 如果在vim界面不小心按了Ctrl …...

基于模糊神经网络的金融序列预测算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于模糊神经网络的金融序列预测算法matlab仿真,根据序列的MAD,RSI,KD等指标实现序列的预测和最终收益分析。 2.测试软件版本以及运行结果展示 MATLAB2022A版本…...

STM32 HAL库常用功能封装

关中断 /*** brief 关闭所有中断(但是不包括fault和NMI中断)* param 无* retval 无*/ void sys_intx_disable(void) {__ASM volatile("cpsid i"); }开中断 /*** brief 开启所有中断* param 无* retval 无*/ void sys_intx_enabl…...

golang zap日志库 打印日志时显示的源文件始终是同一个问题解决方法 zap.Option函数可选项 zap.AddCallerSkip(1) 使用示例

这种情况一般出现在我们对zap日志库进行二次封装的情况下, 在打印日志的时候的源文件非我们期望的文件,如下 原因分析 出现这个问题的原因是zap函数内部在调用 runtime.Caller 时的skip层级不对了,因为我们进行了二次封装,所以za…...

BL196MQTT远程IO模块助力智能楼宇自动化升级

在智能楼宇自动化领域,每一个细节的优化都能带来整体效率与舒适度的显著提升。钡铼技术的BL196MQTT远程IO模块,以其卓越的灵活性和强大的性能,正在成为这一领域中推动楼宇自动化升级的关键力量。 钡铼技术IOy系列:创新与灵活性的…...

【面试宝典】Java面向对象面试题总结(上)

一、重写和重载 在Java中,重写(Override)和重载(Overload)是面向对象编程中两个非常重要的概念,它们都与方法的定义和调用有关,但两者有着本质的区别。 1、重写(Override&#xff…...

如何运用独特的产业运营体系打造一流的数字媒体产业园

如何运用独特的产业运营体系打造一流的数字媒体产业园 2024-08-15 17:37树莓集团 在数字经济蓬勃发展的今天,数字媒体产业作为其中的重要一环,正展现出巨大的潜力和活力。而如何运用独特的产业运营体系,打造一流的数字媒体产业园&#xff0…...

安全基础学习-SHA-256

SHA-256 是一种密码学哈希函数,是 SHA-2(Secure Hash Algorithm 2)家族的一部分。它被广泛用于数据完整性验证、数字签名以及密码存储等领域。 1、SHA-256的原理 SHA-256 生成一个固定长度为 256 位(32 字节)的哈希值。无论输入数据的大小或类型,输出的哈希值始终是 25…...

Redis中Big Key该如何解决?

目录 1、Big Key的产生 2、BigKey场景分析 3、Big Key的危害 4、检测 BigKey 5、解决 BigKey 问题 Big Key拆分 (1)按时间/业务拆分 (2)按哈希(Hash)拆分 (3)按前缀树拆分…...

基于springboot的实习管理系统

TOC springboot207基于springboot的实习管理系统 绪论 1.1研究背景与意义 信息化管理模式是将行业中的工作流程由人工服务,逐渐转换为使用计算机技术的信息化管理服务。这种管理模式发展迅速,使用起来非常简单容易,用户甚至不用掌握相关的…...

土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测

土地利用/土地覆盖数据是生态、环境和气象等领域众多模型的重要输入参数之一。基于遥感影像解译,可获取历史或当前任何一个区域的土地利用/土地覆盖数据,用于评估区域的生态环境变化、评价重大生态工程建设成效等。借助CLUE模型,实现对未来土…...

Rust 之环境搭建

前言 Rust 是一种现代的系统级编程语言,以其内存安全性、高性能和简洁的语法而著称。本文将介绍如何在不同操作系统上搭建 Rust 开发环境,并配置好基础工具,使您能够快速开始 Rust 编程。 1. 安装 Rust Rust 官方推荐使用 rustup 工具来管…...

基于微信小程序地图实现点位标注、覆盖物、地图聊天

目录 小程序部分map标签的使用获取用户经纬度并转换地址地图点击事件覆盖物标注点击并实现弹窗交互数据库及接口部分数据库表结构设计API搭建小程序接口使用注意事项wx.getLocation深入控制地图小程序部分 map标签的使用 创建小程序的步骤这里不再重复赘述,在wxml页面中放一个…...

xxl-job的分片广播+单播

1 介绍一下xxl-job XXL-JOB 是一个分布式任务调度平台,旨在为分布式应用系统提供开箱即用的调度解决方案。它非常易于使用,并具有很高的可扩展性。以下是 XXL-JOB 的详细介绍,包括其核心功能、架构设计、主要组件及其应用场景。 核心功能 简…...

大语言模型如何处理长文本?常用文本分割技术详解

为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

C# 类和继承(抽象类)

抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

Rust 异步编程

Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程

本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...

Java编程之桥接模式

定义 桥接模式(Bridge Pattern)属于结构型设计模式,它的核心意图是将抽象部分与实现部分分离,使它们可以独立地变化。这种模式通过组合关系来替代继承关系,从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...

第7篇:中间件全链路监控与 SQL 性能分析实践

7.1 章节导读 在构建数据库中间件的过程中,可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中,必须做到: 🔍 追踪每一条 SQL 的生命周期(从入口到数据库执行)&#…...

WEB3全栈开发——面试专业技能点P7前端与链上集成

一、Next.js技术栈 ✅ 概念介绍 Next.js 是一个基于 React 的 服务端渲染(SSR)与静态网站生成(SSG) 框架,由 Vercel 开发。它简化了构建生产级 React 应用的过程,并内置了很多特性: ✅ 文件系…...

yaml读取写入常见错误 (‘cannot represent an object‘, 117)

错误一:yaml.representer.RepresenterError: (‘cannot represent an object’, 117) 出现这个问题一直没找到原因,后面把yaml.safe_dump直接替换成yaml.dump,确实能保存,但出现乱码: 放弃yaml.dump,又切…...