(1)哈哈!LED!

作为离开电气工程的逃兵,最近想做Arduno,心情很微妙。翻开一本Arduno书的时候,面对书的电子电路组成部分的时候,真的很熟悉也很陌生。(反正当年也认真准备了研究所考试,虽然后来没考上XD)。

为什么想玩阿斗伊诺?想了很久,可能是因为编程在路上积累了几年学习的信心,相反,Ardunio有很多电路模块,可以减轻入门时对电子电路理解的负担,最想尝试的是使用图形编程语言来控制Arduino。因为以前使用图形编程语言的经验总是给我带来一些差异。

就当做是一种挑战吧!重新探索我曾经离开的领域 … XD

我后来选择基于 Scratch 图型化程式语言,目前基于 Scratch 1.6 而建立的 S4A(Scratch for Arduino)是相对来说比较成熟的产品,如果想要基于 Scratch 2.0 的产品,则有 S2A,不过,几经考虑之后,我后来选择试试目前发展快速、基于 Scratch 2.0 而建立的 mBlock(之前命名为 ScratchBot)。

一样地,我想到哪玩到哪,然后留下一些记录,第一个要来玩的,就是点亮 Ardunio 板子上内建的 LED(Light-Emitting Diode)!

mBlock 与 Arduino 环境准备

首先,可以先到 Makeblock Academy ()下载 mBlock 与 Arduino 驱动程式,如果需要最新的版本,可以至 mBlock.cc 下载,两者略有不同,我的文件将先以 Makeblock Academy 下载的版本为开始。

在安装 mBlock 时需要 Adobe AIR,这是 Scratch 2.0 离线版需要的,请确定安装;接着安装 Arduino 驱动程式完成之后,使用 USB 线连接电脑与 Arduino,并在“装置管理员”中确认一下你的连接埠:

可以看到我使用的是 Arduino Uno,Uno 取自意大利文 Uno Punto Zero,也就是 1.0 的意思,用来代表 Arduino 开发软体进入到 1.0(发表于 2011 年 11 月 30 日),写这个文件时,最新的版子是 R3(Revision 3)。

目前 Makeblock Academy 下载回来的 mBlock,安装完后还是会显示 ScratchBot 的图示(而从 mBlock.cc 下载的版本,已经是显示为 mBlock 图示),按下图示启动之后,于选单“连接”中设定你的 Arduino 版子与连接埠:

第一次要先上传韧体到板子,按下“更新固件”开始上传:

闪烁 On-board LED

照理说,要先来个 Hello, World 之类的,不过 Arduino 上没有装置可以画面啊!一般都会接个 LED 让它闪烁来当第一个 Arduino 的操作体验,不过,这边我还没要介绍怎么拉电路,因此我要直接控制 Arduino Uno 板上子上标示为 L 的 LED 灯:

标示为 L 的 LED 灯有内建电阻,并且是吃 D13 这个脚位的输出,因此,只要设定 D13 脚位为 1,也就是高电位(5V),就可以让它亮起来,设定为 0,也就是低电位(0V)时,就可以让 LED 熄灭,你可以建立以下的程式:

想取得控制方块,只要看它的颜色,就可以知道它在哪个分类,例如上图中的方块,可以分别在“事件”、“控制”与“机器人模块”中找到,如程式所示,当你按图中左上方的旗子时,就可以看到标示为 L 的 LED 灯不停重复地,以一秒的间隔进行闪烁。

当然,这只是为了能快速体验一下如何使用 mBlock 来控制 Arduino,如果要开始衔接电路元件或模组,得了解更多 Arduino 板子上的输出入脚位,以及一些电子电路的知识。

顺便一提的是,上头的 Arduino 图是来自于 Fritzing() 这个基于开源硬体精神(open-source hardware initiative)的电路设计软体,软体本身也是开源,可以在官方网站下载!

(2)点亮外接 LED
在〈mBlock & Arduino(1)哈啰!LED!〉中,我们让 Arduino Uno 板子上标示为 L 的 LED 闪烁,这是为了能立即体验一下如何控制 Arduino,接下来,我们要外接 LED,这就需要对 Arduino 板子以及相关电子电路元件有多一点的认识。

认识数位输出/输入脚位

Arduino Uno 的规格说明,可以在官方网站的 Arduino – ArduinoBoardUno (
)中找到,一下子完整认识板子上所有脚位没有意义,因此,我的文件将采用到哪个讲哪个的方式。

想要能点亮外接的 LED,可以使用数位输出/输入脚位 D0 到 D13,当作为输出时,这些脚位的直流电流最高可以是 40 mA,高电位相对于 GND 是 5V,低电位是 0V。

GND 是 Ground 的意思,一般中文常称为共地或接地,不过,“地”这个名称常引起误会,以为它真的是接到地面去了,在这边,Ground 的意思应该是“基准”,电路中有个共同的电位基准时,当我指电路中某点为 5V,就是指相对于共同的电位基准,也就是相对于 GND 的点是 5V。

在 Arduino Uno 板子上,D0 到 D13,以及 GND 接点的位置如下:

认识 LED

LED 的名称是发光二极体(Light-Emitting Diode),是一种半导体二极体,具有阳极和阴极两个端子,一个 LED 元件的两只接脚长度不同,长的接脚是接正极,短的接脚是接负极,也可以借由塑胶外壳上有平面的那边来识别负极所在:

至于半导体二极体的运作方式,最简单的说法是,当二极体被施以正向电压(也就是正极电位高于负极),且电位差达某个值,二极体能够导电(LED 的话会发出亮光),此时二极体正负极电位差几乎固定,称之为顺向偏压(Forward Bias),不同的二极体顺向偏压不同,需要查阅规格才能得知(LED 的话,可参考 LED 条目中的资料),当二极体被施以逆向电压,二极体不会导电。

理想上,希望二极体施于正向电压而导电时,能拥有无限小的电阻,而施以负向电压时拥有无限大的电阻而不导电,也就是希望电压电流曲线可以如下图:

实际上半导体二极体的电压电流曲线,可以参考维基百科 二极体 条目的这张图:

逆向电压实际上是还有极微小的电流,其中 Vbr 是崩溃电压,一般约数十伏特,超过的话二极体会崩溃而导致大量电流通过,无论如何,必须对流经二极体的电流做出限制,以免二极体因为电流过高而烧毁。

在衔接 LED 时,基本上会串接电阻以提供压降、限制电流,LED 一般需要的电流为 20 mA,若 Arduino 输出脚位为高电位 5V,假设 LED 的顺向偏压为 2V,那电阻压降则为 3V,根据欧姆定律 R = V / I,至少应提供 3V / 0.02A,也就是 150 Ω 的电阻,保守起见,常见使用的是串接 220 Ω 的电阻,如下图:

认识电阻色码

每个电阻器上环绕着一圈圈的颜色,大多是四环,也有五环甚至六环,环的颜色各对应至一个数字,可参考 四环电阻色码计算器 中的图片:

电阻连接时没有方向之分,环的读取就如上图,可用电阻上环分布较密的一端为左开始判读,以上图的四环电阻为例,绿对应至 5,蓝对应至 6,黄对应至 10K,这表示电阻值是 560 KΩ,一般都会直接背“黑、棕、红、澄、黄、绿、蓝、紫、灰、白”这个口诀,代表数值 0 到 9,第三个色码如果是黄就是 4,也就要有四个 0,就是 10K 的意思,第四条色码则是容忍值;如果是上图中下方的五环电阻,红、澄、紫、黑分别对应至 2、3、7 与 1Ω,电阻值就是 237 Ω。

懒得记的话,四环电阻色码计算器 中可以直接输入电阻上的色码,它会帮你计算出电阻值,要不然直接在网路上搜寻“电阻色码”,也会找到计算方式,或其他线上计算器。

认识面包板

谈到面包板,就想到以前学校做实验时的恶梦,没想到现在竟然要来介绍它!面包板基本上就是横向连通、直向连通、上下不通,例如:

同一个连通方向,表示每个孔间都是导通的,有的面包板没有上图中蓝与红的部份,如果有的话,通常蓝那列会拿来接 GND,红那列会拿来接电源正端。如果要将上面 LED 连接的概要图,使用面包板衔接的话,可以像是:

线路复杂时,红列接电源正端,蓝列接电源负端是比较方便的作法,当然,对于简单的线路,不一定要这么做。

Arduino Uno 外接 LED

照按以上的说明,如果想要在 Arduino Uno 上外接 LED,并利用 D3 脚位的输出来点亮 LED,可以如下:

程式的撰写与〈mBlock & Arduino(1)哈啰!LED!〉是相同的,你只要将其中的数位脚位 13 改为 3 就可以了。

(3)按钮控制猫咪

在〈mBlock & Arduino(2)点亮外接 LED〉中,看过了如何使用 Arduino 来控制输出脚位,并使用 LED 来得知输出脚位的状态,使用 LED 来检视脚位输出是经常之应用,看过了基本的脚位输出,接下来来看基本的脚位输入,这边要来透过按键开关来控制输入的信号。

认识按键开关

按键之类的开关有好几种,有两针脚、四针脚、六针脚等,两针脚很单纯,就是按下后两个针脚会接通,四针脚或六针脚的话,实际上要看说明,了解哪些脚位是连通,而哪些是由开关控制,以常见的四针脚开关来说,脚位突出的一边在按键按下前彼此不连通,而与对面脚位是连通的:

如果想实际测试按键开关的运作,可以使用 LED,例如设计以下的电路:

如果实际想接在面包板上测试,5V 电源的部份,可以使用 Arduino 上的 5V 脚位,如下所示:

在读取输入信号之前

在〈mBlock & Arduino(2)点亮外接 LED〉中谈过,脚位 D0 到 D13 可以当作数位输出与输入脚位,在这边,我们用其中一个脚位来试着读取按键开关是否按下,不过,并非单纯设计以下的电路就可以了:

这是因为此时输入脚位没有接受任何讯号或输入悬空时,会因为周遭环境的原因(电子杂讯等)而变为不确定的值,因此,在按键实际按下前,输入脚位可以借由一个下拉电阻(Pull-down resistor)连接到 GND,或者是使用一个上拉电阻(Pull-up resistor),将输入脚位保持在已知状态。例如说,若使用下拉电阻,可以如下设计电路:

就大多数的电路而言,可以选用 10K Ω 的电阻(原因与其他考量,可参考 How do I calculate the required value for a pull-up resistor? );上图的设计方式在按键按下时,输入脚位会得到一个高电位值,未按下则是低电位值。

使用上拉电阻的话,可以如下设计电路:

这样的设计方式下,在按键按下时,输入脚位会得到一个低电位值,未按下则是高电位值。

利用按键控制猫咪

你可以利用程式来侦测按键是否按下,通常会使用 LED 灯来作为程式的输出,像是即使使用上拉电阻方式,也是侦测到按键按下时,让 LED 灯点亮,否则 LED 保持在未点亮状态,不过,这边稍微变化一下,希望按键按下时,Scratch 的猫咪可以喵喵叫,这样比较有趣一些,你可以如下拉设电路:

我们打算读取 D7 的输入讯号,接着在 mBlock 中撰写程式如下:

接着试着执行看看程式,在按下按键时,猫咪会发出 meow 的声音,也会显示以下的图样:

附带一提的是,根据 Arduino – Digital Pins 中的说明,数位脚位都内建有上拉电阻,可以借由 pinMode() 为 INPUT_PULLUP 来打开,这样你在连接电路时,可以不用自行设置上拉电阻,不过,在 mBlock 中,并没有对应的控制方块可以使用的样子。

(4)PWM 模拟类比信号

在〈mBlock & Arduino(2)点亮外接 LED〉中谈过,Arduino 中的 D0 到 D13 可以做为数位输出/输入脚位,如果我们想输出类比讯号呢?例如,想要 2V、2.5V、3.5V 之类的的电压输出,而不是只有高电位的 5V 与低电位的 0V 选择。

在 Arduino 上的 A0 到 A5 脚位,似乎有 ANALOG 字样,不过仔细看是 ANALOG IN,也就是 A0 到 A5 脚位,是用来接收类比讯号之用,不是用来输出类比讯号。

如果想要在 Arduino 上输出类比讯号,也是用数位脚位来做,不过,数位脚位不是只有高电位与低电位吗?怎么做出类比讯号的效果?

认识 PWM

PWM 全名 Pulse Width Modulation,可译为脉冲宽度调变,所谓调变,基本上是指将想传送的讯号编码至一个载体(Carrier),举例来说,我们的 AM(Amplitude modulation) 广播,就广播站台将音乐(讯号)编码在指定的频率(也就是载体)之中。

PWM 是使用高、低电压时间周期来为讯号编码,以模拟类比讯号为例,基本原理是若在一个时间周期中,50% 的时间输出高电位 5V,而 50% 输出的时间输出低电位 0V,那么就整个时间周期来说,平均电压可视为 2.5V,类似地,如果 90% 的时间输出高电位 5V,那么就整个时间周期来说,平均电压可视为 4.5V,若 10% 的时间输出高电位 5V,那么就整个时间周期来说,平均电压可视为 0.5V。

输出高电位时间的百分比,称之为 Duty cycle,许多 Arduino 的介绍中若谈到 PWM,都会引用Arduino – PWM的这张图,以便了解 Duty cycle,以及analyWrite之意义:

稍后我们再来谈analogWrite。若想使用 PWM 模拟类比讯号输出,单只是知道 Duty cycle 还不够,如果你频率不够快,例如像〈mBlock & Arduino(2)点亮外接 LED〉一秒高电位、一秒低电位的,那么,你也只会看到 LED 一亮一暗的,也就是说,PWM 最基本的两个参数是 Duty cycle 与时脉周期(Clock cycle),后面会有个范例,使用 Arduino 的 PWM 脚位并调整 Duty cycle(时脉周期由 Arduino 控制),你的 LED 就可以由暗渐亮,就像调整可变电阻一样。

程式实作的 PWM

了解了 PWM 的基本原理,那么先来使用程式实作 PWM(Bit-banging PWM),在 mBlock 中,最基本的方式,是使用等待方块来实作 Duty cycle 与时脉周期,例如:

这样就实作出 Duty cycle 为 90%,而频率为 2 Hz 的 PWM,实际测量结果,电压约是在 4V 左右跳动,如果你将两个输出的 0、1 对调,那实际测量结果,电压约是在 1V 左右跳动,实际接上 LED 的话,因为频率不大,LED 还是一闪一闪,看不太出类比模拟的效果。

这是因为 mBlock 的等待方块可设定的等待值没办法太小(如果使用 Arduino 官方语言,可以使用delayMicroseconds这个可达微秒的函式),只能稍微模拟出这样的效果,实际上使用等待方块,还有无法多工的缺点,我们另外使用 mBlock 可至毫秒的计数器来实作一个,首先,我们先在“资料和指令”中“新增积木指令”:

这个积木指令主要是用来设置一些变数,而这些变数,会用来计算指定的脚位之输出:

dutyCycle在这边是使用百分比指定的,程式会依据dutyCycle的设定,决定指定的数位脚位何时高电位、何时低电位,从这两张图来看,频率被我设定为 20 Hz。

只要绿旗一被点下,这个模拟 PWM 的回圈就会一直进行,为了能看出亮度变化效果,我另外设置了一个回圈:

这个回圈就只是不断改变 Duty cycle,如果接下 LED,这时能看到 LED 会有亮度的差别。

当然,频率还不够快,因此还是会看出 LED 闪烁,不过大致可看出 Duty cycle 设置为不同的值,LED 亮度有所差别。

Arduino 的 PWM 脚位

在 Arduino 的数位脚位旁,如果标示有 ~ 符号,表示那个脚位可用为 PWM 输出脚位,分别是 D3、D5、D6、D9、D10、D11 脚位,可以使用analogWrite函式来设置 Duty cycle 的值,这个函式可用来控制 Arduino 板子上的硬体 PWM,可设置的值为 0 ~ 255,如方才所看到的 PMW 说明图片,0 为 0% 的 Duty cycle,64 为 25%,127 为 50%,依此类推,在 mBlock 中,则是使用“设置 PWM …”这个方块:

这个程式设置 D6 脚位使用 PWM 输出,你可以实际接上 LED,看看亮度的变化情况。

Arduino 板子上的 PWM,实际上有三个计时器,分别控制着两个 PWM 脚位,如果你想做更多的控制,像是不只能设置 0 ~ 255 的 Duty cycle,不过 mBlock 没有直接的指令可以控制,如果你有兴趣,可以使用 Arduino 的官方语言,并参考Secrets of Arduino PWM这篇文章。

(5)可变电阻、ADC 与节拍器

在〈mBlock & Arduino(4)利用 PWM 模拟类比讯号〉中,我们试着使用 PWM 来模拟类比讯号输出,其中谈到 Arduino 脚位 A0 到 A5,实际上是用来做为类比讯号输入,在这一个主题中,我们将使用这些脚位,并搭配可变电阻(Variable Resistor)来制作一个节拍器。

认识可变电阻

为了要能调整节拍器的速度,我们需要一个可调元件,在这边使用可变电阻,顾名思义,借着调整电阻器上的旋钮,就可以改变电阻值,可变电阻上会标示欧姆数,可分为 A(对数型)、B(线性型)与 C(反对数型),分别代表旋转角度与欧姆值的变化关系,以我手边的这颗可变电阻为例,标示为 A10K,表示为 A 型可变电阻,最高电阻值为 10 KΩ。

可以看到可变电阻有三个接脚,外侧两个接脚两边都可以分别接 GND 与电源,而中间的接脚与另两个接脚之间的电阻值,会因为旋转角度而不同:

视外侧接脚哪个衔接 GND 而哪个衔接电源,可变电阻顺时针与逆时针旋转时的电阻值会分别是增加或减少,一般我们操作旋钮的习惯是顺时针增大讯号(例如音量),逆时针减少,因此,如果是上头照片中的 A10K 可变电阻,左边接脚会接 GND,右边接脚会接电源,中间是讯号输出,这么一来,顺时针旋转时,中间接脚与电源间的电阻值会变小,因而电压输出会增加,逆时针旋转则电压会降低。

类比数位转换器

Arduino 内建类比数位转换器(Analog to Digital Converter, ADC),可使用脚位 A0 到 A5 来个 ADC 输入,可读取 0 到 5V 的电压输入,解析度为 10 个位元,也就是读取而得到的值是 0 到 1023。

如果要读取可变电阻的输出,可以如下衔接电路:

我们打算利用可变电阻改变电压,并利用 Arduino 的 ADC 脚位读取电压变化,转换为节拍 BPM(Beats per minute)。

撰写节拍器程式

在 mBlock 中,有个“弹奏鼓声…”的方块,其中“拍”的设定值,是指每几秒打一下鼓,例如,下面这个方块是指每 2 秒打一下鼓,同理类推,设定“拍”为 4 时,表示每 4 秒打一下鼓:

因此,如果你想要 BPM 为 120 时,“拍”的设定就是 60 / 120 = 0.5,也就是半秒打一下鼓,我们希望转动可变电阻时,BPM 可以从 40 到 208,因此设计了以下这个公式:

为了显示目前设定的 BPM,使用了 Scratch 中的猫咪来显示目前的 BPM,而为了无聊一点,让 Scratch 中的猫咪会随着节拍而放大、缩小,这样在视觉与听觉上,都可以有节拍感…XD

感谢CodeData用户:caterpillar的贡献 著作权归作者所有

整理:宁波家电物联网云平台,中科极动云

听说人走路的节奏是 112 BPM,要不要实际写个程式听听看呢?

(6)使用蜂鸣器来打节拍

在〈mBlock & Arduino(5)可变电阻、ADC 与节拍器〉中,我们利用 mBlock 中的“弹奏鼓声…”方块来发声,这样的话,你的 Arduino 就得一直连接着电脑,这个节拍器才能使用,如果要能够不连接电脑(之后会介绍),那么 Arduino 上就得有自己的发声器,像是蜂鸣器。

使用蜂鸣器

声音基本上来自振动,蜂鸣器基本上可分为压电式与电磁式。

压电式蜂鸣器使用压电材料,这类具有压电效应,简单来说,就是被施以压力时会产生电荷,将机械能转换为电能,这称之为“正压电效应”,如果对压电材料施以电场,材料会产生形变,将电能转换为机械能,这称之为“逆压电效应”,压电式蜂鸣器透过对压电材料外加电压的大小、频率等控制,来达到震动的效果,因而能产生声音。电磁式蜂鸣器则是利用电磁方式,透过通电与否将金属膜吸下或放开来达到振动的效果。

知道蜂鸣器的基本原理,就可以自己写个小程式来发声了,接脚有正负之分,你可以如下衔接电路(其实就只要连接正负极就可以了,够简单吧!):

如上图连接的话,透过简单地让脚位 D7 在高低电位间切换,就可以听到蜂鸣器发出声音了:

“播放脚位…”方块

当然,因为受到“等待”方块的限制,这样实际上能发出的频率有限,在 mBlock 的机器人模块中,其实有个“播放脚位…”方块:

这个方块可以指定哪个数位脚位以指定频率、节拍数驱动蜂鸣器,相当于使用 Arduino 官方语言时,可呼叫的tone函式,只不过,在这边频率的设定,直接使用音阶名称 C2 到 D8 的下拉选单,省去你查询音阶对应的频率,如果你只要是播放几个音阶的话,使用这个是还蛮简单的,只不过,如果你想自行输入频率的话,就没办法了,想做个简单的电子琴或歌曲播放,也会麻烦许多,就像 mBlock 内建的“音乐演奏”范例就落落长:

你可以直接开启范例执行看看,听听看蜂鸣器的效果。真的要做比较有弹性的歌曲播放,或者是电子琴也不是不行,就是要对“播放脚位…”方块做点封装,有兴趣可以自己试试 … XD

(mBlock 2.1 之后,“播放脚位…”方块就可以使用下拉选单或自行指定数值了,这样就有弹性的多了。)

使用蜂鸣器来打节拍

使用“播放脚位…”方块来为〈mBlock & Arduino(5)可变电阻、ADC 与节拍器〉中的节拍器打节拍,程式上撰写倒是还蛮简单的,你可以先如下连接电路:

修改一下〈mBlock & Arduino(5)可变电阻、ADC 与节拍器〉的节拍器程式,如果将来打算可以让 Arduino 可以不连接电脑执行程式,与桌面环境中资源控制的方块要移除,像是控制猫咪的相关方块:

接着试着执行看看程式吧!看看效果如何!

(7)七段显示器之 HELLO!

在〈mBlock & Arduino(2)点亮外接 LED〉中,我们简介过 LED,依需求而定,你可以连接多个 LED 来达到显示目的,像是用多个 LED 制作跑马灯,或者是双色、三色 LED、四色 LED,甚至七段显示器等。

双色、三色、四色 LED

举例来说,双色 LED 可以自行连接线路如下:

如果左边是红色 LED,而右边是绿色 LED,那么上图的接法会是亮红灯,如果对调电源与 GND,那么就会亮绿灯,市面上有现成的、具有两个接脚的双色 LED,是直接将两个 LED 做在同一个塑胶套中,方便想用同一个灯来显示两种状态时使用。三色 LED 是类似的,将三个不同颜色的 LED 做在同一个同一个塑胶套中,通常是 RGB 三色,有多个针脚可用来控制显示的颜色,例如四个针脚的三色 LED:

不同厂商制作的 LED,可能会有不同的针脚配置,基本上确认一下规格就是了,四色 LED 也是类似,有点像是双色 LED 再行电路配置一下:

七段显示器

那么七段显示器呢?实际上就是将七个 LED 连接起来,以便显示数字或字元的元件,有的七段显示器会多一个显示小数点的 LED,生活中应该很常看到这类元件,像是电梯楼层显示、银行叫号机等都看得到。

从上图中可以看出,如何控制电压的方向来令七段显示器的不同 LED 显示,以便达到显示数字或字元,七段显示器通常有十个脚位,其中有两个脚位是连通(这是为了电路布线方便),且与 LED 的阳极或阴极是共用的,例如,上图中的脚位 3 与 8 与 LED 的阳极是共用的,称为共阳极(Common anode)七段显示器,为了让 LED 点亮,对应的 LED 阴极必须是低电位输出,如果你的电路输出讯号至七段显示器脚位是低电位,就使用共阳极。

若是共阴极(Common cathode)则相反,有两个脚位与 LED 脚位的阴极是共用的,例如:

因此,为了让 LED 点亮,对应的 LED 阳极必须是高电位输出,如果你的电路输出讯号至七段显示器脚位是高电位,就使用共阴极。

(有些电路模组会有共阳、共阴两种选择,由于共阳极脚位可以接能供应较大电流的电源,可以不用受限于 Arduino 最大电流 40 mA 的限制,若驱动之元件需要较大电流时可以采用。)

常见的七段显示器通常会有十个脚位,分为两排各五个脚位,两排中间的脚位通常就是共阳或共阴脚位,例如前面的图中,可以看出右排中间脚位与左排中间脚位被细线图示为连通,实际的脚位,还是要查看规格说明,或者是实际使用电位计或电池进行测试。

当然,单一个七段显示器会占用许多输出脚位,如果要多位数使用时,输出脚位将会不够使用,这时可以使用扫描的方式,一次显示一个七段显示器,速度很快下,看来就会像是同时显示,这之后有机会再来看,这边先看看如何控制单一个七段显示器。

用七段显示器说 HELLO

了解了七段显示器的运作,接下来我们来用程式控制 Arduino,令其连接的七段显示器可以显示 HELLO 字样,以下的电路图是依 Fritzing 中的七段显示器图样,并采用共阴极方式来连接,你可以视实际手边的七段显示器来调整:

接下来就是写程式控制了,基本上,只要令对应的脚位为高脚位就可以了,不过,使用程式逐行设置脚位的话,是很没有效率的事,若能将脚位对应设置为清单(阵列),然后用跑回圈的方式,程式会比较简短而有弹性一些,例如配合上图,H、E、L、O 的清单可以是:

这样的话,若要显示 H,可以如下跑回圈:

不过,问题在于,mBlock 中自定义的方块,无法传递清单,这表示,你得复制上头的自订方块,然后改为跑 E 清单,再复制上头的自订方块,然后改为跑 o 清单 …. XD

这样看起来很蠢,因为多一个字元或数字要显示,就得复制一次,怎么办呢?不能传清单的话,那改传字串好了,我们定义出 H、E、L、O 需要的字串:

在这边用 H 表示高电压,L 表示低电压,这么一来,你就可以只用一个“设置七段显示器”自订方块,来显示想要的字样:

如果想要更多的数字或字元显示,那么只要多定义一个字串就可以了,比逐行设定脚位要来得方便多了。

(8)光敏电阻、亮度感应器与光线追踪器

光敏电阻(Photo-sensitive resistor)的电阻值与光线有关,照射于感光面的光线亮度增加时,电阻值会变小,亮度减少时电阻值会加大,其原理是光线照射于半导体,原本稳定的电子受到激发而成为自由电子,常见的材料为硫化镉(Cds)或硒化镉(CdSe),因而常用 Cds 代表光敏电阻。

亮度感应器

由于光敏电阻会因为光照而使得电阻发生改变,若对光敏电阻施以电压,两端的电压就会因为光照发生的电阻值改变,使得压降也跟着变化,我们可以利用这个特性来制作亮度感应器,

如上图的电路设计,输出脚位的电压值会是5 * R2/(R1 + R2),一般光敏电阻的电阻变化,大概是在 10M Ω(黑暗)到 1K Ω(置于阳光下)左右(如果直接以强光接近照射,电阻值还会更低一些),如果要精确地量测照度与电阻的关系,可以用专用照度计来量得照度与电阻之间的关系。

在这边就简单一点,我在目前室内合适的亮度下,量得的光敏电阻值约为 3K Ω 上下,按照上图的话,输出脚位的电压值会是在 3.8 V 左右,接到 Ardunio 的类比输入脚位,应当可以量得 800 左右的数值,你可以如下设计电路:

只要设计一个简单的小程式,就是阳春的照度计了 … XD

当然,这边的照度值不是公定的照度单位,只是从类比输入脚位量得的值,仅供亮度的相对参考,试着增强或遮挡至光敏电阻的光线,你就会看到数值会有不同的变化:

如果亮度感应器的敏感度设计的好一些,搭配自走车,就可以做个简单的循迹车了。

简易光线追踪器

如果会实作简单的亮度感应器,那么就可以用多个亮度感应器,来实作简单的光线追踪了,例如,可使用两个亮度感应器,侦测左右两边的亮度差异,如果两边亮度差异在一定范围内,例如 50 以内,两边 LED 就同时亮,表示亮度差不多,若左边比右边的亮度高 50 以上,就亮左边,反之就是亮右边的 LED,你可以如下设计电路:

程式的撰写则可以如下:

因为我手边仅有的两个光敏电阻规格不同,同样的光源下,测出来的值不太一样,左边那颗比右边那颗约少了 150 左右,因此,在程式中我做了些修正 … XD

(9)伺服马达(舵机)控制

伺服马达(Servo motor)英文常简称 Servo,中文也有人称伺服机,由控制电路、齿轮、直流马达等组成,可使用〈mBlock & Arduino(4)利用 PWM 模拟类比讯号〉中谈过的 PWM 技术来控制马达转动角度,像Plotclock就应用了三个伺服马达,以手臂在白板上绘制出目前的时间。

伺服马达控制原理

伺服马达的基本原理是接受 PWM 讯号,经由内部电路计算出马达的转动角度,根据我查到的资料来看,大多数伺服马达旋转角度是 0 到 180 度,PWM 讯号的频率必须是 50 Hz,控制马达角度的脉冲持续时间约是 1.0 ms 到 2.0 ms,脉冲持续时间若为 1.0 ms 时角度为 0 度,1.2 ms 时角度为 45 度,1.5 ms 时角度为 90 度,2.0 ms 时角度为 180 度。

Plotclock 用的是Tower Pro 9g servos(SG90 digital servo),为三线式伺服马达,红线接电源,棕色的线接 GND,橘色线为讯号线:

在 Fritzing 中,是以红色线接电源,黑色线接地,黄色为讯号线作代表,你可以如下连接线路:

如果直接使用 Arduino 官方语言,可以使用delayMicroseconds函式来控制脉冲宽度,不过 mBlock 中只有“等待”方块,没办法达到这么短的时间控制,然而,mBlock 中有个“设置伺服马达脚位…”的方块,可以直接指定马达转动角度,例如,以下的程式,可以一秒为间隔,不断转动马达为 0、45、90、135 与 180 度:

虽然使用了 PWM 讯号来控制马达转动,不过,这不表示要使用 Arduino 的 PWM 脚位,只不过根据Servo library的说明,除了 Arduino Mega 之外,如果使用了 Arduino 的 Servo 程式库,D9 与 D10 脚位的 PWM 功能就会被停用,因此,通常会把伺服马达的讯号线接在 D9 或 D10 脚位,实际测试 mBlock 的“设置伺服马达脚位…”方块时,也是如此。

有指针的亮度感应器

在〈mBlock & Arduino(8)光敏电阻、亮度感应器与光线追踪器〉中,我们使用光敏电阻制作了简单的亮度感应器,你可以加上伺服马达,配合 SG90 的手臂,作个有指针的亮度感应器,你可以如下拉设电路:

实际测试我手中的光敏电阻,完全盖住它的话,类比输入脚位约可量得 400 左右的值,以手电筒直接照射下,约为 1000 出头的值,因此暂且定义全暗为 400,全亮为 1000,这个范围要转动马达 0 到 180 度,因此,每个类比输入量得的值减去 400,再乘上 0.3,就是打算转动的角度:

因为我们读取指针的习惯,多半是顺时针方向是越来越大,这正好与伺服马达的角度计算方向相反,所以使用 180 减去算出来的角度,就可以改为顺时针指示亮度大小。

(10)mBlock 2.1.4 与 Arduino IDE

到目前为止,可以看到有些 Arduino 的函式,由于受到 mBlock 提供的积木功能而无法直接使用,照理来说,因为 mBlock 是基于 Scratch,应可以撰写Scratch Extensions,而按照Scratchbot新功能介绍的说明,可以透过 mBlock 中 ext 中 s2e 等档案的载入来自行扩充积木,不过,要修改的不是 mBlock 安装目录下的东西,而是 C:Users使用者DocumentsmBlocklibraries 下的档案,这点要注意!

升级至 mBlock 2.1.4

在 mBlock 2.1.4 中,可以使用“编辑/Arduino mode”,这可以看到积木程式转换为 Arduino 官方语言后的写法:

当检视画面转换为 Arduino mode 时,Arduino 不支援的指令,对应的 Scratch 积木方块就不能使用,因此,“事件”中的“当绿旗被点一下”的积木,要改成“Arduino 主程式”积木,而上图是〈mBlock & Arduino(8)光敏电阻、亮度感应器与光线追踪器〉中的程式,在 Arduino mode 中转换的结果。

这对于写程式不怎么熟的人来说还不错,大部份的时间还是可以使用积木来搭建程式,并看看 Arduino 的对应程式码,逐渐熟悉官方语言的写法,就算不想使用官方语言,也可以在积木程式搭建好之后,按下“用 Arduino IDE 编辑”,作些小修改,照样可以完成想要的功能,这样应该比写扩充来得简单一些 … XD

只是,这样就不能使用 Arduino 与 Scratch 直接互动,不过,程式写好了,就可以直接上传至 Arduino,不需要使用 USB 连接电脑了,只要透过 USB 或者是 2.1 mm 的 power jack 来外接电源,就可以执行了。

用 Arduino IDE 编辑

如果想要在 mBlock 的 Arduino mode 中,按下“用 Arduino IDE 编辑”来修改程式,必须下载、安装Arduino IDE,安装好之后,可以在“工具/板子”中设定你的 Arduino 板子,在“工具/序列埠”中设定连接埠:

在上传至 Arduino 之前,要先取消 mBlock 中的连接埠指定,这样才不会造成这两个软体要同时存取连接埠的冲突,接着执行“档案/上传”,就可以将程式上传至 Arduino 了!

如果你的程式码不需要经由 Arduino IDE 修改,也可以直接在 Arduino mode 下,按下“上传至 Arduino”按钮,这会将程式码编译并直接上传至 Arduino。

如果自行上传程式至 Arduino 了,无论是使用 Arduino IDE 上传,或者是在 mBlock 中按下“上传至 Arduino”按钮,想要再度使用 mBlock 控制 Arduino 的话,得记得重新上传 mBlock 的韧体(也就是在指定连接埠之后,再执行一次“串口连接/更新固件”)。

使用 PWM 控制伺服马达

在〈mBlock & Arduino(9)伺服马达控制〉中我们谈过,可使用 PWM 来控制伺服马达转动角度,不过,这要使用到delayMicroseconds函式,而 mBlock 中没有对应的方块,不过,你可以先设计以下的程式:

如果“等待”方块可以支援到如图设定的秒数,在切换至 Arduino mode 之后,直接按下“上传至 Arduino”按钮,伺服马达应该会转动 90 度,不过,等待方块对应的是delay函式,显然没办法支援到这么小的秒数设定,以我实际的测试为例,马达会转动,不过没有转动到 90 度左右。

这时可以按下“使用 Arduino IDE”编辑,找出delay(1000 * 0.0015),将之修改为delayMicroseconds(1500),之后执行“档案/上传”,在程式完成上传后,你的马达应该就可以转动 90 度左右了!

升级 mBlock 2.1.4 后的小问题

附带一提的是,mBlock 2.1.4 的“设置伺服马达脚位…”的角度指定,改成了下拉选单的方式:

这样的设计下,还是可以自行指定角度,不过,之前版本是只有自行指定角度而没有下拉选单,也因此,如果你开启之前 mBlock 版本下写的程式,而其中用到了“设置伺服马达脚位…”的话,新版的 mBlock 就不认得了:

这时记得修正为新的积木方块就是了 … XD

(11)认识红外线接收与发射

我们平常接触红外线的应用,像是电视机、冷气机的遥控器就是个红外线发射器,而电视机、冷气机上则有红外线接收器。

红外线接收器与发射器

人类可见光约为 390 到 700 nm(奈米),其中可见的红光波长约为 620 至 750 nm 左右,而波长超过 760 nm 的光,人类无法感知,称为红外光,一般我们还会听到有近红外光、远红外光等分类,这在不同领域中有不同的分类。

电视机、冷气机等一般常使用 940 nm 波长的红外光,以避免太阳光、室内光源等发出的红外光干扰,其他还有 850 nm、860 nm 等其他波长,最好能让接收器与发射器规格一致,以免造成误判。

上图左侧是红外线接收器,我手边这只三个接脚由左至右分别是讯号、GND 与电源,有的接收器 GND 与电源线会相反,使用时要确认一下。

由于生活周遭物品也会不定时地散发红外光,红外线接收器设计为只对特定频率有反应,常见使用的是 38k Hz;红外线发射器就是个 LED,可发出特定波长的红外线,在 Arduino,可以使用tone函式(是之前谈蜂呜器时有提过)指定以特定频率(像是 38k Hz)发射红外线。

使用 mBlock 测试红外线接收器

如果想要简单地体验、测试一下红外线接收器,可以如下衔接电路:

如果使用 mBlock 2.1 的话,可以如下撰写程式:

如上图撰写程式的话,在还没按上遥控器时,从红外线接收器多半就会收到一堆 1 的讯号,遥控器实际上是有特定编码地发射红外线讯号,你可以在运行程式之后,拿起家里的电视遥控器对着接收器发射,在接收器收到 0 的讯号时,猫咪会以“收到遥控器讯号”的提示文字表示。

使用 IRremote 测试红外线接收器

如果想要用红外线接收器解码遥控器的红外线指令,可以使用IRremote程式库搭配 Arduino IDE 来快速地体验一下,可以到 IRremote 的 Github 按下“Download ZIP”,会下载一个
Arduino-IRremo 档案,解开后将其中目录更名为 Arduino-IRremote,并将整个目录置于 Arduino IDE 安装目录的 libraries 之中:

接着开启 Arduino IDE,就可以在“档案/范例”中,看到 IRremote 相关范例:

如果想测试一下电视遥控器的指令解码,可以开启“IRrecvDemo”范例,电路如先前看到的图衔接就可以了,这个范例程式会从 D11 接收红外线讯号并解码,直接将程式上传至 Arduino,并执行“工具/序列埠监控视窗”,然后按下电视遥控器的电源键,你应该可以看到对应的解码讯息出现:

使用 IRremote 测试红外线发射器

如果使用 mBlock 2.1,那么“播放脚位…”这方块,可以直接指定频率,驱动红外线发射器发出红外线:

若要能发出如遥控器的各种指令红外光,这在 mBlock 中自行以积木建构会是个大工程,在之前的 IRremote 范例中,可以看到“IRsendDemo”范例,可以使用这个范例来测试红外线发射:

按照注解来看,这个范例可以发出 Sony 电视机的电源红外线指令,至于那个Serial.read的if判断,是要看看有无从“序列埠监控视窗”收到输入,也就是你可在先前看到的“序列埠监控视窗”中输入文字然后按下“传送”,这样if条件就会成立,然后按照程式流程发出电源红外线指令,如果不想这么麻烦,就将if的部份注解掉,这样就会不断地发出电源红外线指令了。

电路的部份,只需要如下衔接就可以了,要注意的是,由于 IRremote 的限制,你只能用 D3 脚位来送出讯号:

如果需要测试一下是不是正确地发出红外线指令,你需要另一块 Arduino 板子,如先前在测试接收器的电路的方式衔接,然后上传“IRrecvDemo”范例,那么在“序列埠监控视窗”中,你就可以看到以下的解码讯息:

(12)使用超音波感应器测量距离

超音波感应器蛮常出现在电子机器人的产品上,通常是用来测量距离,超音波感应器各有一个发射及接收超音波的零件,活像两颗大大的眼睛,在制作机器人时,就经常成为造型之一 … XD

认识超音波感应器

如上图看到的,我手边这颗超音波感应器为HC-SR04,左边被标示为 T 的那颗是发射器(Transmitter),会发出 40 kHz 的声波,这个声波超出人类可感知的 20 kHz 上限,因此才称之为超音波,右边那颗被标示为 R 的是接收器(Receiver),可接收超音波。

HC-SR04 脚位从左至右分别为 Vcc、Trig、Echo 与 GND,Vcc 与 GND 就是接 5V 电源及 GND 了,Trig 为输入脚位,Echo 为输出脚位,超音波的发射与接收,就是靠 Trig 与 Echo 这两个脚位,如果你送出 10 微秒的 5V 高电位讯号给 Trig,就会触发超音波的发射,接着 Echo 脚位就会处于 5V 高电位状态,如果接收到反射的超音波讯号,那么 Echo 脚位就会处于 0V 低电位状态:

因此,在超音波发射之后,Echo 的高电位持续时间,就可以搭配音波速度每秒 343.2 公尺,也就是每公分要花费 29.1 微秒左右,计算出超音波感应器与障碍物之间的距离,记得音波往返是走了两倍距离,因此 Echo 的高电位持续时间要除以 2,再用来除以 29.1 微秒,才是与障碍物之间的距离。

如果使用 Arduino 官方语言的话,可以如下撰写程式,以取得超音波感应器与障碍物之间的距离:

pulseIn函式可以计算指定脚位的高电位或低电位持续时间,单位是微秒。

使用 mBlock 超音波感应器方块

嗯?delayMicroseconds与pulseIn在 mBlock 中并没有对应的方块,因此,没什么好继续介绍的了?

实际上,在 mBlock 2.1 中,机器人模块中的 Makeblock 区块里有个“超音波感应器”方块,这原是搭配 Makeblock 超音波感应器模组而使用,这个超音波感应器模组使用 RJ11 接头,而 Makeblock 在 Arduino 板子上设置了八个 RJ11 连接埠,你可以在Me-Baseboard看到相关图片说明。

在说明中,可以看到 Ports on Baseboard Orion to pins on Arduino UNO 这张图,假设我想将超音波感应器连接在 3 号连接埠,它对应的脚位是 D12 与 D13,而在The Upgrade of Me Series Electronic Modules的说明中可以看到,Makeblock 的超音波感应器模组,似乎只是将 Vcc、Trig、Echo 与 GND,直接对应至 RJ11 的相关接点,因此,就来试试看用这个方块吧!

搭配上面這個程式,試著使用以下的電路連接,Trig 連接 D12,Echo 連接 D13:

接著執行程式,你就可以看到貓咪跟你報告距離了 … XD

如果你試著使用 mBlock 超音波感應器方塊,然後轉為 Arduino mode 檢視 Arduino 原始碼,可以發現,它實際上是 MeUltrasonic 程式庫,這可以在 mBlock 安裝目錄的
ext/libraries/makeblock/src 中找到對應的原始碼,其中控制超音波感應器的程式碼,主要是在measure函式:

MePort的dWrite2中,基本上就是在对应脚位作digitalWrite的动作(依 makeblock 的埠决定哪个脚位):

依这个写法模式,似乎很像是 HC-SR04,不过,依上面的程式码来看,它都只用到s2,也就是脚位13,为什么呢?因为 Makeblock 最新的超音波感应器 V3.0,可以自行使用杜邦线接线的脚位只有三个,三个脚位中,有两个分别是接电源与 GND,一个是信号接脚,这意谓着,Trig 与 Echo 必须使用同一个脚位,这也就是为什么,在measure的程式码中,看到的都只有使用s2脚位。

可是 HC-SR04 是四个脚位,Trig 是其中独立的一个脚位,怎么能适用“超音波感应器”方块呢?自行触发 Trig 啰!只是直接使用“设置数位脚位”方块的速度不够快,因此,我想到的是,使用“播放脚位”方块,这可以控制脚位电压高低的频率,建立起类似以下的效果:

简单来说,最后我就只是利用了“超音波感应器”方块底层的pulseIn来取得回波时间而已,这个方法下测出来的距离数值会跳动,不过大致上勉强可用啦!

(这个方法比较适用于 mBlock 2.1.4,在 mBlock 2.1.5 中,韧体上似乎做了些修改,虽然还是可以用相同方法,不过,跳动的范围会变大许多。)

超音波搭配七段显示器

那么,就也来回顾一下〈mBlock & Arduino(7)七段显示器之 HELLO!〉,试着将超音波感应器量得的距离,使用七段显示器来回报吧!

因为只有一颗七段显示器,超过 8 公分就一律显示为 0 了 … XD

清单 numbers 使用字串编码 0 到 8 的数字:

(13)使用摇杆控制

摇杆这东西,经常可见到它的应用,电玩设备就不用说了,我前阵子刚挂掉的行车记录器,上头也有个小摇杆,主要用来上下左右操控选单,以及按下摇杆确认选项 … XD

认识类比摇杆

不同厂商制作的类比摇杆,脚位与标示上可能会有所不同,不过基本上会有五个脚位,分别为电源、GND、X 轴、Y 轴、开关,以我手中的 Keyes_Sjoys 来说:

从左至右的接脚顺序与标示分别是 GND、+5V、VRx、VRy、SW,SW 就是开关输出的意思,在接好 +5V 与 GND,而摇杆不按下的情况下,Keyes_Sjoys 的 SW 会有电压输出,按下摇杆的话,SW 会是 0V。

至于 VRx 与 VRy 输出,是以类别电压输出来表示目前摇杆的方向状态,在未操作摇杆的情况下,VRx 与 VRy 大致是在 2.5V,如果在 X 方向移动,VRx 会有 0 到 5V 变化,如果在 Y 方向移动,VRy 也是有 0 到 5V 变化。

因此,可以将 VRx 与 VRy 接到 Arduino 的类别脚位,依摇杆操作的方向,我实际量得 Arduino 的类比输入值变化为:

使用摇杆控制猫咪

在 Fritzing 中有个通用的摇杆元件,接脚顺序与标示则分别是 VCC、VERT、HORZ、SEL、GND,SEL 就是选择,其实也就是开关的意思:

因此,如果要使用摇杆控制猫咪,可以如下衔接电路,VCC、VERT、HORZ、SEL、GND,SEL 等脚位,就对应至你实际使用的摇杆模组脚位即可:

我要使用摇杆来控制猫咪的上、下、左、右移动,而按下摇杆,猫咪会发出“喵”一声,为了符合操作习惯,以向右为 X 正方向,而向上为 Y 正方向,因此,我用 488 减去 Arduino 从 Keyes_Sjoys 的 VRy 量得的值:

你也可以挑战使用摇杆来控制 3D 立方体旋转喔!

这是自己用“画笔”绘制的,一点点电脑图学的应用,最主要的是,知道 x-y-z 三维座标中某个点,如何绕轴旋转,这部份可参考〈三维直角座标之绕轴旋转〉。

然后,正立方体以 (0, 0, 0) 为中心,订出八个顶点,这部份可参考〈顶点索引阵列〉,只要看第一张图就可以了,我没有用顶点索引阵列,因为在 Scratch(mBlock) 中没办法,因为它的程式元素太少,难以实作顶点索引阵列,因此,我简化了绘图,用最简单(但重复)的方法,直接跑一维清单而已 … 就只是程式码重复了四次,理论上是要跑六个面,不过,跑四个面,每个边就都至少画过一次了 … XD

有兴趣研究一下电脑图学的,可以参考一下我的〈电脑图学入门〉文件。

(14)使用人体动作感应器

被动式红外线感应器(Passive Infrared Sensor, PIR)也经常被称为 PIR 动作感应器(PIR Motion Sensor),是一种可侦测红外线的感测器,生活中许多物品都会发出红外线,而 PIR 主要是侦测人体发出的红外线变化,来判断是否有人体移动发生。

相对于被动式红外线感应器的是主动式红外线感应器,像是洗手台的感应式水龙头,就装有主动式红外线感应器,感应器会主动发射红外线,如果有物体接近遮挡,红外线会反射,依此判断是否要供水。

认识 PIR 模组

PIR 模组外观上可以看到一个白色半球体透镜,你可以打开它,里头可看到 PIR 主要用来感测微量讯号的热电感应器(Pyroelectricity Sensor):

上图中,你可以看到热电感应器下方有两个可焊接的脚位(在 VCC 脚位上方),两个脚位间的电阻值必须够大,PIR 才会作动,你可以接上光敏电阻,当光线越暗,光敏电阻的电阻值就会越大,因此可让 PIR 在黑暗的环境中才作动。

在 PIR 的底部,可以看到 VCC、OUT 与 GND 三个脚位:

我手边的这个 PIR 模组为 DSN-FIR800,感测到红外线变化时,OUT 会输出 3.3V 的电压,并持续一段延迟时间后,再回到 0V 电压。

延迟时间可以透过下图 Tx 可变电阻(使用一字或十字起子)来调整,下图中 Sx 可变电阻,则可用来调整敏感度,对可变电阻顺时针转动 Tx,延迟时间加长(零点几秒到几十分钟),顺时针转动 Sx,可感应的距离增加(约 3 公尺到 7 公尺)。

DSN-FIR800 预设是可重复触发(在上图中左下标示为 H 与 L 的地方调整,连接中间与 H 表示可重复触发),也就是当感测到红外线变化而 OUT 输出 3.3V 电压,在延迟时间内若持续感测到红外线变化,那么就会持续保持 3.3V 电压,直到不再感测到红外线变化后一段延迟时间,才将电压降为 0V,这通常用于判断,人体是否有持续动作(或太久没动静)的场合。

有些厂商制作的模组,可以使用 Jumper 在可重复与不可重复触发之间做调整,会比较方便,不可重复触发,是当感测到红外线变化而 OUT 输出 3.3V 电压,无论延迟时间内有无感测到红外线变化,时间一到就会先降为 0V 电压。

连接 PIR 后,需要有一段几十秒的暖机时间,在这段时间内红外线变化的输出会是不稳定的状态。

感应人体动作来点亮 LED

如果想使用 mBlock 与 Arduino 来取得 PIR 的感应资料,并点亮 LED,可以如下连接电路,其中红线要实际上对应至你的感应器 VCC 脚位,黑线对应至 GND 脚位:

程式很简单,就是根据 OUT 脚位的电位,决定要不要让 LED 点亮:

程式执行后,用手试着在 PIR 前晃动一下,就会看到 LED 点亮,实际上,你可能是在感应到人体移动之后,作些额外的程式动作,而不单只是点亮 LED,因为如果单纯只是要点亮 LED(或者是搭配继电器点亮灯炮),并不需要程式,只要如下连接电路也可以:

如果你手边有光敏电阻,想要测试一下黑暗环境才使得 PIR 作动,那可以如下作暂时性的连接:

这么一来,只有在拿布盖住光敏电阻的情况下,PIR 才会作动,此时用手试着在 PIR 前晃动,LED 才会点亮。

(15)认识晶体管与继电器

Arduino 的 I/O 脚位可供给的电压、电流有限,只能用于 LED 这类小元件,对于需要更高电压或电流的设备,像是直流马达、大型电器等就没办法负担,对于小型直流马达等元件,可以使用晶体管(Transistor)来供给较大量的电流,对于大型电器,可以透过继电器(Relay)来控制。

认识晶体管

实际上,提到晶体管时,多半是指双极型晶体管(Bipolar junction transistor, BJT),依组合的半导体材料,可以分为 NPN 与 PNP 两大类,以 NPN 晶体管为例,是由 N 型半导体与 P 型半导体组合而成:

晶体管有两接面、三个端点,端点分别为集极(Collector)、基极(Base)与射极(Emitter),NPN 晶体管的基本特性是,射极电流 Ie 为基极电流 Ib 与集极电流 Ic 之和,而增益 α = Ic / Ie,β = Ic / Ib,Ib 通常远小于 Ic。

当三个端点施加之偏压不同时,晶体管会处于不同状态:

B-E 为顺向偏压,且 B-C 为顺向偏压时,此时晶体管状态处于饱和区(Saturation region),此时 C 与 E 可视为短路,依电路实际连接情况,Ic 会处于一个饱和电流值。

B-E 为逆向偏压,且 B-C 为逆向偏压时,此时电晶体状态处于截止区(Cutoff region),此时 C 与 E 可视为开路,不过,实际上还是会有少量电流通过,这个现象称为“漏电”(Leakage)。

B-E 为顺向偏压,且 B-C 为逆向偏压时,此时晶体管状态处于动作区(Active region),此时可用于信号放大。

各区实际的偏压,以及 α、β 等值,需要查询晶体管的规格书而定,如果想将晶体管作为开关使用,基本电路之一如下:

如果 Vi 处于高电位状态,那么流经基极的电流 Ib 就是 (Vi – Vbe) / Rb,而流经集极的电流就是 Ic = β * Ib,因此,可以用 Rb 来控制流经 Rl 的电流。

举个例子来说,以下的电路连接,可以让我手边的 2N3904 电晶体驱动一个直流小马达(不过会很烫,不要通电太久…XD):

你可以透过一个小程式来测试一下:

执行程式的话,你就会看到直流马达每转动一秒就停一秒,如果你直接将直流马达一端接到脚位 D8,一端接 GND,在脚位为高电位时,会因为电流不足,无法驱动直流小马达。

如果想驱动 9V 或 12V 以上的马达,可以如下:

由于马达是电力产生磁力,而磁力与马达内部磁铁作用而产生转动,为了避免马达停止供电瞬间而产生的反动电压,会加上一个二极体加以保护。

(如果想运用晶体管提供更大的电流来驱动马达,可以使用两个或多个晶体管的组合,像是达灵顿晶体管;有些 Arduino 相容板,像是Motoduino,本身就内建了可驱动马达的电路,想做马达驱动相关产品时很方便。)

认识继电器

如果要控制电力需求更大的电器,那么可以使用继电器,若是常见的电磁式继电器,其运作原理可使用下图来表示:

当脚位 D8 送出高电位时,晶体管会导通而使得线圈通过电流,因而产生磁力将开关吸合,因而导通电路,脚位 D8 送出低电位时,电流停止通过线圈,磁力消失而开关回到原位,为了避免反动电压,会加上一个二极体保护。

市面上有一些继电器模组,本身已经将相关电阻、二极体与晶体管兜好,例如我手边这颗 Keyes_SRly,还有 LED 显示继电器是否作动:

如果你买的继电器,只是上头蓝色的元件,那么就必须如先前介绍,自行将相关电阻、二极体与晶体管兜好,如果是继电器模组,就只可以直接使用。

首先要注意的是继电器本身的规格,例如上头 SRD-05VDC-SL-C 这个继电器,适用于 10A 的 250V 与 125V 交流电源,以及 10A 的 30V 与 28V 直流电源。

继电器模组上有三个接点,中间那个是共用接点(COMMON),相当于先前概要图中的第 2 个接点,NO 表示常开(Normal Open),也就是平时与共用接点保持开路,相当于先前概要图中第 3 个接点,NC 表示常关(Normal Close),表示平时与共用接点处于接通状态。

继电器的接脚有三个,也就是会有 Vcc、GND 以及开关三个接脚,为了安全起见,这边还是使用继电器控制直流小马达来试试看:

同样只要使用上头撰写的小程式,测试看看直流小马达是否如预期般运作(你还可以听见继电器吸合时滴答滴答的声音)。

(17)四位数七段显示器

在〈mBlock & Arduino(7)七段显示器之 HELLO!〉中谈过七段显示器的原理与运用,如果你需要多个位数,基本上可以自行连接多个七段显示器,只是七段显示器需要的脚位很多啊?Arduino 脚位不够用怎么办?

两位数七段显示器

如果想要自行接线,设计出两位数七段显示器,若使用共阴极七段显示器,可以如下设置电路:

这样的电路,可以使用 10 个脚位,来控制两个七段显示器,其中 D3 到 D10,可分别控制七段显示器上的 LED,而 D13 与 D12,可控制左边与右边的七段显示器哪个要显示,如果 D13 为高电位而 D12 为低电位,那么右边的七段显示器会依 D3 到 D10 哪些脚位为高电位而显示,如果 D13 为低电位而 D12 为高电位,那么左边的七段显示器会依 D3 到 D10 哪些脚位为高电位而显示。

这样不是一次只能显示一个七段显示器吗?没错!不过,只要 D13 与 D12 切换速度够快,那么就会像是同时点亮两个七段显示器!类似地,你可以衔接三位数、四位数等七段显示器!

四位数七段显示器

如果不想要自行接线路,那么市面上有已经衔接好的二合一、四合一等各种位数的七段显示器,以四合一的七段显示器为例,由于每个七段显示器会需要 8 个脚位控制其上的 LED,再加上各 4 个共阴或共阳脚位,因此基本上会有 12 个脚位,当然,如果还要附带有“:”控制等脚位的话,就会有 12 个脚位以上。

我手边这个四位数七段显示器,就是基本的 12 脚位:

依上图来看的话,下方有六个脚位,上方有六个脚位,最左下方的脚位编号是 1,依逆时针依序编号至 6,然后右上方是 7,依逆时针编号至左上方的 12:

当然,最重要的,是知道这些脚位,分别是控制哪个 LED,以及哪些脚位控制哪个七段显示器,这在上图是使用 0 到 3 以及 A 到 H(DP) 表示,0 表示最右边的七段显示器, 3 表示最左边的七段显示器,例如,当 3 为低电位而 0、1、2 为高电位时,那么是控制最左边的七段显示器,至于 A 到 H(DP),如下图表示:

因此,如果想要运用这个四位数七段显示器,可以如下衔接电路:

使用 mBlock 控制七段显示器

衔接好电路之后,那么就可以写程式来控制了,基本上就是用回圈来逐个控制与显示,我们稍微改写一下〈mBlock & Arduino(7)七段显示器之 HELLO!〉中的范例,以达到控制之目的:

其中numbers的内容一样是:

执行程式之后的效果是 …

嗯?由于透过 mBlock 控制 Arduino 会有速度上的限制,因此,你看到的是四个数字轮流闪动,而不是看起来一起亮,不过,这当作了解四位数七段显示器运作原理,倒是不错的方式,如果想要看起来有同时显示的效果,那么可以在 Arduino IDE 中撰写如下的程式,其运作原理与上面的程式是类似的:

在set7Seg中需要一点delay,这样切换速度才不会太快,LED 看起来才会够亮,将程式上传至 Arduino 板子,效果会是这样的 …

视频链接:

(18)74HC595 与七段显示器

在〈mBlock & Arduino(7)七段显示器之 HELLO!〉与〈mBlock & Arduino(17)四位数七段显示器〉都谈过七段显示器,直接使用 Arduino 来控制七段显示器的问题在于,它们会占用到 Arduino 上许多输出脚位,如果想减少 Arduino 上的脚位占用,那么可以使用 4511 或 74HC595 等驱动 IC,或者是选用市面上现成的七段显示器模组。

74HC595 工作原理

使用 74HC595,你可以使用三个脚位来控制八个输出,在正式看到 74HC595 脚位之前,可以先这么想,如果你想要最后八个输出为 10101101,那么一开始令 ST_CP 脚位为低电位,然后提供脚位 DS 高电位,如下图:

接着令 SH_CP 为高电位,将资料推入位移暂存器:

接着令 SH_CP 为低电位,DS 提供 0:

接着再令 SH_CP 为高电位,将资料推入位移暂存器,先前的 1 因此也被推进下一个暂存位置:

重复以上动作,继续将 101101 推入位移暂存器,成为以下状态:

此时令 ST_CP 为高电位,下方储存暂存器会复制位移暂存器的值:

这时储存暂存器的值就可以作为 Q0 到 Q7 脚位输出之用,接下来若要继续提供新的资料给位移暂存器,要令 ST_CP 为低电位,假设接下来又推进一个 1:

那么原先最左边的 1 被推至 Q7′,一个 74HC595 可以提供八个输出,如果想要提供 16 或更多输出,可以串接 74HC595,从上可知,串接方式就是将上一颗 74HC595 的 Q7′ 连接至下一颗 74HC595 的 DS。

连接七段显示器

实际的 74HC595 有 16 个脚位,除了上面谈到的 DS、SHCP、STCP、Q0 到 Q7 以及 Q7′ 之外,还有 VCC、GND、OE 与 MR 脚位:

OE 是指 Output Enable,设置为低电位时表示允许输出,因此在连接七段显示器时,可以直接与 GND 相连;MR 是指 Master Reset,设定为低电位时,表示清除暂存器所有资料。

之前谈到的 DS 表示 Serial data input;SHCP表示SHift register clock pin,又称为Clock Pin;STCP 表示 STorage register clock pin,又称为 Latch Pin。

知道这些脚位的作用,接下来要连接七段显示器,就不是难事了,只要小心不要接错就好了,例如连接一个七段显示器:

实际上 Q0 到 Q7 脚位要怎么接,要看你的资料序列如何安排,上面这个电路图可以搭配以下的程式来依序显示 H、E、L、L、O:

注意!虽然我们没有用到七段显示器的小数点,不过,还是每次将八个数字推入暂存器,只是最后一个推入的数字是 0,以下是实际的效果:

连接多个七段显示器

如果想要连接多个七段显示器,方式之一是串接多个 74HC595,每一次都准备好足够数量的位数,例如两个七段显示器可以如下连接线路:

如此,你可以维持三个输入脚位,但可控制十六个输出;另一个方式是 74HC595 结合多合一七段显示器,例如:

这样的话,只需要一个 74HC595,不过为了控制数字的轮流显示,需要多一个脚位,像上头四个数字,就需要再用到四个脚位,不过还是比不使用 74HC595 少了五个脚位了,下面这个程式可用来控制上头的七段显示器:

同样要记得,虽然没有使用到七段显示器的小数点,我们还是一样一次推入八个数字:

底下是实际的执行效果:

视频链接:

当然,速度不够快,来写个在 Arduino IDE 中类似的程式:

底下是实际的执行效果:

视频链接:


感谢CodeData用户:caterpillar的贡献 著作权归作者所有

整理:宁波家电物联网云平台,中科极动云

编辑:IT智能化专栏

相关推荐