技术文档

风扇与51单片机 玩具上的废旧电机千万别扔,做个单片机控制的智能风扇吧

小编 2024-10-06 技术文档 23 0

玩具上的废旧电机千万别扔,做个单片机控制的智能风扇吧

在中国从北到南都逃脱不了炎热的夏天,天气那么热做一个空调也不太现实,我们何不动手制作一个风扇呢?家里都会一下玩具上的废旧电机,扔掉又太可惜了,直接把电机连在电源两端不能调速又太无聊了,我们何不DIY一个单片机控制的智能风扇,今天给大家展示一下之前做的一个智能风扇,感兴趣的网友可以参考一下。

先来给大家一个制作成功图片

智能风扇

我们所选用的单片机为STC生产的51系列的芯片,初次之外还有一些其它材料像废旧电机、1602显示屏、电机驱动芯片、按键和洞洞板等,对于经常搞单片机diy的网友来说,这些材料都是搞小制作的必需品。

先来介绍一下我们所要制作的智能风扇的功能

1602显示屏

1602显示屏是我们必需品,在这上面我们可以实时读出外界温度以及智能风扇工作状态,显示屏上显示OFF表示风扇不开启,左下角显示智能风扇开启温度,中间显示外界环境的温度,智能风扇分为三个档,温度越高转速越快,大家可以参考一下,如果有技术远远可以扩展的功能很强大。

这个图片显示的风扇开启的状态,除了具有风扇由温度控制开启以外,还可以由使用者强制开启,无论外界温度是多少度都可以开启,但是只能开启最快的档位,在显示屏上我们也可以看到开启的档位为三挡,但是外界温度是很低,这个是我在冬天测试的时候实拍的图片。

我们制作 这个智能风扇尽可能的体现它的价值,如果你想送人的话,特别是自己的女友(通过关注我的粉丝比例来看,喜欢单片机的男生占99.9%)我们可以在显示屏上显示一些你想说的话,就像上图显示的内容,当然这个不是固定的,想显示什么完全是由你自己决定。

正常工作状态

除了显示屏之外我还加了四个按键,左面两个是调节智能风扇的启动温度,启动温度就是指显示屏左下角显示的那个数字,现在是26度我们可以通过左面两个按键进行启动温度的增减,第三个按键就是你想对女神或女友说的话,至于显示什么,得看你想说什么了,第四个按键就是智能风扇强制启动按键,按下之后无论智能风扇处于哪种状态,都能强制启动。

个人觉得还是挺好玩的,现在天气很热,非常具有使用价值,我们可以在有空的时候制作一个,由于文章中不能添加代码,所以想直接要代码的朋友只能说声抱歉了,制作起来不是很难,自己动手完全可以的。

电子制作1 -红外遥控风扇的制作

天气太热,睡觉用鸿运扇吹风,有时候会觉得最慢档的风力还是嫌大。我先后尝试给鸿运扇串接一个吊扇的电感调速器,也试过用可控硅调压作调速器,但即便电源电压调到较低了,低到风扇勉强能启动的程度,但还是感到风扇转速偏大,边吹边睡不太舒服。

这也可能我的这个风扇低压启动性能不好。最后我改用单片机控制,用PWM方波控制这个鸿运扇。通过调整不同占空比来控制转速,结果效果比电感调速或者可控硅调压调速好,风扇转速可以调得很慢,还可以通过间隙性给风扇供电,模拟自然风效果。最后再加个红外遥控功能,用起来比较满意。

现将对应的51单片机红外接收遥控风扇控制电路及软件代码介绍如下,供有兴趣的朋友参考。

图3,装在饮料瓶里的红外接收电路+输出插座。

图4,红外接收+控制电路原理图。

软硬件说明:

图4里用标称输出5V的USB电源模块给系统供电。因为实测其输出电压为6V,所以在其5V输出端串接了一个二极管降压。考虑到控制PWM输出的电源开关会频繁地通断,普通电磁继电器的触点寿命有限,所以采用固态继电器控制220V交流输出插座。图4还画了一个双抛开关继电器,原来想用来控制风扇的快慢档线圈转换的。使用中发现,只要调整PWM不同占空比来控制风扇转速已经能基本满足要求,这个器件就多余了。

(4)此前是4keys控制:

0x16=“0”=总电源开关,控制固态继电器-》开通或关断,每按键一次翻转一次。

0x0c=“1”=快慢档控制,控制动圈继电器-》双刀双抛开关实现快慢档转换,每按键一次翻转一次。

0x44=“VOL- ”= 减速,主继电器断电时间控制, =speed- (主继电器断电时间增加到10就变1)。

0x40=“VOL+ ”= 加速,主继电器开通时间控制,=speed- (主继电器开通时间增加到8就变1)。

(5)后来改为8keys控制:

0x43=“PAUSE/play”= 总电源开关,控制固态继电器-》开通或关断,每按键一次翻转一次。

0x09=“EQ”= 快慢档控制,控制动圈继电器-》双刀双抛开关转换,每按键一次翻转一次。

0x44=“PREV ”= 减速,主继电器断电时间增加到10就停止。

0x40=“NEXT ”= 加速,主继电器断电时间减少到1就停止)。

0x15=“VOL- ”= 减速,主继电器开通时间减少到1就停止。

0x07=“VOL+ ”= 加速,主继电器开通时间增加到10就停止。

(6)单片机软件下载用CH340下载线(如下图5,只用TXD+RXD+GND等3根线)。

(7)P02= HYDZR beeper(PIN38)= P02+10k上拉+1K串接9014-B极,9014-C极+LED+BEEPER.

(8) P03= J1(WANJIA双刀双抛继电器,5A250V) = P03+10k上拉+1K串接9014-B极,9014-C极+WJ113H继电器(RJ=55欧,IJ=58MA)

(9) P04= Jmain(总开关固态继电器) = P03+10k上拉+1K串接9014-B极,9014-C极+固态继电器(IJmain= 12MA)。负载接50W灯,导通时,输出接点压降= 8VAC。

(10)38k红外遥控器(配1838红外接收头= HS0038B):

(11)遥控器按键值

//uchar code Test1[4]={0x16,0x0c,0x08,0x42,};//遥控键0-1-4-7

//uchar code Test2[4]={0x18,0x5e,0x1c,0x5a,};//遥控键2-3-5-6

//uchar code Test3[4]={0x42,0x52,0x4a,0x15,};//遥控键7-8-9-+

按键名称 数据码, 按键名称 数据码, 按键名称 数据码, 按键名称 数据码

0 0x16 1 0x0c 2 0x18 3 0x5e

4 0x08 5 0x1c 6 0xaa 7 0x42

8 0x52 9 0xab - 0x07 + 0x15

eq 0x09 next 0x40 prev 0x44 play 0x87

PAUSE/PLAY 0x43

--------------------------===================================------------------------------

(12)源码:

unsigned char IRtime; //红外信号位周期时长计时器,由T0中断计数。

bit irpro_ok,IRrec_Ok;

unsigned char IRcode[4]; //将接收的红外32位数据按四个字节数据保存

unsigned char IR_time[33]; //分别寄存33个bit的时间

sbit Beep = P0^2; //红外接收提示LED灯+beeper

sbit Speed = P0^3; //9014驱动的动圈继电器J1-快慢档输出端口

sbit Power = P0^4; //固态继电器Jmain-总电源控制输出端口

#define ON 1; //定义led=1=on

#define OFF 0; //定义led=0=off

#define TRUE 1;

#define FALSE 0;

uchar Ton, Toff; //Ton是主继电器开通延时时间,Toff是主继电器关断延时时间。

uchar Ton_count, Toff_count; //Ton_count是主继电器开通计数器,Toff_count是主继电器关断计数器。

uchar F_Speed; //调速模式标志,=TRUE=1是调速状态,=0是正常速度状态。

/*--------------------函数声明----------*/

void Ir_work(void);

void Ircode_pro(void);

void Delay_1ms(unsigned int Tx)

{ unsigned int t1,t2;

for(t1=0;t1<Tx;t1++) for(t2=0;t2<120;t2++);

}

void Beeper(unsigned int Tx)

{ Beep = ON; Delay_1ms(Tx); Beep = OFF; Delay_1ms(10);

}

#define PreloadT0H (65536-250)>>8;

#define PreloadT0L (65536-250)%256;

#define PreloadT1H (65536-50000)>>8;

#define PreloadT1L (65536-50000)%256;

unsigned int PreT0h, PreT0l;

unsigned int PreT1h, PreT1l;

//===================================================================

//T0=0001,设为16位定时工作方式0

void TIME0_init(void)

{ TMOD &= 0Xf0; // 低位T0计数方式清0

TMOD |= 0X01; // T0=计数方式1= 16位,

//T0方式选择位C/T=0=定时工作方式1,= 16位,不自动重装参数

PreT0h= PreloadT0H; PreT0l= PreloadT0L;

TH0= PreT0h; TL0= PreT0l;

TR0 = 1;

ET0=1; //允许计数器0中断

PT0= 1; //T0为最高优先级

}

/*-----------------------*/

void time0_isr (void) interrupt 1 using 1

{ IRtime++; //用于计数2个下降沿之间的时间

TH0= PreT0h; TL0= PreT0l;

}

//==================================================================

//T1设为16位定时工作方式0

void TIME1_init(void)

{

TMOD &= 0X0f; // 高位T1计数方式清0

TMOD |= 0X10; // T1=计数方式1= 16位,

//T1方式选择位C/T=0=定时工作方式1= 16位,不自动重装参数

PreT1h= PreloadT1H; PreT1l= PreloadT1L;

TH1= PreT1h; TL1= PreT1l;

TR1 = 1;

ET1=1; //允许计数器1中断

}

/*----------------------------------*/

uchar Txms_count=0;

void time1_isr(void) interrupt 3

{ TH1= PreT1h; TL1= PreT1l;

if(Txms_count++ >=20)

{ Txms_count = 0;

if(F_Speed==1) //=1是调速状态

{

if(Ton_count++ <Ton)

{ Power=ON; }

else if((Ton_count>=Ton)&&(Toff_count++ <Toff) )

{ Power=OFF; }

if((Ton_count>=Ton)&&(Toff_count>=Toff) )

{ Beeper(2); //=心跳信号,在慢速工作状态时,每个"通电+断电结束"周期响一短声。

Ton_count=0; Toff_count=0; } //定时时间到,计数器清零

}

}

}

/*----------------------------*/

void EX0init(void)

{ IT0 = 1; //指定外部中断0下降沿触发,INT0 (P3.2)

EX0 = 1; //使能外部中断

}

/*-----------------------------*/

void EX0_ISR (void) interrupt 0 //外部中断0服务函数

{ //接收红外信号处理,将接收到各位数占时存储下来

static unsigned char IRcount; //接收位数计数器

static bit startflag; //是否开始处理标志位

if(startflag)

{

if(IRtime>32) //IRtime>32即认为是引导码,丢弃

//引导码=TC9012的头码=53*IRtime=9ms+4.5ms,33*IRtime=8.448ms

//when IRtime=250us,33*IRtime=8250us, 32*IRtime=8000us

{ IRcount=0; } // IR_time[0]=引导码的时间长度=9ms+4.5ms,

IR_time[IRcount]=IRtime;//存储每个位电平的持续时间,用于以后判断是0还是1

IRtime=0; //清零

IRcount++; //接收位数计数器

if(IRcount==33) //收够32位数据了

{ IRrec_Ok=1; IRcount=0; }

}

else

{ IRtime=0; startflag=1; }

}

void Ir_work(void) //根据接收到的红外键值跳转处理程序--

{

switch(IRcode[2])//只判断第三个数码值

{

case 0x43: //key=PAUSE/play=暂停=Jmain主继电器开通或关断,每按键一次翻转一次

F_Speed = FALSE; //FALSE=0==正常速度状态

Power= !Power; Beeper(200); //跟踪Power= ~Power;是同样效果-20220731

break;

case 0x09: //key=EQ =快慢控制继电器)快速或慢速控制(接通1为慢速,接通2为快速)

F_Speed = FALSE; //FALSE=0=正常速度状态

Speed= !Speed; Beeper(200); //每按键一次翻转一次

break;

case 0x44: //=PREV =Toff-- (Jmain主继电器开通时间减少)

F_Speed = TRUE; //TRUE=1=调速状态

if(Toff-- <2)

{ Toff=1; Beeper(1000); } //从2开始,10档速度,每按键一次,断电时间-1s

Beeper(200); break;

case 0x40: //=NEXT =Toff++ (Jmain主继电器开通时间++)

F_Speed = TRUE; //TRUE=1

if(Toff++ >10)

{ Toff=10; Beeper(1000); } //从2开始,10档速度,每按键一次,断电时间+1s

Beeper(200); break;

case 0x15: //=VOL- =Ton-- (Jmain主继电器开通时间--

F_Speed = TRUE; //TRUE=1

if(Ton-- <2)

{ Ton=1; Beeper(1000); } //从2开始,8档速度,每按键一次,通电时间-1s

Beeper(200); break;

case 0x07: //=VOL+ =Ton++ (Jmain主继电器开通时间--

F_Speed = TRUE; //TRUE=1

if(Ton++ >8)

{ Ton= 8; Beeper(1000); } //从2开始,8档速度,每按键一次,通电时间+1s

Beeper(200); break;

default: F_Speed = FALSE; break;

}

irpro_ok=0;//处理完成标志

}

void Ircode_pro(void)

//将接收的32字节存储在IR_time[32],根据时长判断个位是0或1,转为四个字节保存

{ unsigned char i, j, k; unsigned char Code32b,value;

k=1; //将引导码=IR_time[0]去掉,所以令k=1;

for(i=0;i<4;i++) //处理4个字节

{

for(j=1;j<=8;j++) //处理每1个字节的8位数

{

Code32b=IR_time[k]; //1th,取出32位数的的第一位IR_time[1],根据时长来判断是0或1。

if(Code32b>6) //大于某值为1,这个和晶振有关系

// 如果收到1,对应的高电平时间=1.168ms,IR_time[]=1.168ms/IRtime,必定大于等于4。

// 如果收到0,对应的高电平时间=0.56ms,IR_time[]=0.56ms/IRtime,必定>=2。

//7*IRtime=1750us, 6*IRtime=1500us,560/250=2.24, 1168/250=4.67个IR_time

// 另有资料说,1对应的高电平时间=1.69ms,IR_time[]=1690us/250=6.76个IR_time。

//结论:用4或8会得乱码。用5-7解码结果都对,取6较合理。

value|=0x80; //令最高位=1

if(j<8) { value>>=1; } //处理下一位

k++;

}

IRcode[i]=value; //将接收的8位数据按1个字节保存

value=0;

}

irpro_ok=1; //将接收的32位数据按四个字节保存,处理完毕标志位置1

}

/*----------- 主函数-------*/

void main(void)

{//MCU通电瞬间的端口高电平,会令各输出端口的9014导通+继电器吸合通电,改用PNP的9012可避免此问题

Power = OFF; Speed = OFF; Beep = OFF; //开机先令几个输出端口=0,防止继电器通电!

Delay_1ms(500); Beeper(200);

EX0init(); //初始化外部中断

TIME0_init(); //初始化定时器0-红外接收定时

TIME1_init(); //初始化定时器1-继电器开关定时

Ton= 3; Toff= 2; //Ton是主继电器开通和关断的延时时间,一秒为单位,调速才用到

Ton_count=0; Toff_count=0; //主继电器开通和关断计数器,调速时,在T1中断1S后计数

EA = 1; //开总中断

while(1)//主循环

{

if(IRrec_Ok) //如果在INT0接收到正确的红外信号,就跳转这里进行红外数据处理

{ Beeper(30); //接收到红外按键信号,发出提示音

Ircode_pro(); //将接收的32位时长数据按四个字节提取并保存到IRcode[i]

IRrec_Ok=0;

}

if(irpro_ok) //数据处理好后,做对应工作

{ Ir_work(); } //根据红外键值跳转处理程序

}

}

写于20220813

相关问答

51单片机 温控 风扇 转不动?

单片机的温控风扇不转,这个一般是传感器坏了,导致风扇不转,这个一般是热敏电阻有问题,才会导致风扇不转,换一个单片机风扇,或者是热敏电阻就可以了,限风...

单片机 技术与应用”课程标准设计

[回答]1原有教学大纲与新课标的差异原来使用的“单片机技术与应用”课程的教学大纲对知识点分解层层深入,便于学生由浅入深地学习相关知识。但是由于...

单片机 智能 风扇 为什么用蓝牙不用红外技术?

单片机智能风扇使用蓝牙技术而不是红外技术的原因是因为蓝牙技术具有更高的可靠性和更大的传输距离。相比之下,红外技术在传输距离和障碍物遮挡方面存在很大的...

如何利用 单片机 控制 风扇 三档循环?

用io口控制三个继电器,用继电器切换风扇绕组。用io口控制三个继电器,用继电器切换风扇绕组。

CPU 风扇 是PWM控制好还是电压控制好?

建议用PWM。控制原理来完成对直流电机的正转、反转以及其加速、减速过程的控制,在此过程中是通过单片机的定时器加上中断的方式产生不同时长的高低电压脉冲信...

单片机 温度控制系统怎么解决?

单片机温度控制系统可以通过以下步骤来解决:选择合适的传感器:选用温度传感器来监测环境温度。连接传感器:将传感器与单片机连接,以便采集温度数据。编写...

单片机 是干什么用的?做这赚钱么?

单片机,简单理解是控制硬件的微处理器,如我们常用的自动电话,高档风扇等都是,它是一个芯片,需要写入程序才能进行实际自动操作,作这个基本是很难赚钱,因为...

换电磁炉专用电源模块后, 风扇 不停,会是什么原因?

电风扇 换挡与消耗功率的关系同一台电风扇,一档和二档风扇...

[最佳回答]不同的转速肯定消耗的功率不同.可以肯定的是,转速越高,消耗功率越大.不同的风扇,调速原理是不同的.有的是串联一个小变压器(其实不是变压器,形状类...

电子调速 风扇 功率和转速有关吗?

不同的转速肯定消耗的功率不同。可以肯定的是,转速越高,消耗功率越大。不同的风扇,调速原理是不同的。有的是串联一个小变压器(其实不是变压器,形状类似而...

猜你喜欢