G919-GAS软件 JSON格式数据通讯协议-阵列数据解析

G919-GAS软件 JSON格式数据通讯协议-阵列数据解析

版本记录

DateAuthorVersionNote
2024.04.07Dog TaoV1.0发布通讯协议。
2025.05.06Dog TaoV1.11. 增加了【高速采样】模式下的通讯协议。2. 增加了“软件开发建议”小节。

文章目录

  • G919-GAS软件 JSON格式数据通讯协议-阵列数据解析
    • 普通采样模式
      • 精确行列更新
      • 批量行列更新
    • 高速采样模式
    • 软件开发建议
      • 采集板固件
      • 上位机软件

本协议遵从 《G919-GAS软件 JSON格式数据通讯协议》所制定的规范。以下针对阵列结构化数据进行通讯协议制定。

普通采样模式

普通采样模式适合数据采样频率不高(≤2Hz)、数据传输速率较慢(例如蓝牙BLE传输)的场景。一般具备较低响应速度的气体传感器、电化学传感器、阻敏型压力传感器等构成的阵列适合采用此模式进行数据传输。

精确行列更新

精确行列更新的上报格式适用于在一个大型阵列中仅更新单个单元的值。

设备(下位机)的JSON键值定义参考("ID""NT"的键值必须实现,其他可根据需要增删改):

名称IDNTCTROWCOLVAL
功能设备标识符设备网络地址计数行号列号单值
MAC地址(后32位)网络地址(16位)时间戳或数据序号(uint行(uint列(uint对应行列的读出(float
JSON数据类型字符串字符串数字数字数字数字

设备(下位机)的串口(含蓝牙等透传)发送的数据示例:

// Set new value of coordinate (0, 0) to 28.3
{"ID":"25382B57","NT":"785F","ROW":0,"COL":0,"VAL":28.3}
// Set new value of coordinate (0, 1) to 29.9
{"ID":"25382B57","NT":"785F","ROW":0,"COL":1,"VAL":29.9}
// Set new value of coordinate (0, 2) to 32.5
{"ID":"25382B57","NT":"785F","ROW":0,"COL":2,"VAL":32.5}

批量行列更新

批量行列更新的上报格式适用于在一个小型阵列中实时刷新全部或部分单元值。

设备(下位机)的JSON键值定义参考("ID""NT"的键值必须实现,其他可根据需要增删改):

名称IDNTCTROWCOLVAL
功能设备标识符设备网络地址计数行号列号多值
MAC地址(后32位)网络地址(16位)时间戳或数据序号(uint起始行(uint起始列(uint指定行列作为起点的批量读出(float数组)
JSON数据类型字符串字符串数字数字数字数组

设备(下位机)的串口发送的数据示例:

// Set the continuous values starting from coordinate (0, 0)
// e.g., for a 4x4 array, the values are updated in the whole row 0 and row 1, respectively.
{"ID":"25382B57","NT":"785F","ROW":0,"COL":0,"VALS":[28.3, 29.9, 82.1, 46.8, 45.2, 54.6, 31.8, 25.6]}

注意,批量行列更新的顺序是默认按行更新,即沿当前坐标所在的行开始更新到当前行末,随后在下一行从头开始继续更新数据。

高速采样模式

高速采样模式适合数据采样频率高(≥5Hz)、数据传输速率较快(例如串口直连、WiFi传输)的场景。一般具备较高响应速度的压电、热电、光电传感器等构成的阵列适合采用此模式进行数据传输。

高速采样模式采用类似普通采样模式下的“批量行列更新”,直接刷新一个阵列中全部或部分单元值。

设备(下位机)的JSON键值定义参考("ID""NT"的键值必须实现,其他可根据需要增删改):

名称IDNTCTROWCOLVALS1-0VALS1-1VALS1-NVALS2-0VALS2-1VALS2-N
功能设备标识符设备网络地址计数行号列号阵列1第0个时间步的值阵列1第1个时间步的值阵列1第N个时间步的值阵列2第0个时间步的值阵列2第1个时间步的值阵列2第N个时间步的值
MAC地址(后32位)网络地址(16位)时间戳或数据序号(uint起始行(uint起始列(uint指定行列作为起点的批量读出(float数组)同前同前同前同前同前
JSON数据类型字符串字符串数字数字数字数组数组数组数组数组数组

需要特别说明的是,高速采样模式采用多个时间步数据累积同时发送的形式,减少了数据传输的频率、增大了单次数据传输的量。这样可以保证高速采样数据在上位机软件的高效记录与绘制(每次绘制多个数据点)。例如,在10 Hz采样速率下,可以将每秒10个时间步采样的数据累积同时发送,上位机软件每秒绘图1次,每次绘制10个数据点。

设备(下位机)的串口发送的数据示例:

// Set the continuous values starting from coordinate (0, 0){  "ID":  "ESP32_402FA8","CT":  101,"ROW":  0,"COL":  0,"VALS1-0":  [2010.0, 1995.8, 2009.4, 2009.9, 2012.3, 2012.0, 2012.4, 2012.6, 1998.8, 1998.4, 1998.8, 1998.6, 2000.6, 2000.6, 2001.0, 2000.6],"VALS1-1":  [2009.6, 1995.9, 2009.5, 2009.5, 2012.6, 2012.4, 2012.1, 2012.4, 1998.9, 1999.0, 1998.6, 1999.0, 2000.9, 2000.6, 2001.0, 2001.1],"VALS1-2":  [2009.9, 1993.4, 2009.5, 2007.9, 2012.8, 2013.9, 2012.3, 2012.6, 1998.9, 1998.6, 1998.6, 1998.5, 2000.8, 2001.0, 2000.9, 1971.3],"VALS1-3":  [1999.1, 1999.3, 1999.5, 2013.5, 2001.8, 2003.3, 2015.9, 2016.0, 1987.1, 1987.6, 2002.6, 2003.0, 1989.6, 1987.6, 2004.4, 2005.3],"VALS1-4":  [2013.6, 2013.4, 1999.5, 1999.1, 2016.1, 2002.1, 2001.6, 1998.1, 2002.6, 1981.5, 1987.3, 1987.4, 2005.0, 1989.8, 1989.0, 1989.5],"VALS1-5":  [1999.3, 1997.3, 1999.4, 1993.4, 2002.3, 2001.6, 2001.9, 2018.9, 1987.6, 1986.6, 1987.6, 2002.6, 1989.9, 1989.8, 1989.5, 2005.1],"VALS1-6":  [2013.4, 2013.3, 2013.4, 2013.8, 2016.1, 2016.1, 2016.4, 2016.5, 2002.9, 1996.3, 2003.0, 2002.9, 2005.1, 2004.5, 2005.3, 2004.9],"VALS1-7":  [2013.5, 2013.4, 2013.0, 2013.0, 2016.4, 2016.4, 2015.4, 2016.3, 2002.6, 1987.5, 2003.0, 2002.6, 2004.9, 2004.6, 2005.3, 2005.0],"VALS1-8":  [2013.8, 2013.6, 2013.5, 2013.5, 2016.5, 2016.0, 2016.1, 2016.1, 2002.8, 1987.4, 2002.9, 2002.6, 2004.9, 2008.6, 2004.5, 2005.0],"VALS1-9":  [2013.8, 2013.9, 2013.3, 2013.4, 2016.6, 2016.1, 2016.3, 2016.3, 2002.8, 2002.8, 2002.6, 2002.4, 2005.1, 1991.1, 2005.1, 2004.4],"VALS2-0":  [754.5, 750.2, 774.0, 785.4, 767.0, 761.5, 773.9, 756, 772.5, 761.0, 755.5, 759.9, 776, 745.7, 760.5, 782.9],"VALS2-1":  [763.9, 789.4, 774.2, 777.0, 755.7, 767.5, 772.7, 752.4, 776.5, 765.2, 754.7, 753.5, 764.5, 747.0, 759.5, 777.5],"VALS2-2":  [756.4, 783, 770.9, 771.4, 751.9, 763.5, 767.5, 750.5, 771.5, 763.7, 752.5, 754.0, 753.5, 745.4, 756, 798.5],"VALS2-3":  [800.7, 817.7, 814.5, 754.5, 834.7, 825, 790.0, 682.5, 803.4, 806.5, 762.0, 737, 791.0, 791.0, 758.5, 753.7],"VALS2-4":  [723.7, 693, 807, 839.7, 701.9, 754.5, 806.2, 836.7, 749.5, 761.7, 783, 807.5, 732.7, 754.2, 785.5, 816.5],"VALS2-5":  [810.5, 831.9, 845.4, 818.7, 806.2, 824.9, 820.5, 649.2, 806.4, 802.5, 790.9, 757.7, 777.0, 784.9, 803.0, 755.7],"VALS2-6":  [713.5, 697.9, 698.9, 688.5, 679.4, 752.0, 693.0, 697.5, 740.2, 725.5, 703.7, 715.7, 709, 711.5, 722.4, 731.2],"VALS2-7":  [693, 678.7, 706.2, 720.2, 715.2, 712.4, 703.5, 722.7, 738.5, 729.4, 712.9, 738.5, 712.9, 713.7, 730.0, 753.2],"VALS2-8":  [717.9, 699.4, 733.2, 751.5, 734, 721.5, 729.9, 736.9, 761.7, 752.4, 731.5, 765.5, 738.5, 731.0, 753.0, 776.4],"VALS2-9":  [734.0, 715, 734.9, 745.5, 743.2, 728.9, 725.0, 745.5, 767.5, 747.5, 722.2, 744.5, 729.7, 723.5, 737.5, 753.0]
}

软件开发建议

采集板固件

在【普通采样】模式下,数据的采样频率与传输频率不高且一致,因为可以遵循简单的“通道切换->ADC采样->JSON封装->数据传输”的单任务执行序列。

FreeRTOS系统中的任务执行时序图如下所示:

Data Acqu.&Trans. Task ADC Hardware Transmission Hardware 开始一次采样与传输 切换到通道 n 通道 n 就绪 读取通道 n 电压值 返回采样值 loop [通道 0 到 15] 封装 JSON 消息 cJSON_Print() 发送 JSON 数据 发送 JSON 字符串 loop [每次采样周期(如 1 秒)] Data Acqu.&Trans. Task ADC Hardware Transmission Hardware

在【高速采样】模式下,数据的采样频率较高,数据传输频率较低,需要采用队列(FreeRTOS Queue)用于“生产-消费”缓冲。例如,设置两个任务,一个任务用来做数据采集,每0.1秒采集一次数据送到队列中,另外一个任务用来做数据传输,每1秒钟把队列中的10个数据全部发出去。

FreeRTOS系统中的任务执行时序图如下所示:

Data Acquisition Task ADC Hardware FreeRTOS Queue Data Transmission Task Transmission Hardware 开始一次 16 通道数据采集 切换到通道 n 通道 n 准备就绪 读取通道 n 电压值 返回采样值 loop [channels 0 to 15] 将 16 通道采样结果封装至 sample 结构 xQueueSend(sample) loop [every 100 ms (10 Hz)] 开始组装 10 条样本 xQueueReceive(sample[0]) xQueueReceive(sample[1]) xQueueReceive(sample[2]) xQueueReceive(sample[3]) xQueueReceive(sample[4]) xQueueReceive(sample[5]) xQueueReceive(sample[6]) xQueueReceive(sample[7]) xQueueReceive(sample[8]) xQueueReceive(sample[9]) 封装 JSON 消息 cJSON_Print() 发送 JSON 数据 发送 JSON 字符串 loop [every 1 s (1 Hz)] Data Acquisition Task ADC Hardware FreeRTOS Queue Data Transmission Task Transmission Hardware

以下是ESP32平台基于FreeRTOS系统开发的代码示例:

  • Data Acquisition Task(Task1) 以 100 ms 间隔读取 16 通道 ADC 并调用xQueueSendadc_data_t推入队列。
  • FreeRTOS Queue(Queue) 用于在两任务之间做生产-消费缓冲
  • Data Transmission Task(Task2) 每秒取出 10 次xQueueReceive拉取一秒钟的数据样本,随后使用cJSON等库将其封装成含有 “VALS1-0” 到 “VALS1-9” 的JSON,并通过串口或网络接口发送出去。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "driver/adc.h"
#include "esp_log.h"
#include "cJSON.h"        // Include a JSON library (e.g., cJSON)#define ADC_CHANNEL_NUM    16         // Number of ADC channels
#define DATA_QUEUE_LENGTH  10         // 10 samples per second (from 10 Hz)
#define TASK1_DELAY_MS     100        // Task1 delay: 100 ms (10 Hz)
#define TASK2_DELAY_MS     1000       // Task2 delay: 1000 ms (1 Hz)typedef struct {float adc_values[ADC_CHANNEL_NUM]; // Array holds one sample (16 ADC values)
} adc_data_t;static QueueHandle_t adcQueue = NULL;
static const char *TAG = "ESP32_APP";/** Task1: Data Acquisition** - Reads 16 channels using ADC (here simulated by random data).* - Pushes the resulting adc_data_t structure into the queue.* - Runs every 100 ms (10 Hz).*/
void adc_task(void *pvParameters)
{adc_data_t sample;TickType_t ticks = xTaskGetTickCount();while (1) {// Acquire ADC data for 16 channels.// Replace the following loop with real ADC API calls, e.g., adc1_get_raw() if needed.for (int i = 0; i < ADC_CHANNEL_NUM; i++) {// For demonstration, generate a pseudo ADC reading.sample.adc_values[i] = (float)(rand() % 4096) * (3.3f / 4096);}// Push the sample into the queue (non-blocking).if (xQueueSend(adcQueue, &sample, 0) != pdPASS) {ESP_LOGW(TAG, "Queue full! Data sample dropped.");}// Wait 100 ms to maintain a 10 Hz sampling rate.vTaskDelayUntil(&ticks, pdMS_TO_TICKS(TASK1_DELAY_MS));}
}/** Task2: Data Transmission** - Runs at 1 Hz (every second).* - Retrieves 10 samples (one second’s worth of ADC data) from the queue.* - Encapsulates the 10 samples into a JSON object with keys "VALS1-0" to "VALS1-9".* - The JSON object also includes a device ID.* - After building the JSON string, the data is logged (or could be sent over a network interface).*/
void tx_task(void *pvParameters)
{adc_data_t samples[DATA_QUEUE_LENGTH];  // Buffer to hold one-second of datachar keyStr[16];                        // Buffer to format key names (e.g., "VALS1-0")TickType_t ticks = xTaskGetTickCount();while (1) {// Retrieve 10 samples from the queue.for (int i = 0; i < DATA_QUEUE_LENGTH; i++) {if (xQueueReceive(adcQueue, &samples[i], pdMS_TO_TICKS(TASK2_DELAY_MS)) != pdPASS) {ESP_LOGW(TAG, "Failed to retrieve sample %d from queue.", i);// Optionally, you might zero-fill or skip this sample.memset(&samples[i], 0, sizeof(adc_data_t));}}// Create a JSON object.cJSON *root = cJSON_CreateObject();cJSON_AddStringToObject(root, "ID", "ESP32_402FA8");// For each sample, add a key (e.g., "VALS1-0") with its corresponding ADC data array.for (int i = 0; i < DATA_QUEUE_LENGTH; i++) {sprintf(keyStr, "VALS1-%d", i);cJSON *arr = cJSON_CreateArray();for (int j = 0; j < ADC_CHANNEL_NUM; j++) {cJSON_AddItemToArray(arr, cJSON_CreateNumber(samples[i].adc_values[j]));}cJSON_AddItemToObject(root, keyStr, arr);}// Generate the JSON string.char *jsonStr = cJSON_Print(root);ESP_LOGI(TAG, "Transmitted JSON Message:\n%s", jsonStr);// Here you can add code to send the JSON message over a network interface, UART, etc.// Free allocated memory and delete the JSON object.free(jsonStr);cJSON_Delete(root);// Wait 1 second (transmission period).vTaskDelayUntil(&ticks, pdMS_TO_TICKS(TASK2_DELAY_MS));}
}/** app_main: Entry point of the ESP32 application.** - Creates a queue for the ADC data.* - Launches both the ADC acquisition and the transmission tasks.*/
void app_main(void)
{// Create a queue to hold ADC data samples (each sample is adc_data_t).adcQueue = xQueueCreate(DATA_QUEUE_LENGTH, sizeof(adc_data_t));if (adcQueue == NULL) {ESP_LOGE(TAG, "Failed to create ADC data queue");return;}// Create and start the ADC acquisition task.xTaskCreate(adc_task, "adc_task", 2048, NULL, 5, NULL);// Create and start the transmission task.xTaskCreate(tx_task, "tx_task", 4096, NULL, 5, NULL);
}

注意,需要修改"cJSON.c"文件(print_number),使打印JSON字符串(cJSON_Print)的浮点数类型(float)保留一位小数。

/* Render the number nicely from the given item into a string. */
static cJSON_bool print_number(const cJSON *const item, printbuffer *const output_buffer)
{// 省略无关内容/* copy the printed number to the output and replace locale* dependent decimal point with '.' */for (i = 0; i < ((size_t)length); i++){if (number_buffer[i] == decimal_point){output_pointer[i] = '.';i++;output_pointer[i] = number_buffer[i];i++;break;}else{output_pointer[i] = number_buffer[i];}}output_pointer[i] = '\0';output_buffer->offset += (size_t)(i);return true;
}

上位机软件

上位机软件根据应用目标,应当分别实现或者同时实现对普通采样模式、高速采样模式的协议解析支持。同时实现对两种采样模式的协议解析支持时,应当设定一个协议切换功能(普通/高速采样模式选择)。

在【普通采样】模式下,上位机每次接收的是单次刷新数据,考虑到较低的采样频率和对时间同步的较低敏感度,可以直接设置一个中间缓存数据,每次接收到数据后就刷新中间缓存数据。同时,直接采用定时器定时读取中间缓存数据,刷新曲线绘制与数据保存。

在【高速采样】模式下,上位机每次接收到的是上一个时间段中的一批数据,应当将它们依次在历史曲线中绘制和保存。考虑到一些数据传输方式受环境的影响可能存在一定的延时(例如网络传输),可以通过"CT"键的值(时间戳)在上位机软件中进行时间的同步与对齐,即上位机软件在此模式下不应采用定时器刷新的方式绘图和保存数据,而是应该采用“数据驱动”的方式:收到数据后,根据时间戳计算每个时间步的精确时间(X轴值),然后将这些数据点依次绘制和保存。

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

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

相关文章

TCGA数据库临床亚型可用!贝叶斯聚类+特征网络分析,这篇 NC 提供的方法可以快速用起来了!

生信碱移 贝叶斯网络聚类 CANclust是一种基于贝叶斯的聚类方法&#xff0c;系统性地对基因突变、细胞遗传学信息和临床指标进行联合建模&#xff0c;用于多种模态数据的联合聚类分析&#xff0c;并识别在患者群体中反复出现的特征模式。 个体的遗传与环境背景决定其应对疾病的…

【算法】随机快速排序和随机选择算法

文章目录 1、随机快速排序1.1 什么是随机快排1.2 随机快排的好处 2、随机选择算法 前言&#xff1a; 快速排序就是每次划分前&#xff0c;通过一种方法将一个基准值的位置确定好&#xff0c;再进入不同的部分重复相同的工作以此确定好每个值的位置以达到有序。如果你之前并不了…

网络技术基础,NAT,桥接,交换机,路由器

什么是NAT Network Address Translation&#xff08;网络地址转换&#xff09;&#xff0c;它负责将目标IP或源IP进行了改变&#xff0c;相当于一个中间代理&#xff0c;我们家庭常用的路由器就是一个NAT设备&#xff0c;NAT是为了解决IPv4的IP地址快要耗尽的问题&#xff0c;…

DVWA靶场保姆级通关教程--03CSRF跨站请求伪造

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 目录 文章目录 前言 一、low级别的源码分析 二、medium级别源码分析 安全性分析 增加了一层 Referer 验证&#xff1a; 关键点是&#xff1a;在真实的网络环境中&a…

【Ansible自动化运维实战:从Playbook到负载均衡指南】

本文是「VagrantVirtualBox虚拟化环境搭建」的续篇&#xff0c;深入探索Ansible在自动化运维中的核心应用&#xff1a; ✅ Ansible核心技能&#xff1a;Playbook编写、角色&#xff08;Roles&#xff09;模块化、标签&#xff08;Tags&#xff09;精准控制 ✅ 实战场景覆盖&a…

基于STM32、HAL库的STC31-C-R3气体传感器驱动程序设计

一、简介: STC31-C-R3是Sensirion公司推出的一款基于CMOSens技术的CO2传感器,具有以下特点: 测量范围:0-100%体积浓度 I2C数字接口 低功耗设计 高精度和长期稳定性 小尺寸封装(5mm x 5mm) 二、硬件接口: STC31-C-R3 STM32L4xx ---------------------------- VDD (P…

Nginx篇之限制公网IP访问特定接口url实操

一、nginx配置限制IP访问 要在 Nginx 配置中添加 IP 限制&#xff0c;阻止来自指定公网 IP 地址段的访问&#xff0c;并且只对特定路径进行限制&#xff0c;可以在 location 配置中使用 deny 和 allow 指令来控制访问。 二、案例 1. 需求 对来自特定公网的地址段&#xff0…

算法研习:无重复字符的最长子串问题剖析

算法研习:无重复字符的最长子串问题剖析 一、引言 在算法的广袤天地中,字符串相关问题一直是备受关注的焦点。“无重复字符的最长子串”这一问题,不仅在面试中频繁出现,更是对算法思维和编程技巧的一次深度考验。它要求我们从给定字符串中找出不含有重复字符的最长子串的长…

Spring Cloud Gateway路由+断言+过滤

目录 介绍核心功能三大核心Route以服务名动态获取URLPredicate常用断言Path Route PredicateAfter Route PredicateBefore Route PredicateBetween Route PredicateCookie Route PredicateHeader Route PredicateHost Route PredicateQuery Route PredicateRemoteAddr Route Pr…

springboot集成langchain4j记忆对话

流式输出 LLM 一次生成一个标记&#xff08;token&#xff09;&#xff0c;因此许多 LLM 提供商提供了一种方式&#xff0c;可以逐个标记地流式传输响应&#xff0c;而不是等待整个文本生成完毕。 这显著改善了用户体验&#xff0c;因为用户不需要等待未知的时间&#xff0c;几…

【SpringCloud GateWay】Connection prematurely closed BEFORE response 报错分析与解决方案

一、背景 今天业务方调用我们的网关服务报错: Connection prematurely closed BEFORE response二、原因分析 三、解决方案 第一步: 增加 SCG 服务的JVM启动参数,调整连接获取策略。 将连接池获取策略由默认的 FIFO&#xff08;先进先出&#xff09;变更为 LIFO&#xff08…

使用ZYNQ芯片和LVGL框架实现用户高刷新UI设计系列教程(第十一讲)

这一期讲解lvgl中下拉框的基础使用&#xff0c;下拉列表允许用户从选项列表中选择一个值&#xff0c;下拉列表的选项表默认是关闭的&#xff0c;其中的选项可以是单个值或预定义文本。 当单击下拉列表后&#xff0c;其将创建一个列表&#xff0c;用户可以从中选择一个选项。 当…

【神经网络与深度学习】VAE 在解码前进行重参数化

在 VAE 中&#xff0c;解码之前进行重参数化主要有以下几个重要原因&#xff1a; 可微分性 在深度学习里&#xff0c;模型是通过反向传播算法来学习的&#xff0c;而这需要计算梯度。若直接从潜在变量的分布 (q_{\theta}(z|x))&#xff08;由编码器输出的均值 (\mu) 和方差 (…

BBDM学习笔记

1. configs 1.1 LBBDM: Latent BBDM [readme]

mysql主从复制搭建,并基于‌Keepalived + VIP实现高可用

以下是基于 ‌Keepalived VIP‌ 实现 MySQL 主从复制高可用的详细步骤&#xff0c;涵盖主从复制搭建与故障自动切换&#xff1a; 一、MySQL 主从复制搭建&#xff08;基础步骤回顾&#xff09; 1. ‌主库&#xff08;Master&#xff09;配置‌ 修改配置文件‌ /etc/my.cnf&…

CD36.【C++ Dev】STL库的string的使用 (下)

目录 1.reserve函数(不是reverse) 代码示例 2.resize 代码示例 3.reserve和resize的区别 4.shrink_to_fit 代码示例 5.与C语言的配合的接口函数: c_str 代码示例 6.rfind 知识回顾:find函数 rfind 代码示例 练习题: 字符串最后一个单词的长度 代码 提交结果 ​…

STM32的网络天气时钟项目

一、项目概述与硬件架构 1.1 核心功能 本智能天气时钟系统集成了实时天气获取、网络时间同步、环境监测和低功耗管理四大核心功能&#xff1a; 网络数据获取&#xff1a; 通过ESP8266 WiFi模块连接心知天气API&#xff08;每小时更新&#xff09;获取北京标准时间服务器的时…

FPGA DDR4多通道管理控制器设计

DDR4控制器一般采用自带的MIG控制器&#xff0c;用户控制主要是基于MIG IP核进行设计 实际工程项目中可能只挂载了一组DDR&#xff0c;但是用户数据可能有很多种&#xff0c;用户通过给每种数据划分特定地址进行存储&#xff0c;如何实现灵活管理成为设计的关键 为了方便后端数…

低代码 x AI,解锁数智化应用的创新引擎

AI 智能体开发指南 随着全球信息化浪潮的持续推进&#xff0c;数字化、智能化转型已成为企业发展的必经之路。在这个变革的时代&#xff0c;企业面临着前所未有的挑战与机遇。一方面&#xff0c;市场环境瞬息万变&#xff0c;企业需要快速响应并调整业务模式&#xff1b;另一方…

【Spring Boot 注解】@Configuration与@AutoConfiguration

文章目录 Configuration与AutoConfiguration一、Configuration二、AutoConfiguration Configuration与AutoConfiguration 一、Configuration 这是最常用的 Spring 注解之一&#xff0c;表示当前类是一个 配置类&#xff0c;可以定义 Bean 方法&#xff0c;等效于传统的 XML 配…