PocketPCR简介
- PocketPCR 是由 GaudiLabs 发起的一个开源项目,旨在提供一种 袖珍型、低成本、USB供电的 PCR 热循环仪(Thermal Cycler)。它允许生物实验者在桌面或野外环境中进行基础的 DNA 扩增实验。

PocketPCR 结构展示




硬件部分
加热头部分

PCB
BOM
设计ator | 数量 | 名称 | 封装 | 订货号 |
---|
U2 | 1 | SAMD21G18B-A(改自 SAML21) | TQFP-48 7×7mm, 0.5mm 间距 | 556-ATSAMD21G18A-AUT |
U1 | 1 | TLV1117-33 稳压器 | SOT-223 | 595-TLV1117LV33DCYR |
Y1 | 1 | 晶振 32.765 kHz | SMD_3215-2pin_3.2x1.5mm | 520-ECS-327-12.5-34B / 449-LFXTAL009678REEL |
NTC | 1 | 热敏电阻 10K 0.5% 0402 | 0402 | 810-NTCG103JX103DTDS |
设计ator | 数量 | 名称 | 封装/说明 | 订货号 |
---|
S1 | 1 | OLED 显示连接器 | - | 649-SFV30R-1STE1HLF |
S1 | 1 | OLED 显示屏 | OLED_096_1_Flip | - |
J3 | 1 | USB Type-C 插座 | Amphenol_12401610E4-2A | 523-12401610E4#2A |
J1 | 1 | 2 针接头 | 1x02 PinHeader | - |
J2 | 0 | 调试接头(未装) | 2x5, SMD, 1.27mm | - |
设计ator | 数量 | 名称 | 封装 | 订货号 |
---|
Q1, Q2, Q3 | 3 | N-MOS 管(GSD) | SOT-23 | 863-NTR3C21NZT1G |
LED1, LED2 | 2 | 指示灯 | 0805 | - |
设计ator | 数量 | 值 | 封装 | 订货号 |
---|
C3 | 1 | 100uF, 6.3V | 1206 | JMK316ABJ107ML-T |
C2, C5 | 2 | 10uF, 6.3V | 1206 | JMK107ABJ106MA-T |
C1, C4, C12, C14, C16 | 5 | 1uF | 0805 | 810-C2012X7R1C105M-3 / 603-CC805KKX7R7BB105 |
C6–C9 | 4 | 100nF | 0805 | - |
C10, C11 | 2 | 22pF | 0805 | - |
C15, C17 | 2 | 2.2uF | 0805 | 603-CC805KKX7R7BB225 |
R1, R9, R10 | 3 | 4.7kΩ | 0805 | - |
R2, R3 | 2 | 390Ω | 0805 | - |
R5, R7 | 2 | 390kΩ | 0805 | - |
R4, R6 | 2 | 4.7kΩ, 0.1% 精度 | - | 279-CPF0805B4K7E1 |
名称 | 数量 | 说明 / 参数 | 订货号 |
---|
Blower 风扇 | 1 | 30×30×10mm, 5V, 2Pin | 3010 fan |
Heat Block | 1 | Ø19.5mm, 铝合金 6082 | - |
Spring 弹簧 | 1 | 线径 0.4mm / 长度 5mm 或 0.3mm / 10mm | - |
Feets 脚垫 | 4 | 硅胶脚塞,适配 6.5mm+ | MAKSEY Silicone Caps |
Screw M3x6mm | 2 | 黑色十字盘头螺钉 DIN 7985 | - |
Screw M3x16mm | 4 | 黑色十字盘头螺钉 DIN 7985 | - |
Plastic Screw | 2 | M3 白色尼龙或黑色手拧螺钉 | - |
X1, X2 | 2+2 | 六角金属柱,10mm + 20mm, M3 | VT DI 10MM / VT DI 20MM |
名称 | 数量 | 封装 | 订货号 | |
---|
SW1 | 1 | 带按压开关的旋转编码器 | Alps EC11E | 858-EN11-HSB1AQ15 |
Encoder Cap | 1 | 旋钮帽,6mm 轴用 | 套件/批量购买 | |
Rotary Encoder Spring | 1 | 与编码器弹力回弹配合 | - | |
名称 | 数量 | 材质 / 特性 |
---|
PCB1 | 1 | TopHeater 铝基板,导热率 2W,黑色,1.6mm |
PCB2 | 1 | 主控 PCB,FR4 黑色,1.6mm |
PCB3 | 1 | 盖子 PCB,FR4 白色,1.2mm |
名称 | 数量 | 描述 | 型号 |
---|
Beutel ESD 袋 | 1 | ESD 屏蔽袋 76×127 mm,可重复封口 | ESD BEUTEL-S 127 |
CODE
- 这段
loop()
是整个 PocketPCR 热循环控制程序的核心,负责读取传感器、处理界面交互、控制温度状态转换、执行 PID 控制逻辑,并呈现不同的用户界面(主界面、设置界面、运行状态界面等)。整个状态流严格控制 PCR 各个阶段:变性、退火、延伸,并且支持用户自定义每个阶段的时间和温度。
void loop() {
setHeater(0, 0);
sensorValue = analogRead(analogInPin);
setHeater(temperature_mean, TEMPcontrol);
sensorVoltage = 3.3 * sensorValue / 4096;
sensorResistance = (sensorVoltage * NTC_R0) / (3.3 - sensorVoltage);
temperature = 1 / (log(sensorResistance * 1000 / NTC_RN) / NTC_B + 1 / NTC_TN) - 273.15;
temperature_mean = (temperature_mean * 3 + temperature) / 4;
switch (caseUX) {
case CASE_Main:
if (counter > 1) counter = 0;
if (counter < 0) counter = 1;
MenuItem = counter;
draw_main_display();
if (!digitalRead(butPin)) {
while (!digitalRead(butPin));
if (MenuItem == 0) {
caseUX = CASE_Run;
casePCR = PCR_set;
PCRstate = 0;
counter = 0;
}
if (MenuItem == 1) {
caseUX = CASE_Settings;
counter = 0;
}
}
break;
case CASE_Settings:
if (counter > 12) counter = 0;
if (counter < 0) counter = 12;
MenuItem = counter;
minuteMode = (MenuItem % 2 == 1 && settings.value[MenuItem] > 90);
if (!digitalRead(butPin)) {
while (!digitalRead(butPin));
caseUX = CASE_EditSettings;
counter = minuteMode ? settings.value[MenuItem] / 60 : settings.value[MenuItem];
}
draw_setup_display();
break;
case CASE_EditSettings:
if (MenuItem % 2 == 0) {
if (MenuItem == 10) {
if (counter < 1) counter = 1;
if (counter > 99) counter = 99;
} else {
if (counter < 25) counter = 25;
if (counter > 99) counter = 99;
}
} else {
if (minuteMode) {
if (counter < 2) { minuteMode = false; counter = 90; }
} else {
if (counter > 90) { minuteMode = true; counter = 2; }
if (counter < 0) counter = 0;
}
}
if (MenuItem == 11) {
caseUX = CASE_Main;
my_flash_store.write(settings);
}
if (MenuItem == 12) {
caseUX = CASE_Main;
settings = my_flash_store.read();
}
if (MenuItem < 11) {
settings.value[MenuItem] = minuteMode ? counter * 60 : counter;
}
if (!digitalRead(butPin)) {
while (!digitalRead(butPin));
caseUX = CASE_Settings;
counter = MenuItem;
}
draw_setup_display();
break;
case CASE_Run:
TEMPdif = TEMPset - temperature_mean;
TEMPi += TEMPdif;
if (millis() - TEMPclick > 200) {
TEMPclick = millis();
TEMPd = TEMPdif_a[4] - TEMPdif;
TEMPdif_a[4] = TEMPdif_a[3];
TEMPdif_a[3] = TEMPdif_a[2];
TEMPdif_a[2] = TEMPdif_a[1];
TEMPdif_a[1] = TEMPdif_a[0];
TEMPdif_a[0] = TEMPdif;
}
switch (casePCR) {
case PCR_set:
TEMPset = settings.value[PCRstate * 2];
TIMEcontrol = settings.value[PCRstate * 2 + 1];
PIDIntegration = false;
casePCR = PCR_transition;
break;
case PCR_transition:
runPID();
draw_run_display();
if (abs(TEMPset - temperature_mean) < temperature_tollerance) {
PIDIntegration = true;
TEMPi = 0;
TIMEclick = millis();
casePCR = PCR_time;
}
break;
case PCR_time:
runPID();
TIMEcontrol = settings.value[PCRstate * 2 + 1] - (millis() - TIMEclick) / 1000;
draw_run_display();
if (TIMEcontrol <= 0) {
if (PCRstate == 4) caseUX = CASE_Done;
else if (PCRstate == 3) {
PCRstate = 1;
PCRcycle++;
if (PCRcycle > settings.value[10]) PCRstate = 4;
} else {
PCRstate++;
}
casePCR = PCR_set;
}
break;
default:
break;
}
break;
case CASE_Done:
TEMPcontrol = 0;
setHeater(temperature_mean, TEMPcontrol);
display.clearDisplay();
display.setFont(&FreeSans9pt7b);
display.fillRect(10, 10, 100, 40, 1);
display.setCursor(15, 30);
display.setTextColor(0);
display.println("PCR Done");
display.display();
display.setFont();
if (!digitalRead(butPin)) {
while (!digitalRead(butPin));
caseUX = CASE_Main;
counter = MenuItem;
}
break;
default:
break;
}
}
温度控制原理
- 系统通过 热敏电阻 + PID 算法 + 加热器 + 风扇 实现高精度闭环温控。
控制流程概述
-
温度测量:
- 通过热敏电阻(NTC)采集当前温度(使用
analogRead()
)。 - 使用热敏电阻的阻值换算公式与 B 参数模型将电压转换为温度。
-
设定目标温度:
- 根据当前的 PCR 状态(如变性、退火、延伸等),读取 EEPROM 里保存的目标温度
TEMPset
。
-
误差计算与 PID 控制:
- 计算当前温度与目标温度之间的差值
TEMPdif
。 - 调用
runPID()
函数,根据 PID 算法(比例P + 微分D + 积分I)计算出控制量 TEMPcontrol
。
-
执行加热或冷却:
TEMPcontrol = PIDp * TEMPdif + PIDd * TEMPd + (int)PIDIntegration * PIDi * TEMPi;
PIDp
, PIDi
, PIDd
是比例/积分/微分系数。TEMPdif
:当前目标温度与实际温度差。TEMPi
:积分项(误差累加)。TEMPd
:微分项(温差变化速率)。TEMPcontrol
是一个浮点值,代表“应该加热多少”或“应该冷却多少”。
风扇控制:setHeater(float temperature, float power)
- 风扇配合加热器,实现了主动降温机制,使温控反应速度更快、更加精准,尤其适合 PCR 中快速温变需求(例如从 95°C 降至 55°C)。
if (TEMPcontrol > 0)
{
heatPower = power_heating(temperature, power);
analogWrite(fanPin, 0);
analogWrite(heaterPin, heatPower);
}
else
{
heatPower = power_cooling(temperature, power);
analogWrite(fanPin, heatPower);
analogWrite(heaterPin, 0);
}
- 根据
TEMPcontrol
的正负,决定启用加热器或风扇。 - 调用
power_heating()
/ power_cooling()
计算合适的 PWM 占空比。
情况 | 风扇状态 | 作用说明 |
---|
需要升温(TEMPcontrol > 0 ) | 关闭风扇 | 防止风扇带走热量,集中加热 |
需要降温(TEMPcontrol < 0 ) | 开启风扇 | 加快冷却速率,迅速降温 |
温控关闭(如 PCR 结束) | 风扇关闭 | 节能,系统静止 |
CG