CCUS碳捕集沙盘模型控制系统设计:基于STM32与Modbus RTU的碳捕集六段工序时序联动方案
CCUS碳捕集沙盘模型控制系统,涉及吸收塔、再生塔、压缩机、换热器、注入井等多个核心设备的协同控制与动态演示。一套完整的CCUS碳捕集沙盘控制系统,需要同时驱动多段灯带时序演示“烟气进入→吸收→再生→压缩→输送→注入”的完整碳捕集路径,多路信号联动展示正常捕集、检修状态、应急停机等多种工况的一键切换,同时通过不同颜色灯带区分烟气(灰色)、CO₂(蓝色)、封存区(绿色)路径。与双碳沙盘(聚焦碳捕集+零碳园区+综合能源多场景并行)不同,CCUS碳捕集沙盘控制系统的核心是“烟气→吸收→再生→压缩→输送→注入”六段工序的精确时序控制——烟气怎么进、吸收塔怎么控、再生塔怎么切换、压缩怎么走、输送怎么通、注入怎么停,每个环节的控制逻辑必须与实际CCUS工程一致。
本文以已落地的百万吨级CCUS示范工程沙盘模型为案例,梳理CCUS碳捕集沙盘模型控制系统的设计与实现方案,涵盖系统架构、硬件选型、多段灯带时序控制、Modbus RTU寄存器映射及多工况代码实现。
一、CCUS碳捕集沙盘控制系统的技术需求
CCUS碳捕集沙盘的控制系统需求与普通工业沙盘有显著差异:
功能模块 技术要求 实现难度
碳捕集六段时序演示 烟气→吸收→再生→压缩→输送→注入,多段灯带按碳捕集流程时序流动 中高
烟气路径指示 灰色灯带演示烟气从排放源进入吸收塔的路径 中
CO₂路径指示 蓝色灯带演示CO₂从吸收塔→再生塔→压缩→输送的路径 中
封存区指示 绿色灯带演示CO₂注入封存区的路径 中
吸收塔/再生塔温区指示 不同颜色灯带区分吸收塔和再生塔的温度分区(高温/中温/低温) 中
多工况一键切换 正常捕集/检修状态/应急停机,三种工况模式切换 高
故障模拟 模拟吸收塔温度异常、压缩机停机等故障状态 中
基于上述需求,采用STM32+Modbus RTU架构。
二、为什么CCUS碳捕集沙盘采用STM32+Modbus RTU方案
CCUS碳捕集沙盘的控制系统有几个特殊要求:
第一,六段工序时序联动的精度要求高。 各工序之间的衔接延时需精确控制,模拟真实碳捕集过程的节奏。STM32的中断响应精度可达1ms级,配合状态机编程可实现精确的多段时序控制。
第二,多路灯带独立控制的复杂度高。 需要同时控制灰色(烟气)、蓝色(CO₂)、绿色(封存区)三条灯带路径,每条灯带的颜色、流速、时序参数完全不同。STM32配合WS2812B可寻址LED灯带可实现多路独立并行控制。
第三,后期修改频繁。 交付后经常需要根据需求调整(如新增“故障模拟”模式、调整各工序的时序参数、修改碳流路径)。STM32方案通过寄存器在线修改参数即可完成调整,无需重编译代码。
STM32 vs PLC 选型对比:
对比项 PLC方案 STM32方案
硬件成本 8000-15000元 800-1500元
时序控制精度 10-20ms扫描周期 1ms中断响应
多路灯带独立控制 需专用通讯模块 单总线直接驱动
多工况切换逻辑 梯形图实现困难 C语言状态机灵活可控
后期修改 需编程软件授权 寄存器在线修改
为什么用RS485/Modbus RTU:
沙盘模型内部设备分布广泛(烟气区、吸收区、再生区、压缩区、输送区、封存区等),RS485总线支持多点通讯(理论32个节点),一线串接所有设备,布线简洁。Modbus RTU是工业标准协议,支持接入触摸屏、中控平板等第三方设备。
三、系统架构设计
3.1 总体架构
text
┌─────────────────────────────────────────────────────────────────┐
│ 触摸屏/中控平板(Modbus RTU 主站) │
│ 工况切换 速度调节 工序控制 模式切换 │
└─────────────────────────┬───────────────────────────────────────┘
│ RS485(9600,8N1,120Ω终端电阻)
┌─────────────────────────▼───────────────────────────────────────┐
│ STM32F103RCT6 从站 │
│ 指令解析 → 状态机调度 → GPIO/PWM/单总线输出 │
└───────┬─────────┬─────────┬─────────┬─────────┬─────────────────┘
│ │ │ │ │
┌───▼───┐ ┌───▼───┐ ┌───▼───┐ ┌───▼───┐ ┌───▼───┐
│烟气 │ │吸收 │ │再生 │ │压缩 │ │注入 │
│路径 │ │塔灯带 │ │塔灯带 │ │段灯带 │ │段灯带 │
│灯带 │ │ │ │ │ │ │ │ │
└───────┘ └───────┘ └───────┘ └───────┘ └───────┘
3.2 硬件选型
组件 选型 选型理由
主控MCU STM32F103RCT6 256KB Flash,51个GPIO,3个USART
通讯接口 MAX485ESA RS485收发器,工业级抗干扰
灯带 WS2812B(60灯/米) 单总线控制,每灯独立寻址
中控屏 7寸串口屏 支持Modbus RTU主站协议
3.3 GPIO分配表
端口 功能 信号类型 说明
PA9/PA10 USART1 通讯 与中控屏RS485通讯
PB0 烟气路径灯带 单总线输出 WS2812B(灰色)
PB1 吸收塔灯带 单总线输出 WS2812B
PB2 再生塔灯带 单总线输出 WS2812B
PB3 压缩段灯带 单总线输出 WS2812B
PB4 输送段灯带 单总线输出 WS2812B
PB5 注入段灯带 单总线输出 WS2812B(绿色)
四、Modbus寄存器映射设计
以下为CCUS碳捕集沙盘控制系统的寄存器定义(共32个保持寄存器):
4.1 系统控制寄存器(40001-40007)
寄存器地址 偏移地址 功能 数据类型 读写 取值范围 说明
40001 0x0000 系统启停 bit R/W 0/1 0=停止,1=启动
40002 0x0001 运行工况 uint16 R/W 1-3 1=正常捕集,2=检修状态,3=应急停机
40003 0x0002 当前工序 uint16 R 0-6 0=停止,1=烟气,2=吸收,3=再生,4=压缩,5=输送,6=注入
40004 0x0003 速度档位 uint16 R/W 1-5 档位越高,碳捕集节奏越快
40005 0x0004 循环模式 uint16 R/W 0/1 0=单次,1=无限循环
40006 0x0005 系统状态 uint16 R 0-3 0=停止,1=运行中,2=告警,3=故障
40007 0x0006 故障代码 uint16 R 0-99 0=无故障
4.2 灯带与参数寄存器(40008-40017)
寄存器地址 偏移地址 功能 数据类型 读写 说明
40008 0x0007 烟气路径灯带 bit R/W 1=点亮(灰色)
40009 0x0008 吸收塔灯带 bit R/W 1=点亮
40010 0x0009 再生塔灯带 bit R/W 1=点亮
40011 0x000A 吸收塔温度分区 uint16 R/W 1=红(高温),2=橙(中温),3=黄(低温)
40012 0x000B 再生塔温度分区 uint16 R/W 1=红(高温),2=橙(中温),3=黄(低温)
40013 0x000C 压缩段灯带 bit R/W 1=点亮
40014 0x000D 输送段灯带 bit R/W 1=点亮
40015 0x000E 注入段灯带 bit R/W 1=点亮(绿色)
40016 0x000F 碳流流速 uint16 R/W 1-100,灯带流动速度
40017 0x0010 工序间延时 uint16 R/W ms,工序切换间隔
五、核心代码实现
5.1 Modbus从站初始化
cpp
#include “ModbusRTU.h”
#include “Adafruit_NeoPixel.h”
#define SLAVE_ID 1
#define BAUD_RATE 9600
// 灯带GPIO定义
#define LED_FLUE_GAS PB0
#define LED_ABSORBER PB1
#define LED_REGENERATOR PB2
#define LED_COMPRESSOR PB3
#define LED_TRANSPORT PB4
#define LED_INJECTION PB5
#define STAGE_NUM 6
ModbusRTU mb;
uint16_t holdingRegs[32] = {0};
uint16_t stageDurations[STAGE_NUM] = {3000, 4000, 5000, 3000, 3000, 2000};
uint16_t baseDurations[STAGE_NUM] = {3000, 4000, 5000, 3000, 3000, 2000};
enum SystemState { STOPPED, RUNNING, PAUSED, FAULT };
SystemState currentState = STOPPED;
volatile uint8_t currentStage = 0;
volatile uint16_t stageElapsedMs = 0;
Adafruit_NeoPixel strips[6] = {
Adafruit_NeoPixel(40, LED_FLUE_GAS, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(50, LED_ABSORBER, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(50, LED_REGENERATOR, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(30, LED_COMPRESSOR, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(40, LED_TRANSPORT, NEO_GRB + NEO_KHZ800),
Adafruit_NeoPixel(30, LED_INJECTION, NEO_GRB + NEO_KHZ800)
};
void setup() {
SystemClock_Config();
Serial1.begin(BAUD_RATE);
mb.begin(&Serial1);
mb.slave(SLAVE_ID);
mb.addHreg(0, holdingRegs, 32);
mb.onGet(handleRead); mb.onSet(handleWrite); for (int i = 0; i < 6; i++) { strips[i].begin(); strips[i].show(); } Timer1.initialize(1000); Timer1.attachInterrupt(stateMachineTick);}
void loop() {
mb.task();
}
5.2 工序切换与工况控制
cpp
void switchStage(uint8_t stage) {
allLightsOff();
uint32_t colors[STAGE_NUM] = { 0x888888, // 烟气(灰色) 0xCC6633, // 吸收塔(橙褐色) 0xFF6600, // 再生塔(橙色) 0x0066FF, // 压缩段(蓝色) 0x0044CC, // 输送段(深蓝) 0x00FF66 // 注入段(绿色) }; flowLight(strips[stage], colors[stage], stageDurations[stage] / 3);}
void switchMode(uint16_t mode) {
allLightsOff();
switch(mode) { case 1: // 正常捕集 currentState = RUNNING; currentStage = 0; stageElapsedMs = 0; for (int i = 0; i < STAGE_NUM; i++) { switchStage(i); delay(stageDurations[i]); } holdingRegs[5] = 1; break; case 2: // 检修状态 flowLight(strips[1], 0x886633, 800); flowLight(strips[2], 0x886633, 800); for (int i = 0; i < 5; i++) { strips[1].clear(); strips[2].clear(); for (int p = 0; p < strips[1].numPixels(); p++) { strips[1].setPixelColor(p, (i % 2 == 0) ? 0xFFFF00 : 0x000000); strips[2].setPixelColor(p, (i % 2 == 0) ? 0xFFFF00 : 0x000000); } strips[1].show(); strips[2].show(); delay(300); } holdingRegs[5] = 2; break; case 3: // 应急停机 currentState = STOPPED; allLightsOff(); for (int i = 0; i < 5; i++) { for (int j = 0; j < 6; j++) { strips[j].clear(); for (int p = 0; p < strips[j].numPixels(); p++) { strips[j].setPixelColor(p, (i % 2 == 0) ? 0xFF0000 : 0x000000); } strips[j].show(); } delay(200); } holdingRegs[5] = 3; holdingRegs[6] = 1; break; }}
void flowLight(Adafruit_NeoPixel &strip, uint32_t color, int duration) {
int len = strip.numPixels();
int steps = 20;
for (int step = 0; step < steps; step++) {
strip.clear();
int pos = (len * step) / steps;
strip.setPixelColor(pos, color);
if (pos > 0) strip.setPixelColor(pos - 1, color);
strip.show();
delay(duration / steps);
}
}
void allLightsOff() {
for (int i = 0; i < 6; i++) {
strips[i].clear();
strips[i].show();
}
}
5.3 寄存器读写回调
cpp
uint16_t handleRead(uint16_t offset, uint8_t index) {
return holdingRegs[offset];
}
void handleWrite(uint16_t offset, uint8_t index, uint16_t value) {
switch(offset) {
case 0:
if (value == 1 && currentState != RUNNING) {
switchMode(holdingRegs[1]);
currentState = RUNNING;
} else if (value == 0) {
currentState = STOPPED;
allLightsOff();
holdingRegs[2] = 0;
holdingRegs[5] = 0;
}
break;
case 1: holdingRegs[1] = value; if (holdingRegs[0] == 1) switchMode(value); break; case 3: if (value >= 1 && value <= 5) { for (int i = 0; i < STAGE_NUM; i++) { stageDurations[i] = baseDurations[i] / value; } } break; case 10: { uint32_t tempColor = (value == 1) ? 0xFF0000 : (value == 2) ? 0xFF6600 : 0xFFFF00; for (int p = 0; p < strips[1].numPixels(); p++) { strips[1].setPixelColor(p, tempColor); } strips[1].show(); holdingRegs[10] = value; break; } case 11: { uint32_t tempColor2 = (value == 1) ? 0xFF0000 : (value == 2) ? 0xFF6600 : 0xFFFF00; for (int p = 0; p < strips[2].numPixels(); p++) { strips[2].setPixelColor(p, tempColor2); } strips[2].show(); holdingRegs[11] = value; break; } default: holdingRegs[offset] = value; break; } holdingRegs[offset] = value;}
六、关键技术细节
6.1 六段工序状态机设计
CCUS碳捕集沙盘的核心价值在于“烟气→吸收→再生→压缩→输送→注入”六段工序的串联联动:
烟气段:灰色灯带,展示烟气进入吸收塔的路径
吸收段:橙褐色灯带,展示CO₂在吸收塔中被捕获的过程
再生段:橙色灯带,展示CO₂从吸收剂中再生的过程
压缩段:蓝色灯带,展示CO₂被压缩的过程
输送段:深蓝灯带,展示CO₂管道输送的过程
注入段:绿色灯带,展示CO₂注入封存区的过程
各工序之间通过时序计数器触发切换,工序间延时通过寄存器独立调节。
6.2 吸收塔/再生塔温度分区指示
通过寄存器可分别控制吸收塔和再生塔的温度分区指示:
红色:高温运行状态
橙色:中温运行状态
黄色:低温运行状态
七、现场调试要点
现象 排查方向 解决方案
灯带全亮白光 数据线虚接 重新焊接,确认GPIO输出电平
颜色偏色 电源电压不足 测量末端电压,<4.8V需增加供电点
首灯正常后续不亮 MCU主频配置不当 确认系统时钟72MHz
温度分区颜色不变化 寄存器写入失败 检查Modbus通讯
八、总结
CCUS碳捕集沙盘模型控制系统的设计,核心在于三个层面:
六段工序时序联动是核心。 采用状态机编程,将各工序定义为独立状态,各工序之间通过时序计数器触发切换,工序间延时独立可调。
多路灯带独立控制是基础。 六路信号需要精确联动,实现“烟气进、CO₂走、封存绿”的完整演示效果。
控制系统自主可控是保障。 通过Modbus寄存器在线修改参数即可完成调整,无需依赖外部支持。
