树莓派 4B + C#:.NET 8 嵌入式跨平台上位机(传感器数据采集实战)

内容分享2个月前发布 Guluua-
0 0 0

一、核心场景与价值

树莓派 4B 作为低成本嵌入式工控核心,广泛应用于边缘数据采集场景。结合 .NET 8 的跨平台特性,可实现:

嵌入式轻量化部署:.NET 8 应用体积最小压缩至 30MB,适配树莓派 4B 最小 2GB 内存;多传感器兼容:支持 I2C/SPI/UART/GPIO 多种接口,适配温湿度、气压、光照等主流工业传感器;跨平台复用:同一套代码可部署在树莓派(Linux ARM64)、Windows 工控机、Ubuntu 边缘节点,无需修改;工业级稳定:支持定时采集、异常重试、数据缓存,满足 7×24 小时边缘运行需求。

本文以「树莓派 4B + BME280 温湿度气压传感器」为核心,手把手实现从硬件连接、.NET 8 环境搭建到数据采集、存储、跨平台部署的全流程,提供可直接运行的源码与部署脚本。

二、技术栈选型(嵌入式工业级组合)

模块 技术选型 核心优势
基础框架 .NET 8(LTS) 原生支持 Linux ARM64,性能提升 30%+,支持 Trim 瘦身
硬件交互 System.Device.Gpio + Iot.Device.Bindings 微软官方物联网库,覆盖 200+ 传感器,跨平台无依赖
传感器通信 I2C 总线(优先)/ SPI / UART 树莓派 4B 原生支持,接线简单,适配多数工业传感器
数据存储 SQLite(本地缓存)+ 日志文件 轻量化无部署成本,适配嵌入式低资源场景
部署方式 .NET 自包含发布(linux-arm64) 无需树莓派安装 .NET Runtime,直接运行
调试工具 Visual Studio 2022 远程调试 + 树莓派 SSH 本地开发、远程调试,提升开发效率

三、环境准备(3 步到位)

3.1 树莓派硬件与系统准备

硬件清单
核心:树莓派 4B(2GB/4GB 版本,推荐 4GB 用于多传感器扩展);传感器:BME280(温湿度+气压,I2C 接口,性价比高);辅助:40Pin 杜邦线(母对母)、5V 电源(树莓派+传感器供电)、SD 卡(≥16GB)。 系统安装
下载官方系统:Raspberry Pi OS (64-bit)(Debian 12 内核,支持 ARM64);用 Raspberry Pi Imager 烧录 SD 卡,启用 SSH(烧录时勾选「设置 SSH 密码」「配置 WIFI」);插入 SD 卡启动树莓派,通过 SSH 连接(工具:Putty/Xshell,IP 可通过路由器管理页查询)。

3.2 树莓派硬件接口启用(I2C 核心)

BME280 采用 I2C 通信,需先启用树莓派 I2C 总线:

SSH 连接树莓派,执行配置命令:


sudo raspi-config

选择「Interface Options」→「I2C」→ 选择「Yes」启用 I2C;重启树莓派生效:


sudo reboot

验证 I2C 启用:重启后执行以下命令,若显示
i2c-1
则成功:


ls /dev/i2c-*

3.3 .NET 8 环境部署(树莓派 + 开发机)

3.3.1 开发机环境(Windows 10/11)

安装 Visual Studio 2022(17.10+),勾选「.NET 桌面开发」「.NET 多平台应用 UI 开发」;安装 .NET 8 SDK:下载地址(自动适配 Windows x64)。

3.3.2 树莓派环境(Linux ARM64)

SSH 连接树莓派,执行以下命令安装 .NET 8 SDK(ARM64 版本):


# 下载 .NET 8 SDK 安装脚本
wget https://dot.net/v1/dotnet-install.sh -O dotnet-install.sh
# 授予执行权限
chmod +x dotnet-install.sh
# 安装 .NET 8 SDK(ARM64 架构)
sudo ./dotnet-install.sh --version 8.0.0 --install-dir /usr/share/dotnet --architecture arm64
# 配置环境变量(永久生效)
echo 'export PATH=$PATH:/usr/share/dotnet' >> ~/.bashrc
source ~/.bashrc

验证安装:执行
dotnet --version
,显示
8.0.0
则成功。

四、Step1:传感器硬件连接(树莓派 4B + BME280)

BME280 引脚定义与树莓派 4B 40Pin 对应(I2C 模式):

BME280 引脚 功能 树莓派 4B 引脚(物理编号) 树莓派引脚功能
VCC 供电(3.3V) 1 脚 3.3V 电源(避免 5V 烧板)
GND 接地 6 脚 GND
SDA I2C 数据线 3 脚 SDA1(GPIO2)
SCL I2C 时钟线 5 脚 SCL1(GPIO3)

连接注意事项:

必须使用 3.3V 供电,BME280 不支持 5V,否则会烧毁传感器;杜邦线接线牢固,避免接触不良导致数据采集失败;树莓派 4B 的 I2C 总线编号为
1
(后续代码中需配置)。

五、Step2:.NET 8 项目创建与依赖安装

5.1 创建项目(开发机 Windows)

打开 Visual Studio 2022 → 「创建新项目」→ 搜索「控制台应用」→ 命名为
RaspberryPiSensorCollector
→ 选择框架
.NET 8
;右键项目 → 「属性」→ 「生成」→ 目标平台选择「Any CPU」,取消「首选 32 位」;右键项目 → 「管理 NuGet 程序包」,安装以下依赖:


# 微软官方物联网设备绑定库(支持 BME280 等 200+ 传感器)
Install-Package Iot.Device.Bindings -Version 3.0.0
# GPIO 控制核心库(I2C/SPI 底层依赖)
Install-Package System.Device.Gpio -Version 8.0.0
# SQLite 本地数据存储(嵌入式轻量数据库)
Install-Package Microsoft.Data.Sqlite -Version 8.0.0
# 日志库(工业场景排障用)
Install-Package Serilog.Sinks.Console -Version 5.0.0
Install-Package Serilog.Sinks.File -Version 5.0.0

5.2 项目结构设计(模块化适配多传感器)


RaspberryPiSensorCollector/
├─ Config/          # 配置类(传感器地址、采集间隔等)
├─ Data/            # 数据模型与存储
├─ Hardware/        # 硬件适配(I2C初始化、传感器驱动)
├─ Services/        # 核心服务(采集服务、日志服务)
└─ Program.cs       # 入口程序

六、Step3:核心代码实现(传感器采集+数据存储)

6.1 配置类(统一管理参数,便于维护)


// Config/SensorConfig.cs
namespace RaspberryPiSensorCollector.Config
{
    /// <summary>
    /// 传感器采集配置
    /// </summary>
    public class SensorConfig
    {
        /// <summary>
        /// I2C 总线编号(树莓派 4B 默认为 1)
        /// </summary>
        public int I2CBusId { get; set; } = 1;

        /// <summary>
        /// BME280 传感器 I2C 地址(默认 0x76,部分模块为 0x77)
        /// </summary>
        public int Bme280Address { get; set; } = 0x76;

        /// <summary>
        /// 采集间隔(毫秒,默认 2000ms = 2秒)
        /// </summary>
        public int CollectInterval { get; set; } = 2000;

        /// <summary>
        /// SQLite 数据库路径(树莓派上的存储路径)
        /// </summary>
        public string DbPath { get; set; } = Path.Combine(AppContext.BaseDirectory, "sensor_data.db");

        /// <summary>
        /// 日志文件路径
        /// </summary>
        public string LogPath { get; set; } = Path.Combine(AppContext.BaseDirectory, "logs", "collector.log");
    }
}

6.2 数据模型与存储(SQLite 本地缓存)


// Data/SensorData.cs(数据模型)
namespace RaspberryPiSensorCollector.Data
{
    /// <summary>
    /// 传感器采集数据模型
    /// </summary>
    public class SensorData
    {
        /// <summary>
        /// 主键 ID
        /// </summary>
        public int Id { get; set; }

        /// <summary>
        /// 采集时间戳(UTC+8)
        /// </summary>
        public DateTime CollectTime { get; set; } = DateTime.Now.ToUniversalTime().AddHours(8);

        /// <summary>
        /// 温度(℃)
        /// </summary>
        public float Temperature { get; set; }

        /// <summary>
        /// 湿度(%RH)
        /// </summary>
        public float Humidity { get; set; }

        /// <summary>
        /// 气压(hPa)
        /// </summary>
        public float Pressure { get; set; }

        /// <summary>
        /// 传感器型号
        /// </summary>
        public string SensorModel { get; set; } = "BME280";
    }
}

// Data/SqliteStorage.cs(SQLite 存储服务)
using Microsoft.Data.Sqlite;

namespace RaspberryPiSensorCollector.Data
{
    public class SqliteStorage
    {
        private readonly string _dbPath;

        public SqliteStorage(string dbPath)
        {
            _dbPath = dbPath;
            // 初始化数据库表
            InitTable();
        }

        /// <summary>
        /// 创建传感器数据表
        /// </summary>
        private void InitTable()
        {
            using var connection = new SqliteConnection($"Data Source={_dbPath}");
            connection.Open();

            var createTableCmd = connection.CreateCommand();
            createTableCmd.CommandText = @"
                CREATE TABLE IF NOT EXISTS SensorData (
                    Id INTEGER PRIMARY KEY AUTOINCREMENT,
                    CollectTime TEXT NOT NULL,
                    Temperature REAL NOT NULL,
                    Humidity REAL NOT NULL,
                    Pressure REAL NOT NULL,
                    SensorModel TEXT NOT NULL
                );";
            createTableCmd.ExecuteNonQuery();
        }

        /// <summary>
        /// 插入传感器数据
        /// </summary>
        public void InsertSensorData(SensorData data)
        {
            try
            {
                using var connection = new SqliteConnection($"Data Source={_dbPath}");
                connection.Open();

                var insertCmd = connection.CreateCommand();
                insertCmd.CommandText = @"
                    INSERT INTO SensorData (CollectTime, Temperature, Humidity, Pressure, SensorModel)
                    VALUES (@CollectTime, @Temperature, @Humidity, @Pressure, @SensorModel);";
                insertCmd.Parameters.AddWithValue("@CollectTime", data.CollectTime.ToString("yyyy-MM-dd HH:mm:ss.fff"));
                insertCmd.Parameters.AddWithValue("@Temperature", data.Temperature);
                insertCmd.Parameters.AddWithValue("@Humidity", data.Humidity);
                insertCmd.Parameters.AddWithValue("@Pressure", data.Pressure);
                insertCmd.Parameters.AddWithValue("@SensorModel", data.SensorModel);

                insertCmd.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                Serilog.Log.Error($"SQLite 存储失败:{ex.Message}");
            }
        }
    }
}

6.3 硬件适配(I2C 初始化 + BME280 驱动)


// Hardware/Bme280Sensor.cs
using Iot.Device.Bme280;
using Iot.Device.Bmxx80;
using System.Device.I2c;
using RaspberryPiSensorCollector.Config;
using RaspberryPiSensorCollector.Data;

namespace RaspberryPiSensorCollector.Hardware
{
    /// <summary>
    /// BME280 传感器驱动封装
    /// </summary>
    public class Bme280Sensor : IDisposable
    {
        private readonly I2cDevice _i2cDevice;
        private readonly Bme280 _sensor;
        private bool _disposed = false;

        public Bme280Sensor(SensorConfig config)
        {
            // 初始化 I2C 设备(树莓派总线 1 + 传感器地址)
            var i2cSettings = new I2cConnectionSettings(config.I2CBusId, config.Bme280Address);
            _i2cDevice = I2cDevice.Create(i2cSettings);
            
            // 初始化 BME280 传感器
            _sensor = new Bme280(_i2cDevice);
            // 配置传感器采集精度(平衡精度与功耗)
            _sensor.TemperatureSampling = Sampling.LowPower;
            _sensor.PressureSampling = Sampling.LowPower;
            _sensor.HumiditySampling = Sampling.LowPower;
        }

        /// <summary>
        /// 读取传感器数据
        /// </summary>
        public SensorData ReadData()
        {
            try
            {
                // 触发传感器测量并读取数据
                _sensor.TryReadTemperature(out var temperature);
                _sensor.TryReadHumidity(out var humidity);
                _sensor.TryReadPressure(out var pressure);

                return new SensorData
                {
                    Temperature = (float)Math.Round(temperature.DegreesCelsius, 2),
                    Humidity = (float)Math.Round(humidity.Percent, 2),
                    Pressure = (float)Math.Round(pressure.Hectopascals, 2)
                };
            }
            catch (Exception ex)
            {
                Serilog.Log.Error($"BME280 数据读取失败:{ex.Message}");
                return null;
            }
        }

        // 释放资源(避免 I2C 总线占用)
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (_disposed) return;
            if (disposing)
            {
                _i2cDevice?.Dispose();
            }
            _disposed = true;
        }
    }
}

6.4 核心采集服务(定时采集+异常重试)


// Services/CollectorService.cs
using RaspberryPiSensorCollector.Config;
using RaspberryPiSensorCollector.Data;
using RaspberryPiSensorCollector.Hardware;

namespace RaspberryPiSensorCollector.Services
{
    public class CollectorService
    {
        private readonly SensorConfig _config;
        private readonly Bme280Sensor _sensor;
        private readonly SqliteStorage _storage;
        private readonly CancellationTokenSource _cts = new();

        public CollectorService(SensorConfig config)
        {
            _config = config;
            _sensor = new Bme280Sensor(config);
            _storage = new SqliteStorage(config.DbPath);
        }

        /// <summary>
        /// 启动采集服务(异步非阻塞)
        /// </summary>
        public async Task StartAsync()
        {
            Serilog.Log.Information("传感器采集服务启动成功,采集间隔:{0}ms", _config.CollectInterval);
            
            while (!_cts.Token.IsCancellationRequested)
            {
                try
                {
                    // 1. 读取传感器数据
                    var sensorData = _sensor.ReadData();
                    if (sensorData == null)
                    {
                        Serilog.Log.Warning("本次采集数据为空,重试中...");
                        await Task.Delay(1000, _cts.Token);
                        continue;
                    }

                    // 2. 日志输出(控制台+文件)
                    Serilog.Log.Information(
                        "采集成功 | 时间:{0} | 温度:{1}℃ | 湿度:{2}%RH | 气压:{3}hPa",
                        sensorData.CollectTime.ToString("HH:mm:ss.fff"),
                        sensorData.Temperature,
                        sensorData.Humidity,
                        sensorData.Pressure
                    );

                    // 3. 本地存储(SQLite)
                    _storage.InsertSensorData(sensorData);
                }
                catch (Exception ex)
                {
                    Serilog.Log.Error($"采集服务异常:{ex.Message}");
                }
                finally
                {
                    // 等待下一次采集
                    await Task.Delay(_config.CollectInterval, _cts.Token);
                }
            }
        }

        /// <summary>
        /// 停止采集服务(优雅退出)
        /// </summary>
        public void Stop()
        {
            _cts.Cancel();
            _sensor.Dispose();
            Serilog.Log.Information("传感器采集服务已停止");
        }
    }
}

6.5 入口程序(初始化+启动服务)


// Program.cs
using Serilog;
using RaspberryPiSensorCollector.Config;
using RaspberryPiSensorCollector.Services;

namespace RaspberryPiSensorCollector
{
    class Program
    {
        static async Task Main(string[] args)
        {
            // 1. 初始化配置
            var config = new SensorConfig();

            // 2. 初始化日志(控制台+文件轮转)
            Log.Logger = new LoggerConfiguration()
                .MinimumLevel.Information()
                .WriteTo.Console()
                .WriteTo.File(
                    path: config.LogPath,
                    rollingInterval: RollingInterval.Day, // 按天轮转日志
                    retainedFileCountLimit: 7, // 保留7天日志
                    outputTemplate: "[{Timestamp:HH:mm:ss.fff}] [{Level:u3}] {Message:lj}{NewLine}{Exception}"
                )
                .CreateLogger();

            try
            {
                Log.Information("=== 树莓派 .NET 8 传感器采集服务启动 ===");
                
                // 3. 启动采集服务
                var collectorService = new CollectorService(config);
                await collectorService.StartAsync();
            }
            catch (Exception ex)
            {
                Log.Fatal(ex, "采集服务启动失败");
            }
            finally
            {
                Log.CloseAndFlush();
            }
        }
    }
}

七、Step4:树莓派部署与运行(自包含发布)

7.1 开发机发布 .NET 8 应用(适配 ARM64)

打开 Visual Studio 2022 终端(工具 → 终端),执行发布命令:


# 发布为 Linux ARM64 自包含应用(无需树莓派安装 .NET Runtime)
dotnet publish -c Release -r linux-arm64 --self-contained true -o ./publish/raspberrypi

发布完成后,
./publish/raspberrypi
目录下会生成可执行文件(无后缀,名称为项目名
RaspberryPiSensorCollector
)。

7.2 上传发布文件到树莓派

使用 SFTP 工具(如 WinSCP)连接树莓派(IP+SSH 账号密码);在树莓派
/home/pi
目录下创建
SensorCollector
文件夹;将发布目录
./publish/raspberrypi
下的所有文件上传到
~/SensorCollector

7.3 树莓派运行采集服务

SSH 连接树莓派,进入应用目录:


cd ~/SensorCollector

授予执行权限:


chmod +x ./RaspberryPiSensorCollector

运行应用(需 sudo 权限访问 I2C 总线):


sudo ./RaspberryPiSensorCollector

验证运行:控制台输出以下日志则成功:


[14:30:00.123] [INF] === 树莓派 .NET 8 传感器采集服务启动 ===
[14:30:00.456] [INF] 传感器采集服务启动成功,采集间隔:2000ms
[14:30:02.789] [INF] 采集成功 | 时间:14:30:02.789 | 温度:25.36℃ | 湿度:45.23%RH | 气压:1013.25hPa

7.4 设置开机自启(工业场景必备)

为确保树莓派重启后自动运行采集服务,配置 systemd 服务:

创建服务文件:


sudo nano /etc/systemd/system/sensor-collector.service

粘贴以下内容(注意修改路径为实际应用路径):


[Unit]
Description=Raspberry Pi .NET 8 Sensor Collector Service
After=network.target

[Service]
User=root
WorkingDirectory=/home/pi/SensorCollector
ExecStart=/home/pi/SensorCollector/RaspberryPiSensorCollector
Restart=always  # 崩溃自动重启
RestartSec=5    # 重启间隔 5 秒

[Install]
WantedBy=multi-user.target

保存并退出(按
Ctrl+O
→ 回车 →
Ctrl+X
);启用并启动服务:


# 重新加载 systemd 配置
sudo systemctl daemon-reload
# 启用开机自启
sudo systemctl enable sensor-collector.service
# 启动服务
sudo systemctl start sensor-collector.service

验证服务状态:


sudo systemctl status sensor-collector.service

显示「active (running)」则成功,后续树莓派重启后会自动运行采集服务。

八、Step5:跨平台验证(Windows 开发机测试)

.NET 8 应用支持跨平台运行,无需修改代码即可在 Windows 上测试(需 USB 转 I2C 适配器):

硬件:Windows 开发机 + USB 转 I2C 适配器(如 CH341A)+ BME280;软件:安装 I2C 适配器驱动(CH341A 驱动可通过设备管理器安装);修改配置(Windows 上 I2C 总线编号可能为 0,需调整):


// SensorConfig.cs 中修改 I2CBusId
public int I2CBusId { get; set; } = 0; // Windows 上的 I2C 总线编号

本地运行:Visual Studio 按 F5 直接启动,即可在 Windows 上采集传感器数据。

九、工业场景关键优化(树莓派嵌入式适配)

9.1 权限优化(避免每次 sudo 运行)

树莓派默认用户
pi
加入 I2C 权限组,无需 sudo 即可访问:


sudo usermod -aG i2c pi
sudo reboot

重启后可直接运行:
./RaspberryPiSensorCollector

9.2 镜像瘦身(适配嵌入式低存储)

发布时启用 Trim 优化,减小应用体积 30%-50%:


dotnet publish -c Release -r linux-arm64 --self-contained true -o ./publish/raspberrypi 
  -p:PublishTrimmed=true -p:TrimMode=partial

优化后应用体积可从 100MB+ 压缩至 30MB 左右。

9.3 低功耗优化(边缘节点长期运行)

调整传感器采样精度:将
Sampling.LowPower
改为
Sampling.UltraLowPower
,降低传感器功耗;延长采集间隔:根据场景调整
CollectInterval
(如 10 秒采集一次,
CollectInterval = 10000
);关闭树莓派不必要服务(如蓝牙、WiFi,仅保留有线网络):


sudo systemctl disable bluetooth
sudo systemctl stop bluetooth

9.4 数据备份(工业数据不丢失)

定时备份 SQLite 数据库到 U 盘或云存储,示例脚本(
backup.sh
):


#!/bin/bash
# 备份 SQLite 数据库到 /media/pi/USB-DISK/backup
BACKUP_DIR="/media/pi/USB-DISK/backup"
DB_PATH="/home/pi/SensorCollector/sensor_data.db"

if [ -d "$BACKUP_DIR" ]; then
    cp "$DB_PATH" "$BACKUP_DIR/sensor_data_$(date +%Y%m%d).db"
    echo "备份成功:$(date +%Y-%m-%d %H:%M:%S)" >> "$BACKUP_DIR/backup.log"
else
    echo "U盘未挂载" >> "/home/pi/SensorCollector/backup_error.log"
fi

添加定时任务(每天凌晨 2 点备份):


crontab -e
# 添加以下内容
0 2 * * * /home/pi/SensorCollector/backup.sh

十、多传感器扩展(工业场景进阶)

10.1 新增 DHT11 温湿度传感器(GPIO 接口)

硬件连接:DHT11 的 VCC→3.3V、GND→GND、DATA→GPIO4(树莓派 7 脚);安装依赖:
Install-Package Iot.Device.Bindings
(已包含 DHT11 驱动);新增
Dht11Sensor.cs
驱动类,复用
CollectorService
逻辑即可实现多传感器并行采集。

10.2 数据上传云平台(MQTT 协议)

集成 MQTT 客户端,将数据上传到工业 IoT 平台(如阿里云、华为云):

安装依赖:
Install-Package MQTTnet -Version 3.10.0
;新增
MqttUploadService.cs
,在采集数据后调用 MQTT 发布接口;配置 MQTT 服务器地址、Topic、账号密码,支持断线重连。

10.3 远程控制(HTTP API)

添加 ASP.NET Core 迷你 API,实现远程调整采集间隔、启停服务:

安装依赖:
Install-Package Microsoft.AspNetCore.Builder -Version 8.0.0
;入口程序中添加 HTTP 服务:


var builder = WebApplication.CreateBuilder();
var app = builder.Build();
app.MapGet("/api/interval/{ms}", (int ms, CollectorService service) => {
    config.CollectInterval = ms;
    return Results.Ok($"采集间隔已调整为 {ms}ms");
});
app.Run("http://*:5000"); // 树莓派监听 5000 端口

远程访问:
http://树莓派IP:5000/api/interval/5000
即可将采集间隔调整为 5 秒。

十一、避坑指南(树莓派嵌入式场景)

11.1 I2C 传感器无法识别

原因 1:传感器地址错误(BME280 常见地址 0x76/0x77),用
i2cdetect -y 1
命令查询实际地址;原因 2:接线错误(SDA/SCL 接反),重新核对引脚对应关系;原因 3:权限不足,执行
sudo usermod -aG i2c pi
并重启。

11.2 应用运行闪退(ARM64 架构不匹配)

解决方案:发布时确保指定
--runtime linux-arm64
,而非
linux-x64
(树莓派 4B 是 ARM64 架构)。

11.3 SQLite 数据库写入失败

原因:应用目录无写入权限,执行
chmod 777 /home/pi/SensorCollector
授予权限;避免:发布时将数据库路径配置到
/home/pi
目录(非系统目录,权限宽松)。

11.4 树莓派重启后服务未自动运行

检查服务配置文件路径是否正确(
/etc/systemd/system/sensor-collector.service
);执行
sudo systemctl status sensor-collector.service
查看错误日志,修复配置后重新加载:
sudo systemctl daemon-reload

十二、总结

树莓派 4B + .NET 8 实现嵌入式上位机,核心优势在于「轻量化部署、跨平台复用、工业传感器生态完善」。通过本文方案,可快速落地边缘数据采集场景,且代码可无缝迁移到 Windows/Linux 工控机,降低多平台开发成本。

工业场景落地关键:

硬件接口优先选择 I2C(接线简单、功耗低,适配多数传感器);应用发布采用「自包含模式」,避免依赖树莓派系统环境;配置开机自启与异常重启,确保 7×24 小时稳定运行;数据本地缓存+定时备份,避免边缘节点断网导致数据丢失。

该方案可直接应用于智能农业、机房监控、工业边缘采集等场景,如需适配其他传感器(如光照、气体、振动传感器),仅需通过
Iot.Device.Bindings
库扩展驱动类,无需修改核心采集逻辑。

© 版权声明

相关文章

暂无评论

none
暂无评论...