陈帅华的个人网站 - 探索技术艺术与国学之美

Arduino硬件编程入门

全篇共 5671 字。按500字/分钟阅读,预计用时 11.3 分钟。

Arduino开发套件

在入门 Arduino 硬件编程之前,你需要先准备一套 Arduino 开发套件,开发套件包括了 Arduino 硬件、很多导线、很多LED灯、很多传感器。下图是我使用的开发套件,我用的这款硬件的全称叫 Arduino UNO R3,UNO R3 是 Arduino 的型号,它是官 Arduino 官方承认的适合新手入门的基础款硬件。

Arduino开发套件

我手里的 Arduino 开发套件是 2017 在电商平台上购买的,购买的价格我已经记不起来了,价格区间大约在 200-300 元之间。你可以先从 arduino 官方网站商店 里找到适合你的 Arduino 硬件型号。当然最核心的硬件就是这块 Arduino 开发板。我用的这块开发板的处理器是 ATmega328;工作电压是 5V;数字 IO 脚有14个,其中有6个作为 PWM 输出,我会在后边的教程介绍 PWM是什么;模拟输入脚有6个;Flash 闪存大小有 32KB,其中 0.5KB 用于 bootloader;工作时钟为 16MHz;整块开发板的尺寸是 6cm 乘以 5.33cm。

Arduino开发套件

Arduino集成开发环境

Arduino 硬件编程语言的语法建立在 C/C++ 语言之上。我之前没有过深入的 C/C++ 的编程经验,但是我敢说,只要你是一名程序员(包括前端)你就能学会 Arduino 硬件编程,因为连我都觉得很容易,你一定也可以。而且现在 Typescript 作为 JavaScript 的超集在 JS 的基础上增加了对强类型的支持,那么即便你是第一次接触 C/C++ 语言,只要保持热爱与好奇心,就能轻松学会,并且走得很远。

有了良好的心理准备,就快去下载 Arduino 集成开发环境 开始入门 Arduino 硬件编程的世界吧。之所以称它为集成开发环境,是因为它不止是一款代码编辑器,它还包括了围绕 Arduino 硬件开发过程的相关功能,比如这个软件还能把程序编译好,然后上传到 Arduino 开发板硬件中运行,他还有串口监视器功能,用来显示和输出从各种传感器通过 Arduino 开发板传过来的数字或模拟信号。它还有其他功能,等待你去发掘。最近我在 Arduino 的官网上还看到官方发布了 Arduino CLI 命令行工具,开发者可以像使用 NPM 那样贡献自己的程序代码给全世界的 Arduino 开发者,从这可以看出 Arduino 正在构建一个生态环境。

上图,左边是 Arduino 集成开发环境的启动界面,右边是它的主界面。把 Arduino 开发板通过USB供电数据线连接到电脑,在 Arduino 开发环境窗口的顶部找到“工具”菜单,然后在“开发板”和“端口”选项的下拉菜单中找到和你使用的 Arduino 硬件型号匹配的选项,我在上面说过我用的硬件型号是 Arduino UNO。“端口”就是你的电脑用于和外部设备对接的接口,只要你正确的把 Arduino 开发板和你的电脑USB口连接起来,就会在“端口”的下拉菜单中找到它,然后选择它。

快去下载它,亲自动手试试吧,只有经过实践的知识才是你自己的知识。

点亮一个LED

LED 就是发光二极管,他有正/负极之分,如果接反正负极 LED 就会不发光,LED 的内阻很小,长时间使用时必须串联限流电阻以控制通过它的电流。用 Arduino 点亮第一个LED灯,就相当于用 JavaScript 在控制台打印出一句“Hello World”,用更夸张但也合理的比喻来讲,这就相当于是你在月球上踩下的第一个的脚印,却是你迈入 Arduino 创意硬件编程的最伟大的一步。万事开头难,只要开一个好头,剩下的无非就是不断的重复。

就和我个人网站的 Slogan 说的那样,我会把“探索技术艺术与国学之美”当作时刻提醒我人生要开往的方向的座右铭,围绕它探索我所能做的一切。如果说 Arduino 编程是一门技术,那么如何用 Arduino 驱动来塑造一件关于“光”的装置就是一门艺术,而点亮第一个 LED 灯,就是这门艺术的开始。

首先编程,先把一个 Arduino 程序的结构搭建起来。

void setup() {
  // 在这里写初始化代码,这些代码只运行1次
  // ...
}

void loop() {
  // 在这里写的代码会重复执行
  // ...
}

认识2个简单的 Arduino 内置函数,分别是 pinMode()digitalWrite()。第一个函数用来指定引脚为输入还是输出模式,所以它叫“pinMode”——“引脚模式”,他接收两个参数,第一个参数是要设定哪一个引脚,参数类型是整型,如果要设置 13 号引脚的模式就传入 13 作为第一个参数;第二个参数是要设置的模式,INPUT 常量代表输入模式,OUTPUT 常量代表输出模式。下面是 setup() 函数内的代码,这里的代码只执行一次,用于初始化各种设置,所以设置引脚模式的函数适合在这里执行。将引脚设置为输出模式就是将该引脚用于发送数字信号,这种信号的本质是电流的通与断,对应的数字就是1和0。

void setup() {
  // 13 号引脚设置为输出模式
  pinMode(13, OUTPUT);
}
void loop() {
}

digitalWrite() 函数也接收两个参数,第一个参数也是指定引脚;第二个参数也是可以设置为两个常量:HIGH 代表高电平,LOW 代表低电平,通俗一点说就是一个表示“通电”,一个表示“断电”。所以这个函数是用来给某个引脚通电或断电的。如果给 13 号引脚通电,自然就能点亮一个连接在 13 号引脚上的LED灯。修改 setup() 函数。

void setup() {
  // put your setup code here, to run once:
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);
}
void loop() {
}

好了,现在点击“上传”按钮上传你的代码到 Arduino 开发板,然后就看到连接到 13 号引脚的 LED 灯被点亮了。如何区分 LED 的正负极呢,记住比较长的那一根是正极,较短的那一根是负极。我们已经用程序控制 13 号引脚为输出模式,就相当于是电源的正极,而且我们还控制了 13 号引脚现在是高电平,高电平就是高电压,接地的 0V 电压与 13 号引脚的高电压之间形成电压差,负电荷从低电压的地方流向高电压的地方,正电荷从高电压流向低电压,形成电流。(“电”字越看越不像)。

到现在为止,还没有用到 loop() 函数,为了用到它,我要再想一个需求,就是让这个 LED 一闪一闪的,而不是一直亮着。这就要介绍第三个函数:delay(),顾名思义就是制造延迟和停顿的效果。loop() 函数中的代码是按顺序执行的,delay() 函数能够阻塞住 Arduino 执行后边的代码,就像前端代码里边的同步Ajax请求会阻塞界面的渲染,用户会感觉到卡顿,这是我们不希望看到的。但是这里的 dealy() 函数制造的延迟卡顿是我们希望看到的效果。

void setup() {
  // 让 13 号引脚作为发送/输出数字信号的用途
  pinMode(13, OUTPUT);
}
void loop() {
  // 给 13 号引脚高输出高电平,13 号引脚和接地引脚之间形成电压差,
  // 连接在其间的 LED 因为感觉到有电流的通过而发光。
  digitalWrite(13, HIGH);
  
  // 立即停顿 100 毫秒,这会让 13 号引脚保持100 毫秒的高电平,
  // LED 灯就会保持 100 毫秒的发光状态 。
  delay(100);
  
  // 立即让 13 号引脚输出低电平,13 号引脚和 0V 的接地引脚没有电压差,
  // 或者说电压差微小到不足以维持 LED 发光
  // 所以此时 LED 会立即灭掉。
  digitalWrite(13, LOW);
  
  // 保持 LED 不亮的状态 100 毫秒。
  delay(100);
  
  // 执行到这里,重新从 loop 函数的第一行代码开始执行。
}

保存,编译,上传,最终看到我们想要的效果——LED 每 100 毫秒闪烁一次。快试着去修改 LED 亮与灭的延迟时长,或者再多写几行代码控制 LED 有更多闪烁的延迟时长。我猜你应该已经联想到了摩尔斯电码,试着做下去吧。

Arduino 开发板上还有一个小灯也在和 LED 保持着一样闪烁频率,它就在 13 号引脚的旁边。如果你的手里没有 LED,你就可以控制这个接脚的闪烁,它相当于 Arduino 给 13 号引脚内置的用于测试高/低电平的小灯。当 13 号引脚输出高电平,这个小灯就亮;当 13 号引脚输出低电平,这个小灯就灭。它叫接脚 13,他和 13 号引脚的不同就是 13 号引脚是一个插槽,能连接外部器件,而接脚 13 只是通过小灯的亮/灭状态反映引脚 13 的高/低电平。

好了!我们已经点亮了第一颗 LED 灯,万事开头难,可知点亮第一颗 LED 对你来说它的意义是何等重大。回过头来,看看还有哪里可以做得更好吧!不妨把我们的代码重构一下。上面的代码中,有三处用到了 13 号引脚,可能下次我们想要用别的引脚,比如 8 号引脚,这就需要把三处的 13 修改为 8,所以我们把引脚号定义为一个变量 led,这样就只需修改 led 一个变量。

// 定义整数型变量 led,并赋值 13。
int led = 13;

void setup() {
  // 将 13 号引脚设置为输出模式
  pinMode(led, OUTPUT);
}
void loop() {
  // 向 13 号引脚输出高电平
  digitalWrite(led, HIGH);
  // 立即开始延迟半秒
  delay(500);
  // 此时 LED 已经亮了半秒了,
  // 立即向 13 号引脚输出低电平,也就是不给 13 号引脚通电,
  // 此时 LED 立即灭掉。
  digitalWrite(led, LOW);
  // 立即开始延迟 100 毫秒
  delay(100);
  
  // 本次循环执行到这里就结束了,本次循环消耗了 600 毫秒的时间,
  // 然后立即从 loop 方法的第一行代码:digitalWrite(led, HIGH) 开始新一轮的循环。
}

你学到了三个函数:pinMode()digitalWrite()delay();学会了控制 LED 的闪烁频率;知道了 13 号引脚和接地引脚;还知道了如何区分 LED 的正负极。收获满满,继续前行!

点亮一排LED

我们已经点亮了第一颗 LED 灯,为什么不试着点亮一排 LED 灯呢。对他人提出“得寸进尺”的要求就会让人产生厌恶,对自己提出“得寸进尺”的要求就会让自己进步,让我们都做一个对他人宽容,而对自己“得寸进尺”的人吧!

我记得初中物理课学过电路知识,串联电路和并联电路。刚才点亮一颗 LED 灯使用的是串联电路:LED 的正极接到 13 号引脚,负极接到接地引脚。现在要点亮一排 LED 灯,就用并联电路实现吧!每一颗 LED 都相当于是并联电路上的一条支路。可是每个引脚和接地插槽只能插一个 LED 灯,要怎么样才能达到并联 LED 灯的目的呢?这就需要一块面包板的帮忙,下图就是一块面包板。

它分为三部分,上、中、下。上边和下边的原理相通,它们水平方向的电路是相通的,但是我手里拿的这个面包并不是水平方向完全相通的,它在中间的位置断开了。中间这部分又分为上下两侧,这两侧是不相通的,但是两侧的每一列都是相通的。图中的黑色小东西是一个开关,因为每次很难按上去又很难扣下来,干脆就在上边待着吧!这个开关有四个“脚”,它现在把上下两侧本不相通的电路连接起来了。

准备两根导线,我用红色表示正极,黑色表示负极,所以我把红色导线的一端插到 13 号引脚,另一端插到面板板上标示红线的一侧;把黑色导线的一端插到接地引脚上,另一段插到面包板标示蓝线的一侧。注意发光二极管的正负极不要接反。

要不要让这一排 LED 灯闪烁起来呀,编写程序控制它们一起闪烁吧,就像控制一个 LED 闪烁那样。

我的另一个教程介绍如何 使用 Arduino 制作LED流水灯效果

结语

无论做什么事,在行动之前,先想清楚大致方向。我越来越能认识到,没有方向的努力只是在浪费时间,他会分散你的精力,消磨你的意志,而我们的精力和意志其实很有限,所以要像珍惜生命一样保护好你的精力,尽量做到你种下的每一颗种子都能开花结果,所以才需要在你准备撒下种子前大致地想清楚后边的每一步如何走,你的终极目标,以及是否值得。还有一句忠告:不要试图一口就想吃成一个胖子,揠苗助长,祸患无穷。还有,你一定要找到一个支撑你不断前行的动力来源,可以是摸不着的类似信念的东西,也可以是摸得着的东西,但尽量是一个足够长久到你能实现自己梦想的东西。

我的学习过程

创作者 » 陈帅华
版权声明 » 自由转载-保持署名-非商用-非衍生
发布日期 » 2019年7月19日 周五
关键词