基于Arduino与树莓派的智能电子秤:从传感器到Web服务的全栈实践

基于Arduino与树莓派的智能电子秤:从传感器到Web服务的全栈实践 1. 项目概述从传统称重到智能物联的跨越在零售、仓储、家庭厨房乃至个人健康管理领域称重都是一个基础且高频的需求。传统的电子秤功能单一数据往往“阅后即焚”无法与数字世界产生更多交互。作为一名嵌入式开发爱好者我一直在思考如何给这个日常工具注入一些“智能”。这次我决定动手打造一台集高精度称重、本地显示、数据记录甚至简单交互于一体的智能电子秤核心硬件选择了经典的“微控制器单板计算机”组合Arduino负责高实时性的传感器数据采集Raspberry Pi则作为大脑处理数据、驱动外设并搭建简易的Web服务。这个项目的核心在于融合与解耦。Arduino Uno凭借其简单可靠的模拟数字转换ADC接口专精于读取HX711称重模块的微弱信号这是保证测量稳定性的基石。而树莓派则利用其强大的计算能力和丰富的生态如Python库、数据库、Web框架轻松实现了数据可视化OLED、用户交互按键、蜂鸣器、环境感知超声波测距以及历史数据存储。这种架构既发挥了各自平台的优势又通过串口通信清晰划分了职责使得系统稳定且易于扩展。最终成品不仅能精准称重至克级还能记录每次称量数据并通过网页远程查看将一个简单的测量动作变成了可追溯、可分析的数据节点。2. 核心硬件选型与电路设计解析2.1 主控与传感器为何是Arduino HX711 树莓派在硬件选型上我经过了仔细的权衡。称重传感器的信号非常微弱且易受干扰需要专用的高精度、低噪声模拟前端来处理。这就是HX711模块不可替代的原因。它是一个24位模数转换器ADC芯片专为桥式传感器如称重传感器设计内部集成了可编程增益放大器能直接将传感器输出的毫伏级差分信号放大并转换为数字值其精度和抗干扰能力远非普通MCU自带的ADC可比。那么谁来读取HX711的数据呢直接使用树莓派的GPIO口通过Python库驱动HX711是可行的但树莓派作为一个运行Linux的复杂系统其GPIO的实时性和稳定性在持续高速采样时可能不如专一的微控制器。因此我引入了Arduino Uno。它的任务非常纯粹以稳定的频率如10Hz与HX711通信读取原始重量数据然后通过串口UART发送给树莓派。这样即使树莓派上的Python程序因其他任务稍有延迟也不会影响底层数据的连续采集确保了称重响应的实时性。树莓派以Raspberry Pi 4 Model B为例则扮演系统主控的角色。它通过USB串口接收Arduino发来的数据同时驱动OLED显示屏I2C接口实时显示重量监听按键输入控制蜂鸣器发声并读取MPU6050姿态传感器和超声波传感器HC-SR04的数据。这种分工明确的架构让系统既稳健又功能强大。2.2 外设功能定义与接口分配除了核心的称重链路其他外设的加入是为了提升用户体验和系统智能性OLED显示屏 (0.91英寸, SSD1306驱动)用于本地显示重量、单位、状态信息如“稳定”、“去皮”。选择I2C接口型号仅需两根信号线SDA, SCL节省GPIO资源。有源蜂鸣器提供声音反馈。例如重量稳定时短鸣一声去皮成功时发出特定音调。通过一个GPIO口配置为输出模式直接驱动即可注意要串联一个220Ω的限流电阻。轻触按键实现去皮Tare功能。按下时树莓派将当前重量值记录为零点偏移量后续读数自动减去此值。需要配置一个GPIO口为输入模式并启用内部上拉电阻。超声波传感器 (HC-SR04)这是一个有趣的扩展。我将其安装在秤体上方用于检测物体是否放入或移出称重区域。当检测到物体接近时自动唤醒屏幕并准备称重物体移开一段时间后自动熄屏节能。它需要两个GPIO口一个用于触发Trigger一个用于回响Echo。MPU6050六轴姿态传感器用于检测电子秤是否被水平放置。如果秤体倾斜称重结果将不准确。MPU6050可以实时读取三轴加速度计数据树莓派通过I2C读取后计算倾角当倾角超过阈值如5度时在OLED上显示“请水平放置”的警告。这大大提升了测量的可靠性。注意电源管理是关键。HX711模块和称重传感器需要稳定的5V或3.3V供电具体看模块规格。树莓派和Arduino的USB口可以提供5V电源但务必确保总电流在树莓派供电能力范围内尤其是使用多个传感器时。建议为称重传感器部分单独供电并与树莓派共地以避免数字电路噪声干扰敏感的模拟信号。2.3 电路连接实战与Fritzing图解读根据上述设计我们需要在面包板或PCB上完成电路搭建。下图清晰地展示了所有元件的连接关系此处应插入Fritzing接线图图中需包含Arduino Uno、树莓派、HX711模块、称重传感器、OLED、蜂鸣器、按键、超声波传感器、MPU6050并清晰标注所有连线。接线要点详解HX711与ArduinoHX711的VCC接Arduino5VGND接GND。DT(Data) 接 Arduino 数字引脚3。SCK(Clock) 接 Arduino 数字引脚2。称重传感器的四根线通常为红、黑、白、绿接入HX711模块对应的E,E-,A-,A端子具体顺序需参考传感器说明书接错可能导致读数反向或为零。Arduino与树莓派Arduino的TX引脚接树莓派GPIO的RX(GPIO15, 物理引脚10)。Arduino的RX引脚接树莓派GPIO的TX(GPIO14, 物理引脚8)。切记还要将Arduino的GND与树莓派的GND相连共地是通信的基础。I2C设备OLED MPU6050与树莓派树莓派的SDA(GPIO2, 物理引脚3) 接OLED和MPU6050的SDA。树莓派的SCL(GPIO3, 物理引脚5) 接OLED和MPU6050的SCL。所有I2C设备的VCC接3.3V或5V根据器件要求GND接树莓派GND。其他GPIO设备与树莓派蜂鸣器正极通过220Ω电阻接GPIO口如GPIO17负极接GND。按键一端接GPIO口如GPIO27另一端接GND。GPIO口配置为内部上拉输入未按下时为高电平按下时被拉低到GND。超声波传感器VCC接5VGND接GNDTrig接GPIO口如GPIO23Echo接GPIO口如GPIO24。搭建时建议先分模块测试如先让Arduino读取重量并串口打印再测试树莓派的OLED显示最后再整合便于排查问题。3. 嵌入式软件Arduino固件与树莓派Python核心3.1 Arduino端稳定的数据采集与串口通信Arduino端的代码核心是高效、准确地与HX711通信并将处理后的重量数据通过串口发送出去。这里需要使用HX711库如bogde/HX711它封装了复杂的时序操作。#include HX711.h // HX711电路连接定义 #define LOADCELL_DOUT_PIN 3 #define LOADCELL_SCK_PIN 2 HX711 scale; // 校准参数至关重要 float calibration_factor -7050.0; // 这个值需要实际校准得出 long zero_factor 0; // 去皮后的零点值 void setup() { Serial.begin(115200); // 与树莓派通信的波特率 scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN); // 初始化传感器 scale.set_scale(calibration_factor); scale.tare(); // 启动时执行一次去皮获取零点 zero_factor scale.read_average(); // 记录当前零点读数 } void loop() { if (scale.is_ready()) { // 读取原始值并应用校准系数单位通常为克(g)或千克(kg) float weight scale.get_units(5); // 读取5次取平均提高稳定性 // 简单的数字滤波防止显示值跳动过快 static float last_stable_weight 0; if (abs(weight - last_stable_weight) 0.5) { // 变化超过0.5g才更新 last_stable_weight weight; } // 通过串口发送数据格式如 WEIGHT:123.45 Serial.print(WEIGHT:); Serial.println(last_stable_weight, 2); // 保留两位小数 } delay(100); // 控制采样频率约10Hz }关键点解析校准因子 (calibration_factor)这是将HX711原始读数转换为实际重量的魔法数字。你需要用一个已知重量的标准砝码如500g进行校准。公式为新校准因子 (原始读数 * 已知重量) / 当前读数。这是一个迭代过程可能需要微调几次。去皮 (tare)scale.tare()函数会将当前重量设为零点。在代码中我们在setup()里执行一次以消除秤盘自重。滤波与稳定性判断直接读取的原始值会有微小跳动。代码中通过多次平均(get_units(5))和阈值判断只在重量发生显著变化时才更新输出这能使得显示屏上的数字看起来非常稳定而不是不停闪烁。3.2 树莓派端多线程数据融合与业务逻辑树莓派上的Python程序是项目的大脑它需要同时处理多个任务读取串口、更新显示、监听按键、控制蜂鸣器、读取超声波和MPU6050数据。使用多线程是理想的选择。import serial import threading import time import board import busio import adafruit_ssd1306 from PIL import Image, ImageDraw, ImageFont import RPi.GPIO as GPIO # 1. 初始化 # 串口初始化 ser serial.Serial(/dev/ttyAMA0, 115200, timeout1) # 根据实际串口设备名调整 # I2C与OLED初始化 i2c busio.I2C(board.SCL, board.SDA) oled adafruit_ssd1306.SSD1306_I2C(128, 32, i2c) # GPIO初始化 BUZZER_PIN 17 BUTTON_PIN 27 GPIO.setmode(GPIO.BCM) GPIO.setup(BUZZER_PIN, GPIO.OUT) GPIO.setup(BUTTON_PIN, GPIO.IN, pull_up_downGPIO.PUD_UP) current_weight 0.0 tare_offset 0.0 is_stable False display_on True # 2. 串口读取线程 def read_serial_thread(): global current_weight, is_stable while True: if ser.in_waiting: line ser.readline().decode(utf-8).rstrip() if line.startswith(WEIGHT:): try: raw_weight float(line.split(:)[1]) # 应用去皮偏移 net_weight raw_weight - tare_offset # 稳定性判断逻辑略 current_weight net_weight except ValueError: pass time.sleep(0.01) # 3. 按键检测与去皮函数 def button_callback(channel): global tare_offset tare_offset current_weight # 将当前重量设为新的零点 beep(200, 0.2) # 发出确认音 print(fTare set. Offset: {tare_offset}g) GPIO.add_event_detect(BUTTON_PIN, GPIO.FALLING, callbackbutton_callback, bouncetime300) # 4. OLED显示更新函数 def update_display(): # 清屏 oled.fill(0) image Image.new(1, (oled.width, oled.height)) draw ImageDraw.Draw(image) font ImageFont.load_default() # 绘制重量信息 weight_text f{current_weight:7.2f} g draw.text((0, 0), weight_text, fontfont, fill255) # 绘制状态信息 if not is_stable: draw.text((0, 16), Stabilizing..., fontfont, fill255) elif tare_offset ! 0: draw.text((0, 16), Tared, fontfont, fill255) oled.image(image) oled.show() # 5. 超声波传感器检测线程用于自动唤醒/休眠屏幕 def ultrasonic_thread(): global display_on TRIG 23 ECHO 24 GPIO.setup(TRIG, GPIO.OUT) GPIO.setup(ECHO, GPIO.IN) last_activity time.time() while True: # 发送触发脉冲并测量距离代码略 distance measure_distance(TRIG, ECHO) if distance 20: # 20厘米内有物体 last_activity time.time() if not display_on: display_on True oled.poweron() elif time.time() - last_activity 30: # 30秒无活动 if display_on: display_on False oled.poweroff() time.sleep(1) # 启动线程 threading.Thread(targetread_serial_thread, daemonTrue).start() threading.Thread(targetultrasonic_thread, daemonTrue).start() # 主循环更新显示 try: while True: if display_on: update_display() time.sleep(0.1) # 显示刷新率约10Hz except KeyboardInterrupt: GPIO.cleanup() oled.poweroff() ser.close()代码设计心得线程安全多个线程会访问共享变量如current_weight。在简单应用中Python的全局变量和time.sleep带来的自然交错通常足够但对于更复杂的应用应考虑使用threading.Lock。事件驱动与轮询按键采用事件回调add_event_detect效率最高串口和超声波检测使用轮询但通过time.sleep控制频率避免CPU占用率过高。资源释放在程序退出KeyboardInterrupt时务必清理GPIO状态、关闭串口和关闭OLED屏幕这是一个好习惯。4. 结构设计与3D打印从模型到实体的实现4.1 功能性结构设计考量电子秤的外壳不仅是容器更是保证测量精度的关键部件。我的设计目标有三个稳固、易用、美观。力学结构核心是称重传感器的安装。我选择的是常见的悬臂梁式称重传感器。在3D模型中我设计了一个双层结构。底层是主壳体用于固定Arduino、树莓派、面包板等所有电子部件。上层是一个圆形的称重盘。传感器的一端必须刚性固定在底层基座上另一端则刚性连接上层的称重盘。这样当物体放在秤盘上时力会通过秤盘传递到传感器的受力端使其发生微小的形变从而输出电信号。任何非刚性的连接如使用软性胶粘都会引入误差甚至损坏传感器。传感器保护在传感器与秤盘、基座的连接处我设计了限位槽和加强筋确保受力方向垂直且均匀防止侧向力或扭力损坏传感器脆弱的金属梁。人机交互布局OLED屏幕以一定倾角朝用户方向安装便于阅读。轻触按键放置在侧面易于操作的位置。超声波传感器朝上安装检测上方区域。所有开孔USB口、电源口、散热孔都预先在模型上留好位置。走线与维护壳体内部预留了线槽和扎线带固定位让飞线井然有序。底盖设计为可拆卸式通过螺丝固定方便日后检修或升级部件。4.2 3D建模与打印实战我使用Blender进行建模对于这类功能性为主的机械结构Fusion 360可能是更专业的选择但Blender的免费和强大也完全能满足需求。建模步骤精确测量首先用游标卡尺测量每一个电子元件的实际尺寸长宽高、安装孔距、接口位置。绘制草图根据元件布局绘制底座和秤盘的基本轮廓。实体建模通过挤出、倒角、布尔运算等操作创建出带有内部空腔、支柱、卡槽的壳体。细节处理添加螺丝柱、加强筋、散热格栅、按键孔、屏幕窗口等细节。装配检查在软件中将所有电子元件模型可以简单用方块代替导入进行虚拟装配检查是否有干涉空间是否足够。打印设置与后处理材料选择PLA材料。它强度足够打印性能好且价格便宜。对于承重部位可以考虑提高填充率建议25%-40%。切片设置层高0.2mm能兼顾精度和速度。必须开启支撑因为壳体内部通常有悬空结构如内部的螺丝柱顶部。支撑材料选择“可剥离”或“树状”支撑以减少后处理难度。打印方向将模型底朝下放置打印。这样能保证与打印平台接触的底面非常平整这对于电子秤的稳定性至关重要。避免将重要的承重面作为侧面打印因为层间结合力通常弱于层内强度。后处理打印完成后小心去除支撑。用锉刀或砂纸打磨结合面确保秤盘与基座的安装面平整。对于需要高精度的传感器安装面甚至可以稍微打磨后涂一层薄薄的环氧树脂固化后再打磨平整以获得完美的平面。踩坑实录第一次打印时我忽略了支撑导致内部一些关键的支撑柱打印失败整个顶盖塌陷。第二次支撑设置过于密集极难拆除差点损坏模型。最终发现在Blender或切片软件中手动添加支撑柱并在模型设计时就考虑好打印方向尽量减少悬垂结构才是最好的办法。5. 数据持久化与Web服务搭建5.1 数据库设计与Python交互为了让称重数据有意义我们需要将其存储起来。我选择轻量级的SQLite数据库它无需安装服务器一个文件就是整个数据库非常适合树莓派上的嵌入式应用。根据项目描述中的表结构我将其简化为两个核心表并增加了时间戳和用户关联如果有多用户需求-- 创建数据库文件 smart_scale.db CREATE TABLE IF NOT EXISTS measurements ( id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, raw_weight REAL NOT NULL, -- 原始读数 net_weight REAL NOT NULL, -- 去皮后净重 unit TEXT DEFAULT g, is_tared BOOLEAN DEFAULT 0, user_id INTEGER DEFAULT 1, -- 简单用户管理默认用户为1 FOREIGN KEY (user_id) REFERENCES users(id) ); CREATE TABLE IF NOT EXISTS users ( id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT UNIQUE NOT NULL, email TEXT );在Python中使用sqlite3标准库进行操作import sqlite3 from datetime import datetime class DatabaseManager: def __init__(self, db_pathsmart_scale.db): self.conn sqlite3.connect(db_path, check_same_threadFalse) # 允许多线程访问 self.cursor self.conn.cursor() self._init_db() def _init_db(self): # 执行上面的建表SQL pass def save_measurement(self, raw_weight, net_weight, is_taredFalse, user_id1): sql INSERT INTO measurements (timestamp, raw_weight, net_weight, is_tared, user_id) VALUES (?, ?, ?, ?, ?) # 使用datetime.now()获取更精确的时间 self.cursor.execute(sql, (datetime.now().isoformat(), raw_weight, net_weight, is_tared, user_id)) self.conn.commit() def get_recent_measurements(self, limit50): sql SELECT timestamp, net_weight, unit FROM measurements WHERE user_id 1 ORDER BY timestamp DESC LIMIT ? self.cursor.execute(sql, (limit,)) return self.cursor.fetchall() def close(self): self.conn.close() # 在主程序中集成 db DatabaseManager() # 当一次稳定的称重完成时保存数据 if is_stable and abs(current_weight - last_saved_weight) 0.5: db.save_measurement(raw_weight_from_arduino, current_weight, (tare_offset ! 0)) last_saved_weight current_weight5.2 使用Flask构建简易Web监控界面我们希望在局域网内的任何设备手机、电脑上都能查看实时重量和历史记录。使用Flask微框架可以快速实现。from flask import Flask, render_template, jsonify, request import threading # 假设主称重程序在一个全局对象中运行这里需要共享数据 # 例如使用一个全局字典 scale_data scale_data {current_weight: 0.0, is_stable: False, unit: g} app Flask(__name__) db_manager DatabaseManager() # 复用之前的数据库管理器 app.route(/) def index(): 提供主页面 return render_template(index.html) # 需要创建 templates/index.html app.route(/api/current) def get_current_data(): API接口获取当前重量数据 return jsonify(scale_data) app.route(/api/history) def get_history(): API接口获取历史数据 limit request.args.get(limit, default50, typeint) records db_manager.get_recent_measurements(limit) # 将数据格式化为列表字典 history [{time: r[0], weight: r[1], unit: r[2]} for r in records] return jsonify(history) app.route(/api/tare, methods[POST]) def perform_tare(): API接口执行去皮操作通过网页按钮触发 # 这里需要触发一个信号让主线程执行去皮操作 # 可以使用线程安全的队列 queue.Queue tare_queue.put(TARE) # 假设有一个全局队列 return jsonify({status: tare command sent}) if __name__ __main__: # 在一个单独的线程中运行Flask避免阻塞主称重循环 flask_thread threading.Thread(targetlambda: app.run(host0.0.0.0, port5000, debugFalse, threadedTrue)) flask_thread.daemon True flask_thread.start() # 主线程继续运行之前的称重循环...对应的templates/index.html可以是一个简单的页面使用Chart.js绘制历史重量曲线并自动刷新当前重量!DOCTYPE html html head titleSmart Scale Dashboard/title script srchttps://cdn.jsdelivr.net/npm/chart.js/script /head body h1智能电子秤监控/h1 div h2当前重量: span idcurrentWeight0.00/span span idunitg/span/h2 p状态: span idstatus稳定/span/p button onclicksendTare()去皮(Tare)/button /div div canvas idweightChart width800 height400/canvas /div script // JavaScript代码定时获取当前数据、历史数据并更新图表 const ctx document.getElementById(weightChart).getContext(2d); const chart new Chart(ctx, { /* 配置图表 */ }); function updateCurrentWeight() { fetch(/api/current) .then(response response.json()) .then(data { document.getElementById(currentWeight).textContent data.current_weight.toFixed(2); document.getElementById(status).textContent data.is_stable ? 稳定 : 不稳定; }); } function updateHistory() { fetch(/api/history?limit100) .then(response response.json()) .then(data { // 更新Chart.js图表数据 chart.data.labels data.map(d new Date(d.time).toLocaleTimeString()); chart.data.datasets[0].data data.map(d d.weight); chart.update(); }); } function sendTare() { fetch(/api/tare, { method: POST }) .then(response response.json()) .then(data alert(data.status)); } setInterval(updateCurrentWeight, 500); // 每0.5秒更新一次当前重量 setInterval(updateHistory, 5000); // 每5秒更新一次历史图表 /script /body /html现在在树莓派上运行这个整合了Flask的程序后同一局域网下的设备浏览器访问http://[树莓派IP地址]:5000就能看到一个实时监控仪表盘了。6. 系统集成、校准与问题排查6.1 整机组装与系统上电流程当所有硬件3D打印件、电路和软件Arduino固件、树莓派Python程序都准备好后就可以进行最终组装了。硬件固定使用热熔胶或双面泡沫胶将Arduino、树莓派、面包板牢固地粘贴在底座壳体内。将HX711模块、超声波传感器也用胶固定在设计好的位置。特别注意称重传感器本身不能用胶完全粘死其固定端和受力端必须与壳体刚性接触通常用螺丝压紧但传感器金属梁部分必须保持自由状态任何胶粘剂接触到梁体都会影响其形变导致测量失准。布线整理用扎线带将导线理顺固定在预留的线槽内避免杂乱。尤其注意HX711连接到称重传感器的四根线最好用绞合的方式或使用屏蔽线以减少电磁干扰。软件部署将完整的Python项目包含主程序、数据库文件、Flask模板等拷贝到树莓派上。确保所有依赖库已安装pip install pyserial RPi.GPIO adafruit-circuitpython-ssd1306 pillow flask。设置程序开机自启动可以通过systemd服务或者写入/etc/rc.local实现。上电测试顺序建议先单独给Arduino上电打开串口监视器查看是否有正确的重量数据输出此时秤盘应为空。确认无误后再启动树莓派和整个系统。6.2 传感器校准获得准确读数的关键步骤校准是电子秤能用的前提。你需要一个或多个已知精确重量的砝码如100g, 500g, 1kg标准砝码。粗调零点确保秤盘空载在Arduino代码中调用scale.tare()。此时读数应接近0。计算校准因子将一个已知重量的砝码如known_weight 500.0克放在秤盘上。读取此时HX711输出的原始读数平均值scale.read_average()记为raw_reading。最初的校准因子可以设为-1000这样的经验值。通过公式计算新的因子new_calibration_factor (raw_reading * known_weight) / current_reading。但更简单的方法是迭代调整在Arduino代码中修改变量calibration_factor的值。上传代码观察串口输出的重量值。如果显示值小于实际砝码重量将calibration_factor的绝对值增大例如从-7050改为-7100。如果显示值大于实际砝码重量将calibration_factor的绝对值减小。重复这个过程直到显示值稳定在砝码实际重量附近。线性度验证用不同重量的砝码如100g, 200g, 1kg测试看整个量程内是否都准确。理想情况下一个校准因子应能保证全量程的线性。如果偏差较大可能需要分段校准或检查传感器安装是否受力均匀。6.3 常见问题与排查技巧实录在调试过程中我遇到了不少典型问题这里汇总一下问题现象可能原因排查步骤与解决方案重量读数始终为0或接近01. HX711与传感器接线错误。2. 传感器本身损坏。3. 供电不足。1. 用万用表检查传感器桥臂电阻通常输入/输出阻值约1kΩ且两两相等。2. 交换传感器A和A-的接线试试。3. 确保HX711模块供电电压稳定5V。读数不稳定跳动剧烈1. 机械安装不稳秤盘或传感器晃动。2. 电气噪声干扰。3. 电源纹波大。1. 检查所有螺丝是否拧紧传感器安装是否牢固无晃动。2. 将信号线DT, SCK远离电源线使用绞合线或屏蔽线。3. 在HX711的电源引脚附近并联一个100uF的电解电容和一个0.1uF的瓷片电容滤波。4. 在Arduino代码中增加软件滤波如滑动平均、中值滤波。读数漂移随时间缓慢变化1. 传感器或HX711模块预热。2. 环境温度变化。3. 机械结构应力释放。1. 系统上电后预热10-15分钟再进行校准和使用。2. 定期如每天使用前执行一次去皮操作。3. 检查3D打印件是否因内应力或温度发生形变。树莓派无法读取串口数据1. 串口设备名错误。2. 串口被系统占用如蓝牙。3. 波特率不匹配。1. 在终端输入ls /dev/tty*查看可用的串口设备常见的是/dev/ttyAMA0或/dev/ttyS0。2. 禁用树莓派串口控制台功能sudo raspi-config- Interface Options - Serial Port - 登录Shell选NO硬件串口选YES。3. 确保Arduino和Python代码中的波特率设置一致如115200。OLED屏幕不显示1. I2C地址错误。2. 接线错误或接触不良。3. 未启用I2C接口。1. 使用命令sudo i2cdetect -y 1扫描I2C设备确认OLED的地址通常0x3C。2. 检查SDA、SCL是否接反电源是否接通。3. 在sudo raspi-config中启用I2C。网页无法访问1. Flask服务未启动。2. 防火墙阻止了5000端口。3. IP地址错误。1. 检查Python程序是否在运行有无报错。2. 在树莓派上尝试curl http://localhost:5000。3. 使用hostname -I获取树莓派正确IP地址。一个宝贵的实操心得在最终封装外壳前务必进行长时间的稳定性测试例如连续运行24小时。观察在无人操作的情况下零点是否漂移读数是否异常。这能帮助发现一些潜在的、间歇性的硬件或软件问题。