
智能UV固化灯(PCB阻焊绿油维修专用)最新版本支持OTA升级
简介
一款亮度可调,可定时,可手机控制,可用于多种场景的智能UV固化灯(ArduinoIDE开发)V2.0的PCB搭配V1.6的程序,后续可以直接OTA升级
简介:一款亮度可调,可定时,可手机控制,可用于多种场景的智能UV固化灯(ArduinoIDE开发)V2.0的PCB搭配V1.6的程序,后续可以直接OTA升级开源协议
:GPL 3.0
(未经作者授权,禁止转载)描述
演示视频
项目说明
本项目是基于上一代UV灯改进而来,同样是ArduinoIDE设计的,主要由软件+PCB+3D模型组成,功能如下:在UV灯顶部设计有3个按键和一个0.96寸OLED,左右按键主要用于“切换不同菜单”,中间键主要负责“确认和退出”,菜单主要有“亮度控制菜单;定时菜单;电量菜单,散热风扇菜单,手机控制菜单”组成。
项目相关功能
主要由亮度控制菜单;定时菜单;电量菜单,散热风扇菜单,手机控制菜单组成的一些功能:
亮度控制:通过IO口输出PWM信号来控制MOS管开关,从而实现亮度调节,当UV灯工作时氛围灯显示蓝色。
定时器菜单:主要用于一些特定场景的定时熄灭,小时,分钟,秒都是可以进行定时的,当然使用的是ESP8266内部的定时器,时间会有偏差,并不是特别准确(秒很准),比如当固化阻焊绿油,可以定时1分钟倒计时,(氛围灯显示绿色),时间到自动熄灭,外加蜂鸣器提醒,可以自由设置时间。
电量菜单:由于这个灯珠有15W所以是非常耗电的,我设置了一个低电量提醒功能,当电量小于(30%~5%区间可调),进行低电量报警,提醒用户充电。
散热风扇菜单:主要用于控制风扇转速,加快UV灯铝基板与电池的散热,同样采用PWM方式控制。
手机控制菜单:当进入该菜单,ESP8266会生成一个WIFI当手机连上WIFI,并通过手机浏览器输入IP地址,就可以实现单机控制UV灯。
设计原理
本次更新主要为了弥补一代的不足之处:
1:一代设计的是黑色外壳,同时由于内部螺母没有很多的处理,使用热熔螺母容易出现滑丝的情况,且受力不合理,二代改为预埋螺母连接更加牢靠。
2:一代是一个5向按键控制,占用IO口较多,导致无法增加蜂鸣器电路和风扇控制电路,二代,改为3个按键,且支持蜂鸣器与散热风扇独立控制。


** 3:对一代的充电电路做了更新,由原来的FM4256更换为IP2326(8V/1.5A)输出,充电更快。(最近充电宝爆炸的事情比较火,所以为了更保险一点,我还设计了热敏电阻)充电更安全。
**


** 4:一代设计的是黑色吸光,且外壳不适合嵌入亚克力,所以二代对氛围灯进行了增加,更加直观。
5:电池保护电路同样进行了改进,采用四颗MOS管两两并联,可保证电池电流大功率输出。**


软件说明
软件部分主要使用的库有
#include "U8g2lib.h //OLED驱动库
#include //ESP8266WIFI库
#include //Web网页库
#include //WS2812氛围灯库
主要setup函数有:
通过一个for循环进行IO口的初始化,非常适合定义多个IO口场合
for(int i=0; i<3; i++)
pinMode(Key[i], INPUT_PULLUP); //输入上拉模式
pinMode(LED, OUTPUT);
digitalWrite(LED,LOW);
analogWrite(LED, map(uv_brightness, 0, 100, 0, 1023));
pinMode(Fan, OUTPUT);
analogWrite(Fan, map(fan_speed, 0, 100, 0, 1023));
pinMode(Buzzer, OUTPUT);
}
loop函数:电池电量监测-->判断WIFI是否连接-->按键是否被按下-->定时函数-->氛围灯函数-->蜂鸣器函数-->绘制显示界面-->刷新显示
void DianChi(){
// 1. 读取电池电压
voltage = readBatteryVoltage();
percent = calculateBatteryPercent(voltage);
// 2. 检查低电量
static bool lowBatteryWarningShown = false;
if (percent < LOW_BATTERY_PERCENT) {
if (!lowBatteryWarningShown) {
displayLowBatteryWarning();
lowBatteryWarningShown = true;
ledState = LED_PINK_BLINK; // 设置LED为粉色闪烁
triggerLowBatteryAlarm(); // 触发低电量蜂鸣报警
}
} else {
lowBatteryWarningShown = false;
// 检查充电状态(假设充电时电压高于8.6V)
if (voltage > 8.6) {
if (percent < 100) {
ledState = LED_PURPLE_BREATH; // 充电中
} else {
ledState = LED_OFF; // 充电完成
// 停止任何蜂鸣声
buzzerState = BUZZER_OFF;
noTone(Buzzer);
}
} else if (ledState == LED_PINK_BLINK) {
ledState = LED_OFF; // 退出低电量状态
buzzerState = BUZZER_OFF; // 关闭低电量报警
noTone(Buzzer);
}
}
}
void handleButtons(){
//防抖处理
if(millis() - lastDebounceTime < debounceDelay) return;
//选择按键
if(digitalRead(Key[0]) == LOW && !button_select_clicked){
button_select_clicked = 1;
triggerKeyBeep(); // 按键提示音
if(current_screen == ZHU_JIE_MIAN){
//主菜单进入子菜单
switch(menu_selection){
case 0: current_screen = LIANG_DU; break;
case 1: current_screen = DING_SHI; break;
case 2: current_screen = DIAN_LIANG; break;
case 3: current_screen = FENG_SHAN; break;
case 4: current_screen = SHOU_JI_WIFI;
activateWifiAP();//激活WIFI热点
break;
}
}else if(current_screen == DING_SHI){
//定时器专用逻辑
if(timerState == SETTING){
startTimer();
}else if(timerState == RUNNING || timerState == FINISHED){
cancelTimer();
current_screen = ZHU_JIE_MIAN;//返回主菜单
}
}else if(current_screen == SHOU_JI_WIFI){
deactivateWifiAP();//关闭WIFI热点
current_screen = ZHU_JIE_MIAN;
}else{
current_screen = ZHU_JIE_MIAN;
}
lastDebounceTime = millis();
return;
}
//上按键
if(digitalRead(Key[1]) == LOW){
triggerKeyBeep(); // 按键提示音
switch(current_screen){
case ZHU_JIE_MIAN:
menu_selection = (menu_selection - 1 + NUM_ITEMS) % NUM_ITEMS;
break;
case LIANG_DU:
uv_brightness = min(100,uv_brightness + 5);
analogWrite(LED, map(uv_brightness, 0, 100, 0, 255));
break;
case DING_SHI:
if(timerState == SETTING){
//循环选择时间单位
if(selectedUnit == HOURS) selectedUnit = MINUTES;
else if(selectedUnit == MINUTES) selectedUnit = SECONDS;
else selectedUnit = HOURS;
}
break;
case FENG_SHAN:
fan_speed = min(100, fan_speed + 5);
analogWrite(Fan, map(fan_speed, 0, 100, 0, 255));
break;
case DIAN_LIANG:
battery_warning = min(30, battery_warning + 1);
break;
}
lastDebounceTime = millis();
return;
}
//下按键
if(digitalRead(Key[2]) == LOW){
triggerKeyBeep(); // 按键提示音
switch(current_screen){
case ZHU_JIE_MIAN:
menu_selection = (menu_selection + 1) % NUM_ITEMS;
break;
case LIANG_DU:
uv_brightness = max(0, uv_brightness - 5);
analogWrite(LED, map(uv_brightness, 0, 100, 0, 255));
break;
case DING_SHI:
if(timerState == SETTING){
//增加当前单位值
if(selectedUnit == HOURS) setHours = (setHours + 1) % 24;
else if(selectedUnit == MINUTES) setMinutes = (setMinutes + 1) % 60;
else setSeconds = (setSeconds + 1) % 60;
}
break;
case FENG_SHAN:
fan_speed = max(0, fan_speed - 5);
analogWrite(Fan, map(fan_speed, 0, 100, 0, 255));
break;
case DIAN_LIANG:
battery_warning = max(5, battery_warning - 1);
break;
}
lastDebounceTime = millis();
return;
}
// 当UV灯手动开启时,设置蓝色呼吸灯
if (uv_brightness > 0 && timerState != RUNNING) {
ledState = LED_BLUE_BREATH;
} else if (uv_brightness == 0 && ledState == LED_BLUE_BREATH) {
ledState = LED_OFF;
}
//重置按钮状态
if (digitalRead(Key[0]) == HIGH) button_select_clicked = 0;
}
void handleTimer() {
if (timerState == RUNNING) {
// 定时器运行时设置LED为绿色常亮
ledState = LED_GREEN_SOLID;
unsigned long elapsed = millis() - startMillis;
if (elapsed >= remainingTime) {
// 倒计时结束
timerState = FINISHED;
remainingTime = 0;
// 关闭UV灯和风扇
uv_brightness = 0;
fan_speed = 0;
// 关闭相关设备
analogWrite(LED, map(uv_brightness, 0, 100, 0, 1023));
analogWrite(Fan, map(fan_speed, 0, 100, 0, 1023));
// 关闭LED
ledState = LED_OFF;
// 发出结束提示音
triggerTimerEndBeep(); // 使用特殊结束音
} else {
// 更新剩余时间
remainingTime -= elapsed;
startMillis = millis();
}
}
// 更新闪烁状态
if (millis() - lastBlink > BLINK_INTERVAL) {
blinkState_LED = !blinkState_LED;
lastBlink = millis();
}
}
void handleLEDs() {
switch(ledState) {
case LED_OFF:
setAllLEDs(0, 0, 0); // 关闭所有LED
break;
case LED_BLUE_BREATH:
updateBreathEffect(0, 0, 255); // 蓝色呼吸效果
break;
case LED_GREEN_SOLID:
setAllLEDs(0, 255, 0); // 绿色常亮
break;
case LED_PINK_BLINK:
updateBlinkEffect(255, 20, 147); // 粉色闪烁效果
break;
case LED_PURPLE_BREATH:
updateBreathEffect(148, 0, 211); // 紫色呼吸效果
break;
}
}
void drawInterface() {
u8g2.clearBuffer();
updateDisplay(voltage, percent);//所有界面显示电池状态
switch(current_screen) {
case ZHU_JIE_MIAN:
drawMainMenu();
break;
case LIANG_DU:
drawBrightnessMenu();
break;
case FENG_SHAN:
drawFanMenu();
break;
case DIAN_LIANG:
drawBatteryMenu();
break;
case DING_SHI:
drawTimerMenu();
break;
case SHOU_JI_WIFI:
draWifiMenu();
break;
}
}
安装说明
实物图




设计图
未生成预览图,请在编辑器重新保存一次BOM
暂无BOM
克隆工程知识产权声明&复刻说明
本项目为开源硬件项目,其相关的知识产权归创作者所有。创作者在本平台上传该硬件项目仅供平台用户用于学习交流及研究,不包括任何商业性使用,请勿用于商业售卖或其他盈利性的用途;如您认为本项目涉嫌侵犯了您的相关权益,请点击上方“侵权投诉”按钮,我们将按照嘉立创《侵权投诉与申诉规则》进行处理。
请在进行项目复刻时自行验证电路的可行性,并自行辨别该项目是否对您适用。您对复刻项目的任何后果负责,无论何种情况,本平台将不对您在复刻项目时,遇到的任何因开源项目电路设计问题所导致的直接、间接等损害负责。










