【Arduino】ESP32/ESP8266 JSON格式解析

目录

1、JSON

2、JSON语法格式

基本概念:

语法规则:

数据类型:

示例:

3、JSON解析

单一对象JSON解析(无嵌套)

JSON数组解析

使用ArduinoJson官网在线工具解析JSON信息

ESP8266闪存存储的JSON解析

通过api获取天气预报json格式并解析打印输出

4、发送json格式


1、JSON

JSON是一种简洁、易于理解和使用的数据格式,主要用于存储和传输数据。它基于JavaScript语言的标准,但与任何编程语言无关,因此广泛用于不同的编程环境中。

2、JSON语法格式

基本概念:

-数据对象:由一系列“名/值对”组成,用于表示复杂的数据结构。

- 数组:由一系列值组成,这些值是有序的。

语法规则:

- 数据以“名/值”对的形式呈现,其中“名”和“值”由冒号分隔。

- 对象用大括号`{}`表示,对象中的“名/值”对由逗号分隔。

- 数组用中括号`[]`表示,数组中的值也由逗号分隔。

数据类型:

-名称:必须用双引号`""`括起来。

- 值:可以是数字、字符串、布尔值(true/false)、数组、对象或null。

示例:

- 数字:"value": 25

- 字符串:"name": "taichi-maker"

- 布尔值:"bool_value": true

-数组:

"info": [{"name": "taichi-maker", "website": "www.taichi-maker.com"}, {"year": 2020, "month": 12, "day": 30}]

- 对象:

{
  "info": 
  {
    "name": "taichi-maker",
    "website": "www.taichi-maker.com"
  }
}
  1. 注意:
  • 对象和数组:

对象可以包含多个数据,包括其他对象和数组,但不能直接存放对象或数组。

数组可以包含多个对象或值,但不能直接存放“名/值”对。

  • 混合使用:

- 对象和数组可以相互嵌套,一个对象的值可以是数组,反之亦然

  • 对象是用来存储数据的,而数组是用来存储有序集合的。

3、JSON解析

解析JSON格式信息是一个较为繁琐的工作,因此我们将借助解析Arduino – ESP8266平台中解析JSON格式信息的第三方库——ArduionJson库,该库是目前最受好评的解析JSON信息第三方库。

解析json格式的过程就是反序列号过程

注意版本号,不同版本可能会有区别,当前使用版本为7.0.4。该版本提供了两个工具,一个在线解析json格式代码工具,一个故障排除工具。

ArduinoJson Assistant 6

ArduinoJson Troubleshooter

单一对象JSON解析(无嵌套)

以下方json信息解析示例

{
  "gatew": "admin5555",
  "time": 153034324,
  "tag1": 15.32,
  "tag2": 0,
  "tag3": 43,
  "tag4": "33"
}

代码实现

#include <ArduinoJson.h>
 
void setup() {
  Serial.begin(9600);
  
}
 
void loop() {
  Serial.println("");
  //1、JsonDocument doc  对象
  JsonDocument doc;
// 2、即将解析的json文件
String json="{\"gatew\": \"admin5555\",\"time\": 153034324,\"tag1\": 15.32,\"tag2\": 0,\"tag3\": 43,\"tag4\": \"33\"}";


//3、反序列化数据
DeserializationError error = deserializeJson(doc, json);

if (error) {
  Serial.print("deserializeJson() failed: ");
  Serial.println(error.c_str());
  return;
}
  // 4:获取解析后的数据信息
const char* gatew = doc["gatew"]; // "admin5555"
long time = doc["time"]; // 153034324
float tag1 = doc["tag1"]; // 15.32
int tag2 = doc["tag2"]; // 0
int tag3 = doc["tag3"]; // 43
const char* tag4 = doc["tag4"]; // "33"
 
  // 通过串口监视器输出解析后的数据信息
  Serial.print("gatew = ");Serial.println(gatew);
  Serial.print("tag1 = ");Serial.println(tag1);
  Serial.print("tag2 = ");Serial.println(tag2);
  Serial.print("tag3 = ");Serial.println(tag3);
  Serial.print("tag4 = ");Serial.println(tag4);
  Serial.print("time = ");Serial.println(time);
  delay(1000);
  }

测试ok,间隔1s输出解析后的数据信息。

JSON数组解析

[
  {
    "name": "taichi-maker"
  },
  {
    "website": "www.taichi-maker.com"
  }
]

示例程序内容

#include <ArduinoJson.h>
void setup() {
  Serial.begin(9600);
}
void loop() {
  Serial.println("");
  //1、JsonDocument doc  对象
  JsonDocument doc;
// 2、即将解析的json文件
String json="[{\"name\":\"taichi-maker\"},{\"website\": \"www.taichi-maker.com\"}]";


//3、反序列化数据
DeserializationError error = deserializeJson(doc, json);

if (error) {
  Serial.print("deserializeJson() failed: ");
  Serial.println(error.c_str());
  return;
}
  // 4:获取解析后的数据信息
const char* name = doc[0]["name"]; // "taichi-maker"
const  char* website = doc[1]["website"]; // www.taichi-maker.com
  // 通过串口监视器输出解析后的数据信息
  Serial.print("name = ");Serial.println(name);
  Serial.print("website = ");Serial.println(website);
  delay(1000);
  }

使用ArduinoJson官网在线工具解析JSON信息

#include <ArduinoJson.h>

JsonDocument doc;

DeserializationError error = deserializeJson(doc, input);

if (error) {
  Serial.print("deserializeJson() failed: ");
  Serial.println(error.c_str());
  return;
}

const char* gatew = doc["gatew"]; // "admin5555"
long time = doc["time"]; // 153034324
float tag1 = doc["tag1"]; // 15.32
int tag2 = doc["tag2"]; // 0
int tag3 = doc["tag3"]; // 43
const char* tag4 = doc["tag4"]; // "33"

ESP8266闪存存储的JSON解析

        在开发物联网项目时,大型JSON信息存储再程序中,将会占用大量系统动态内存,严重的甚至会出现系统控制程序空间不足问题。因此,我们需要将大型JSON文件存储在ESP8266的闪存系统中。暂未研究。

通过api获取天气预报json格式并解析打印输出

api格式

天气实况 | 心知天气文档

{
  "results": [
    {
      "location": {
        "id": "C23NB62W20TF",
        "name": "西雅图",
        "country": "US",
        "path": "西雅图,华盛顿州,美国",
        "timezone": "America/Los_Angeles",
        "timezone_offset": "-07:00"
      },
      "now": {
        "text": "多云", //天气现象文字
        "code": "4", //天气现象代码
        "temperature": "14", //温度,单位为c摄氏度或f华氏度
        "feels_like": "14", //体感温度,单位为c摄氏度或f华氏度
        "pressure": "1018", //气压,单位为mb百帕或in英寸
        "humidity": "76", //相对湿度,0~100,单位为百分比
        "visibility": "16.09", //能见度,单位为km公里或mi英里
        "wind_direction": "西北", //风向文字
        "wind_direction_degree": "340", //风向角度,范围0~360,0为正北,90为正东,180为正南,270为正西
        "wind_speed": "8.05", //风速,单位为km/h公里每小时或mph英里每小时
        "wind_scale": "2", //风力等级,请参考:http://baike.baidu.com/view/465076.htm
        "clouds": "90", //云量,单位%,范围0~100,天空被云覆盖的百分比 #目前不支持中国城市#
        "dew_point": "-12" //露点温度,请参考:http://baike.baidu.com/view/118348.htm #目前不支持中国城市#
      },
      "last_update": "2015-09-25T22:45:00-07:00" //数据更新时间(该城市的本地时间)
    }
  ]
}
#include <ArduinoJson.h>
#include <ESP8266WiFi.h>

const char *ssid = "Xiaomi Civi 3"; // WiFi账号
const char *password = "12345678c";  // WiFi密码
 
const char* host = "api.seniverse.com";     // 将要连接的服务器地址  
const int httpPort = 80;                    // 将要连接的服务器端口      

// 心知天气HTTP请求所需信息
String reqUserKey = "Smlv4QbicqLpVYlXH";   // 私钥
String reqLocation = "Wuhan";            // 城市
String reqUnit = "c";                      // 摄氏/华氏

void setup(){
  Serial.begin(9600);          
  Serial.println("");
  
  // 连接WiFi
  connectWiFi();
}
 
void loop(){
  // 建立心知天气API当前天气请求资源地址
  String reqRes = "/v3/weather/now.json?key=" + reqUserKey +
                  + "&location=" + reqLocation + 
                  "&language=en&unit=" +reqUnit;

  // 向心知天气服务器服务器请求信息并对信息进行解析
  httpRequest(reqRes);
  delay(3000);
}
 
// 向心知天气服务器服务器请求信息并对信息进行解析
void httpRequest(String reqRes){
  WiFiClient client;

  // 建立http请求信息
  String httpRequest = String("GET ") + reqRes + " HTTP/1.1\r\n" + 
                              "Host: " + host + "\r\n" + 
                              "Connection: close\r\n\r\n";
  Serial.println(""); 
  Serial.print("Connecting to "); Serial.print(host);

  // 尝试连接服务器
  if (client.connect(host, 80)){
    Serial.println(" Success!");
 
    // 向服务器发送http请求信息
    client.print(httpRequest);
    Serial.println("Sending request: ");
    Serial.println(httpRequest);  
 
    // 获取并显示服务器响应状态行 
    String status_response = client.readStringUntil('\n');
    Serial.print("status_response: ");
    Serial.println(status_response);
 
    // 使用find跳过HTTP响应头
    if (client.find("\r\n\r\n")) {
      Serial.println("Found Header End. Start Parsing.");
    }
    
    // 利用ArduinoJson库解析心知天气响应信息
    parseInfo(client); 
  } else {
    Serial.println(" connection failed!");
  }   
  //断开客户端与服务器连接工作
  client.stop(); 
}

// 连接WiFi
void connectWiFi(){
  WiFi.begin(ssid, password);                  // 启动网络连接
  Serial.print("Connecting to ");              // 串口监视器输出网络连接信息
  Serial.print(ssid); Serial.println(" ...");  // 告知用户NodeMCU正在尝试WiFi连接
  
  int i = 0;                                   // 这一段程序语句用于检查WiFi是否连接成功
  while (WiFi.status() != WL_CONNECTED) {      // WiFi.status()函数的返回值是由NodeMCU的WiFi连接状态所决定的。 
    delay(1000);                               // 如果WiFi连接成功则返回值为WL_CONNECTED                       
    Serial.print(i++); Serial.print(' ');      // 此处通过While循环让NodeMCU每隔一秒钟检查一次WiFi.status()函数返回值
  }                                            // 同时NodeMCU将通过串口监视器输出连接时长读秒。
                                               // 这个读秒是通过变量i每隔一秒自加1来实现的。                                              
  Serial.println("");                          // WiFi连接成功后
  Serial.println("Connection established!");   // NodeMCU将通过串口监视器输出"连接成功"信息。
  Serial.print("IP address:    ");             // 同时还将输出NodeMCU的IP地址。这一功能是通过调用
  Serial.println(WiFi.localIP());              // WiFi.localIP()函数来实现的。该函数的返回值即NodeMCU的IP地址。  
}

// 利用ArduinoJson库解析心知天气响应信息
void parseInfo(WiFiClient client){
  // String input;

StaticJsonDocument<768> doc;

DeserializationError error = deserializeJson(doc, client);

if (error) {
  Serial.print(F("deserializeJson() failed: "));
  Serial.println(error.f_str());
  return;
}

JsonObject results_0 = doc["results"][0];

JsonObject results_0_location = results_0["location"];
const char* results_0_location_id = results_0_location["id"]; // "C23NB62W20TF"
const char* results_0_location_name = results_0_location["name"]; // "西雅图"
const char* results_0_location_country = results_0_location["country"]; // "US"
const char* results_0_location_path = results_0_location["path"]; // "西雅图,华盛顿州,美国"
const char* results_0_location_timezone = results_0_location["timezone"]; // "America/Los_Angeles"
const char* results_0_location_timezone_offset = results_0_location["timezone_offset"]; // "-07:00"

JsonObject results_0_now = results_0["now"];
const char* results_0_now_text = results_0_now["text"]; // "多云"
const char* results_0_now_code = results_0_now["code"]; // "4"
const char* results_0_now_temperature = results_0_now["temperature"]; // "14"
const char* results_0_now_feels_like = results_0_now["feels_like"]; // "14"
const char* results_0_now_pressure = results_0_now["pressure"]; // "1018"
const char* results_0_now_humidity = results_0_now["humidity"]; // "76"
const char* results_0_now_visibility = results_0_now["visibility"]; // "16.09"
const char* results_0_now_wind_direction = results_0_now["wind_direction"]; // "西北"
const char* results_0_now_wind_direction_degree = results_0_now["wind_direction_degree"]; // "340"
const char* results_0_now_wind_speed = results_0_now["wind_speed"]; // "8.05"
const char* results_0_now_wind_scale = results_0_now["wind_scale"]; // "2"
const char* results_0_now_clouds = results_0_now["clouds"]; // "90"
const char* results_0_now_dew_point = results_0_now["dew_point"]; // "-12"

const char* results_0_last_update = results_0["last_update"]; // "2015-09-25T22:45:00-07:00"

  // 通过串口监视器显示以上信息
  
  int results_0_now_code_int = results_0_now["code"].as<int>(); 
  int results_0_now_temperature_int = results_0_now["temperature"].as<int>(); 
   String  results_0_now_text_Str = results_0_now["text"].as<String>();

  Serial.println(F("======Weahter Now======="));
  Serial.print(F("Weather Now: "));
  Serial.println(results_0_now_code_int);
  Serial.print(F("Temperature: "));
  Serial.println(results_0_now_temperature_int);
  Serial.print(F("天气: "));
  Serial.println(results_0_now_text_Str);
  Serial.println(F("========================"));
}

串口打印结果

4、发送json格式

esp8266以json的格式往mqtt服务发数据,数据格式如下:

上行topic:esp8266/tsest

{
  "gatew": "admin5555",
  "time": 153034324,
  "tag1": 15.32,
  "tag2": 0,
  "tag3": 43,
  "tag4": "33"
}

1、发送固定格式

#include <ESP8266WiFi.h>
#include <PubSubClient.h>

// WiFi
const char *ssid = "999"; // WiFi账号
const char *password = "sp888888";  // WiFi密码

// MQTT Broker
const char *mqtt_broker = "39.98.87.103";//服务器Ip
const char *topic = "esp8266/io_test";//主题topic。下行topic,根据这个进行控制
const char *mqtt_username = "PubSubClien1"; //用户名
const char *mqtt_password = "";//密码
const int mqtt_port = 1883;//服务端口号

WiFiClient espClient;
PubSubClient client(espClient);
      unsigned long previousMillis = 0;// 将保存上次触发的时间点,默认为0
      // 定义常量:触发间隔,单位是毫秒,1000 = 1秒
      const long interval = 3000;
void setup() {
    // 串口波特率: 115200;
    Serial.begin(115200);
    delay(1000); 

    // 连接WIFI网络
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.println("连接WiFi网络中...");
    }
    Serial.println("连接到WIFI网络");

    // 连接MQTT服务
    client.setServer(mqtt_broker, mqtt_port);
   // client.setCallback(callback);
    while (!client.connected()) {
        String client_id = "esp8266-client-";
        client_id += String(WiFi.macAddress());
        Serial.printf("客户端%s连接到MQTT 服务\n", client_id.c_str());
        if (client.connect(client_id.c_str(), mqtt_username, mqtt_password)) {
            Serial.println("已连接MQTT服务");//已连接公共EMQX MQTT代理
        } else {
            Serial.print("失败,状态为 ");
            Serial.print(client.state());
            delay(2000);
        }
    }

    // 发布和订阅
    //client.publish(topic, "hello emqx");//发布
      client.subscribe(topic);//订阅
    

}
char* payloadJson="{\"gatew\": \"admin5555\",\"time\": 153034324,\"tag1\": 15.32,\"tag2\": 0,\"tag3\": 43,\"tag4\": \"33\"}";

void loop() {
    client.loop();
    unsigned long currentMillis = millis();//获取当前时间
      //如果(当前时间 - 上次触发的时间 >) 说明该进行下一次触发了。
  if (currentMillis - previousMillis >= interval)
  {
    
    // 将上次触发事件更新为 "当前时间"
    previousMillis = currentMillis;
    client.publish(topic, payloadJson);
    Serial.println(payloadJson);
   }
}

2、获取io状态以及传感器数据,通过json格式发送给mqtt。

测试代码

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>
#include <ArduinoJson.h>
// WiFi
const char *ssid = "999";  // WiFi账号
const char *password = "sp888888";  // WiFi密码
// MQTT Broker
const char *mqtt_broker = "39.98.87.103";  // 服务器Ip
const char *topic1 = "esp8266/io_test/w";  // 主题topic。下行topic,根据这个进行控制
const char *topic2 = "esp8266/io_test/r";  // 主题topic。下行topic,根据这个进行控制
const char *mqtt_username = "PubSubClien1";  // 用户名
const char *mqtt_password = "";  // 密码
const int mqtt_port = 1883;  // 服务端口号
WiFiClient espClient;
PubSubClient client(espClient);
unsigned long previousMillis = 0;  // 将保存上次触发的时间点,默认为0
//传感器
#define DHTPIN 2   // 连接到DHT传感器的数字引脚
#define DHTTYPE DHT11   // DHT 11
DHT dht(DHTPIN, DHTTYPE);
//定义4的标志位,存放4个io的状态。
int key1=0;
int key2=0;
int key3=0;
int key4=0;
void setup() {
    // 串口波特率: 9600;
    Serial.begin(9600);
   // pinMode(0,OUTPUT);
    //pinMode(5,OUTPUT);
    //pinMode(6,OUTPUT);
   // pinMode(7,OUTPUT);
    //digitalWrite(0,HIGH);
   // digitalWrite(5,HIGH);
    //digitalWrite(6,HIGH);
    //digitalWrite(7,HIGH);
    delay(1000); 
    // 连接WIFI网络
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.println("连接WiFi网络中...");
    }
    Serial.println("连接到WIFI网络");

    // 连接MQTT服务
    client.setServer(mqtt_broker, mqtt_port);
    // client.setCallback(callback);
    while (!client.connected()) {
        String client_id = "esp8266-client-";
        client_id += String(WiFi.macAddress());
        Serial.printf("客户端%s连接到MQTT 服务\n", client_id.c_str());
        if (client.connect(client_id.c_str(), mqtt_username, mqtt_password)) {
            Serial.println("已连接MQTT服务");//已连接公共EMQX MQTT代理
        } else {
            Serial.print("失败,状态为 ");
            Serial.print(client.state());
            delay(2000);
        }
    }
    // 发布和订阅
    // client.publish(topic, "hello emqx");//发布
    client.subscribe(topic1);//订阅
    client.subscribe(topic2);//订阅
    dht.begin();//初始化温湿度传感器
}
void loop() {
    client.loop();
    unsigned long currentMillis = millis();  // 获取当前时间
    // 如果(当前时间 - 上次触发的时间 >) 说明该进行下一次触发了。
    if (currentMillis - previousMillis >= 5000) {
        // 将上次触发事件更新为 "当前时间"
        previousMillis = currentMillis;
        // 温湿度传感器
        float h = dht.readHumidity();
        // 读取湿度度(%RH)
        float t = dht.readTemperature();
        // 读取湿度(℃)  
        // 检查传感器是否有任何读取失败,并提前退出(重试)。
        if (isnan(h) || isnan(t)) {
            Serial.println(F("从DHT传感器读取失败!"));
            //return;  // 如果传感器读取失败,直接退出此次循环
        } 
        // 序列化 JSON 数据
        DynamicJsonDocument doc(256); // 定义一个大小为 256 字节的 JSON 文档
        doc["temp"] = t;
        doc["hum"] = h;
        doc["key1"] = key1;
        doc["key2"] = key2;
        doc["key3"] = key3;
        doc["key4"] = key4;   
      // 分配足够的内存
        char payloadJson[256]; 
    //将 JSON 文档 doc 序列化为 JSON 字符串,并将其存储在 payloadJson 字符数组中,
    //然后将序列化后的 JSON 字符串的长度存储在 length 变量中
        size_t length = serializeJson(doc, payloadJson, sizeof(payloadJson));
        // 发布 MQTT 消息
        client.publish(topic2, payloadJson);
        // 打印到串口
        Serial.print(F("湿度: "));
        Serial.print(h);
        Serial.print(F(",温度: "));
        Serial.println(t);
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

VScode 修改 Markdown Preview Enhanced 主题与字体

VScode 修改 Markdown Preview Enhanced 主题与字体 1. 修改前后效果对比2. 修改主题2.1 更改默认主题2.2 修改背景色 3. 修改字体 VS Code基础入门使用可查看&#xff1a; VS Code 基础入门使用&#xff08;配置&#xff09;教程 其他Vs Code 配置可关注查看&#xff1a; Vs C…

ElasticSearch 与 OpenSearch:拉开性能差距

Elasticsearch 与 OpenSearch&#xff1a;扩大性能差距 对于任何依赖快速、准确搜索数据的组织来说&#xff0c;强大、快速且高效的搜索引擎是至关重要的元素。对于开发人员和架构师来说&#xff0c;选择正确的搜索平台可以极大地影响您的组织提供快速且相关结果的能力。在我们…

docker(二):Centos安装docker

文章目录 1、安装docker2、启动docker3、验证 官方文档&#xff1a;https://docs.docker.com/engine/install/centos/ 1、安装docker 下载依赖包 yum -y install gcc yum -y install gcc-c yum install -y yum-utils设置仓库 yum-config-manager --add-repo http://mirrors…

在xAnyLabeling中加载自己训练的yolov8s-obb模型进行半自动化标注

任务思路&#xff1a; 先使用xAnyLabeling标注一部分样本&#xff0c;训练出v1版本的yolov8-obb模型&#xff0c;然后加载yolov8-obb模型到xAnyLabeling中对其余样本进行半自动化标注。节省工作量。 任务流程&#xff1a; 1.准备xAnyLabeling标注工具 下载代码&#xff0c;…

Linux 第二十八章

&#x1f436;博主主页&#xff1a;ᰔᩚ. 一怀明月ꦿ ❤️‍&#x1f525;专栏系列&#xff1a;线性代数&#xff0c;C初学者入门训练&#xff0c;题解C&#xff0c;C的使用文章&#xff0c;「初学」C&#xff0c;linux &#x1f525;座右铭&#xff1a;“不要等到什么都没有了…

利用PS在不伤背景的前提下根据颜色去除图像上不想要的内容

下面为一个例子&#xff0c;去除图像上红色的虚线 Step1.用套索工具框选带有颜色的部分 Step2.切换到魔术棒工具&#xff0c;上端选项中&#xff0c;点击与选区交叉&#xff0c;连续这一项不要勾选 Step3.在需要去除的部分点击一下即可在框选范围内选中所有同颜色的区域&#x…

【IC前端虚拟项目】验证环境env与base_teat思路与编写

【IC前端虚拟项目】数据搬运指令处理模块前端实现虚拟项目说明-CSDN博客 上一篇里解决了最难搞的axi_ram_model,接下来呢就会简单又常规一些了,比如这一篇要说的env和base_test的搭建。在这里我用了gen_uvm_tb脚本: 【前端验证】验证自动化脚本的最后一块拼图补全——gen_t…

Cross-Image Attention for Zero-Shot Appearance Transfer——【代码复现】

本文发表于SIGGRAPH 2024&#xff0c;是一篇关于图像编辑的论文&#xff0c;Github官网网址如下&#xff1a; garibida/cross-image-attention&#xff1a; “Cross-Image Attention for Zero-Shot Appearance Transfer”的正式实现 (github.com) 一、基本配置环境准备 请确保…

数组实现循环队列

1、分析 循环队列最主要的特点为当前面的空间被pop后&#xff0c;后面的数据可以插入到前面空余的数据中去&#xff1b; 所以最难的部分为判断什么时候为空什么时候为满&#xff1a; a、空满问题 我们先来分析当数据满时&#xff0c;head和tail相等&#xff08;tail认为是指…

架构设计之学新而知故

缘由 因为一些特殊的机缘&#xff0c;接触到洋葱架构等一些新架构设计概念。 尝试理解了一段时间&#xff0c;就想简单梳理下对它们的理解&#xff0c;以达到学新而知故 &#x1f603; 信息增益 以前计算机专业并不设置通信领域的信息论的专业课程&#xff0c;但是&#xf…

条件变量解决同步问题之打印金鱼

说明 本代码为jyy老师上课演示条件变量解决同步问题示例(本人只做记录与分享) 本人未使用老师封装的POSIX线程库, 直接在单文件中调试并注释 问题描述 有三类线程 T1 若干: 死循环打印< T2 若干: 死循环打印> T3 若干: 死循环打印_ 任务: 对线程同步&#xff0c;使得屏幕…

eNSP中小型园区网络拓扑搭建(下)

→b站直通车&#xff0c;感谢大佬← →eNSP中小型园区网络拓扑搭建&#xff08;上&#xff09;← 不带配置命令的拓扑图已上传~ 配置ospf SW5 # ospf 1 router-id 5.5.5.5area 0.0.0.0network 192.168.51.5 0.0.0.0network 192.168.52.5 0.0.0.0area 0.0.0.10network 192.1…

MATLAB函数fir1的C语言移值

要移值的matlab函数&#xff1a; h3 fir1(16,[0.25 0.50]); C语言版本 #include <iostream> #include <cmath>#define PI acos(-1)double sincEasy(double *x, int len, int index) {double temp PI * x[index];if (temp 0) {return 1.0; // sinc(0) 1}ret…

如何在 Linux / Ubuntu 上下载和安装 JMeter?

Apache JMeter 是一个开源的负载测试工具&#xff0c;可以用于测试静态和动态资源&#xff0c;确定服务器的性能和稳定性。在本文中&#xff0c;我们将讨论如何下载和安装 JMeter。 安装 Java&#xff08;已安装 Java 的此步骤可跳过&#xff09; 安装 Java 要下载 Java&…

01、什么是ip、协议、端口号知道吗?计算机网络通信的组成是什么?

声明&#xff1a;本教程不收取任何费用&#xff0c;欢迎转载&#xff0c;尊重作者劳动成果&#xff0c;不得用于商业用途&#xff0c;侵权必究&#xff01;&#xff01;&#xff01; 目录 前言 计算机网络 网络ip地址 网络协议 网络端口号 前言 最近有个项目要用到相关文章…

NOR FLASH介绍

参考 http://t.csdnimg.cn/gHcrG 一、NOR FLASH简介 XIP技术:https://blog.csdn.net/ffdia/article/details/87437872?fromshareblogdetail NOR Flash 和 NAND Flash 的特点和应用举例&#xff1a; NOR Flash&#xff1a; 特点&#xff1a; 支持随机访问&#xff0c;可以直接…

【ROS2】节点

文章目录 ROS2 节点示例&#xff1a;创建并运行成功一个节点1. 创建功能包2. 编写源文件、CMakeLists.txt、package.xml3. 编译功能包4. 设置环境变量5. 运行节点6. 查看节点 参考链接 ROS2 节点 机器人的每一项功能&#xff0c;都被称为是一个节点。 每个节点都是一个独立的…

@PostConstruct

PostConstruct initializeBean方法–> PostProcessor.postProcessBeforeInitialization–> InitDestroyAnnotationBeanPostProcessor.postProcessBeforeDestruction 被PostConstruct注解的方法会在Bean初始化的时候被调用&#xff0c;如下图&#xff1a; 继承关系如下…

json-server 模拟接口服务

前端开发经常需要模拟接口请求&#xff0c;可以通过 json-server 实现。 1. 安装 json-server 在前端项目的终端命令行中执行 npm i json-server2. 创建数据源 在项目中新建文件 db.json &#xff0c;与 package.json 同级&#xff0c;内容为模拟的数据 注意 json 文件对格式…

基于SSM的“网约车用户服务平台”的设计与实现(源码+数据库+文档)

基于SSM的“网约车用户服务平台”的设计与实现&#xff08;源码数据库文档) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SSM 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 系统功能 首页 站内新闻浏览 打车信息查询功能 在线打车功能…