ATTINY10与TP4056打造微型可穿戴发光吊坠:从硬件选型到嵌入式编程全解析
1. 项目概述:当微型单片机遇见个性化饰品
几年前,我开始痴迷于将电子设备“藏”进日常物品里,让科技以一种更诗意、更隐秘的方式存在。可穿戴设备是个绝佳的载体,但市面上的产品要么功能雷同,要么体积庞大。我一直想做一个既是个性化饰品,又内含精巧电子系统的作品。直到我看到那些化学实验室里的小药水瓶,灵感来了——何不做一个会发光、能变色,还能无线充电的迷你药水瓶吊坠?
这个项目的核心挑战非常明确:如何在直径仅10毫米的玻璃瓶内,塞进完整的发光系统、控制电路和电池,并且还要实现便捷的充电。这直接指向了两个关键技术选型: ATTINY10微控制器 和 TP4056充电管理芯片 。ATTINY10可能是市面上最小的可用单片机之一,仅有6个引脚,SOT23-6封装,面积比一粒米还小,但“五脏俱全”,足以驱动一颗智能LED并处理触摸输入。而TP4056则是单节锂电池充电的“国民级”芯片,电路简单可靠,成本极低。将它们组合起来,一个微型、低功耗、可充电的发光核心就诞生了。
整个项目流程可以概括为:首先,设计并制作能塞进瓶底的微型主控PCB;其次,为不可更换的锂电池配备保护板;然后,将电路、电池、LED与环氧树脂一同封装进玻璃瓶,制作成吊坠本体;最后,设计一个兼具充电与状态显示的3D打印支架。这不仅仅是一个手工制作,更是一次在毫米尺度上进行系统集成、电源管理和嵌入式编程的实践,非常适合对微型化电子DIY、可穿戴设备开发感兴趣的朋友。无论你是想学习超小型PCB设计,还是想了解如何安全地为嵌入式项目供电,亦或是单纯想创造一个独一无二的发光饰品,这个项目都能提供一条清晰的路径。
2. 核心硬件选型与设计思路解析
2.1 主控芯片:为什么是ATTINY10?
在可穿戴和微型化项目中,主控芯片的选型几乎是决定性的。常见的Arduino Nano、ESP8266等开发板虽然易用,但体积对于这个药水瓶项目来说无疑是巨无霸。我们需要在极致的体积、足够的性能和可开发性之间找到平衡点。
我最终选择了 ATTINY10 ,主要基于以下几点考量:
- 极致的体积 :SOT23-6封装,尺寸仅为2.9mm x 1.6mm,几乎是贴片元件中的“纳米级”选手,为PCB布局留下了宝贵空间。
- 够用的性能 :虽然只有1KB的Flash和32B的SRAM,但它是一颗真正的、采用AVR内核的微控制器,支持C语言编程,可以通过专门的核心库在Arduino IDE中进行开发。这对于控制一颗WS2812系列的智能LED(如本项目使用的SK6805)和响应一个触摸开关来说,性能绰绰有余。
- 低功耗特性 :它支持多种睡眠模式。在项目中,我试图让它在LED关闭时进入深度睡眠,将功耗降至微安级,虽然最终因触摸唤醒配置问题未能完美实现,但这说明了其潜力。对于电池供电的设备,这是延长续航的关键。
注意 :ATTINY10的开发环境搭建比常规ATmega328P芯片(如Arduino Uno所用)稍显复杂。你需要安装一个名为“ATTiny10Core”的第三方开发板支持包,并使用USBasp等专用编程器进行烧录,无法通过串口直接上传。
2.2 电源与充电方案:TP4056与DW01的黄金组合
对于任何内置锂电池的项目,安全是第一要务。我们既要安全充电,也要防止电池过放损坏。
-
充电管理:TP4056 TP4056是一款线性单节锂离子电池充电管理芯片。它的外围电路极其简单,仅需几个电阻电容即可工作。我选择它的原因:
- 电路简单 :典型应用电路仅需1个编程电阻(设定充电电流)、2个滤波电容和1个状态指示LED。这大大简化了充电支架的PCB设计。
- 充电状态明确 :它有两个开漏输出的状态引脚(
CHRG和STDBY),可以方便地外接LED或像本项目一样,通过光耦将信号传递给主控MCU(ATTINY84)进行读取和显示。 - 成本低廉且易得 :这是最重要的因素之一,在各大电子商城都能以极低的价格购得。
-
电池保护:DW01+FS8205A 锂电池最怕过充、过放和短路。TP4056负责“喂饱”电池,而保护电池安全则是DW01的职责。DW01是一颗锂电池保护IC,配合双MOS管FS8205A使用,构成了标准的保护板电路。
- 过充保护 :当检测到电池电压高于约4.25V-4.35V(可调)时,断开充电回路。
- 过放保护 :当检测到电池电压低于约2.4V-3.0V时,断开放电回路,防止电池深度放电损坏。
- 过流/短路保护 :当放电电流过大或短路时,迅速切断电路。 由于吊坠内的电池将被完全封装,不可更换,加入这套保护电路是 绝对必要 的。我直接从一个廉价的TP4056模块上拆下了这套保护电路,既节省成本又保证了可靠性。
2.3 人机交互与显示:触摸与OLED的取舍
在微型吊坠上,传统的按键开关太占空间。我采用了从 TP223触摸模块 上拆下的触摸芯片。TP223是单键触摸检测芯片,输出高电平或低电平信号,体积小(SOT23-6),灵敏度可通过外部电容调节,非常适合作为隐藏式开关。
对于充电支架,我需要一种方式来直观显示充电状态。最初考虑用LED,但信息量太少。最终我选择了一块 0.42英寸的SSD1306 OLED屏幕 。理由如下:
- 高信息密度 :小小的屏幕可以显示电池图标、充电百分比动画、像素画等丰富内容。
- 低功耗 :OLED是自发光,显示深色内容时功耗极低。
- 接口简单 :使用I2C接口,仅需两根数据线(SCL, SDA)即可驱动,节省ATTINY84的IO口。
光耦(PS2802-4) 在这里起到了关键的电平转换和隔离作用。TP4056的状态引脚输出是相对于电池地的,而ATTINY84和OLED的工作电压是5V(来自USB)。直接用导线连接会导致共地问题,可能干扰充电电路甚至损坏芯片。光耦将充电电路的“状态信号”以光的形式传递到主控侧,实现了电气隔离,安全又可靠。
3. 吊坠本体PCB设计与组装实录
3.1 瓶底开孔与微型PCB布局
项目的第一个物理挑战就是改造玻璃瓶。要在其底部开一个直径10mm的圆孔,用于放入PCB。我使用了皮秒激光,这是一种超高精度的加工工具,能干净地切割玻璃而不产生裂纹。对于没有此类设备的朋友,有几种替代方案:
- 金刚石玻璃钻头 :配合手电钻或台钻,低速、加水冷却钻孔。这是最可行的家用方案,但需要极高的耐心和稳定性,玻璃极易崩裂。
- 线锯或旋转锉 :风险更高,不推荐新手尝试。
- 定制玻璃瓶 :直接寻找瓶底有开口或平底的微型玻璃瓶,这是最省事的办法。
PCB设计是本次项目的精髓。在EasyEDA中,我需要在直径不到10mm的圆形区域内放置ATTINY10、TP223触摸芯片、一个100nF的退耦电容、一个用于设置LED颜色的0603贴片拨码开关,以及两个用于充电连接的裸露焊盘。
- 布局策略 :采用双层板,顶层主要放置芯片和电容,底层放置拨码开关和大部分走线。将充电正负极焊盘设计在板子边缘,方便与充电支架的探针接触。
- 走线挑战 :0603封装的元件已经非常小,走线需要设置为4-6mil(0.1-0.15mm)。必须反复进行DRC(设计规则检查),确保线宽、线距符合PCB制造商(如JLCPCB)的工艺能力。电源线要适当加粗。
- LED连接 :SK6805 LED需要四根线(5V, GND, DIN, DOUT)。为了将其引到瓶塞处,我使用了细漆包线。先在PCB上焊接好线,再将LED端穿过软木塞,最后将线焊到LED引脚上。漆包线柔软且绝缘,非常适合这种内部飞线。
3.2 锂电池保护板的集成与绝缘处理
从TP4056模块上拆下的保护板包含了DW01和FS8205A。我将其焊接在了一块单独雕刻的薄型单面覆铜板上。这里的关键是 绝缘 。
- 整体包裹 :用高温胶带或绝缘麦拉片将整个保护板包裹起来,防止其元件引脚与电池金属外壳或吊坠内部其他金属部件接触导致短路。
- 电池连接 :使用点焊机将镍片焊接到电池电极上,再通过导线连接到保护板。如果没有点焊机, 务必使用低温焊锡快速焊接 ,避免高温烫伤电池内部结构引发危险。焊接后同样要做好绝缘。
- 输出端连接 :保护板的输出端(B+, B-)通过导线连接到主控PCB的电源输入点。
为了增加趣味性,我尝试用激光在电池表面刻上了装饰性图案。 这是一个需要极度谨慎的操作! 必须使用极低的功率进行表面打标,绝不能击穿电池外壳。更安全稳妥的做法是使用定制贴纸。
3.3 环氧树脂封装与最终组装
这是将电子部件转化为艺术品的步骤,也是最容易出错的环节。
- 预处理 :用热熔胶临时密封玻璃瓶底PCB安装孔的边缘缝隙,防止浇筑时树脂泄漏。这层胶后期很容易剥除。
- 固定与布线 :将带保护板的电池、主控PCB放入瓶内。将连接LED的漆包线从软木塞中央预先钻好的小孔中穿出。调整内部元件位置,使其大致居中。
- 混合与浇筑 :
- 按比例精确混合环氧树脂A剂和B剂。我选用了高透明度、低气泡型的树脂。
- 关键技巧 :在树脂中加入少量 天空蓝荧光粉 。这样即使在LED关闭时,吊坠在紫外线或强光照射后也能发出微弱的夜光,效果倍增。
- 沿瓶壁缓慢倒入树脂,避免直接冲击元件产生气泡。倒至接近瓶口。
- 除泡与固化 :
- 将整个瓶子放入 真空干燥箱 抽真空是去除气泡的最佳方法。家用条件下,可以用热风枪(低档)轻轻吹拂树脂表面,帮助气泡上升破裂,但要注意距离,避免局部过热。
- 穿出LED的线缆本身可以作为排气通道。在树脂初步凝固(呈胶状但未完全硬化)前,轻轻提拉线缆,有助于排出深处的气泡。
- 静置24-48小时使其完全固化。
- 收尾 :树脂固化后,剥除底部的热熔胶。将LED嵌入软木塞的孔中,并用少量胶水固定。在软木塞顶部拧入一个小金属环,用于连接项链。最后,在主控PCB背面粘贴一小块薄钢片,用于与充电支架的磁铁吸附固定。
4. 充电支架的电路与结构设计
4.1 双路充电与状态监控电路
充电支架需要同时为两个吊坠充电,因此我设计了一个双路TP4056电路。每路独立工作,互不干扰。电路的核心设计点在于状态监控:
- 传统LED指示的弊端 :TP4056的标准电路用LED指示状态(常亮/闪烁/灭)。但我们需要让单片机“知道”这个状态。
- 光耦隔离方案 :我使用 PS2802-4 (一个包含4个光耦的芯片)。将每路TP4056的
CHRG和STDBY引脚通过限流电阻连接到光耦的发光二极管侧。当这些引脚输出低电平时,光耦导通。 - 单片机读取 :光耦另一侧的三极管集电极接ATTINY84的IO口和上拉电阻。当光耦导通,IO口被拉低;光耦断开,IO口被上拉至高电平。这样,ATTINY84就能通过检测两个IO口的高低电平组合,判断出当前是“充电中”、“充满”还是“未接电池”状态。
- 编程逻辑 :在ATTINY84的程序中,不断轮询这两路信号。根据状态组合,在OLED屏幕上显示对应的动画,例如一个空瓶子逐渐被液体填满的像素动画。
4.2 磁吸探针充电接口设计
为了实现优雅的“放上即充”体验,我采用了 磁吸+Pogo Pin(弹簧探针) 的方案。
- 磁铁 :在支架每个充电槽的底部嵌入 3x3x1mm的钕磁铁 ,与吊坠PCB背面的钢片相互吸附。这保证了吊坠能被牢固、准确地对准在充电位置上。
- Pogo Pin :在每个充电槽的中心位置,安装一对(正负极)弹簧探针。当吊坠被磁铁吸下来时,探针被压缩,其尖端与吊坠PCB上的裸露充电焊盘可靠接触。探针的弹簧结构能补偿微小的位置偏差和高度公差,确保接触良好。
- PCB布局 :支架的PCB上,探针的焊盘要足够大且牢固。走线要能承受充电电流(通常500mA-1A)。
4.3 3D打印外壳与结构整合
使用Fusion 360设计支架外壳。结构分为三层:
- 底层(Base Plate) :容纳USB-C接口、主控PCB、OLED屏幕和磁铁。设计有卡槽和螺丝柱用于固定PCB。
- 中间层(Shelf) :这是核心结构件,上面有精确放置的凹槽,用于固定两个充电模块的PCB和Pogo Pin。凹槽的位置必须与底层磁铁的位置严格对准。
- 上层(顶盖或装饰层) :保护内部电路,并留有OLED屏幕的开窗。
打印时建议使用层高0.1mm-0.15mm以获得更精细的表面。如果打印件有翘曲,可能会影响Pogo Pin的高度,导致接触不良。可以在安装Pogo Pin的孔位处设计微小的调整空间,或在安装后使用少量环氧树脂进行加固。
将USB-C接口的D+和D-引脚(经过适当的分压电阻)连接到ATTINY84的编程引脚(如RESET, SCK, MOSI, MISO),这样就能通过USBasp编程器,直接通过USB-C口对支架上的ATTINY84进行程序烧录,无需再打开外壳,非常方便。
5. 软件编程要点与调试心得
5.1 ATTINY10上的LED控制程序
ATTINY10的资源极其紧张,因此代码必须精简。核心任务是驱动一颗SK6805(兼容WS2812协议)并响应触摸信号。
// 示例代码框架,基于 ATTiny10Core 库
#include <tinyNeoPixel.h>
#define PIN_LED 0 // 假设LED数据线接在PB0
#define PIN_TOUCH 1 // 触摸信号接在PB1
tinyNeoPixel pixel = tinyNeoPixel(1, PIN_LED, NEO_GRB + NEO_KHZ800);
uint8_t mode = 0;
bool lastTouchState = HIGH;
bool ledOn = true;
void setup() {
pinMode(PIN_TOUCH, INPUT_PULLUP); // TP223输出低有效,启用内部上拉
pixel.begin();
pixel.setBrightness(30); // 设置亮度以省电
pixel.show();
}
void loop() {
bool currentTouchState = digitalRead(PIN_TOUCH);
// 检测触摸下降沿(按下)
if (lastTouchState == HIGH && currentTouchState == LOW) {
delay(50); // 简单防抖
if (digitalRead(PIN_TOUCH) == LOW) { // 确认按下
mode = (mode + 1) % 4; // 循环切换4种模式
changeMode(mode);
}
}
lastTouchState = currentTouchState;
// 根据模式更新LED
if (ledOn) {
switch(mode) {
case 0: // 呼吸灯
breatheEffect();
break;
case 1: // 彩虹渐变
rainbowEffect();
break;
// ... 其他模式
}
}
delay(10); // 主循环延迟
}
void changeMode(uint8_t m) {
// 可以在这里添加模式切换的特殊效果,如快速闪烁一下
}
关键点与踩坑记录 :
- 时序要求 :WS2812系列LED对数据时序要求非常严格。
tinyNeoPixel库针对ATTINY10进行了高度优化,确保了时序准确性。不要尝试用纯延时函数模拟,成功率极低。 - 省电设计 :最初试图在LED关闭时让ATTINY10进入
SLEEP_MODE_PWR_DOWN。但发现配置外部中断(通过触摸唤醒)在ATTINY10上较为复杂,且TP223的输出信号需要被正确解读。为了项目进度,我暂时放弃了睡眠模式,改为在关闭模式时,将LED的电源控制引脚(由另一个IO口模拟)拉低,并让主循环空转,这是最简单的省电方法。实测待机电流仍在几百微安级别,有优化空间。 - IO口复用 :ATTINY10只有3个可用IO口(PB0, PB1, PB2)。一个用于LED数据,一个用于触摸输入,最后一个用于控制LED电源(或作为拨码开关输入)。需要仔细规划。
5.2 ATTINY84上的充电状态显示与动画
充电支架上的ATTINY84资源相对宽裕,主要任务是读取光耦状态、驱动OLED显示。
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>
#define OLED_RESET -1
Adafruit_SSD1306 display(128, 32, &Wire, OLED_RESET);
#define CHRG_1_PIN 2 // 第一路充电状态
#define STDBY_1_PIN 3
// ... 定义第二路引脚
void setup() {
pinMode(CHRG_1_PIN, INPUT_PULLUP);
// ... 初始化其他引脚
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
}
void loop() {
int chrg1 = digitalRead(CHRG_1_PIN);
int stdby1 = digitalRead(STDBY_1_PIN);
// 状态判断逻辑
// CHRG低,STDBY高:充电中
// CHRG高,STDBY低:充满
// 两者都高:未接电池或错误
// 两者都低:通常不会出现
display.clearDisplay();
if (chrg1 == LOW && stdby1 == HIGH) {
drawChargingAnimation(1, batteryLevel); // 绘制第一路充电动画
} else if (chrg1 == HIGH && stdby1 == LOW) {
drawFullBattery(1); // 绘制第一路满电图标
} else {
drawNoBattery(1); // 绘制第一路无电池图标
}
// ... 处理第二路
display.display();
delay(500); // 更新频率0.5Hz
}
动画实现技巧 :在32x32像素的画布上绘制一个简单的药水瓶轮廓,然后根据模拟的“电量百分比”,用 fillRect 函数从瓶底向上绘制填充块,循环几张不同填充高度的图片,就能形成“药水逐渐加满”的动画效果。图片数据可以存放在程序存储空间( PROGMEM )中。
5.3 程序烧录与调试中的实际问题
- ATTINY10编程器选择 :必须使用支持TPI编程协议的编程器,如 USBasp 。在Arduino IDE中,需要正确选择板卡类型(如“ATTiny10 @ 8MHz (internal)”)和编程器。烧录时,有时需要按住编程器上的“编程”按钮再上电,才能进入编程模式。
- 电源噪声干扰 :在调试吊坠时,发现有时触摸不灵敏或LED颜色错乱。这通常是电源问题。在ATTINY10的VCC和GND之间紧贴芯片增加一个 100nF的陶瓷电容 ,并确保电池保护板输出稳定,问题得以解决。
- OLED显示不稳定 :支架上电后OLED偶尔白屏或不显示。检查发现是I2C上拉电阻问题。SSD1306模块通常自带4.7kΩ上拉电阻,但可能强度不够。我在ATTINY84的SCL和SDA线上额外增加了 10kΩ的上拉电阻到5V ,显示立刻稳定。
- 充电电流设置 :TP4056的充电电流由PROG引脚与GND之间的电阻决定。公式为
I_CHG = 1200V / R_PROG。例如,想要500mA充电电流,R_PROG = 1200 / 0.5 = 2400Ω,选用2.4kΩ电阻。对于容量较小的电池(如本项目用的401010电池,约100mAh),建议将电流设置为 0.2C-0.5C ,即20mA-50mA,以保护电池寿命。我选择了1.2kΩ电阻,电流约为1A,这偏大了,后来调整为3kΩ(约400mA)更为合适。
6. 项目总结与可扩展方向
回顾整个项目,最大的成就感来自于将一堆微小的元件,通过设计、编程和手工,变成了一个既有观赏性又有技术内涵的作品。从在EDA软件里纠结每一根走线,到小心翼翼地用环氧树脂封装,再到最后磁吸充电时OLED亮起动画的瞬间,每一步都充满了挑战和乐趣。
几个让我印象深刻的教训:第一,微型化设计必须 先规划后动手 ,尤其是空间布局,最好能用卡尺测量并制作1:1的模型进行验证。第二,锂电池安全无小事,保护电路 绝不能省略 ,焊接和测试时要格外小心。第三,软件上的省电优化往往比硬件更复杂,需要反复测试和权衡。最后,3D打印件的精度会直接影响结构件的配合,重要的定位孔位最好留出 调整余量 。
这个项目本身还有很大的扩展空间。例如,可以为ATTINY10增加一个微型加速度计,实现敲击切换颜色或摇动变色的功能。充电支架可以升级为无线充电(Qi)版本,让体验更加无缝。甚至可以在瓶内加入更复杂的电路,实现蓝牙连接,用手机APP自定义灯光模式。对于想要更亮效果的朋友,可以尝试寻找发光效率更高的LED,或者使用侧发光LED配合光导材料,让整个瓶身均匀发光。
它不仅仅是一个吊坠,更是一个微缩的嵌入式系统开发平台。你可以替换里面的程序,让它变成心率监测器的模拟显示、变成一个随音乐闪烁的律动灯,或者只是一个安静呼吸的陪伴光。技术的乐趣,就在于用这些冰冷的元器件,创造出充满个人温度和想象力的作品。希望这个详细的分享,能为你点亮自己创作之路提供一块有用的垫脚石。
更多推荐



所有评论(0)