未连接 点击连接 STM32 串口
📟 手动输入: pH EC (μS/cm) 浏览器不支持 Web Serial 时的备用方案

--

电导率 μS/cm

--

土壤 pH 值

--

综合污染指数 CPI

--

系统时间

📸 上传玉米照片

AI 基于植被指数 (ExG/GLI/HSV) 自动识别生长阶段

三叶期 · 抽雄期 · 开花期 · 腊熟期
GROWTH STAGE

玉米生长阶段选择

AI 拍照自动识别,也可手动切换

DASHBOARD

实时监测数据

🔬

电导率 Conductivity

-- μS/cm

下限 --上限 --

微量元素状态

--

📋

阶段信息

当前阶段--
适宜 EC--
🎯

微量元素需求

下限: -- μS/cm

上限: -- μS/cm

📡

原始传感器

pH ADC: --

EC ADC: --

运行时间: -- s

📈

电导率趋势 (最近120条)

TECHNICAL DOCUMENTATION

硬件架构 | 软件设计 | 核心代码

完整系统技术文档

📐 硬件系统架构

┌──────────────────────────────────────────────────────────┐
│                    感知层 (Sensor Layer)                   │
│                                                          │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐   │
│  │ TDS 电导率探头 │  │ 蓝色电位器    │  │ 反射式红外    │   │
│  │ (SEN0244)    │  │ (pH 模拟 6.5~9.5) │  │ (株高监测)    │   │
│  │ 0~2.3V 输出  │  │ 0~3.3V 分压   │  │ 数字 GPIO     │   │
│  └──────┬───────┘  └──────┬───────┘  └──────┬───────┘   │
│         │ PA1 ADC          │ PA0 ADC         │ PB0 GPIO    │
│         ▼                  ▼                 ▼            │
│  ┌──────────────────────────────────────────────────┐    │
│  │         STM32F103C8T6 主控 (Cortex-M3 72MHz)      │    │
│  │                                                   │    │
│  │  ┌─ ADC1 4通道轮询 ──┐  ┌─ CPI 污染指数计算 ──┐   │    │
│  │  │ PA0: pH (电位器)   │  │ 0.5×|pH-6.8|/6.8 +  │   │    │
│  │  │ PA1: EC (TDS)      │  │ 0.5×EC/150          │   │    │
│  │  └──────────────────┘  └──────────────────────┘   │    │
│  │                                                   │    │
│  │  ┌─ 输出 ────────────────────────────────────┐    │    │
│  │  │ OLED: PB6(SCL)/PB7(SDA)  I2C SSD1306       │    │    │
│  │  │ LED×3: PB12(绿)/PB13(黄)/PB14(红)           │    │    │
│  │  │ 蜂鸣器: PB1 GPIO  四级污染报警               │    │    │
│  │  │ 按键×2: PB10(K1)/PB11(K2) 模式/导出          │    │    │
│  │  │ USART1: PA9(TX)/PA10(RX) 115200bps          │    │    │
│  │  └────────────────────────────────────────────┘    │    │
│  └──────────────────┬───────────────────────────────┘    │
│                     │ PA9 TX                              │
└─────────────────────┼────────────────────────────────────┘
                      │
┌─────────────────────┼────────────────────────────────────┐
│              通信层 (Communication Layer)                 │
│                     ▼                                     │
│  ┌──────────────────────────────────┐                    │
│  │    CH340 USB-TTL 串口模块        │                    │
│  │    115200 bps · 8N1 · 3.3V TTL  │                    │
│  └──────────────┬───────────────────┘                    │
│                 │ USB                                     │
│                 ▼                                         │
│  ┌──────────────────────────────────┐                    │
│  │    浏览器 Web Serial API          │                    │
│  │    Chrome/Edge 直读串口数据        │                    │
│  │    零驱动 · 零安装 · 打开即用       │                    │
│  └──────────────────────────────────┘                    │
└──────────────────────────────────────────────────────────┘
    

📸 硬件实物照片

TDS电导率探头
感知层

TDS 电导率探头

SEN0244 防水探头,0~2.3V 模拟输出,量程 0~1000 μS/cm。插入土壤浸出液中测量离子浓度。

STM32开发板+蜂鸣器
主控

STM32F103C8T6 开发板 + 蜂鸣器

Cortex-M3 72MHz 主控,板载有源蜂鸣器用于超标报警,LED×3 三级污染指示。

OLED显示屏
显示层

0.96寸 OLED 显示屏

SSD1306 驱动,128×64 分辨率,I2C 接口。本地实时显示 pH/EC/CPI/污染等级。

CH340 USB转TTL
通信层

CH340 USB 转 TTL 模块

USB 转串口芯片,连接 STM32 PA9(TX)/PA10(RX),115200 bps 传输传感器数据。

ST-LINK下载器
编程工具

ST-LINK/V2 下载调试器

SWD 接口(SWCLK/SWDIO/GND/3.3V),Keil MDK 一键编译下载,支持断点调试。

反射式红外传感器
感知层

反射式红外传感器

数字 GPIO 接口 (PB0),检测叶片是否遮挡红外光,间接反映植株高度变化。

光敏电阻
感知层

光敏电阻传感器

模拟量输出 (PA3 ADC),贴在叶片背面检测透光率变化,间接反映叶色/叶绿素变化。

面包板
结构件

MB-102 面包板 + 连接线

830 孔面包板,搭配杜邦线、跳线、飞线,搭建传感器与 STM32 电路连接原型,无需焊接。

📋 硬件模块详解

1. TDS 电导率探头 感知层

模拟量 TDS 传感器(SEN0244),输出范围 0~2.3V,经 STM32 12位 ADC(PA1)采样后换算为电导率值(μS/cm)。探头防水设计,可直接插入土壤浸出液。土壤中重金属离子(Cu²⁺、Pb²⁺、Cd²⁺)和微量元素(Zn²⁺、Fe²⁺)溶解后增加溶液电导率——读数越高 → 离子浓度越高 → 潜在污染越重

依据:HJ 802-2016《土壤 电导率的测定 电极法》、ISO 7888:1985 标准温度补偿公式

2. pH 电位器(模拟输入)感知层

使用套件自带的蓝色电位器旋钮模拟 pH 值输入(范围 6.5~9.5),通过 STM32 ADC(PA0)采样。选择电位器而非真实 pH 玻璃电极的原因:pH 电极易碎、需标定液 KCL 保护液、维护复杂——不适合初中实验场景。演示效果一致,且避免了维护难题。

3. 反射式红外传感器 感知层

数字 GPIO 接口(PB0),TIM2 定时器每 10ms 采样一次。传感器固定在植株前方,检测叶片是否遮挡红外反射光 → 间接反映植株生长高度变化。配合干净对照土与污染土的对比实验,验证重金属对植物生长的抑制效应。

4. 0.96寸 OLED 显示屏 显示层

SSD1306 驱动芯片,128×64 分辨率,I2C 接口(PB6 SCL, PB7 SDA),地址 0x3C。三页面可切换:监测页(pH/EC/CPI)、植物页(红外状态/株高)、数据页(运行时间/记录数)。1Hz 刷新频率。

5. CH340 USB 转串口模块 通信层

USB 转 TTL 串口芯片,连接 STM32 PA9(TX)/PA10(RX),115200 bps 速率传输传感器数据。配合浏览器 Web Serial API,无需安装任何驱动,Chrome/Edge 浏览器直接读取串口数据,实现真正的"零安装"体验。

6. LED 三级指示 + 蜂鸣器报警 人机交互

三级 LED(PB12 绿 / PB13 黄 / PB14 红)配合有源蜂鸣器(PB1)实现四级污染报警:CPI<0.3 绿灯无蜂鸣;0.3~0.6 黄灯间歇蜂鸣;0.6~1.0 红灯急促蜂鸣;>1.0 红灯闪烁+持续蜂鸣。

🔌 引脚接线表

STM32 引脚连接外设类型说明
PA0蓝色电位器ADC1_IN0pH 值模拟输入 (6.5~9.5)
PA1TDS 电导率探头ADC1_IN1电导率模拟采样,12位分辨率
PA2热敏电阻ADC1_IN2土壤温度采集 (温度补偿用)
PA3光敏电阻传感器ADC1_IN3植物叶色监测 (透光率变化)
PA9CH340 RXUSART1_TX串口发送传感器数据 (115200bps)
PA10CH340 TXUSART1_RX串口接收 (备用)
PB0反射式红外传感器GPIO Input株高/叶片遮挡检测,TIM2 10ms 采样
PB1有源蜂鸣器GPIO Output超标报警 (四级:无/间歇/急促/持续)
PB6OLED SCLI2C1_SCLSSD1306 OLED 时钟线
PB7OLED SDAI2C1_SDASSD1306 OLED 数据线
PB10按键 K1GPIO Input (IPU)短按:切换 OLED 页面 (监测/植物/数据)
PB11按键 K2GPIO Input (IPU)串口导出历史数据
PB12LED 绿色GPIO Output正常状态指示 (CPI < 0.3)
PB13LED 黄色GPIO Output轻度污染指示 (CPI 0.3~0.6)
PB14LED 红色GPIO Output中/重度污染指示 (CPI > 0.6)
PA13ST-LINK SWDIOSWD程序下载/调试数据线
PA14ST-LINK SWCLKSWD程序下载/调试时钟线

⚙ 系统工作流程

STM32 上电复位
    ↓
初始化 时钟(72MHz) / GPIO / ADC1 / I2C1 / USART1 / TIM2 / NVIC
    ↓
OLED 显示启动画面 (CornMonitor Ready)
    ↓
┌─────────────────────────────────────────────────┐
│              主循环 (10Hz = 100ms)                │
│                                                  │
│  ┌─ ADC 轮询 ──────────────────────────────┐    │
│  │ PA0→pH(4次均值)  PA1→EC(4次均值)         │    │
│  │ PA2→温度         PA3→光敏               │    │
│  └──────────────────────────────────────────┘    │
│                    ↓                              │
│  ┌─ 算法计算 ──────────────────────────────┐    │
│  │ CPI = 0.5×|pH-6.8|/6.8 + 0.5×EC/150   │    │
│  │ 四级分类 → LED + 蜂鸣器控制              │    │
│  └──────────────────────────────────────────┘    │
│                    ↓                              │
│  ┌─ 输出 ──────────────────────────────────┐    │
│  │ OLED 刷新 (1Hz)                          │    │
│  │ 串口输出: [ts] pH=xxx EC=xxx (1Hz)      │    │
│  │ W25Q Flash 存储 (每10秒)                 │    │
│  └──────────────────────────────────────────┘    │
│                    ↓                              │
│           CH340 → 电脑 USB                         │
│                    ↓                              │
│     浏览器 Web Serial API → 实时显示              │
└─────────────────────────────────────────────────┘
    

时序控制

SysTick 毫秒定时器 — 主循环用 TIM2 定时器中断产生 10ms 基准(100Hz),g_tick 全局计数器提供毫秒级时间戳。ADC 采集 100Hz(每 10ms 读一次),CPI 计算和串口输出降频到 1Hz(每 1000ms 一次),OLED 刷新 1Hz。

🧠 软件系统设计

状态机设计

🟢

初始化 (INIT)

HSE 8MHz→PLL×9→72MHz
GPIO / ADC1 / I2C1 / USART1 / TIM2 / NVIC 初始化
SSD1306 OLED 上电自检
TDS 传感器预热 3 秒

🔵

采集 (ACQUIRING)

每 100ms 读 ADC 四通道(4次均值)
每 1s 计算 CPI + 更新 OLED
每 1s 串口输出数据行
每 10s W25Q Flash 存储

🟡

故障 (ERROR)

TDS 超量程 (>1000 μS/cm) → 告警
OLED 显示 "ERR" 闪烁
串口持续发送最后有效数据
LED 红灯快闪

Web Serial API — 浏览器端

浏览器通过 navigator.serial.requestPort() 弹出串口选择器,用户选择 CH340 后开始接收 STM32 数据。JavaScript 正则解析 [N] pH=xxx EC=xxx 格式的文本行,更新仪表盘卡片和 Canvas 趋势图。串口断开后 3 秒自动重连,浏览器不支持时自动降级为手动输入面板。

AI 图像识别 — 服务端

用户上传玉米照片 → Flask /api/analyze 接收 → PIL + NumPy 计算 ExG/GLI/HSV 植被指数 → 四条件级联判定生长阶段 → 返回阶段名称、置信度、植被指数详情 → 前端自动切换 EC 阈值范围。

📡 通信协议详解

STM32 → 浏览器 串口数据格式

串口速率 115200 bps, 8N1,每 1 秒发送一行文本数据:

// 数据格式: [时间戳] pH=pH值 EC=电导率 raw0=ADC0原始值 raw1=ADC1原始值 [123] pH=720 EC=315 raw0=2048 raw1=1536 // pH=720 表示 pH = 7.20 (除以100) // EC=315 表示电导率 = 315 μS/cm // raw0/raw1 为可选字段,用于调试

TDS ADC 采样协议

PA0 引脚 ADC1_IN0,12位分辨率 (0~4095),3.3V 参考电压。连续采样 4 次取平均值消除电源噪声。

电导率换算:EC (μS/cm) = ADC_avg × 3.3 / 4096 × 系数

I2C OLED 通信协议

标准 I2C 协议,SSD1306 驱动芯片,地址 0x3C,速率 100kHz。PB6(SCL) / PB7(SDA) 开漏输出 + 外部 4.7kΩ 上拉电阻。采用 6×8 英文字库进行字符显示。

💻 核心代码模块

STM32 固件 — ADC 轮询读取

/** * ADC1 四通道轮询读取 (每通道 4次取平均) * PA0=pH PA1=EC PA2=温度 PA3=光敏 */ void adc_read(void) { for (int ch = 0; ch < 4; ch++) { u32 sum = 0; ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_55Cycles5); for (int i = 0; i < 4; i++) { ADC_SoftwareStartConvCmd(ADC1, ENABLE); // 软件触发转换 while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)); // 等待完成 sum += ADC_GetConversionValue(ADC1); // 读 12bit 值 } g_adc[ch] = sum / 4; // 均值滤波 } }

STM32 固件 — CPI 综合污染指数

float calc_cpi(float pH, u16 ec) { float pH_part = fabs(pH - 6.8) / 6.8; float ec_part = ec / 150.0; // EC_clean = 150 μS/cm return 0.5 * pH_part + 0.5 * ec_part; } // 四级污染判定 if (cpi < 0.3) { led_green(); buzzer_off(); } // 正常 else if (cpi < 0.6) { led_yellow(); buzzer_slow(); } // 轻度 else if (cpi < 1.0) { led_red(); buzzer_fast(); } // 中度 else { led_flash(); buzzer_cont(); } // 重度

STM32 固件 — 主循环 + 串口输出

int main(void) { cfg_clock(); // HSE 8MHz → PLL ×9 → 72MHz cfg_gpio(); // PA0/1 AIN, PA9/10 AF_PP, PB6/7 AF_OD, etc. cfg_adc(); // ADC1 独立模式, ExternalTrigConv=None (关键!) cfg_usart(); // USART1 115200-8N1 cfg_i2c(); // I2C1 100KHz, SSD1306 OLED cfg_tim2(); // TIM2 100Hz (7200-1 / 100-1) cfg_nvic(); // DMA + TIM2 中断优先级 while (1) { if (g_tick % 10 == 0) { // 100Hz: ADC 采集 adc_read(); } if (g_tick % 100 == 0) { // 10Hz: 算法计算 float ph = g_adc[0] * 14.0 / 4096; u16 ec = g_adc[1] * 1000 / 4096; float cpi = calc_cpi(ph, ec); } if (g_tick % 1000 == 0) { // 1Hz: OLED + 串口输出 oled_show(ph, ec, cpi); uart_send("["); uart_num(g_tick/1000); uart_send("] pH="); uart_num((int)(ph*100)); uart_send(" EC="); uart_num(ec); uart_send("\r\n"); // 输出示例: [60] pH=720 EC=315 } } }

Python Flask — AI 图像识别后端

def analyze_corn_stage(image_bytes): """PIL + numpy 植被指数分析, 无外部模型依赖""" from PIL import Image import numpy as np img = Image.open(io.BytesIO(image_bytes))\ .convert('RGB').resize((400, 400)) arr = np.array(img, dtype=np.float32) r, g, b = arr[:,:,0], arr[:,:,1], arr[:,:,2] # ExG 植被指数 (Woebbecke 1995) exg = np.clip(2.0*g - r - b, -255, 255) exg_mean = float(np.mean(exg)) # GLI 绿叶指数 (Gitelson 2002) denominator = 2.0*g + r + b + 1e-6 gli = (2.0*g - r - b) / denominator gli_mean = float(np.mean(gli)) # 植被覆盖度 veg_cover = float(np.mean(exg > 20)) * 100 # HSV 色彩分割: 绿色 H[40,150] / 黄色 H[10,50] hsv = np.array(Image.fromarray( np.clip(arr,0,255).astype(np.uint8) ).convert('HSV'), dtype=np.float32) h, s, v = hsv[:,:,0], hsv[:,:,1]/255, hsv[:,:,2]/255 green_h_pct = float(np.mean((h>40)&(h<150)&(s>0.15))) * 100 yellow_h_pct = float(np.mean((h>10)&(h<50)&(s>0.08)&(s<0.6))) * 100 soil_pct = float(np.mean((s<0.2)&(v<0.5))) * 100 # 纹理分析: 20px patch 局部标准差 (Meyer & Neto 2008) tex_map = np.zeros_like(gli) for y in range(0, 400, 20): for x in range(0, 400, 20): yy, xx = slice(y,min(y+20,400)), slice(x,min(x+20,400)) tex_map[yy, xx] = np.std(exg[yy, xx]) tex_mean = float(np.mean(tex_map)) # 四阶段级联判定 yg_ratio = yellow_h_pct / (green_h_pct + 1e-6) if yellow_h_pct > 10 and yg_ratio > 0.28 and green_h_pct < 55: stage, conf = 4, 70 + min(20, int(yg_ratio*50)) // 腊熟期 elif veg_cover > 40 and yellow_h_pct > 8: stage, conf = 3, 60 + min(30, int(yellow_h_pct*3)) // 开花期 elif veg_cover < 28 and soil_pct > 22: stage, conf = 1, 60 + min(25, int(soil_pct/2)) // 三叶期 elif veg_cover > 35 and exg_mean > 15: stage, conf = 2, 60 + min(30, int((veg_cover-35)/2)) // 抽雄期 else: stage, conf = 2, 50 return {"stage": stage, "name": STAGES[stage]["name"], "confidence": min(95, max(50, conf)), "veg_cover": round(veg_cover,1), "method": "ExG+GLI+HSV"}

JavaScript — Web Serial API 串口读取

async function connectSerial() { const port = await navigator.serial.requestPort(); await port.open({ baudRate: 115200 }); const reader = port.readable.getReader(); let buffer = ''; while (true) { const { value, done } = await reader.read(); if (done) break; buffer += new TextDecoder().decode(value); // 按行分割数据 const lines = buffer.split('\n'); buffer = lines.pop(); // 保留不完整行 for (const line of lines) { const m = line.match(/\[(\d+)\]\s+pH=(\d+)\s+EC=(\d+)/); if (m) { const data = { ts: parseInt(m[1]), ph: parseInt(m[2]) / 100, // 还原为 7.20 ec: parseInt(m[3]) // 电导率 μS/cm }; renderData(data); // 更新仪表盘 } } } }

🧠 AI 识别算法

采用纯图像处理方案(植被指数法),无深度学习依赖,无需 GPU,PIL + NumPy 即可运行。所有算法均有农学/遥感文献支撑。

算法一览

技术公式文献来源用途
ExG 超绿指数2G - R - BWoebbecke et al. (1995)
Trans. ASAE, 被引 1000+
区分植被与土壤背景
GLI 绿叶指数(2G-R-B)/(2G+R+B)Gitelson et al. (2002)
Remote Sens. Environ., 被引 900+
量化绿色覆盖度
HSV 色彩分割H∈[40,150] 绿
H∈[10,50] 黄
标准计算机视觉鲜绿叶片 vs 衰老黄叶
纹理 局部标准差std(ExG, 20px)Meyer & Neto (2008)
Comput. Electron. Agric.
苗期土壤(简单) vs 拔节叶片(复杂)

四阶段判定规则

判定优先级 (级联, 从上到下):

① 腊熟期: yellow_pct > 10% 且 黄绿比 > 0.28 且 green_pct < 55%
    ↳ 特征: 叶片大量变黄, 绿色占比下降

② 开花期: veg_cover > 40% 且 yellow_pct > 8%
    ↳ 特征: 雄穗开花, 植被茂密, 开始出现黄色花粉

③ 三叶期: veg_cover < 28% 且 soil_pct > 22%
    ↳ 特征: 幼苗阶段, 裸土面积大, 绿色覆盖小

④ 抽雄期: veg_cover > 35% 且 ExG > 15
    ↳ 特征: 茎秆伸长, 植被覆盖增加, 超绿指数高

默认: 抽雄期 (置信度 50%)

⚡ 为什么不用 YOLO/CNN 深度学习?

  • 零外部依赖 — 无需 PyTorch/TensorFlow/GPU,PIL + NumPy 已够
  • 农学文献支撑 — ExG (Woebbecke 1995)、GLI (Gitelson 2002) 均为经典植被指数
  • 测试集准确率 4/4 (100%) — 四阶段测试样本全部正确识别
  • 适合初中场景 — 算法可解释性强,学生能理解每个判定步骤

四阶段 EC 阈值与微量元素需求

阶段图标国际对应EC 阈值 (μS/cm)微量元素需求
三叶期🌱VE ~ V6100 ~ 300Zn / Fe → 根系发育
抽雄期🌿V7 ~ VT250 ~ 500N / K → 茎叶生长
开花期🌼R1 ~ R2280 ~ 550B / Zn → 花粉活力
腊熟期🌽R3 ~ R6250 ~ 500K / P → 籽粒饱满

依据: Ritchie et al. (1997) How a Corn Plant Develops (ISU) | Marschner (2012) Mineral Nutrition of Higher Plants | 农业部 (2013) 中国玉米施肥指南

🛡 数据质量保障

🔢 ADC 多次采样均值

每通道连续采样 4 次取平均值,消除电源纹波和随机噪声干扰。

🌡 温度补偿算法

EC₂₅ = EC_t / (1 + 0.02×(t-25)),ISO 7888:1985 标准公式,消除温度对电导率的影响。

🔄 串口自动重连

串口断开后 3 秒间隔自动重连,无需人工干预。STM32 重新上电也能自动恢复。

📋 COM 口智能扫描

自动扫描所有 COM 口,优先匹配 CH340 设备,读取数据验证格式后锁定端口。

✅ 正则校验过滤

仅解析匹配 [N] pH=xxx EC=xxx 格式的数据行,忽略噪声和乱码。

📱 手动输入降级

浏览器不支持 Web Serial API 时自动显示手动输入面板,保证所有场景可用。

⚡ 技术亮点

🌐 Web Serial API — 浏览器原生串口通信

替代传统 pyserial + PyInstaller EXE 方案(39MB 下载、杀毒误报、驱动兼容性问题)。浏览器直读 CH340 串口,零驱动、零安装、打开网页就能用。串口解析逻辑全部放在前端 JavaScript,后端仅保留 AI 分析 API。

🧠 纯图像处理 AI — 无模型依赖

基于 Woebbecke (1995) ExG 超绿指数 + Gitelson (2002) GLI 绿叶指数 + HSV 色彩分割 + Meyer (2008) 纹理分析,四项农学文献支撑的植被指数级联判定玉米四阶段。仅需 PIL + NumPy,无需 PyTorch/GPU。

📊 四阶段动态 EC 阈值

AI 识别玉米生长阶段后自动切换 EC 阈值范围(三叶期 100~300 / 抽雄期 250~500 / 开花期 280~550 / 腊熟期 250~500),实现"识别什么阶段 → 匹配什么标准"的智能比对。

🔬 CPI 综合污染指数

独创的综合评分体系 CPI = 0.5×|pH-6.8|/6.8 + 0.5×EC/150,将 pH 偏离度和电导率归一化为 0~1+ 的单值指数,四级分类(正常/轻度/中度/重度)驱动 LED + 蜂鸣器硬件报警。

📚 19 篇权威参考文献

覆盖 HJ 802-2016 国家标准、ISO 7888:1985 国际标准、USEPA Method 120.1、Ritchie 玉米阶段经典文献、Marschner 植物营养学权威著作——每个算法选择都有明确学术依据

📋 软件基础设置信息

STM32 IDEKeil MDK v5 (uVision V5.06)
编译器ARMCC V5.06 update 5 (build 528)
主控芯片STM32F103C8T6 (Cortex-M3, 64KB Flash, 20KB SRAM)
时钟HSE 8MHz → PLL ×9 → 72MHz
标准库STM32F10x Standard Peripheral Library V3.5.0
C 语言标准C99 (--c99)
MicroLIB已启用(精简 math 库,注意不支持 %f 格式化)
工程定义STM32F10X_MD, USE_STDPERIPH_DRIVER
启动文件startup_stm32f10x_md.s (中等密度)
编程器ST-LINK/V2 (SWD 接口)
后端语言Python 3.10+
前端语言JavaScript ES6+ (Web Serial API)
核心依赖Flask 3.x, Pillow, NumPy, Web Serial API
AI 方案ExG + GLI + HSV 植被指数 (纯 NumPy 实现,无外部模型)
传感器采样率STM32 端 ADC 100Hz, 串口输出 1Hz, 浏览器端 1Hz 刷新
串口速率115200 bps, 8N1, 文本行协议
部署架构Windows Server + Ubuntu 22.04 nginx HTTPS 反向代理

🌍 部署架构

用户 Chrome/Edge
    │
    ▼
https://cdqtech.online/corn-monitor/
    │
    ▼
┌─────────────────────────────────────────┐
│  Ubuntu 22.04 (124.221.224.40)          │
│  nginx + Let's Encrypt SSL              │
│  location /corn-monitor/ {              │
│      proxy_pass http://111.229.185.164:5022/; │
│  }                                      │
└────────────┬────────────────────────────┘
             │ HTTP (内网)
             ▼
┌─────────────────────────────────────────┐
│  Windows Server (111.229.185.164)       │
│  Python Flask web_server.py :5022       │
│                                          │
│  GET  /            → 仪表盘 HTML         │
│  GET  /tech        → 技术文档 (本页)     │
│  POST /api/analyze → AI 图像识别        │
│  GET  /api/health  → 健康检查           │
└─────────────────────────────────────────┘
             │
             │ Web Serial API (浏览器本地)
             ▼
┌─────────────────────────────────────────┐
│  用户电脑                                │
│  Chrome → navigator.serial → CH340     │
│  → STM32F103C8T6 串口数据              │
└─────────────────────────────────────────┘
    

浏览器通过 HTTPS 加载页面后,Web Serial API 在用户本地电脑直接读取 CH340 串口数据,不经过服务器中转。AI 拍照分析通过 HTTPS POST 发送到 Flask 后端处理。此架构实现了"敏感数据不出本地,AI 计算在服务端"的最佳实践。