Raspberry Pi传感器数据采集与可视化系统
- [Raspberry Pi传感器数据采集与可视化系统](#Raspberry Pi传感器数据采集与可视化系统)
-
- 内容简介
- 第一章:项目背景与系统架构设计
-
- [1.1 物联网时代的边缘计算](#1.1 物联网时代的边缘计算)
- [1.2 项目目标](#1.2 项目目标)
- [1.3 系统整体架构](#1.3 系统整体架构)
- 第二章:硬件准备与底层原理深度解析
- 第三章:开发环境搭建与系统配置
-
- [3.1 操作系统初始化](#3.1 操作系统初始化)
- [3.2 Python环境与依赖库安装](#3.2 Python环境与依赖库安装)
- [3.3 验证硬件连接](#3.3 验证硬件连接)
- 第四章:传感器驱动编写与数据采集模块
-
- [4.1 DHT22驱动封装](#4.1 DHT22驱动封装)
- [4.2 BMP280驱动封装](#4.2 BMP280驱动封装)
- [4.3 统一数据采集服务](#4.3 统一数据采集服务)
- 第五章:基于Pandas的数据存储与管理
-
- [5.1 数据模型设计](#5.1 数据模型设计)
- [5.2 数据存储管理器类](#5.2 数据存储管理器类)
- [5.3 数据清洗与预处理](#5.3 数据清洗与预处理)
- 第六章:数据可视化方案一------Matplotlib静态绘图
-
- [6.1 绘图逻辑](#6.1 绘图逻辑)
- 第七章:数据可视化方案二------Plotly与Dash实时Web系统
-
- [7.1 Dash应用结构](#7.1 Dash应用结构)
- [7.2 构建实时仪表盘](#7.2 构建实时仪表盘)
- [7.3 代码深度解析](#7.3 代码深度解析)
- 第八章:系统部署与自动化运维
-
- [8.1 使用Systemd管理服务](#8.1 使用Systemd管理服务)
- [8.2 日志管理](#8.2 日志管理)
- [8.3 性能优化与注意事项](#8.3 性能优化与注意事项)
- 第九章:总结与展望
-
- [9.1 项目总结](#9.1 项目总结)
Raspberry Pi传感器数据采集与可视化系统
内容简介
本文将详细介绍如何利用Raspberry Pi(树莓派)搭建一套完整的环境监测系统。我们将集成DHT22温湿度传感器与BMP280气压温度传感器,深入解析其通信协议与驱动编写。在软件层面,我们将使用Python的Pandas库构建高效的数据存储管道,并利用Matplotlib进行本地数据分析,最终结合Plotly与Dash框架打造一个实时的Web可视化仪表盘,实现数据的远程监控与交互。
第一章:项目背景与系统架构设计
1.1 物联网时代的边缘计算
随着物联网技术的飞速发展,边缘计算设备在数据采集领域的地位日益重要。Raspberry Pi作为一款信用卡大小的单板计算机,凭借其强大的计算能力、丰富的GPIO接口以及庞大的社区支持,成为了物联网项目的首选核心平台。在实际应用中,环境数据的采集(如温度、湿度、气压)是智能家居、农业自动化以及工业监控的基础。
1.2 项目目标
本项目的核心目标是构建一个闭环的监测系统,具体包括:
- 感知层:通过I2C和单总线协议驱动传感器硬件。
- 数据处理层:使用Python进行数据清洗、格式化,并利用Pandas进行结构化存储。
- 应用层:提供两种可视化方案,一是基于Matplotlib的静态分析报表,二是基于Plotly的实时Web监控界面。
1.3 系统整体架构
系统采用分层架构设计,确保各模块解耦,便于维护与扩展。
- 硬件层 :
- 主控:Raspberry Pi 4B (或3B+/Zero W)。
- 传感器组:DHT22(温湿度)、BMP280(气压/温度)。
- 连接:面包板、杜邦线、上拉电阻。
- 驱动层 :
- 使用Python标准库
ctypes或成熟的第三方库(如Adafruit CircuitPython)与硬件通信。
- 使用Python标准库
- 数据层 :
- 内存缓存:使用List或Queue暂存实时数据。
- 持久化:CSV文件存储(轻量级),Pandas DataFrame作为中间处理介质。
- 表现层 :
- 本地脚本:Matplotlib生成历史趋势图。
- Web服务:Flask/Dash框架提供HTTP服务,前端使用Plotly.js渲染动态图表。
第二章:硬件准备与底层原理深度解析
在编写代码之前,深入理解硬件特性与通信协议是确保数据采集稳定性的关键。
2.1 核心控制器:Raspberry Pi GPIO
树莓派的GPIO(通用输入输出)引脚是连接物理世界的桥梁。本项目中,我们将主要使用以下引脚:
- 3.3V Power (Pin 1/17):为传感器供电。注意BMP280和DHT22通常工作在3.3V,切勿接5V以免烧毁。
- Ground (Pin 6/9/14...):公共地。
- GPIO 4 (Pin 7):用于连接DHT22数据引脚(可自定义)。
- GPIO 2 (SDA) / GPIO 3 (SCL):I2C总线的数据线与时钟线,用于连接BMP280。
2.2 温湿度传感器:DHT22 (AM2302)
DHT22是一款含有已校准数字信号输出的温湿度复合传感器。
技术规格
- 湿度测量范围:0-100% RH(精度±2%RH)。
- 温度测量范围:-40~80℃(精度±0.5℃)。
- 通信协议:单总线。
通信时序详解
DHT22使用的是专有的单总线协议,对时序要求极为严格。
- 主机发起起始信号:GPIO配置为输出模式,拉低电平至少1ms(通常建议18ms),然后拉高20-40微秒。
- 等待响应:GPIO配置为输入模式。DHT22会拉低电平80微秒,再拉高80微秒作为响应信号。
- 数据传输 :数据共40位(16位湿度+16位温度+8位校验和)。
- '0'信号:低电平50us + 高电平26-28us。
- '1'信号:低电平50us + 高电平70us。
由于Linux内核并非实时操作系统(非RTOS),直接使用Python的time.sleep()控制微秒级延时往往不够精准,容易导致读取失败。因此,通常推荐使用C语言编写底层驱动或使用pigpio库的波(Wave)功能来确保时序的准确性。
2.3 气压温度传感器:BMP280
BMP280是博世推出的绝对气压传感器,专为移动应用设计,通过I2C或SPI接口通信。
技术规格
- 气压测量范围:300~1100 hPa。
- 温度测量范围:-40~85℃。
- 接口:I2C(地址0x76或0x77)。
I2C通信原理
I2C(Inter-Integrated Circuit)是一种两线式串行总线。
- SDA (Serial Data):双向数据线。
- SCL (Serial Clock) :时钟线。
树莓派内部集成了I2C控制器,通过开启内核模块(dtparam=i2c_arm=on),我们可以直接在Linux文件系统中访问I2C设备。BMP280内部有寄存器映射表,我们需要读取其校准参数,然后读取原始的气压和温度数据,最后根据数据手册提供的公式进行补偿计算。
第三章:开发环境搭建与系统配置
3.1 操作系统初始化
假设我们使用Raspberry Pi OS (64-bit)。
-
启用接口 :使用
sudo raspi-config进入配置界面,在 "Interface Options" 中启用 I2C 和 SSH。 -
更新系统:
bashsudo apt-get update sudo apt-get upgrade -y
3.2 Python环境与依赖库安装
为了保持环境整洁,建议使用Python虚拟环境。
bash
# 安装系统级依赖(用于构建Python扩展库)
sudo apt-get install python3-dev python3-pip libatlas-base-dev
# 创建项目目录
mkdir ~/sensor_system
cd ~/sensor_system
# 创建并激活虚拟环境
python3 -m venv venv
source venv/bin/activate
# 安装核心库
pip install pandas matplotlib plotly dash adafruit-circuitpython-dht adafruit-circuitpython-bmp280 board
- Pandas:数据分析神器,用于处理时间序列数据。
- Matplotlib:Python绘图库的基石。
- Plotly/Dash:用于构建交互式Web应用。
- Adafruit CircuitPython:Adafruit提供的硬件驱动库,极大地简化了底层操作,比直接操作寄存器更稳定且跨平台。
3.3 验证硬件连接
在编写主程序前,需确认I2C设备已被识别。
bash
sudo i2cdetect -y 1
如果BMP280接线正确,输出矩阵中应显示 76 或 77 的字样。DHT22由于是单总线,无法通过此命令检测,需通过代码测试。
第四章:传感器驱动编写与数据采集模块
我们将采用面向对象的设计模式,封装传感器类,提高代码的复用性。
4.1 DHT22驱动封装
虽然可以直接操作GPIO,但为了稳定性,我们使用Adafruit库。该库底层使用了pigpio的守护进程,能极大降低读取错误率。
python
import time
import board
import adafruit_dht
class DHT22Sensor:
def __init__(self, pin=board.D4):
"""
初始化DHT22传感器
:param pin: GPIO引脚,默认为D4 (物理引脚7)
"""
self.sensor = adafruit_dht.DHT22(pin)
self.last_measurement = None
def read_data(self):
"""
读取温湿度数据
:return: (temperature, humidity) 或
"""
try:
temperature = self.sensor.temperature
humidity = self.sensor.humidity
# 简单的数据有效性检查
if humidity is not None and temperature is not None:
self.last_measurement = (temperature, humidity)
return temperature, humidity
else:
return None, None
except RuntimeError as error:
# DHT传感器读取失败很常见,通常是因为时序问题
print(f"读取DHT22出错: {error.args[0]}")
# 返回上一次的有效数据或None
if self.last_measurement:
return self.last_measurement
return None, None
except Exception as error:
print(f"DHT22严重错误: {error}")
raise error
# 测试代码
if __name__ == "__main__":
dht = DHT22Sensor()
for i in range(5):
t, h = dht.read_data()
print(f"DHT22 - 温度: {t:.1f}C, 湿度: {h:.1f}%")
time.sleep(2)
4.2 BMP280驱动封装
BMP280通过I2C通信,我们需要读取其校准系数并进行浮点运算。
python
import board
import busio
import adafruit_bmp280
class BMP280Sensor:
def __init__(self, address=0x76):
"""
初始化BMP280
:param address: I2C地址,通常为0x76或0x77
"""
i2c = busio.I2C(board.SCL, board.SDA)
try:
self.sensor = adafruit_bmp280.Adafruit_BMP280_I2C(i2c, address=address)
# 配置采样率等参数(可选)
self.sensor.sea_level_pressure = 1013.25 # 设置海平面气压用于计算海拔
except ValueError:
print("未找到BMP280传感器,请检查连线或地址!")
self.sensor = None
def read_data(self):
"""
读取气压和温度
:return: (temperature, pressure, altitude)
"""
if self.sensor is None:
return None, None, None
try:
temperature = self.sensor.temperature
pressure = self.sensor.pressure
altitude = self.sensor.altitude
return temperature, pressure, altitude
except Exception as e:
print(f"读取BMP280出错: {e}")
return None, None, None
# 测试代码
if __name__ == "__main__":
bmp = BMP280Sensor()
t, p, a = bmp.read_data()
print(f"BMP280 - 温度: {t:.1f}C, 气压: {p:.1f}hPa, 海拔: {a:.1f}m")
4.3 统一数据采集服务
现在,我们需要将两个传感器整合,并生成带有时间戳的数据记录。
python
import time
from datetime import datetime
class SensorService:
def __init__(self):
self.dht = DHT22Sensor()
self.bmp = BMP280Sensor()
def collect_sample(self):
"""
采集一次样本
:return: 包含所有传感器数据的字典
"""
# 读取DHT22
dht_temp, dht_hum = self.dht.read_data()
# 读取BMP280
bmp_temp, bmp_pressure, bmp_alt = self.bmp.read_data()
# 创建时间戳
timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
# 构建数据字典
record = {
'timestamp': timestamp,
'dht_temp': dht_temp,
'dht_humidity': dht_hum,
'bmp_temp': bmp_temp,
'bmp_pressure': bmp_pressure,
'bmp_altitude': bmp_alt
}
return record
# 模拟采集
if __name__ == "__main__":
service = SensorService()
while True:
data = service.collect_sample()
print(data)
time.sleep(5)
第五章:基于Pandas的数据存储与管理
采集到的原始数据如果不进行管理,将毫无价值。Pandas是处理此类结构化数据的最佳工具。
5.1 数据模型设计
我们将创建一个DataFrame来存储数据。索引为时间戳,列为各个传感器读数。
5.2 数据存储管理器类
为了防止内存溢出,我们不会将所有数据一直保存在内存中,而是定期写入CSV文件。
python
import pandas as pd
import os
from datetime import datetime
class DataManager:
def __init__(self, file_path='sensor_data.csv'):
self.file_path = file_path
self.columns = ['timestamp', 'dht_temp', 'dht_humidity', 'bmp_temp', 'bmp_pressure', 'bmp_altitude']
# 如果文件不存在,创建并写入表头
if not os.path.exists(self.file_path):
df_init = pd.DataFrame(columns=self.columns)
df_init.to_csv(self.file_path, index=False)
print(f"已创建数据文件: {self.file_path}")
def save_record(self, record):
"""
将单条记录追加到CSV文件
"""
# 将字典转换为DataFrame
df_new = pd.DataFrame([record])
# 追加模式写入CSV
df_new.to_csv(self.file_path, mode='a', header=False, index=False)
def load_recent_data(self, minutes=30):
"""
加载最近N分钟的数据用于绘图
"""
if not os.path.exists(self.file_path):
return pd.DataFrame(columns=self.columns)
# 读取CSV,解析时间戳
try:
df = pd.read_csv(self.file_path, parse_dates=['timestamp'])
except pd.errors.EmptyDataError:
return pd.DataFrame(columns=self.columns)
# 过滤最近时间的数据
cutoff = datetime.now() - pd.Timedelta(minutes=minutes)
recent_df = df[df['timestamp'] > cutoff]
return recent_df
# 测试数据管理
if __name__ == "__main__":
manager = DataManager()
# 模拟一条数据
fake_data = {
'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
'dht_temp': 25.5,
'dht_humidity': 60.2,
'bmp_temp': 25.3,
'bmp_pressure': 1012.5,
'bmp_altitude': 50.0
}
manager.save_record(fake_data)
print("数据已保存。")
print(manager.load_recent_data(1))
5.3 数据清洗与预处理
在实际应用中,传感器数据常包含噪声(如DHT22偶尔会返回None或异常值)。Pandas提供了强大的清洗功能:
- 缺失值处理 :
df.fillna(method='ffill')使用前向填充来处理偶发的读取失败。 - 异常值过滤:例如,如果温度读数突然跳变到85度(DHT系列传感器常见的错误码),应将其剔除。
python
def clean_data(self, df):
# 剔除无效温度值 (假设正常范围 -20 到 50)
df = df[(df['dht_temp'] > -20) & (df['dht_temp'] < 50)]
# 前向填充缺失值
df.fillna(method='ffill', inplace=True)
return df
第六章:数据可视化方案一------Matplotlib静态绘图
Matplotlib适合用于生成历史报表或离线分析图表。我们可以编写一个脚本,定期生成PNG图片并保存,或者通过邮件发送。
6.1 绘图逻辑
我们需要绘制双Y轴图表:左轴表示温度(℃),右轴表示湿度(%)和气压。
python
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
class Plotter:
def __init__(self, data_manager):
self.manager = data_manager
def generate_history_plot(self, output_file='history_plot.png', hours=24):
# 加载过去24小时的数据
minutes = hours * 60
df = self.manager.load_recent_data(minutes)
if df.empty:
print("无数据可绘图")
return
# 设置中文字体支持(如果系统安装了中文字体)
plt.rcParams['font.sans-serif'] = ['SimHei'] # 或者 'WenQuanYi Micro Hei' on Linux
plt.rcParams['axes.unicode_minus'] = False
fig, ax1 = plt.subplots(figsize=(12, 6))
# 绘制温度曲线
color = 'tab:red'
ax1.set_xlabel('时间')
ax1.set_ylabel('温度 (℃)', color=color)
ax1.plot(df['timestamp'], df['dht_temp'], color=color, label='DHT22 Temp', marker='o', markersize=2)
ax1.plot(df['timestamp'], df['bmp_temp'], color='tab:orange', linestyle='--', label='BMP280 Temp')
ax1.tick_params(axis='y', labelcolor=color)
ax1.legend(loc='upper left')
# 创建第二个Y轴用于气压
ax2 = ax1.twinx()
color = 'tab:blue'
ax2.set_ylabel('气压', color=color)
ax2.plot(df['timestamp'], df['bmp_pressure'], color=color, label='Pressure', alpha=0.5)
ax2.tick_params(axis='y', labelcolor=color)
ax2.legend(loc='upper right')
# 格式化X轴时间显示
ax1.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))
fig.autofmt_xdate() # 自动旋转日期标签
plt.title(f'环境监测数据 - 最近{hours}小时')
plt.tight_layout()
plt.savefig(output_file)
plt.close()
print(f"图表已保存至 {output_file}")
# 使用示例
if __name__ == "__main__":
manager = DataManager()
plotter = Plotter(manager)
plotter.generate_history_plot()
这段代码展示了如何利用Matplotlib的twinx功能在一张图上展示不同量纲的数据,并通过Pandas读取的时间序列数据自动适配X轴刻度。
第七章:数据可视化方案二------Plotly与Dash实时Web系统
这是本项目的核心亮点。传统的Matplotlib图表是静态的,无法满足实时监控的需求。Plotly提供了交互式图表,而Dash框架让我们可以用纯Python代码构建Web App,无需编写HTML/JavaScript。
7.1 Dash应用结构
一个Dash应用通常由两部分组成:
- Layout (布局):定义UI长什么样。
- Callbacks (回调):定义UI如何交互。
7.2 构建实时仪表盘
我们将创建一个每秒自动更新的网页,显示实时数据和历史趋势。
python
import dash
from dash import dcc, html, Input, Output
import plotly.graph_objs as go
from datetime import datetime
import time
# 假设前面的类定义都在同一个文件中或已导入
# from sensor_module import SensorService, DataManager
# 初始化
sensor_service = SensorService()
data_manager = DataManager()
# 初始化Dash App
app = dash.Dash(__name__)
# 定义布局
app.layout = html.Div(style={'backgroundColor': '#f4f4f4', 'padding': '20px'}, children=[
html.H1("树莓派环境监测站", style={'textAlign': 'center', 'color': '#333'}),
# 实时数据显示卡片
html.Div([
html.Div([
html.H3("当前温度 (DHT22)", style={'textAlign': 'center'}),
html.H2(id='live-temp', style={'textAlign': 'center', 'color': 'red'}),
], className='four columns', style={'width': '30%', 'display': 'inline-block', 'background': 'white', 'padding': '10px', 'borderRadius': '10px'}),
html.Div([
html.H3("当前湿度", style={'textAlign': 'center'}),
html.H2(id='live-hum', style={'textAlign': 'center', 'color': 'blue'}),
], className='four columns', style={'width': '30%', 'display': 'inline-block', 'background': 'white', 'padding': '10px', 'borderRadius': '10px', 'marginLeft': '5%'}),
html.Div([
html.H3("当前气压", style={'textAlign': 'center'}),
html.H2(id='live-pres', style={'textAlign': 'center', 'color': 'green'}),
], className='four columns', style={'width': '30%', 'display': 'inline-block', 'background': 'white', 'padding': '10px', 'borderRadius': '10px', 'marginLeft': '5%'}),
], style={'marginBottom': '20px'}),
# 历史趋势图
dcc.Graph(id='live-graph'),
# 隐藏的Interval组件,用于定时触发回调
dcc.Interval(
id='interval-component',
interval=5*1000, # 5秒更新一次
n_intervals=0
)
])
# 定义回调函数
@app.callback(
[Output('live-temp', 'children'),
Output('live-hum', 'children'),
Output('live-pres', 'children'),
Output('live-graph', 'figure')],
[Input('interval-component', 'n_intervals')]
)
def update_metrics(n):
# 1. 采集新数据
record = sensor_service.collect_sample()
# 2. 保存数据
data_manager.save_record(record)
# 3. 更新实时数值显示
temp_str = f"{record['dht_temp']:.1f} °C" if record['dht_temp'] else "N/A"
hum_str = f"{record['dht_humidity']:.1f} %" if record['dht_humidity'] else "N/A"
pres_str = f"{record['bmp_pressure']:.1f} hPa" if record['bmp_pressure'] else "N/A"
# 4. 更新历史图表
# 获取最近1小时的数据
df = data_manager.load_recent_data(minutes=60)
# 创建Plotly图表
fig = go.Figure()
if not df.empty:
# 温度曲线
fig.add_trace(go.Scatter(
x=df['timestamp'], y=df['dht_temp'],
mode='lines+markers', name='温度 (DHT22)',
line=dict(color='red')
))
# 气压曲线 (使用次坐标轴)
fig.add_trace(go.Scatter(
x=df['timestamp'], y=df['bmp_pressure'],
mode='lines+markers', name='气压',
line=dict(color='green'),
yaxis='y2'
))
# 湿度曲线
fig.add_trace(go.Scatter(
x=df['timestamp'], y=df['dht_humidity'],
mode='lines+markers', name='湿度',
line=dict(color='blue'),
yaxis='y3' # 这里简化处理,实际可能需要配置layout overlaying
))
# 配置图表布局,包含双Y轴
fig.update_layout(
title='实时环境趋势 (最近1小时)',
xaxis_title='时间',
yaxis=dict(title='温度 (℃)', titlefont=dict(color='red'), tickfont=dict(color='red')),
yaxis2=dict(title='气压', titlefont=dict(color='green'), tickfont=dict(color='green'), anchor='x', overlaying='y', side='right'),
legend=dict(orientation="h", yanchor="bottom", y=1.02, xanchor="right", x=1),
margin=dict(l=40, r=40, t=40, b=40)
)
return temp_str, hum_str, pres_str, fig
if __name__ == '__main__':
# 注意:在开发模式下运行,生产环境建议使用gunicorn + nginx
app.run_server(debug=True, host='0.0.0.0', port=8050)
7.3 代码深度解析
dcc.Interval:这是Dash实现实时更新的核心组件。它每隔设定的毫秒数触发一次回调函数,无需手动编写多线程循环。- 回调逻辑 :
update_metrics函数既是数据的消费者(绘图),也是数据的生产者(采集并保存)。这种设计在低频采集(如每5秒一次)中是可行的。如果采集频率极高(如100Hz),则应将采集过程放在独立的后台线程中,通过全局变量或Redis共享数据,避免阻塞Web响应。 - Plotly双Y轴 :通过
yaxis='y2'和overlaying='y'配置,我们成功在一张图表上展示了量级差异巨大的温度和气压数据,且互不干扰。
第八章:系统部署与自动化运维
让脚本在终端前台运行是不够的,我们需要它开机自启并在崩溃后自动重启。
8.1 使用Systemd管理服务
在Linux系统中,Systemd是标准的进程管理工具。
-
创建服务文件 :
sudo nano /etc/systemd/system/sensor_web.service内容如下:
ini[Unit] Description=Sensor Data Visualization Web App After=network.target [Service] # 替换为你的实际路径 WorkingDirectory=/home/pi/sensor_system # 指定虚拟环境的Python解释器 ExecStart=/home/pi/sensor_system/venv/bin/python app.py # 自动重启策略 Restart=on-failure RestartSec=10 User=pi Environment=PYTHONUNBUFFERED=1 [Install] WantedBy=multi-user.target -
启用并启动服务:
bashsudo systemctl daemon-reload sudo systemctl enable sensor_web.service sudo systemctl start sensor_web.service -
查看状态 :
sudo systemctl status sensor_web.service
8.2 日志管理
Systemd会自动捕获标准输出。使用 journalctl -u sensor_web.service -f 可以实时查看系统日志,这对于调试传感器读数异常非常有帮助。
8.3 性能优化与注意事项
- SD卡寿命:频繁写入CSV可能会损耗树莓派的SD卡。虽然对于本项目频率(每5秒一次)影响不大,但在高频工业场景下,建议将数据写入内存盘或外接USB硬盘/SSD。
- 传感器漂移:DHT22在长时间运行后可能会出现读数漂移。建议在代码中加入定期校准逻辑,或者对比两个温度传感器(DHT22和BMP280)的读数,若差异过大则发出警报。
- 网络访问:通过配置路由器的端口转发,可以在公网访问树莓派的8050端口,实现远程监控。但务必添加Nginx反向代理并开启HTTPS加密,甚至添加Dash的Basic Auth认证,防止数据泄露。
第九章:总结与展望
9.1 项目总结
本文详细构建了一个基于Raspberry Pi的完整物联网系统。从底层的GPIO时序分析,到中间层的数据清洗与Pandas存储,再到顶层的Web可视化,我们覆盖了全栈开发的各个环节。
- 硬件方面:掌握了I2C与单总线通信的原理与接线。
- 软件方面:熟练运用了Python的面向对象编程、Pandas的时间序列处理能力以及Dash框架的交互式开发模式。