查看: 32215|回复: 33

Arduino教程 Lesson 14--自制风扇

[复制链接]
本帖最后由 Jane 于 2014-6-5 17:23 编辑

该教程实验平台:Arduino入门套件
上一篇教程:
Arduino教程 Lesson 13-- 彩灯调光台

由于我们新版的入门套件还未面世,所以对于现在的入门套件还没法做这个实验~当然你也可以自己找材料

这次,我们会做一个小风扇。同时会接触两件新元件——继电器、直流电机。继电器,我们可以理解为是用较小的电流去控制较大电流的一种“自动开关”。在这里,继电器是用来控制电机转动的。

所需材料
  • 1×  5mm LED灯
  • 2×  220欧电阻
  • 1×  按钮
  • 1×  继电器 HRS1H-S -DC5V
  • 1×  小电机
  • 1 × 风扇叶片

STEP 1: 硬件连接

按下图进行连线,按钮连接到数字2。按钮一端连接5V,另一端连接GND,并用一个220Ω的电阻作为下拉电阻,以防引脚悬空干扰。继电器有6个引脚,分别标有序号。1,2引脚为继电器的输入信号,分别接Arduino的数字引脚和GND。3,4,5,6为继电器输出的控制引脚,这里只使用4,6两个引脚。我们把继电器想成一个开关,开关也只要用到两个引脚。


1.jpg


STEP 2: 输入代码
  1. int buttonPin = 2;                          // button连接到数字2
  2. int relayPin = 3;                           // 继电器连接到数字3
  3. int relayState = HIGH;                      // 继电器初始状态为HIGH
  4. int buttonState;                            // 记录button当前状态值
  5. int lastButtonState = LOW;                  // 记录button前一个状态值
  6. long lastDebounceTime = 0;                  
  7. long debounceDelay = 50;                    //去除抖动时间

  8. void setup() {
  9.        pinMode(buttonPin, INPUT);
  10.        pinMode(relayPin, OUTPUT);
  11.   
  12.        digitalWrite(relayPin, relayState);       // 设置继电器的初始状态
  13. }

  14. void loop() {
  15.        int reading = digitalRead(buttonPin);   //reading用来存储buttonPin的数据
  16.   
  17.        // 一旦检测到数据发生变化,记录当前时间
  18.        if (reading != lastButtonState) {   
  19.                    lastDebounceTime = millis();
  20.         }
  21.   
  22.        // 等待50ms,再进行一次判断,是否和当前button状态相同
  23.        // 如果和当前状态不相同,改变button状态
  24.        // 同时,如果button状态为高(也就是被按下),那么就改变继电器的状态
  25.        if ((millis() - lastDebounceTime) > debounceDelay) {
  26.               if (reading != buttonState) {
  27.                       buttonState = reading;
  28.       
  29.                        if (buttonState == HIGH) {
  30.                                  relayState = !relayState;
  31.                        }
  32.                }
  33.          }
  34.          digitalWrite(relayPin, relayState);

  35.          // 改变button前一个状态值
  36.          lastButtonState = reading;
  37. }
复制代码
通过按键,可以控制电机和LED的开和关。



STEP 3: 代码回顾
代码的大部分内容,基本应该没有什么难度了,主要说下按键去抖问题。代码中:
  1.   if (reading != lastButtonState) {   
  2.          lastDebounceTime = millis();
  3.   }
  4.   if ((millis() - lastDebounceTime) > debounceDelay) {
  5.          if (reading != buttonState) {
  6.                ……
  7.          }
  8.   }
复制代码
reading有变化之后,不是立马就采取相应的行动,而是先“按兵不动”,先看看这个信号是不是“错误信号”,所以再等待一阵,(也就是通过millis来实现这个等待过程的),发现确实是前方发过来的正确信号,然后执行相关动作。

之所以这么做的原因是,按键在被按下时,会有个抖动的过程,而不是立马由低变高,或者由高变低。所以这个过程中,可能会产生错误信号,我们通过程序中的这种方法,来解决硬件上的这个问题。


STEP 4:
硬件回顾
继电器
我们可以把继电器理解为一个“开关”,实际上是用比较小的电流去控制较大电流的“开关”。这里只是为了让初学者了解继电器工作原理,所以没有使用较大的电源器件,还是选用是需要5V就能驱动的直流电机。

我们来看下继电器的内部构造:


12.jpg

这款继电器一共有6个引脚。1,2 引脚是用来接Arduino数字引脚和GND。通过数字引脚来驱动继电器。1,2两端为线圈两端。Arduino给HIGH后,线圈中就有电流,线圈就会产生磁性(就像磁铁一样),吸合中间的触片(能听到“哒”一声),常开端(NO)就与公共端导通。相反,如果Arduino给LOW,线圈中没有电流,常闭端(NC)就与公共端导通

所以,电路中我们接了4,6引脚用于控制电机和LED的通断,(当然也可以用引脚3,6)。

直流电机、直流减速电机与舵机的区别
普通直流电机是我们接触比较多的电机。一般只有两个引脚,上电就能转,正负极反接则反向转动。如你所见,它做着周而复始的圆周运动,无法进行角度的控制,不过可以通过电机驱动板,可以对转速进行控制,不过由于普通电机转速过快,所以,一般不直接用在智能小车上。
直流减速电机是在普通电机加上了减速箱,这样便降低了转速,使得普通电机有的更广泛的使用空间,比如可以用于智能小车上。同样也可以通过PWM来进行调速。
舵机也是一种电机,它使用一个反馈系统来控制电机的位置,可以用来控制角度。所以,舵机经常用来控制一些机器人手臂关节的转动。


下一篇教程:Arduino教程 Lesson 15--红外接收


flugkatze  见习技师

发表于 2014-12-22 21:01:14

为什么我接上继电器串口就失效了?拔掉继电器就又能访问串口
回复

使用道具 举报

Jane  管理员
 楼主|

发表于 2014-12-23 15:07:43

flugkatze 发表于 2014-12-22 21:01
为什么我接上继电器串口就失效了?拔掉继电器就又能访问串口

电源有没有接错
回复

使用道具 举报

simon_xu  初级技师

发表于 2014-12-25 23:00:42

为什么电机转2S左右就自动停止了?
回复

使用道具 举报

Jane  管理员
 楼主|

发表于 2014-12-26 10:10:02

simon_xu 发表于 2014-12-25 23:00
为什么电机转2S左右就自动停止了?

可能是我们这批次的电机电流有点大,你联系下我们的售后吧~
回复

使用道具 举报

KinFu  高级技师

发表于 2014-12-26 14:01:35

Jane老师的教程贴总是那么细腻
回复

使用道具 举报

inv  学徒

发表于 2015-1-11 18:47:35

搞不定啊,插上电源风扇直接就转了。唯一的办法就是先不接电扇,然后这时开关可以控制灯开关,然后再插电扇。这时候可以通过按开关打开电扇,但是又关不掉电扇和灯了。。。。。
回复

使用道具 举报

Jane  管理员
 楼主|

发表于 2015-1-12 10:19:48

inv 发表于 2015-1-11 18:47
搞不定啊,插上电源风扇直接就转了。唯一的办法就是先不接电扇,然后这时开关可以控制灯开关,然后再插电扇 ...

电机直接接在UNO上5V和GND能转起来吗?
回复

使用道具 举报

inv  学徒

发表于 2015-1-17 15:45:57

Jane 发表于 2015-1-12 10:19
电机直接接在UNO上5V和GND能转起来吗?

能,一接电直接就转了,代码没起作用。。。
回复

使用道具 举报

Jane  管理员
 楼主|

发表于 2015-1-17 20:04:46

inv 发表于 2015-1-17 15:45
能,一接电直接就转了,代码没起作用。。。

一直都转吗?有没有出现过一会儿就停了的情况
回复

使用道具 举报

Jane  管理员
 楼主|

发表于 2015-1-23 10:30:08

inv 发表于 2015-1-17 15:45
能,一接电直接就转了,代码没起作用。。。

问题解决了吗?
回复

使用道具 举报

Mr.why  见习技师

发表于 2015-2-9 23:09:22

Q1:为什么设buttonState、lastButtonState 2个中间变量?
Q2:最后一句,什么意思
// 改变button前一个状态值
         lastButtonState = reading;
Q3:int relayState = HIGH;这句不是开始就设置继电器4,6脚连通,灯亮电机转。实际效果是灯亮电机先转2s,然后灯灭电机停。。。然后按按钮灯亮电机转。。。再按按钮灯灭电机停。WHY?
回复

使用道具 举报

Jane  管理员
 楼主|

发表于 2015-2-10 10:14:34

Mr.why 发表于 2015-2-9 23:09
Q1:为什么设buttonState、lastButtonState 2个中间变量?
Q2:最后一句,什么意思
// 改变button前一个状 ...

A1:  buttonState是按钮当前的状态,lastButtonState是记录上一个状态的,意义不同的。
A2: lastButtonState = reading;意思是把按钮改变的状态值赋给lastButtonState用于和下一个状态进行比较。
A3: 先排除是不是接线错误了,如果不是的话,不接电机试试看,灯是不是正常运行

回复

使用道具 举报

simonliying  见习技师

发表于 2015-3-13 11:32:32

实际效果是灯亮电机先转2s,然后灯灭电机停。。。然后按按钮灯亮电机转。。。再按按钮灯灭电机停。  将电机和button去掉, 只保留继电器和LED灯, 然后使用最简单的测试程序:

int relayPin = 4;                           // 继电器连接到数字8

void setup() {
        pinMode(relayPin, OUTPUT);
       digitalWrite(relayPin, HIGH);       // 设置继电器的初始状态

}

void loop() {
  // put your main code here, to run repeatedly:

}

加电后灯会点亮1s左右, 然后熄灭。 是否继电器本身有问题啊? 对于初始阶段, 继电器要怎样精准操作呢?
回复

使用道具 举报

simonliying  见习技师

发表于 2015-3-13 11:32:40

实际效果是灯亮电机先转2s,然后灯灭电机停。。。然后按按钮灯亮电机转。。。再按按钮灯灭电机停。  将电机和button去掉, 只保留继电器和LED灯, 然后使用最简单的测试程序:

int relayPin = 4;                           // 继电器连接到数字8

void setup() {
        pinMode(relayPin, OUTPUT);
       digitalWrite(relayPin, HIGH);       // 设置继电器的初始状态

}

void loop() {
  // put your main code here, to run repeatedly:

}

加电后灯会点亮1s左右, 然后熄灭。 是否继电器本身有问题啊? 对于初始阶段, 继电器要怎样精准操作呢?
回复

使用道具 举报

Jane  管理员
 楼主|

发表于 2015-3-13 17:11:14

simonliying 发表于 2015-3-13 11:32
实际效果是灯亮电机先转2s,然后灯灭电机停。。。然后按按钮灯亮电机转。。。再按按钮灯灭电机停。  将电机 ...

你检查下是不是继电器没有连接好,继电器那个引脚比较短,会不会出现没接触好的原因。。
回复

使用道具 举报

simonliying  见习技师

发表于 2015-3-13 17:52:04

继电器的管脚是很短。 是否接触面包班良好我也很难判断。 从自制风扇的表现上来看, 只要过了头1-2秒, 整个操作是正常的,表明继电器的在后面工作是正常的。 就是初始加电的表现不正常。 版主有用新版开发者套件里的继电器和面包板试过吗?
回复

使用道具 举报

Jane  管理员
 楼主|

发表于 2015-3-16 14:45:30

simonliying 发表于 2015-3-13 17:52
继电器的管脚是很短。 是否接触面包班良好我也很难判断。 从自制风扇的表现上来看, 只要过了头1-2秒, 整 ...

回头我试试看哈~
回复

使用道具 举报

Cain  初级技匠

发表于 2015-3-16 19:32:01

simonliying 发表于 2015-3-13 17:52
继电器的管脚是很短。 是否接触面包班良好我也很难判断。 从自制风扇的表现上来看, 只要过了头1-2秒, 整 ...

2s,是板子重启的时间,您可以把int relayState = HIGH;  改成int relayState = LOW;规避了会自动变化的现象。
回复

使用道具 举报

linck  见习技师

发表于 2015-7-28 22:42:07

我是刚买的套件,也是这个问题啊。按下按钮后要么是闪灭,要么是转2s后停止。LED和电机是同步的,去掉电机只要LED,也是同样。反复几次后,WINDOWS提示ARDUINO在USB口上有电涌,怕把电脑弄坏了,就没有再试。

应该是继电器的问题吧?
回复

使用道具 举报

EricKong  学徒

发表于 2015-7-31 19:04:01

我接通电源也是直接电机转了,所以我把电机放在继电器5脚,默认relayState=LOW。

另外我有个问题是关于直流电机对IR的干扰,我用IR电源键控制继电器(开关)进而控制直流电机,启动电机没有问题,但是电机一旦启动,

用于监控红外的串口就是各种错误码刷屏了,根本停不下来。。。


  1. void loop()
  2. {
  3.     //是否接收到解码数据,把接收到的数据存储在变量results中
  4.     if (irrecv.decode(&results))
  5.     {
  6.         //接收到的数据以16进制的方式在串口输出
  7.         Serial.println(results.value, HEX);

  8.         //如果红外的电源键,则处理直流电机开关(继电器)
  9.         if(results.value == 0xFD00FF)
  10.         {
  11.           relayState = !relayState;             // 取反      
  12.           digitalWrite(relayPin,relayState);    // 改变继电器状态        
  13.         }
  14.         irrecv.resume();                        // 继续等待接收下一组信号
  15.     }   
  16. }
复制代码
回复

使用道具 举报

12下一页
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
wifi气象站

硬件清单

btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2019 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail