65.9K
CodeProject 正在变化。 阅读更多。
Home

将 Arduino 连接到面包板以点亮 LED

starIconstarIconstarIconstarIconstarIcon

5.00/5 (5投票s)

2018年6月5日

CPOL

12分钟阅读

viewsIcon

23102

本文将指导您将 Arduino 连接到面包板,然后控制 LED。

刚开始使用 Arduino 并想尝试一个简单的项目?这个项目大约需要 45 分钟,很有趣,甚至还有闪烁的灯光!

本文有两种版本

如果您有时间,做这两个项目都很有趣。您将学习如何处理同一个应用程序,一个真实的,一个虚拟的。

让我们开始吧。

引言

本文将引导您完成一个涉及 Arduino、面包板和少量 LED 的简单项目。

该项目将指导您完成制作 8 位二进制计数器所需的步骤。一旦它正常工作,您就可以轻松地尝试其他序列和效果。这是 Arduino 的一个很棒的入门项目,或者如果您很久没有使用 Arduino 了,这是一个重新开始的好方法。

入门

要通过 Arduino 控制一些 LED,您需要以下物品:1 块 Arduino 板,1 块面包板,1 个 200 至 1000 欧姆的电阻,8 个红色 LED,以及 11 根跳线。

  1. 将一根跳线从 Arduino 上的 GND 引脚连接到面包板上的 1a 引脚。

  2. 在面包板的 1b 和 1g 引脚之间添加一个 220-1000 欧姆的电阻。

  3. 从面包板的 1j 引脚连接一根线到上方负极 (-) 电源轨。

  4. 现在该将 LED 添加到面包板上了。为了减少所需的导线数量,我们将把每个 LED 的阴极(短引脚)直接插入上方负极电源轨。首先,将一个 LED 的阳极(长引脚)插入 14j,阴极插入上方电源轨。您可能需要弯曲阳极引脚才能实现此目的。

  5. 接下来,将另一个 LED 插入面包板,阳极在 16j,阴极在上方电源轨。继续这样做,直到您添加了所有 8 个 LED。为了确保您的 LED 间距合适,请尝试将每个 LED 的阳极插入比前一个 LED 靠右两行的位置。最终,LED 阳极将插入 14、16、18、20、22、24、26 和 28 行。

  6. 现在,将一根导线从 Arduino 的数字引脚 12 连接到最左侧 LED 的行 - 第 14 行

  7. 然后,将一根导线从引脚 11 连接到下一个 LED 的行:16。

  8. 继续这样做,从左到右连接,直到您将 Arduino 的导线连接到所有 LED。如果一切按计划进行,您将完成将 Arduino 的引脚 5 连接到面包板的第 28 行。

  9. 将一根导线从模拟引脚 0 连接到面包板上的任何未使用的行。在下面的示例中,导线已插入端口 7a。

就这样!您已经准备好编写代码来使您的二进制计数器工作了。

添加代码

请注意,这与配套文章“将 Arduino 连接到面包板以在 Tinkercad 仪表板中实现”完全相同。

现在,是时候编写代码来让我们的二进制计数器工作了。在 Arduino 世界中,编写并上传到 Arduino 设备上的程序称为“草图”。一个草图可以包含多个文件,只要它们都保存在同一个目录中即可。由于这是一个非常简单的项目,我们将把所有代码放在一个文件中。

要输入代码,如果您使用的是真实的 Arduino 硬件,您需要下载 Arduino IDE,或者如果您使用的是 Tinkercad,则打开代码视图。

当您打开 Arduino IDE 时,您将看到一个带有顶部简单工具栏的代码编辑屏幕。在工具栏的左侧,将有两个按钮:一个勾号和一个箭头。它们看起来会像这样

单击勾号将检查并编译您的代码。单击箭头将检查并编译您的代码,然后将其上传到您的 Arduino。要成功上传,您必须使用 USB 数据线将 Arduino 连接到计算机。然后,打开“工具”菜单,打开“端口”,然后选择您的 Arduino 连接到的端口。如果您只有一个 Arduino 连接,将只有一个端口可供选择。

Arduino 草图是用 C++ 编写的。Arduino IDE 支持 C++11,因此您可以随意使用它的所有新功能。我们将坚持使用 C++98,因为这是 Tinkercad Arduino 支持的版本。这样,我们的代码无论您在哪里运行它都能正常工作。请注意,Arduino 环境不包含 C++ 标准库。因此,您将无法使用 vector 或 C++ string 等。有一个用于 Arduino 的 C++ 标准库实现 可在 GitHub 上找到,但本项目不需要它。

首先,我们将介绍一些函数,我们需要使用它们来让 Arduino 点亮我们的 LED。这些函数都可以在全局范围内使用。您无需导入任何内容即可使用它们。

我们需要使用的第一个函数是 pinMode。此函数用于告知 Arduino 一个引脚将用于输入还是输出。它的用法如下:

pinMode(10, OUTPUT);

这将按照预期将引脚 10 设置为输出模式。第二个参数可以设置为 INPUTOUTPUT。这些都是任何 Arduino 草图中都可以全局访问的常量。

接下来是 digitalWrite。此函数允许我们打开或关闭特定的输出引脚。要关闭或打开引脚,我们可以使用另外两个全局常量:LOWHIGH。这些常量没什么特别的。如果您在 Arduino 源代码中查找它们,您会发现 LOW0HIGH1。因此,例如,要关闭引脚 10,您可以写入以下任一项:

digitalWrite(10, LOW);

digitalWrite(10, 0)

要打开引脚 10,您可以使用以下任一项:

digitalWrite(10, HIGH);

digitalWrite(10, 1)

接下来是 analogRead。顾名思义,analogRead 用于从 Arduino 的模拟引脚之一读取模拟值。

我们需要最后一个函数是 delay。此函数与其名称所示的作用完全一致。它会导致 Arduino 在执行任何更多代码之前暂停。它接受一个参数:暂停的毫秒数。因此,要暂停执行 1 秒,您可以写入:

delay(1000);

delay 函数对我们的二进制计数器很重要,因为我们会在每次增加计数器后暂停片刻。尽管 Arduino 体积小巧且功能不强大,但它仍然可以非常快速地从 0 数到 255,以至于我们甚至看不到计数器 LED 的变化。

要输入代码,如果您使用的是真实的 Arduino 硬件,您需要 下载 Arduino IDE,或者如果您使用的是 Tinkercad,则打开代码视图。为此,请点击“Code”按钮,然后在下拉菜单中选择“Text”——默认设置为“Blocks”。

现在我们了解了将要使用的 Arduino 函数,让我们深入研究使我们的二进制计数器工作的代码。为了保持一切井井有条,我们将把我们的计数器封装在一个类中

class BinaryCounter {
};

接下来,让我们用类需要的变量和方法来填充它,以完成它的工作

class BinaryCounter {
  private:      
    static const uint8_t digitCount = 8;
    const uint8_t pins[digitCount] = {12, 11, 10, 9, 8, 7, 6, 5};
    uint8_t count = 0;

    static const uint8_t showSingleValuePin = 0;
    uint8_t valuetoShow = 255;

  public:
    BinaryCounter();
    void increment();
    uint8_t* getBinaryDigits(uint8_t num);
    void clearLights();
};

让我们快速看一下刚刚添加的变量。首先,我们有一个计数器,用于记录我们的二进制计数器将包含的位数。如果需要,我们可以很容易地将此数字 8 硬编码,但将其存储在一个地方使我们的代码在需要更改二进制计数器位数时非常容易更新。

接下来,我们有一个包含每个 LED 所连接引脚号的数组。我们按从左到右的顺序排列它们。这将在以后使事情变得非常简单,当我们想要从左到右遍历引脚以打开或关闭 LED 时。

接下来,我们有一个将存储计数器当前值的变量。

为什么是 uint8_t,您可能会问,而不是 int?在 Arduino 上,int 占用 16 位内存。顾名思义,uint8_t 只占用 8 位。而且由于我们使用 8 个 LED,我们只需要 8 位就可以表示我们可以显示的任何数字。虽然在这个小程序中没有区别,但养成仅使用所需资源的习惯是个好主意。Arduino 只有 2KB 的 RAM,所以很容易很快用完。

现在是时候着手处理我们代码的核心部分了。我们将从编写 BinaryCounter 类的构造函数开始。

BinaryCounter::BinaryCounter() {
  //set all counter pins to output mode
  for(int i = 0; i < digitCount; i++) {
    pinMode(pins[i], OUTPUT);  
  }

构造函数只做一件事:它遍历我们将要使用的引脚,并将它们设置为输出模式。

接下来,我们需要一个接受 uint8_t 并返回 uint8_t 数组的方法。只有一个技巧:C 和 C++ 不允许您返回整个数组。但我们可以很容易地在堆上创建一个数组并返回指向其第一个元素的指针,所以我们将这样做。我们只需要记住在完成后删除它。

uint8_t* BinaryCounter::getBinaryDigits(uint8_t num) {

  // Make a byte array to hold all of the binary digits.
  uint8_t *digits = new uint8_t[digitCount];
  memset(digits, 0, digitCount * sizeof(uint8_t));

  uint8_t remaining = num;
  uint8_t currentPosition = digitCount-1;

  while(remaining > 0) {
    digits[currentPosition] = remaining % 2;
    remaining /= 2;
    currentPosition--;
  }

  return digits;
}

第一行代码创建一个足够大的 uint8_t 数组来保存我们的所有位数,第二行代码将数组的所有元素设置为 0

接下来,我们进行将整数转换为二进制数的实际过程。

整数到二进制转换背后的数学原理相对简单。我们只需取我们的数字,并不断除以 2,直到剩下 0。在每一步,如果当前剩余的数字可被 2 整除,则该步的二进制数字为 0。如果当前数字不能被 2 整除,则该步的二进制数字为 1。有关更深入的解释,请参阅 这篇博文。理解整数到二进制转换的最佳方法是手动进行几次转换。完成此操作后,您会发现整个过程更容易理解。

请注意,我们正在向后遍历 digits 数组来设置值。我们将整数转换为二进制的方法按从右到左的顺序给出数字。通过向后遍历数组,我们确保为每个引脚设置正确的值。

完成后,我们返回指向 digits 数组开头的指针。

接下来,我们将添加代码来递增计数器并打开代表当前二进制计数的 LED

void BinaryCounter::increment() {
  uint8_t* binaryDigits;

  if(analogRead(showSingleValuePin) > 500) {
    binaryDigits = getBinaryDigits(valuetoShow);
  }
  else {
    binaryDigits = getBinaryDigits(count);

    if(count == 255) {
      count = 0;
    } else {
      count++;  
    }
  }

  for(int i = 0; i < digitCount; i++) {
      digitalWrite(pins[i], binaryDigits[i]);
  }

  delete binaryDigits;
  delay(500);
}

我们首先检查是否有一根导线连接到模拟引脚 0(在 showSingleValuePin 中设置)。如果是,我们从 valuetoShow 中的值生成一个 8 位代码。如果没有连接导线,那么我们运行递增计数器的代码。

如果我们正在运行计数器,我们首先调用 getBinaryDigits 将当前计数转换为二进制数字数组。

由于我们从 getBinaryDigits 返回的数组按从左到右的顺序包含数字,而我们的 pins 数组按从左到右的顺序包含输出引脚,我们可以使用一个简单的 for 循环来遍历两个数组并将每个引脚设置为其在 binaryDigits 数组中的相应值。

由于 digitalWrite 将 0 作为第二个参数传递时会关闭引脚,在接收到 1 时会打开引脚,因此净结果是我们的 LED 显示当前的二进制计数:任何数字为零的 LED 会熄灭,任何数字为一的 LED 会点亮。

在循环打开和关闭 LED 后,我们删除 binaryDigits 数组,因为我们不再需要它了。忘记这一步非常重要。如果您这样做,您的程序将有内存泄漏。Arduino 将很快耗尽内存并锁定。这不会损坏 Arduino,但您的计数器只会工作一小段时间然后冻结。

接下来,我们检查计数是否已达到 255,因为 255 是我们可以用 8 个 LED 在二进制中表示的最大数字。如果已达到 255,我们将计数器重置为 0。否则,我们将计数加 1。您可能会注意到,我们实际上可以跳过此检查并直接递增计数器。由于 255 是 uint8_t 可以容纳的最大值,如果我们尝试在计数已经是 255 时递增计数,它只会溢出到 0。

但是,在这种情况下,最好是明确的。依赖 uint8_t 从 255 溢出回 0 是可以的,但这样做会使我们的代码更难理解。即使您是唯一查看代码的人,如果您在几个月不看代码后回来查看,您可能会感到困惑。

最后,我们延迟 500 毫秒。这会导致 Arduino 在移动到下一个数字之前暂停半秒。

这就是 BinaryCounter 类的内容。我们快完成了!我们只需要再写几行代码来初始化我们的计数器并使其计数

BinaryCounter *counter;

void setup()
{
  counter = new BinaryCounter();
}

void loop()
{
  counter->increment();
}

我们首先创建一个全局变量来存储 BinaryCounter 的指针。总的来说,开发者会尽量避免使用全局变量。然而,Arduino 编程环境有些受限。创建全局 BinaryCounter 是使其可供 Arduino 的 loop 函数使用的唯一方法。

接下来,我们看到两个函数:setuploop。它们都是 Arduino 编程环境的一部分。setup 函数在 Arduino 启动并执行您的程序时运行一次。然后 Arduino 会持续运行 loop 函数。

我们的其余代码很简单:在 setup 中,我们创建一个新的 BinaryCounter 实例。然后,每次 loop 运行时,我们都会调用计数器的 increment 函数来设置 LED 并递增计数器。

和……就这样!这就是使二进制计数器工作的全部代码。

在 Arduino IDE 中,确保您的 Arduino 已连接到计算机,然后单击上传按钮。

现在,请放松,享受观看您的二进制计数器运转吧!

完整代码列表

class BinaryCounter {
  private:
    static const uint8_t showSingleValuePin = 0;
    static const uint8_t digitCount = 8;
    const uint8_t pins[digitCount] = {12, 11, 10, 9, 8, 7, 6, 5};
    uint8_t count = 0;
    uint8_t valuetoShow = 255;

  public:
    BinaryCounter();
    void increment();
    uint8_t* getBinaryDigits(uint8_t num);
};


BinaryCounter::BinaryCounter() {
  //set LED all pins to output mode
  for(int i = 0; i < digitCount; i++) {
    pinMode(pins[i], OUTPUT);  
  }
}


uint8_t* BinaryCounter::getBinaryDigits(uint8_t num) {
  // Make a byte array to hold all of the binary digits.
  uint8_t *digits = new uint8_t[digitCount];
  memset(digits, 0, digitCount * sizeof(uint8_t));

  uint8_t remaining = num;
  uint8_t currentPosition = digitCount-1;

  while(remaining > 0) {
    digits[currentPosition] = remaining % 2;
    remaining /= 2;
    currentPosition--;
  }

  return digits;
}

void BinaryCounter::increment() {

  uint8_t* binaryDigits;

  if(analogRead(showSingleValuePin) > 500) {
    binaryDigits = getBinaryDigits(valuetoShow );
  }
  else {
    binaryDigits = getBinaryDigits(count);

    if(count == 255) {
      count = 0;
    } else {
      count++;  
    }
  }

  for(int i = 0; i < digitCount; i++) {
      digitalWrite(pins[i], binaryDigits[i]);
  }

  delete binaryDigits;
  delay(500);
}

BinaryCounter *counter;

void setup()
{
  counter = new BinaryCounter();
}

void loop()
{
  counter->increment();
}
© . All rights reserved.