燃气自动调火开关
简介
家里老人做饭两次忘了关火,太危险了,所以做一个定时开关,实现两个功能:1.可定时关火;2.可定时关小火。同时,不影响手动功能
简介:家里老人做饭两次忘了关火,太危险了,所以做一个定时开关,实现两个功能:1.可定时关火;2.可定时关小火。同时,不影响手动功能开源协议
:GPL 3.0
(未经作者授权,禁止转载)描述
项目说明
本项目为燃气自动调火开关,主要目的是减少忘记关火引起火灾的可能。
开源协议
开源协议:GPL 3.0
项目相关功能
主要功能为:1.定时 关火(初始化时间30分钟,最小定时1分钟,最长定时120分钟,如果感觉不够,可以自己改);2定时关小火(默认关闭,手动开启);3.手动关火、调火不受影响
(另外补充说明:显示的时间为倒计时其实时间,比如定时关火设定的是10,定时关小火设定的是6,那意思是6分钟后把火关小,然后再等4分钟会自动关火。本来没这个说明,但经过我老婆的神理解,我觉得还是得说清楚,否则有人和我老婆一样认为关小火的时间是小火保持的时间,就很无语了,哈哈哈)
本项目为首次公开,为本人原创项目。项目未曾在别的比赛中获奖。
项目进度
本项目电子元件十分便宜,最贵的可能是3d打印零件
设计原理
一、电路部分
本项目电路原理比较简单,电路实现的功能为:1.根据位置传感器,确定燃气开关位置;2.根据定时器设定时间和燃气开关位置控制电机转动,并在指定位置停止;3.关闭状态开启单片机低功耗模式
主控芯片:PY32f002a
时间显示:TM1650+0.28寸三位共阴极数码管
电机控制:YX-1818AM
时间设定:EC11编码器
位置传感器:CC6207霍尔传感器
以上芯片元件的原理这里就不在赘述了,大家可以网上查阅手册。
试着用ai画了个思维导图:
根据上面的功能,我们需要单片机控制的管脚为:
1.W_1,W_2,W_3位置传感器3个,分别对应点火开关的关闭,小火以及电机初始位置
2.TM1650控制信号两个: 模拟SCL、SDA
3.EC11输出管脚3个 :KEY_A,KEY_B,KEY_C
4.YX-1818AM控制信号两个:MOTOR_1A,MOTOR_1B
5.MOS关电源控制(配合低功耗模式降低外围电路功耗)1个:PA3
6.信号LED管脚1个:PA4
以上总共需要引脚12个
二、软件部分
这里重点说一下思路。
1.定时器
这个开关重点就是定时关火和调火,所以定时器是核心,我这里用的是通用定时器16,把它设定为1分钟中断一次,然后找两个变量,TIMER1控制关火时间,TIMER2控制调小火时间,中断发生就 TIMER1--;TIMER2--;这样就可以根据设定的TIMER1,TIMER2大小来调整两个时间的长短。关小火是可以选择的功能,所以为了省事,把TIMER2变量初始化为999,如果有需要再调小TIMER2即可。
2.显示
因为有两个时间可设定,所以用EC11的按键功能进行切换,并用led的亮灭来指示目前显示的是什么时间。默认启动显示为TIMER1,默认值30分钟,显示TIMER1的时候,指示灯熄灭状态,按以下EC11,显示TIMER2,同时指示灯亮起。
另外为了监视电量,启用单片机的内部电源监控通道,由于我使用的是1s锂电,当电压低于3v时,每秒显示一次blo
3.位置监控
三个位置传感器,其中W1是控制芯片的低功耗模式启动关闭,同时控制mos管启动关闭外围电路,W2是关小火的位置指示,W3是电机初始位置传感器,不论是关小火还是关闭燃气开关,操作完成后电机都要回到初始位置。这三个位置传感器的输入引脚都要设定为外部触发中断模式
下面是主程序,其余的代码就不贴了,有兴趣的直接去看附件的源码吧,编程水平有限,轻拍。下面的代码我让kimi帮我整理了一下,顺便写了下注释:
int main(void)
{
/* 初始化EC11计数值 */
EC11_COUNT = 0;
/* 初始化HAL库 */
HAL_Init();
/* 配置ADC */
APP_ADCConfig();
/* 配置系统时钟 */
APP_SystemClockConfig();
/* 使能GPIOA、B、F的时钟 */
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE();
/* 初始化EC11引脚 */
EC11_PIN_INIT();
/* 初始化TIM16 */
TIM16Config();
/* 初始化LED */
MYLED_Init();
/* 初始化I2C引脚 */
I2C_PIN_INIT();
/* 配置外部中断 */
Configure_EXTI();
/* 初始化W1和W3的外部中断 */
W1_W3_EXTIConfig();
/* 初始化CC6207相关的GPIO */
GPIO_CC6207_INIT();
/* 初始化电机控制相关的GPIO */
MOTOR_GPIO_INIT();
/* 初始化TM1650显示驱动 */
TM1650_INIT();
/* 设置TM1650进入睡眠模式 */
TM1650_SET(SYS_ADD, SYS_SLEEP);
/* 主循环 */
while (1)
{
/* 获取当前时间 */
TIME = HAL_GetTick();
/* 重新初始化TM1650 */
TM1650_INIT();
/* 启动ADC转换 */
HAL_ADC_Start(&hadc);
/* 等待ADC转换完成 */
HAL_ADC_PollForConversion(&hadc, 1000000);
/* 获取ADC值 */
adc_value = HAL_ADC_GetValue(&hadc);
/* 计算VCC电压 */
T_VCC = (4095 * 1.2) / adc_value;
/* 如果电池电压低于3V,显示电池电量低的提示 */
if (T_VCC < 3)
{
/* 每秒钟切换显示电池电量低的提示和当前计时 */
if ((TIME % 2000) < 1000)
{
TIM1650_DIS(ADD1, 10); // 显示'B'
TIM1650_DIS(ADD2, 11); // 显示'L'
TIM1650_DIS(ADD3, 12); // 显示'O'
}
else
{
/* 根据DSP_FLAG显示TIMER1或TIMER2的值 */
if (DSP_FLAG)
{
TIM1650_DIS(ADD1, TIMER1 / 100);
TIM1650_DIS(ADD2, (TIMER1 / 10) % 10);
TIM1650_DIS(ADD3, TIMER1 % 10);
}
else
{
TIM1650_DIS(ADD1, TIMER2 / 100);
TIM1650_DIS(ADD2, (TIMER2 / 10) % 10);
TIM1650_DIS(ADD3, TIMER2 % 10);
}
}
}
else
{
/* 如果电池电压正常,显示正常计时 */
if (DSP_FLAG)
{
TIM1650_DIS(ADD1, TIMER1 / 100);
TIM1650_DIS(ADD2, (TIMER1 / 10) % 10);
TIM1650_DIS(ADD3, TIMER1 % 10);
}
else
{
TIM1650_DIS(ADD1, TIMER2 / 100);
TIM1650_DIS(ADD2, (TIMER2 / 10) % 10);
TIM1650_DIS(ADD3, TIMER2 % 10);
}
}
/* 如果W1为高电平,且TIMER1为0,则启动电机向前运行 */
if (W1 == 1 && TIMER1 <= 0)
{
MOTOR_FORWARD();
}
/* 如果W1为低电平,W3为高电平,则使电机向后运行 */
if (W1 == 0 && W3 == 1)
{
for (int i = 0; i < 60000; i++); // 延时 不知道啥原因使用hal_delay就会影响进入低功耗,所以用了个空循环代替。这个延时主要是为了给马达一个缓冲时间,不要马上反转
MOTOR_BACKWARD();
}
/* 如果W1和W3都为低电平,则停止电机并进入低功耗模式 */
if (W1 == 0 && W3 == 0)
{
MOTOR_STOP();
TM1650_SET(SYS_ADD, SYS_SLEEP);
TIMER1 = 30;
// 关闭TM1650、W2、W3的电源
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_All, GPIO_PIN_RESET);
HAL_GPIO_WritePin(LED_PORT, LED_PIN, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_All, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_All, GPIO_PIN_RESET);
PWR_STOP_MODE(); // 进入低功耗模式
}
/* 如果TIMER2为0且TIMER1大于0,则执行特殊操作 */
if (TIMER2 <= 0 && TIMER1 > 0)
{
TIMER2 = 0;
while (TIMER2_FLAG == 0)
{
MOTOR_BACKWARD(); // 电机向后运行
}
if (TIMER2_FLAG == 1)
{
while (W3 == 1)
{
MOTOR_FORWARD(); // 电机向前运行
}
MOTOR_STOP(); // 停止电机
TIMER2 = 999; // 重置TIMER2
}
}
}
}
三、外壳及机械设计
其实这个定时开关的机械部分设计才是关键,因为要自动控制的同时不影响手动控制,想了很久,突然灵光一闪,传动改为上下传动即可。用FreeCAD设计了一下机械结构,截了个图简单说明一下:图里两个大的部分比较明显,就是外壳和上盖,下面还有个方形的,是外挂的电池盒,电池盒自己用砖头在两侧开个螺丝孔,用螺丝拧在外壳上就行。主要说明一下外壳里的零件:右边翠绿色的是一个N20的减速电机,这个减速马达要选3v的,而且减速比越大越好,我这个每分钟大概是40转的。左边的就是上下两层设计的主齿轮和负责带动主轴转动的从动轮。从动轮的方形凸起中间有个3mm的圆孔,内嵌一个3mm直径的钕磁铁,主齿轮上有个凸台,凸台的侧面也内嵌一个3MM直径的钕磁铁。中心轴是用来联接灶台旋转轴和原旋转按钮的,外径为六边形设计,从而可以被主轴带动。主齿轮中孔是圆形的,所以不会影响主齿轮的运转,从而手动控制不会受到影响。目前图上还可以看到从动轮凸起指向的方向就是W1传感器安装的地方,下面外壳上的两个方形柱子则是W2,W3安装的位置。我是直接用胶把这三个传感器粘在外壳上的。
因为我是3d打印的,所以外壳前面设计成了双层,主要为了增加个空气隔热仿制内层变形,同时最外层也可以贴一层锡箔纸或者防火胶带来进一步隔热。另外前面的那个螺丝固定位置画图时没注意,会抵住上盖,但问题不大,用斜口钳减掉一部分就可以。就像下面那张图片一样,斜着减掉一角就行了。
下面就是安装好后内部的样子:
低功耗时的待机电流:
注意事项
没啥特别注意的,就是程序我也不知道哪儿有冲突,不能使用delay函数,一用就无法进入低功耗模式,所以我用空循环做了个简单延时。懒的深究了,对我们这些业余爱好者不不要要求太高,能用就行,对吧。
另外我用的电池是个450mah的锂电,5月19日充满的时候4.15v,20天了,刚刚去测了一下,还有3.9v,这样算起来至少能用3个月吧,如果觉得时间太短了,可以换个大点的电池。
唯一需要注意的是py32的PACK我用的是1.1.0版本,高版本可能会编译报错。pack我放在附件了。
其他
演示视频地址:
工程附件:参加活动的作品必须把工程相关的程序附件上传至开源平台或个人的代码存储云端,附件最大支持50M上传(请勿在立创工作区上传,有限制)
评论