用发光二极管构建电路是学习电子学和 Arduino 的好方法。调试一切都相对容易,因为 LED 要么亮着,要么不亮,所以如果有意外的东西闪烁,你可能有某种错误。在下一步中,我们将只使用一个发光二极管。拿任何有两条腿的发光二极管来说,它应该是这样的:
图 16:各种颜色的指示灯
现在,你们大多数人都听说过发光二极管。这里发光二极管的特殊之处在于,它们只能让电流单向通过,所以你在用它们制作电路时必须小心,因为如果你用错误的方式布线,它们不会闪烁。基本上,你必须确定哪条腿是正的,哪条腿是负的。有两种方法可以找到答案:
图 17:确定发光二极管的正极和负极引线
大多数时候,你会寻找一条更长的腿,你会把它连接到一个加号上。如果腿已经被切断,你需要找出腿的极性,你可以通过观察腿附近的平坦边缘(在发光二极管的外壳上)来找到负腿。关于发光二极管,有一个重要的事实你必须记住。他们有点自我毁灭的本性。他们会尽可能多地汲取电流,直到耗尽为止。为了防止这种行为,我们必须使用一种叫做电阻器的电子元件。电阻器将限制发光二极管可用的电流量,并防止发光二极管自毁。
电阻的阻值以欧姆为单位。在确定发光二极管的正确电阻时,需要进行一些计算。您必须查看发光二极管的规格,然后在此处填写可用的表格以找到合适的电阻值。对于 Arduino,没有那么多电压可用。总是 3.3 伏或 5 伏。我喜欢对发光二极管保持安全,所以我将对 3.3 伏的发光二极管使用 100 欧姆的电阻,对 5 伏的发光二极管使用 220 欧姆的电阻。您可以根据自己的目的对其进行微调,但是一般来说,在使用 Arduino 和 LEDs 时,您只需要两种类型的电阻。
从实际的发光二极管开始,你根本不需要任何类型的电阻。首先,你只需要一个普通的发光二极管。如果你按照上一节的内容,你已经上传了一个发光二极管闪烁的程序。现在,引脚 13 已经内置了一个电阻,因此下一个示例中不需要额外的电阻。紧挨着引脚 13,有一个接地引脚。Arduino 的制造者故意这样做,这样我们就可以尝试下一个例子。将称为二极管的较长引脚放入引脚 13,将较短引脚放入 GND。如果您不确定数字引脚 13 的位置,请将 Arduino 侧翻,并将引脚插入孔中:
图 18:从侧面观察的 Arduino Uno 板
如果您正确插入了发光二极管,您应该会看到它以与板载发光二极管相同的节奏闪烁。你的 Arduino 现在正在控制一个电子元件。如果房间里有点暗,就把灯关了,欣赏一下这个场景。但这只是开始。在下一节中,我们将在此基础上进行构建。
本节零件清单:
- Arduino 一号
- USB 电缆
- 3x 100 欧姆电阻器
- 面包板
- 1 个 5 毫米红色发光二极管
- 1 个 5 毫米黄色发光二极管
- 1 个 5 毫米绿色发光二极管
- 4x 线路板跳线
该示例的接线如下所示:
图 19: Arduino Uno 红绿灯布线
我们将红色发光二极管连接到引脚 13,黄色发光二极管连接到引脚 12,绿色发光二极管连接到引脚 11。我们将为红灯和绿灯设置相同的时间。从红色到绿色的过渡会快一点。从绿色到红色的过渡通常需要一点时间。我们来看看代码:
void setup() {
// initialize red light pin
pinMode(13, OUTPUT);
// initialize yellow light pin
pinMode(12, OUTPUT);
// initialize green light pin
pinMode(11, OUTPUT);
}
void loop() {
// turn the red light on
digitalWrite(13, HIGH);
digitalWrite(12, LOW);
digitalWrite(11, LOW);
// wait
delay(5000);
// turn the yellow light on together with red
// at least that's the way they work in some parts of Europe
digitalWrite(13, HIGH);
digitalWrite(12, HIGH);
digitalWrite(11, LOW);
// wait
delay(1000);
// turn the green light on
digitalWrite(13, LOW);
digitalWrite(12, LOW);
digitalWrite(11, HIGH);
// wait
delay(5000);
// turn the yellow light on
digitalWrite(13, LOW);
digitalWrite(12, HIGH);
digitalWrite(11, LOW);
// wait
delay(1000);
//start over
}
当您将代码上传到 Arduino 板时,红色指示灯将闪烁。这是有意的,这样你就知道当程序上传时,管脚 13 会随机地上下移动。这样,将来就不会在上面附加一些移动或敏感的组件。对于我们的红绿灯来说,这简直给上传带来了更多的乐趣。当程序开始运行时,第一个灯将是红色的。然后黄灯就会显示出来。在欧洲,红灯和黄灯一起亮,然后红绿灯显示绿灯。我们将模拟这种行为,以便您可以看到两个指示灯可以同时亮起。只要有电,Arduino 就会继续从红灯切换到绿灯,然后再切换回来。
这个例子中有一个非常重要的新组件,那就是试验板。试验板是一个有用的部件,因为一个人不需要太了解焊接就可以开始使用电子设备。当我刚开始的时候,它确实帮助了我很多。使用原型板的另一个优点是,构建基本电路不需要很长时间,如果出现问题,您可以快速重新排列组件。原型板的孔下是导线,例如:
图 20:原型板布线
原型板的缺点是它不能容纳很多元件,而且通过焊接,我们的电路会小很多。但是,对于一个刚刚开始构建电子电路的人来说,这是一个完美的起点。很难总结使用原型试验板的注意事项。通过查看未来章节中的示例,您将会对如何使用原型板有所了解。
假设大多数阅读这本书的人将来自软件开发背景。谈到线路板(以及一般的电子电路),我们需要指出一件重要的事情。有些 bug 很难发现,因为除了软件组件之外,还有错误接线的可能性。一些错误的接线可能来自对原型板中引线连接方式的误解。
我最大的误解之一是,当我买了一个有多条电源线的试验板,但它们没有从板的左边一直延伸到右边。它们在电线中间有一个缺口,这就是较长的实验板的工作原理。如果您没有意识到这一事实,您可能会认为组件将处于通电状态。但它们不会工作,因为电源轨停在中间,你必须用额外的电线连接它们,以确保它们获得电流。你可能会失去很多时间,直到你发现到底发生了什么。有一些版本的试验板中间没有裂缝,但只是为了让你知道更大的试验板上电源线之间的间隙。我将在下图中用红线描绘间隙:
图 21:较大试验板中间电源线之间的未桥接间隙
本节零件清单:
- Arduino 一号
- USB 电缆
- 10 倍 100 欧姆电阻器
- 面包板
- 10 倍 5 毫米红色发光二极管
- 1x 面包板跳线;如果你的电阻引线短,最多 11 根导线
赛昂人之眼效应我就不多说了;如果你不熟悉,就查一下。从电子学的角度来看,这是一个从左到右不断亮起的红灯。我将尝试用这个例子保存一些电线,所以我将向您展示如何为整个电线制作一个只有一根电线的版本。但是也可以像前面的例子一样,每个 LED 使用一根线;完全由你决定。这里有一个只有一根电线的例子:
图 22:带有单跳线
的赛昂人之眼版本
第一个指示灯插入 Arduino 数字引脚 4。最后一个是数字引脚 13。在将电阻器连接到发光二极管之前,不要忘记将每个引脚都连接到电阻器上。此外,不要忘记仔细检查发光二极管的极性,因为如果您将负发光二极管引脚连接到引脚输出,该示例将完全不起作用。你可能想知道什么是错的,事实上,你所做的只是把发光二极管转错了方向。这种情况经常发生,尤其是有人刚刚起步的时候。由于视角的原因,您可能很难阅读上图中的引脚连接,也很难知道必须将元件的引脚插入何处。这里有一个完整的示意图来帮助你。作为预防措施,请记住,一行总共有 10 个发光二极管:
图 23:赛昂人之眼接线示意图
我们在本例中控制的发光二极管数量明显多于上一节。当控制所有的发光二极管时,我们将不得不使用循环结构。下面是代码:
// define the starting pin as a constant
const int startPin = 4;
// total number of LEDs
const int numLEDs = 10;
// current LED will go from 0-9
int currentLed = 0;
// direction will be 1 and -1
int direction = 1;
void setup() {
// initialize the pins with a for loop
for (int i = startPin; i < startPin + numLEDs; i++) {
// set pin mode to output
pinMode(i, OUTPUT);
}
}
void loop() {
// turn the led on
digitalWrite(startPin + currentLed, HIGH);
// wait for 100 ms
delay(100);
// turn the led off
digitalWrite(startPin + currentLed, LOW);
// move to the next LED
currentLed += direction;
// go back up if we've reached the bottom
if (currentLed < 1) {
direction = 1;
}
// go back down if we've reached the top
if (currentLed >= numLEDs - 1) {
direction = -1;
}
}
我认为这个例子在黑暗中看最合适。所以花点时间去享受吧。这个例子可以作为一个很好的起点,为大范围的特殊发光二极管灯的效果。想象一下,你可以改变发光二极管的颜色,并在打开和关闭时以某种随机的顺序排列它们。在节日期间,你可以把这个作为礼物送给别人。不知道为什么,光效总会让人会心一笑。如果你建立了这个例子,试着用它玩一会儿,做出各种效果。在下一节中,我将更进一步。
这个例子将非常复杂,因为它在一个小的无焊料实验板上。我们将使用比前几节多得多的电线。发光二极管的数量也将增加。
本节零件清单:
- Arduino 一号
- USB 电缆
- 13x 100 欧姆电阻器
- 面包板
- 13x 5 毫米发光二极管
- 18x 线路板跳线
在本节中,我们将使用 13 个发光二极管构建一个数字显示器。最初的想法是这样的:
图 24:一位数显示的 13 个发光二极管
在这里,所有 10 位数字都显示在倒计时中:
图 25: 13 个指示灯倒计时
这个例子的布线有点复杂,尤其是如果你刚刚开始使用试验板。在树立榜样的同时,努力保持专注。你可以用你认为最好的方式重新布线这个例子。以下是我完整的接线模式:
图 26:倒计时示例接线模式
这个例子更多的是为了练习。实际上,您将使用七段显示器。但这是我们研究发光二极管行为的部分,所以我们用发光二极管而不是七段显示器构建了这个例子。但是,要完成这个示例,您还需要一件东西,即代码:
// define the starting pin as a constant
const int startPin = 1;
// total number of LEDs
const int numLEDs = 13;
// we'll start the countdown at 9
int count = 9;
// here is each digit mapped to the state of the pins
int numberMatrix[][13] = {
{1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1}, // 0
{1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0}, // 1
{1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0}, // 2
{1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0}, // 3
{1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1}, // 4
{1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1}, // 5
{1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1}, // 6
{1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0}, // 7
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, // 8
{1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1}, // 9
};
void setup() {
// initialize the pins with a for loop
for (int i = startPin; i < startPin + numLEDs; i++) {
// set pin mode to output
pinMode(i, OUTPUT);
}
}
void loop() {
// go through the pins for the current count, turn them on an off
for (int i = 0; i < numLEDs; i++) {
digitalWrite(startPin + i, numberMatrix[count][i]);
}
// wait for a second
delay(1000);
// count down
count--;
if (count < 0) {
// start over
count = 9;
// turn all the LEDs off
for (int i = startPin; i < startPin + numLEDs; i++) {
digitalWrite(i, LOW);
}
// wait for a second and start over
delay(1000);
}
}