文章目录
前言
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,在单片机之间、上下位机之间的通信中被广泛应用。
一、JSON特点
语法简单
语法简洁:JSON 的语法基于 JavaScript 的对象和数组字面量表示法,非常直观和简洁。它使用键值对来表示数据,易于阅读和编写。
数据格式灵活
数据格式灵活:支持多种数据类型,包括字符串、数字、布尔值、数组、对象等,可以方便地表示复杂的数据结构。
轻量化
轻量级:相比其他一些数据交换格式(如 XML),JSON 的数据量较小,在网络传输和存储方面具有优势,能够有效减少通信带宽和存储空间的占用。
跨语言使用
跨语言支持:几乎所有的编程语言都提供了对 JSON 的解析和生成支持,这使得它在不同类型的单片机和上位机(如 PC、手机等)之间进行数据交换时非常方便,无需考虑语言差异。
二、JSON数据结构
对象
对象:由花括号 {} 包围,包含一系列键值对。键是字符串,值可以是任意数据类型。例如:{“name”: “John”, “age”: 30, “isStudent”: false}。
数组
数组:由方括号 [] 包围,包含一系列元素,元素可以是任意数据类型。例如:[1, 2, 3, “four”, true]。
三、JSON在单片机之间通信的应用
数据封装与传输
数据封装与传输:单片机通常资源有限,JSON 的轻量级特性使其成为一种理想的数据格式。当多个单片机之间需要进行数据交互时,例如传感器节点与控制节点之间的通信,传感器节点可以将采集到的数据(如温度、湿度、光照强度等)封装成 JSON 格式的字符串,然后通过串口、SPI 等通信接口发送给控制节点。控制节点接收到数据后,再解析 JSON 字符串,获取其中的具体数据值,进行相应的处理。
四、JSON示例代码
以 C 语言为例,在单片机中使用 cJSON 库来处理 JSON 数据。假设要发送一个包含温度和湿度数据的 JSON 消息,代码如下:
#include "cJSON.h"
// 模拟采集到的温度和湿度数据
float temperature = 25.5;
float humidity = 60.0;
int main() {
// 创建一个JSON对象
cJSON *root = cJSON_CreateObject();
// 向JSON对象中添加温度和湿度数据
cJSON_AddNumberToObject(root, "temperature", temperature);
cJSON_AddNumberToObject(root, "humidity", humidity);
// 将JSON对象转换为字符串
char *json_string = cJSON_Print(root);
// 这里可以通过串口等方式将json_string发送出去
// 释放内存
cJSON_Delete(root);
free(json_string);
return 0;
}
五、JSON在上位机与单片机之间通信的应用
数据交互
数据交互:上位机(如 PC 端的应用程序或手机 APP)与单片机之间经常需要进行数据交互。例如,上位机向单片机发送控制指令,或者从单片机获取传感器数据、设备状态等信息。JSON 格式可以方便地对这些数据进行封装和传输。上位机将指令或请求数据封装成 JSON 格式发送给单片机,单片机解析 JSON 数据并执行相应操作,然后将结果以 JSON 格式返回给上位机。上位机再解析返回的 JSON 数据,进行显示或进一步处理。
六、JSON示例代码
示例代码:在 Python 中使用 json 模块处理 JSON 数据,与单片机进行通信(假设通过串口与单片机通信)。以下是一个简单的示例,向上位机发送一个包含设备状态的
JSON 消息:
import serial
import json
# 假设串口配置
ser = serial.Serial('COM1', 9600, timeout=1)
# 模拟设备状态数据
device_status = {
"power": "on",
"mode": "auto",
"temperature": 26.0
}
# 将设备状态数据转换为JSON格式字符串
json_data = json.dumps(device_status)
# 通过串口发送JSON数据
ser.write(json_data.encode())
# 从串口接收数据(假设接收的也是JSON格式)
received_data = ser.readline().decode().strip()
if received_data:
# 解析接收到的JSON数据
received_json = json.loads(received_data)
print(received_json)
ser.close()
七、JSON解析与生成
解析
解析:无论是单片机还是上位机,在接收到 JSON 数据后,需要使用相应的 JSON 解析库来解析数据。解析过程就是将 JSON 格式的字符串转换为编程语言中的数据结构,以便于程序进行处理。例如,在 C 语言中可以使用 cJSON 库,在 Java 中可以使用 Gson 或 Jackson 库,在 Python 中使用内置的 json 模块等。
生成
生成:当需要将数据发送出去时,需要将程序中的数据结构转换为 JSON 格式的字符串。同样,不同的编程语言都提供了相应的方法来生成 JSON 数据。例如,在 C 语言中使用 cJSON 库的相关函数来创建 JSON 对象并转换为字符串,在 Python 中使用 json.dumps() 函数将字典或其他数据结构转换为 JSON 字符串。
在单片机之间、上下位机之间的通信中,JSON 以其简洁、灵活、轻量级和跨语言的特点,成为一种非常实用的数据交换格式,能够有效地实现数据的封装、传输和解析,提高通信的效率和可靠性。
八、Python中的数据解析
1.字符串解析
解析为基本数据类型
1.1整数
整数:使用int()函数可以把字符串解析成整数。若字符串不能被解析为整数,就会抛出ValueError异常。
str_num = "123"
num = int(str_num)
print(num)
1.2浮点数
浮点数:使用float()函数能够将字符串解析成浮点数。若字符串无法解析为浮点数,同样会抛出ValueError异常。
str_float = "3.14"
float_num = float(str_float)
print(float_num)
1.3布尔数
布尔值:Python 没有内置直接把字符串解析成布尔值的函数,但可以自定义函数来实现。
def str_to_bool(s):
if s.lower() == 'true':
return True
elif s.lower() == 'false':
return False
else:
raise ValueError("Invalid boolean string")
str_bool = "True"
bool_value = str_to_bool(str_bool)
print(bool_value)
1.4JSON格式字符串
JSON 格式字符串:使用json模块的loads()函数可以将 JSON 格式的字符串解析为 Python 的列表、字典等数据类型。
import json
json_str = '{"name": "John", "age": 30}'
data = json.loads(json_str)
print(data)
1.5CSV格式字符串
CSV 格式字符串:使用csv模块可以解析 CSV 格式的字符串。
import csv
from io import StringIO
csv_str = "name,age\nJohn,30\nJane,25"
reader = csv.reader(StringIO(csv_str))
for row in reader:
print(row)
2.字节解析
2.1解析为整数
可以使用int.from_bytes()方法将字节对象解析为整数。
byte_data = b'\x01\x02'
num = int.from_bytes(byte_data, byteorder='big')
print(num)
2.2解析为字符串
使用decode()方法能够把字节对象解析为字符串。
byte_str = b'Hello, World!'
str_data = byte_str.decode('utf-8')
print(str_data)
3.列表解析
3.1解析嵌套列表
可以使用循环遍历嵌套列表,提取所需的数据。
nested_list = [[1, 2], [3, 4]]
for sub_list in nested_list:
for item in sub_list:
print(item)
4.字典解析
4.1解析嵌套字典
同样使用循环遍历嵌套字典,提取所需的数据。
nested_dict = {"person": {"name": "John", "age": 30}}
for key, value in nested_dict.items():
if isinstance(value, dict):
for sub_key, sub_value in value.items():
print(f"{sub_key}: {sub_value}")
else:
print(f"{key}: {value}")
5.XML 解析
Python 提供了多种解析 XML 数据的方式,这里以xml.etree.ElementTree模块为例。
import xml.etree.ElementTree as ET
xml_data = '<root><person><name>John</name><age>30</age></person></root>'
root = ET.fromstring(xml_data)
for person in root.findall('person'):
name = person.find('name').text
age = person.find('age').text
print(f"Name: {name}, Age: {age}")
6.自定义数据类型解析
如果要解析自定义的数据类型,一般需要定义特定的解析函数。例如,解析一个自定义格式的日期字符串。
def parse_date(date_str):
parts = date_str.split('-')
if len(parts) == 3:
year, month, day = map(int, parts)
return (year, month, day)
else:
raise ValueError("Invalid date format")
date_str = "2023-10-01"
date = parse_date(date_str)
print(date)
以上就是 Python 中各种常见数据类型的解析过程,不同的数据类型需要采用不同的解析方法。