微控制器项目-DIY-爱好者指南-全-
微控制器项目 DIY 爱好者指南(全)
原文:
zh.annas-archive.org/md5/67f8d4d372308227d4de7050f0a8f157译者:飞龙
前言
本书将向你介绍微控制器技术。它特别关注两个非常强大的微控制器板——Blue Pill 和 Curiosity Nano,以及如何将传感器连接到它们以解决问题和支持日常生活场景。此外,本书还涵盖了使用发光二极管(LEDs)和液晶显示器(LCDs)向微控制器板用户显示传感器信息。
微控制器板是用于从环境获取信息的小型实用计算机,使用传感器。在这本书中,每一章都将专注于使用微控制器技术解决的具体问题,结合实际传感器的使用。
许多目标读者都希望从基于微控制器的项目开始,但他们可能不知道如何开始,包括他们需要使用哪些基本硬件、软件工具和电子元件。本书将涵盖这些内容。
本书中的一章介绍了电子领域,检查和回顾了你在本书中将使用的常见电子元件。另一章提供了 C 和 C++的介绍,这些语言将用于大多数章节中编写 Blue Pill 和 Curiosity Nano 应用程序。
本书最重要的一个方面是,通过微控制器板进行传感器编程比以前更加有效和简单,因为有几个易于使用的编码库支持它们,这在使用它们获取模拟或数字数据时节省了时间和精力。本书解释了常见的传感器编程库。
本书面向的对象
这本书旨在为希望深入了解微控制器板编程世界的学者、爱好者、极客和工程师提供帮助。此外,本书也适合数字电子和微控制器板初学者。如果你已经是一位熟练的电子爱好者或程序员,当你想要使用微控制器板高效地编写传感器代码时,你可能会发现这本书很有帮助。
使用其他类型微控制器板(如 Arduino 板)的人可能会发现这本书很有用,因为它包括了对 Blue Pill 和 Curiosity Nano 微控制器板的介绍,这有助于在需要 Arduino 微控制器板的电子项目中理解和应用它们所需的技能迁移。
对数字电路和 C 和 C++编程语言的基本了解是可取的,但不是必需的。这是一本面向刚开始进行数字电子项目的读者的微控制器板入门书籍。
本书涵盖的内容
本书涵盖了使用 C++编程 Blue Pill 和 Curiosity Nano 微控制器板的技术主题,包括常用传感器的描述以及它们如何电子连接到微控制器板。本书共分为 14 章,如下所示:
第一章,微控制器和微控制器板简介,向读者介绍了微控制器技术,并解释了如何安装用于编程书中使用的 Blue Pill 和 Curiosity Nano 微控制器板的集成开发环境(IDEs)。
第二章,微控制器板的软件设置和 C 编程,概述了 C 语言,并介绍了用于本书大部分章节编码示例的 Blue Pill 和 Curiosity Nano 微控制器板编程。
第三章,使用按钮开关 LED 的开关,解释了如何使用微控制器板上的按钮来启动一个过程,例如打开或关闭 LED,以及如何最小化来自按钮的电气噪声。
第四章,使用光敏电阻测量光照量,专注于如何将光敏电阻连接到 Blue Pill 和 Curiosity Nano 微控制器板来测量环境中的光照量。结果将在连接到这些板的红色、绿色和蓝色 LED 上显示。
第五章,湿度和温度测量,描述了如何连接实用的 DHT11 传感器来测量环境的湿度和温度,如何在计算机上显示其值,以及如何使用易于使用的 LM35 温度传感器,在两个 LED 上显示其值。
第六章,使用高亮度 LED 的摩尔斯电码 SOS 视觉警报,展示了如何使用高亮度 LED 显示摩尔斯电码 SOS 信号,从而增加其可见性。本章还解释了如何使用晶体管作为开关来增加 LED 的亮度。
第七章**,制作一个拍手开关,向读者描述如何使用声音(拍手)制作电子无线控制。当麦克风检测到连接到微控制器板上的两个拍手声时,将发送一个信号来激活连接到它的设备,并点亮一个 LED 灯。
第八章**,气体传感器,向读者介绍了连接到微控制器板的传感器,该传感器会与环境中的特定气体发生反应。
第九章,物联网温度记录系统,展示了如何使用 Blue Pill 微控制器板和温度传感器构建一个物联网(IoT)温度记录器。其数据将通过 ESP8266 模块使用 Wi-Fi 进行传输。
第十章,物联网植物花盆湿度传感器,解释了如何使用微控制器板和湿度传感器构建一个数字设备来监测植物花盆的土壤并确定是否需要浇水,如果土壤过于干燥,将通过无线方式发送警报通知用户。
第十一章,物联网太阳能(电压)测量,继续使用运行在微控制器板上的物联网软件,通过 ESP8266 WiFi 模块测量从太阳能板通过传感器获得的电压。该应用将使用 ESP8266 WiFi 信号将传感器数据发送到互联网。
第十二章**,COVID-19 数字体温测量(体温计),探讨了利用红外温度传感器开发非接触式体温计的有趣项目。其测量的温度数据通过 I2C 协议发送到 Blue Pill 微控制器板,并在 I2C 液晶显示屏上显示。
第十三章**,COVID-19 社交距离警报,解释了如何编程一个测量两人或多人之间两米距离的微控制器板。在 COVID-19 的新常态下,由于与感染者近距离接触感染病毒的风险更高,我们需要保持社交距离。世界卫生组织建议至少保持两米的距离;这个规则因国家而异,但普遍认为两米的距离是安全的。
第十四章**,COVID-19 20 秒洗手计时器,包含了一个在 Blue Pill 微控制器板上运行的计时器项目,确保人们按照世界卫生组织的建议洗手 20 秒,以预防 COVID-19 感染。该项目在液晶显示屏(LCD)上显示时间计数。一个超声波传感器检测用户是否在挥手以启动计数。
为了最大限度地利用这本书
为了充分利用本书,读者需要具备基本的计算机编程和主要操作系统(如 Windows 或 macOS)的知识,尽管本书有一章介绍了 C 语言。为了编译和运行本书中描述的编程示例,读者应在他们的计算机上预先安装最新的 Arduino IDE(Blue Pill 板可以使用 Arduino IDE 编程)和用于编程 Curiosity Nano 微控制器板的 MPLAB X IDE;其中一章解释了如何安装和使用它们。本书中包含的所有针对 Blue Pill 微控制器板的程序示例都应在 Windows、macOS 和 Linux 操作系统上运行。针对 Curiosity Nano 微控制器板的程序在运行 Windows 和 Linux 操作系统的计算机上进行了测试。
如果您使用的是本书的数字版,我们建议您自己输入代码或通过 GitHub 仓库(下一节中提供链接)访问代码。这样做将有助于避免与代码复制和粘贴相关的任何潜在错误。
本书的一些先决条件包括具备基本的计算机编程和电子学知识,以及一些材料,例如无焊面包板、许多杜邦线、LED 灯和电阻。
阅读本书后,您可以继续实验章节中使用的传感器,也许还可以编程并将其他传感器连接到微控制器板上,因为本书为微控制器板编程和使用提供了坚实的基础。
下载示例代码文件
您可以从 GitHub(github.com/PacktPublishing/DIY-Microcontroller-Projects-for-Hobbyists)下载本书的示例代码文件。如果代码有更新,它将在现有的 GitHub 仓库中更新。
我们还提供其他代码包,这些代码包来自我们丰富的图书和视频目录,可在github.com/PacktPublishing/找到。查看它们吧!
Code in Action
本书的相关“Code in Action”视频可以在bit.ly/3cZJHQ5查看。
下载彩色图像
我们还提供了一份包含本书中使用的截图/图表彩色图像的 PDF 文件。您可以从这里下载:static.packt-cdn.com/downloads/9781800564138_ColorImages.pdf。
使用的约定
本书使用了多种文本约定。
文本中的代码:表示文本中的代码单词、数据库表名、文件夹名、文件名、文件扩展名、路径名、虚拟 URL、用户输入和 Twitter 昵称。以下是一个示例:“将下载的WebStorm-10*.dmg磁盘映像文件作为系统中的另一个磁盘挂载。”
代码块设置如下:
html, body, #map {
 height: 100%; 
 margin: 0;
 padding: 0
}
当我们希望将你的注意力引到代码块中的特定部分时,相关的行或项目将被设置为粗体:
[default]
exten => s,1,Dial(Zap/1|30)
exten => s,2,Voicemail(u100)
exten => s,102,Voicemail(b100)
exten => i,1,Voicemail(s0)
任何命令行输入或输出都应如下编写:
$ mkdir css
$ cd css
小贴士或重要注意事项
看起来是这样的。
联系我们
我们始终欢迎读者的反馈。
一般反馈:如果你对这本书的任何方面有疑问,请在邮件主题中提及书名,并通过 mailto:customercare@packtpub.com 给我们发邮件。
勘误:尽管我们已经尽一切努力确保内容的准确性,但错误仍然可能发生。如果你在这本书中发现了错误,我们将不胜感激,如果你能向我们报告这一点。请访问www.packtpub.com/support/errata,选择你的书籍,点击勘误提交表单链接,并输入详细信息。
盗版:如果你在互联网上以任何形式遇到我们作品的非法副本,如果你能提供位置地址或网站名称,我们将不胜感激。请通过 mailto:copyright@packt.com 与我们联系,并提供材料的链接。
如果你有兴趣成为作者:如果你在某个领域有专业知识,并且你感兴趣的是撰写或为书籍做出贡献,请访问authors.packtpub.com。
分享你的想法
一旦你阅读了《DIY Microcontroller Projects for Hobbyists》,我们很乐意听听你的想法!请点击此处直接访问此书的亚马逊评论页面并分享你的反馈。
你的评论对我们和科技社区都很重要,并将帮助我们确保我们提供高质量的内容。
第一章:第一章:微控制器和微控制器板简介
在本章中,您将学习如何设置编程微控制器的基本软件工具,以及如何将基本电子元件作为编程初学者示例的起点。我们将从微控制器及其定义、它们在我们日常生活中的重要性和应用的一般介绍开始。然后,我们将对第 chapters 中执行的其他微控制器项目所需的数字和模拟电子进行简化解释。在这里,我们还将解释本书项目中可能使用的设备。最后,我们将简要描述本书将使用的蓝色药丸和好奇纳米微控制器板。
具体来说,我们将涵盖以下主要主题:
- 
微控制器简介 
- 
执行本书项目所需的模拟和数字电子概述 
- 
蓝色药丸和好奇纳米微控制器板的描述 
我们还将介绍如何安装编程蓝色药丸和好奇纳米所需的软件驱动程序和集成开发环境(IDEs)。完成本章介绍后,您将能够应用您关于集成开发环境(一种软件工具)安装的知识,来编写用于使 LED 闪烁的强制性的Hello World程序。这将使用 C 语言在蓝色药丸和好奇纳米上运行。如果您目前对 C 编程了解不多,请不要担心;我们为您准备了内容;第二章,微控制器板的软件设置和 C 编程,包括一个温和但简洁的 C 编程教程。
技术要求
本书描述的两个微控制器板(蓝色药丸和好奇纳米)可以使用不同的 IDE 进行编程。IDE 是一种包含代码编辑器、编译环境、调试选项等在内的编程和调试软件工具。许多 IDE 也用于通过 USB 端口连接上传编译后的程序到微控制器板。
这些是您需要在计算机上安装的 IDE:
- 
Arduino IDE:这是一个最初为编程 Arduino 微控制器板而创建的免费 IDE,但如果您为其安装了一个库,您也可以用它来编程蓝色药丸微控制器板。 
- 
MPLAB® X IDE:由 Curiosity Nano 制造商 Microchip 开发。这是一个用于编程 Curiosity Nano 的免费 IDE。 
我们将在本章中解释如何安装和使用这些 IDE。
本章中使用的代码可以在本书的 GitHub 仓库中找到:
github.com/PacktPublishing/DIY-Microcontroller-Projects-for-Hobbyists/tree/master/Chapter01
本章的“代码在行动”视频可以在以下链接找到:bit.ly/3zSOg8O
对于硬件,你需要以下材料:
- 
一款普通的 LED 灯——任何颜色都可以。 
- 
220 欧姆电阻;0.25 瓦。 
- 
无焊接面包板,用于连接 LED 和电阻,以及一些公对公跳线,以在组件和微控制器板之间建立电气连接。 
- 
用于连接你的微控制器板到计算机的 micro USB 线。 
- 
当然是 Blue Pill 和 Curiosity Nano 板!Blue Pill 板有几个供应商和制造商,它使用 STM32F103C8T6 微控制器。对于 Curiosity Nano,我们使用名为PIC16F15376 Curiosity Nano PIC® MCU 8-Bit 嵌入式评估板的版本,产品编号 DM164148,由 Microchip 制造。 
- 
需要一个编程适配器,例如ST-Link/V2。这个电子接口将允许你将编译后的代码上传到 Blue Pill,从你的计算机到 Blue Pill 微控制器板建立通信。ST-Link/V2 需要四根公对公杜邦线。 
本书中使用的一些传感器可以以实用模块的形式在传感器套件中找到,例如 Kumantech 37 合 1 传感器套件:
此套件可以与多种类型的微控制器板一起使用,包括 Blue Pill 和 Curiosity Nano。有时,购买这样的传感器套件进行实验其传感器模块是很方便的。其他一些套件包括电阻和代码示例等组件。
微控制器简介
在本节中,我们将重点介绍什么是微控制器以及它的主要部分。了解微控制器的能力以及它们作为许多嵌入式系统的基本组成部分是如何使用的非常重要,这样它们就可以用于实际项目。嵌入式系统是一种计算机子系统,通常作为更大计算机系统的一部分运行,例如,包含微控制器的无线路由器。让我们从微控制器的定义开始。
微控制器(也称为微控制器单元,或 MCU)是一个非常小的、封装在集成电路(IC)中的计算机系统。它封装了执行任务所需的所有计算组件,执行数值计算,从传感器读取数据,在内存中保存数据和程序,并将数据发送到执行器,以及其他动作。大多数微控制器执行模拟-数字转换(ADC),从传感器获取模拟数据并将其转换为数字值。关于 ADC 的更多内容将在第四章中解释,使用光敏电阻测量光照量。数字值由二进制值(1 或 0)定义。下一节将更详细地解释这些值。
微控制器内部有一个像心跳一样的时钟信号,它协调微控制器中任务和其他动作的执行。这个时钟信号没有微处理器(用于台式电脑和笔记本电脑)那么快,但对于执行基本操作,如读取传感器或控制电机来说已经足够了。它们的内部内存有限,但足以存储运行特定任务的程序。一般来说,微控制器不使用外部数据存储设备,如硬盘。它们运行所需的一切都封装在其集成电路(IC)中。
集成电路(IC)是一个密集封装在小型扁平塑料件中的电子电路。它包含许多微小的电子组件和电连接引脚。集成电路以不同的封装方式制造。双列直插封装(DIL)容纳两排电连接引脚。四列扁平封装(QFP)每侧有 8-70 个引脚,适用于表面贴装焊接。微控制器以及其他电子部件都封装在集成电路中。
一些微控制器的引脚使用 DIL 封装组织成两排。其他集成电路,如 STM32 微控制器,有四排引脚,这被称为 QFP。
微控制器也被称为芯片上的计算机。它们通常功耗低,当然,体积也小。其中一些甚至比指甲盖还小!微控制器通常用于执行特定任务和执行特定应用,例如一次控制咖啡机的内部功能。微控制器适用于需要专用和有限计算机功能的情况。
微控制器板
微控制器板是一个包含微控制器和其他支持组件(如分压器/移位器、USB 接口、连接引脚、电阻、电容器和外部时钟)的电子电路。
微控制器板的目的在于便于将外部设备、传感器和执行器连接到微控制器上,从而加速项目原型设计。例如,Blue Pill 微控制器板在其中心包含其微控制器,并且它还有一些支持其功能的其他组件。
类似于 Blue Pill 的微控制器板具有输入/输出 (I/O) 端口,或引脚,传感器、电机和其他电子组件和设备都连接到这些端口上。这些板将通过端口读取或向它们发送数据。这些板还具有有用的引脚,如地线和电压引脚,因此传感器和其他组件可以连接到它们以工作。一些 I/O 引脚读取来自传感器的模拟电压或将模拟电压发送到执行器(例如,电机),而其他则是用于读取和发送数字电压的数字引脚,通常是 0 和 5 伏特,或 0 和 3.3 伏特。所有计算机(包括微控制器)都使用包含 0 和 1 的数字二进制数进行内部工作。二进制值 0 由 0 伏特表示,二进制值 1 由 3.3 或 5 伏特表示。例如,发送到数字端口的数字值(1)可以打开连接到它的 LED。
下一节定义了什么是电子学,以及什么是模拟电子学和数字电子学。这些定义对于理解某些电子组件和电子电路的工作原理非常重要,这些内容将在本书的章节中使用。
本书中项目所需的模拟和数字电子学的概述
电子学是技术和物理学的一个分支,涉及电子在导体、半导体、气体或真空中移动的发射和行为。电子学还涉及电子电路和设备的设计。图 1.1 展示了一个基本电子电路的图,该电路由电源(电池)、电阻和光源(发光二极管,或 LED)组成:

图 1.1 – 电子电路的示例
电子从电池的负极(黑色)通过电路流向 LED,从而点亮它。如果你现在还不理解这个电路及其组件,请不要担心。我们将在接下来的段落中回顾这些内容,并在其他章节中使用它们。模拟电子学是提供和处理连续变量电压信号的电子电路,例如,从 0 伏特变化到 3.3 伏特的模拟电压。相反,数字电子学提供和处理代表二进制值的离散电压信号。例如,0 伏特代表二进制中的0,而 3.3 伏特代表二进制中的1,之间不使用其他电压。这就是计算机和微控制器在最低级别内部工作的方式。微控制器将模拟值转换为数字值,以便处理传入的信号,然后以数字方式处理它们。这被称为模数转换(ADC)。我们需要了解其他章节中将要涵盖的四个关键电子术语,这些是用于测量电子流动的标准单位:
- 
电流:电流是电路中电子流动的速度。电子从电源的负极(如电池)通过导电材料流向正极。这被称为直流(DC)。负极被称为地(GND,或 G),有时也称为地球。电流以安培或amps(安培)为单位测量,用字母I或i表示。 
- 
电压:这是电子电路中电源正负极之间电势能差的电测量。它以伏特(V)为单位测量。它被认为是电路电源的压力推动带电电子(电流)通过电/电子电路。 
- 
功率:功率是测量电路或设备将能量从一种形式转换为另一种形式的速率的量度。功率以瓦特(W)为单位测量。例如,60 瓦的灯泡比 40 瓦的灯泡更亮,因为 60 瓦的灯泡以更高的速率将电能转换为光能。 
- 
电阻:电导体的电阻是测量电子通过导体传递电流难易程度的量度。它以欧姆为单位测量,用希腊字母欧米茄(Ω)表示。欧姆定律描述了许多电导材料的导电性。它规定,导体两点之间的电流与两点之间的电压成正比,其中其电阻是恒定的。这个定律可以用数学公式 I=V/R 来描述,这对于计算电子电路中的电流、电压或电阻非常有用。 
在本节中,我们介绍了电子电路中使用的标准测量单位的基本知识,您将在本书的所有章节中应用这些知识。下一节将介绍在开始实验电子电路和微控制器板之前您也需要了解的重要电子元件。
基本电子元件
以下是在许多微控制器板项目和本书中描述的大多数项目中常用的电子元件。它们使我们能够控制电子电路中的电流。我们将回顾四个主要电子元件:电阻、二极管、电容器和晶体管。
电阻
电阻通常用于减少电子电路中的电子流动。电阻对于允许某些组件(如 LED)在电路中正常工作而不烧毁是有用的。电阻中的电阻水平可以是固定的或可变的。一些电阻的阻值可以从一到数千欧姆(千欧或 kΩ)到数百万欧姆(兆欧或 MΩ)。电阻还通过其功率额定值来衡量,以瓦特为单位。这指的是它们在不过热并损坏的情况下可以承受的电流量。
图 1.2展示了如何读取电阻的值:

图 1.2 – 一个显示如何计算电阻值的图表。图片来源:“电阻色码”,由 Adim Kassn 提供,许可协议为 CC-BY-SA-3.0
重要提示
如图 1.2所示,色带颜色为:
0: 黑色
1: 棕色
2: 红色
3: 橙色
4: 黄色
5: 绿色
6: 蓝色
7: 紫色
8: 银色
9: 白色
1%公差的色带是棕色,2%是红色,5%是金色,10%是银色。您可以通过此链接访问彩色图表:commons.wikimedia.org/wiki/File:Resistor_color_code.png。
常见电阻有四条色带(有些有五条色带,但这在一般电子电路中很少使用)来确定它们的欧姆值:
- 
第一条色带表示其欧姆值的第一位数字。 
- 
第二条色带显示第二位数字。 
- 
第三条色带表示第三位数字(通常是零的数量)。 
- 
第四条色带确定电阻公差,这是电阻精度的度量。例如,如果色带是银色,这意味着电阻将根据其标称值有 10%的公差变化。 
在微控制器板项目中使用的许多电阻都是 1/4 瓦电阻,这对于简单应用来说足够了。
二极管
二极管是一种电子元件,只允许电流单向流动。电路中的电流通过二极管的阳极(+)流入,并通过其阴极(-)流出。二极管通常用于保护电子电路的某些部分免受反向电流的影响。它们还帮助将交流电(AC)转换为直流电,以及其他应用。当我们将电机连接到微控制器板上时,二极管也用于保护微控制器板,以避免电压反冲。这发生在当电机供电电流突然中断或减少时,电机两端会出现突然的电压峰值。然而,二极管会导致电压下降约 0.7V。二极管被制造出来可以处理一定量的安培(电流)和电压。例如,1N4004 二极管被评定为可以处理 1 安培(A)和 400 伏特(V),这比我们在本书的项目中使用的要高得多。二极管周围的带子表示阴极,通常连接到电源的地线端子。另一个引脚是阳极,通常连接到电源的正极(+)。一种常见的二极管类型是发光二极管(LED),当有电子通过时它会发光。它们有不同的尺寸、颜色和形状。与普通二极管一样,LED 也是极化的,因此电流以一个方向进入和离开 LED。如果过多的电流通过 LED,这将损坏它。你需要串联连接一个电阻来降低其电流,从而保护它。对于许多微控制器板应用,至少 220 欧姆的电阻就足够了。
电容
这是一种电子元件,可以暂时存储(储存)电荷。一旦电流停止通过电容,电荷将留在其中,并且一旦电容连接到电路,就可以立即放电。电容可以存储的电荷量以法拉(f)为单位来衡量。由于法拉是一个非常大的数值,许多电容的容量都小于一法拉。电容可以承受一定的最大电压。在微控制器应用中,10V、16V、25V 和 50V 的电容很常见。它们有两种类型:单片(它们没有极性)和电解(它们有极性)。
电解电容器比单片电容器大,它们的极性通过一个带子在一侧标记阴极引脚,另一个带子标记阳极引脚来表示。记住,阴极引脚连接到电源的接地端,而阳极连接到电源的正电压端。电解电容器的典型值从 1 微法拉到 47,000 微法拉不等。电容器可用于微控制器板项目,用于过滤(清理)数字或模拟信号(去除电气噪声),它们可以将交流电压转换为直流电压等。使用极化(电解)电容器时要非常小心!它们可以储存大量的能量。你永远不应该触摸其引脚(引线),短路,或反向连接。确保在项目中连接电解电容器时,将其正极(+)引脚连接到电路电源的正极(电源是一种为电子电路或电气设备提供稳定电源的电子/电气组件)和将电容器的负极引脚连接到电路电源的负极。尊重其极性。如果你将它们反向(极性错误)连接,它们将会损坏并可能爆炸。单片(陶瓷)电容器没有极性。它们的引脚(引线)在电路中的连接方式无关紧要。电容器的典型容量范围从 0.5 皮法拉到 1 微法拉。
晶体管
晶体管可以作为一个非常快速的数字开关。晶体管对于开关高电流电路或设备(如电机和风扇)非常有用。它还可以用作电流放大器,形成逻辑门(与、或、非等);这种电流也称为负载。流行的且价格低廉的例子有 BC548 和 2N2222 晶体管。晶体管被设计成可以承受一定量的电流和电压(例如,BC548 晶体管的最大电流为 100 mA 和 30 V)。
图 1.3 展示了本节中解释的基本电子组件:

图 1.3 – 电子组件(从左到右显示):一个电阻器,一个二极管,一个 LED,一个单片电容器和一个晶体管
下一节描述了一个名为无焊面包板(solderless breadboard)的工具,它对于连接电子组件和微控制器板非常有用。
无焊面包板
你可以在微控制器板项目中使用的另一个非常有用的部件是无焊面包板,如图 图 1.4 所示。它用于电子电路的快速原型设计。它的塑料基座有排成行的电连接插座,有多种尺寸、形状和颜色:

图 1.4 – 面板列和行的连接
请记住,如果你在一行垂直的孔中插入两根电线,那么它们将电连接。标有–和+符号的水平行在水平方向上是电连接的,如图 1.4所示。
本节描述了重要且常用的电子组件,如电阻和 LED,这些组件常用于涉及微控制器板的电子项目中。下一节将描述本书中使用的蓝色药丸和好奇心纳米微控制器板。
蓝色药丸和好奇心纳米微控制器板的描述
本节解释了以下照片中展示的蓝色药丸和好奇心纳米微控制器板。它们的上下行孔将连接到引脚头,其中大部分是端口。图 1.5 展示了蓝色药丸微控制器板,中间显示了 STM32 微控制器芯片:

图 1.5 – 蓝色药丸微控制器板
图 1.6 是好奇心纳米微控制器板的特写。注意其中心显示的 PIC16F15376 微控制器芯片:

图 1.6 – 好奇心纳米微控制器板
板中央的黑色菱形组件是微控制器。前几张照片中的两个板还没有引脚头。原因是,在某些项目中,需要将电线和电子组件直接焊接到一个无头板上,尽管在这本书中你不需要这样做。然而,一些好奇心纳米板允许引脚插入并牢固地固定,无需焊接。此外,你可以购买已经焊接好引脚的蓝色药丸。或者,你也可以将引脚头焊接在蓝色药丸和好奇心纳米板的两端。以下是如何焊接电子组件的教程:www.makerspaces.com/how-to-solder/.
图 1.7 展示了蓝色药丸微控制器板倒置,其引脚头已经焊接好,并有一个独立的引脚行:

图 1.7 – 一个已经将引脚焊接好的蓝色药丸
一旦板上有引脚头,你就可以将它们插入无焊面包板中,并开始使用它们进行原型设计,无需将电线或组件直接焊接在板上,这就是我们将在本书的项目中使用它们的方式。
我们选择这些微控制器板作为本书的示例,因为它们价格低廉、功能多样(你可以将不同类型的传感器、LED 灯、电机等连接到它们),并且编程和使用相对简单。微控制器板极大地简化了短时间内构建原型的工作。你还可以将它们应用于与 COVID-19 相关的项目,我们将在本书的多个地方对此进行回顾。
此外,了解使用不同系列和制造商的微控制器板总是有益的,因为每个板都有不同的功能和优势。Blue Pill 使用 STM32 微控制器系列的微控制器,而 Curiosity Nano 与 PIC 系列的微控制器配合工作。
Blue Pill 有 37 个通用 I/O 引脚,包括端口 PA0 – PA15、PB0 – PB15 和 PC13 – PC15。例如,I/O 端口 PC13 在 Blue Pill 上标记为 C13。
Curiosity Nano 有 35 个 GPIO 端口,包括 RA0、R1、RA2、RA3、RA4、RA5、RB0、RB3、RB4、RC7、RD0、RD1、RD2、RD3、RC2、RC3、RB2、RB1、RC4、RC5、RC6 和 RD4 等。我们将在 第二章 微控制器板的软件设置和 C 语言编程 中回顾这些端口的编程。表 1.1 展示了本书中使用的两个微控制器板的技术规格:

表 1.1 – Blue Pill 和 Curiosity Nano 的技术规格
Blue Pill 和 Curiosity Nano 的运行速度比大多数 Arduino 微控制器都要高得多。例如,Arduino Uno 微控制器板的运行速度为 16 MHz。
安装 IDE
接下来,我们将解释安装和使用 Curiosity Nano 和 Blue Pill 微控制器板 IDE 的必要步骤。
为 Curiosity Nano 板安装 MPLAB X IDE
下一步将展示如何下载和安装用于编程 Curiosity Nano 的 MPLAB X 工具。本节还将解释 MPLAB X IDE 的主要部分:
- 
您首先需要登录到免费的 myMicrochip 服务(Microchip 是 Curiosity Nano 的制造商)。填写此网页上的注册表单: www.microchip.com/wwwregister/RegisterStep1.aspx。
- 
注册后,从以下链接下载 MPLAB X IDE: www.microchip.com/mplab/mplab-x-ide。
- 
前往 下载 选项卡,根据您使用的操作系统下载 IDE。 
- 
下载安装程序后,按照以下说明安装 MPLAB X IDE: microchipdeveloper.com/mplabx:installation。
- 
您还需要下载并安装免费的 XC8 C 编译器来编程 Curiosity Nano。打开此链接: www.microchip.com/mplab/compilers。
- 
然后,转到编译器下载选项卡,根据您的操作系统下载安装文件。 
- 
从那里下载 XC8 编译器的最新版本。这个版本适合编程本书中使用的 Curiosity Nano 所带的 PIC16F15376 微控制器。请按照以下链接中的说明安装 XC8 编译器: microchipdeveloper.com/xc8:installation。
下载 XC8 编译器可能需要一些时间,所以请耐心等待。下一节将描述 MPLAB X IDE 中常用的组件。
理解 MPLAB X IDE 的主要组件
本节描述了您将用于编辑程序、编译程序等 IDE 的主要部分。
图 1.8是 MPLAB X IDE 的截图:

图 1.8 – MPLAB X IDE 的主要部分
在图 1.8中描述的主要部分包括文本编辑器(代码区域),它将在本书的其他章节中使用。IDE 中最重要的按钮之一是运行按钮,它编译、运行并将二进制(编译)文件上传到 Curiosity Nano 板。
下面是启动新编码项目的步骤:
- 
点击文件/新建项目以创建一个新的项目。 
- 
点击代码选项卡,并在代码区域开始编写您的代码。 
- 
点击运行图标以编译并将您的代码上传到微控制器板。控制台将显示有关进程的消息,并确定一切是否按计划进行。 
与其他微控制器板(如 Blue Pill)不同,您需要在 Curiosity Nano 微控制器板使用之前配置输入和输出端口。您可以使用一个名为MPLAB X 代码配置器(MCC)的特殊插件来完成此操作。您应该为 MPLAB X IDE 安装 MCC 插件。MCC 是一个免费的图形编程环境,它有助于配置微控制器端口,以及其他应用。它将生成必要的 C 编程头文件库,用于从微控制器端口读取数据和向微控制器端口写入数据。
此网页解释了如何在 MPLAB X IDE 中安装 MCC:www.microchip.com/mplab/mplab-code-configurator。
安装它的最简单方法是点击 MPLAB X IDE 主菜单上的工具/插件,然后从那里下载并安装。
我们已经创建了一个 MPLAB X 项目模板,其中我们为 Curiosity Nano 配置了输入和输出端口,并处理了其上的数字和模拟数据。我们已使用 MCC 插件设置 I/O 端口,因此您可能不再需要为本书中解释的项目和其他项目使用 MCC 插件。这是一个方便的模板,因为它包含了处理 Curiosity Nano 一些端口的输入和输出 C 编程函数所需的所有必要库。我们将在第二章中回顾这些库和 C 编程函数,微控制器板软件设置和 C 编程。该模板项目名为16F15376_Curiosity_Nano_IOPorts.zip,存储在我们的 GitHub 主页上。
只需下载 zip 文件,解压它,然后在 MPLAB X 中打开项目。
安装 Arduino IDE 和 Blue Pill 库
您可以使用 Arduino IDE 来编程 Blue Pill 微控制器板。按照以下步骤安装 Arduino IDE:
- 
从此网站下载 Arduino IDE 的 Windows、macOS 或 Linux 版本: www.arduino.cc/en/main/software。不要忘记下载适合您操作系统的正确 IDE 安装程序。
- 
运行您刚刚下载的安装程序,并按照屏幕上的说明操作。 
- 
识别 Arduino IDE 的主要选项。 
图 1.9显示了 Arduino IDE 及其主要部分和区域。控制台是一个有用的组件,其中 IDE 显示错误或警告消息。状态栏显示程序编译和上传状态:

图 1.9 – Arduino IDE 的主要部分
图 1.9显示了 Arduino IDE 的主要部分,包括其代码编辑器、状态栏、菜单栏和控制台。最常用的功能之一是上传按钮,它编译您的程序并将其编译后的代码上传到 Blue Pill。以下步骤显示了如何将程序上传到 Blue Pill 以及如何在 IDE 中安装必要的库:
- 
通过点击 Arduino 菜单栏中的文件/示例/01.基础/Blink来打开一个示例程序。这将帮助您熟悉 Arduino IDE。一个名为Blink的程序将打开。点击验证按钮来编译它并为微控制器板生成二进制文件。上传按钮将验证、编译、生成二进制文件,然后将文件上传到微控制器板。 
- 
在将程序上传到 Blue Pill 之前,您需要在 Arduino IDE 上安装一个库来编程 Blue Pill。要安装 Blue Pill 库,从 IDE 的菜单栏点击File/Preferences。然后,将出现一个新窗口。点击Additional Boards Manager URLs右侧的小窗口图标,并添加以下链接以安装库: dan.drown.org/stm32duino/package_STM32duino_index.json,如图图 1.10所示:![图 1.10 – 写入链接库的 IDE 的偏好设置选项]() 图 1.10 – 写入链接库的 IDE 的偏好设置选项
- 
在图 1.10所示的上端窗口中点击OK(Additional Boards Manager URLs),然后在Preferences窗口中点击OK按钮。 
- 
现在,在菜单栏上,转到Tools/Board/Boards Manager。这将打开Boards Manager对话框。 
- 
确保您选择 STM32F1xx,并仅安装窗口上出现的包。
- 
关闭该窗口,点击Tools/Board/STM32F1 Boards,然后选择Generic STM32F103C series选项,如图所示的以下截图。确保其变体为64k Flash,上传方法为STLINK,其 CPU 速度为72MHz, Optimize: Smallest。图 1.11显示了 IDE 中的 Blue Pill 配置: 

图 1.11 – 包含 Blue Pill 所需选项的工具菜单
IDE 应该已经准备好开始为 Blue Pill 编写代码了。在那之前,我们需要安装一个名为ST-Link/V2的接口,以便将我们的代码上传到 Blue Pill。与其他微控制器板不同,我们不能通过 micro-USB 线直接将编译后的程序上传到 Blue Pill。一种简单的方法是使用 ST-Link/V2 接口,这是一个单线接口模块(SWIM),仅使用四根线。
ST-Link/V2 是一个 USB 接口,用于编程和调试 STM32 微控制器应用程序,主要用于将程序上传到 Blue Pill 微控制器板。
在连接 ST-Link/V2 之前,您需要在您的计算机上安装其驱动程序。以下解释了如何在 Windows 上安装 ST-Link/V2 驱动程序。从以下链接下载驱动程序:www.st.com/en/development-tools/stsw-link009.html。
下载并解压 zip 文件,根据您是否使用 32 位或 64 位计算机运行dpinst_amd64.exe或dpinst_x86.exe。大多数最新的都是 64 位。按照显示的说明安装其驱动程序。
这里是安装 ST-Link/V2 到 macOS 的说明:www.st.com/en/development-tools/stsw-link007.html#overview。
这里是安装 ST-Link/V2 到 Linux 的说明:freeelectron.ro/installing-st-link-v2-to-flash-stm32-targets-on-linux/。
重要提示
如果你在 Linux 上运行 Arduino IDE,请以 root 用户身份运行 IDE 以获取 USB 访问权限。
或者,你可以尝试这个开源工具集,用于在 Windows、macOS 或 Linux 上安装 ST-Link/V2:github.com/stlink-org/stlink。
Arduino IDE 提供了一个串行监视器,可以通过点击 IDE 主菜单中的 工具/串行监视器 来访问。它将通过使用特殊的编码函数显示从 Blue Pill 发送到 USB 串行端口的 数据。第五章,湿度与温度测量,解释了如何使用串行监视器。它可以用于在计算机屏幕上显示从传感器获得的数据、变量的值以及其他类似操作。
下一节将描述如何使用 MPLAB 和 Arduino IDE 运行一个简单的程序,该程序将使 LED 每秒闪烁一次。这将是一个实用的例子,帮助你熟悉编程 Blue Pill 和 Curiosity Nano 板。
你的第一个项目——闪烁的 LED
这个小型项目演示了如何将 LED 连接到微控制器板,以及如何编程其 I/O 端口,以便你可以不断循环地打开 LED,等待 1 秒(1,000 毫秒),关闭 LED,再等待另一秒,然后再次打开 LED。
该项目还演示了如何将编译后的程序上传到微控制器板。这是一个重要的入门项目,因为你以后可以重用此代码来向端口发送信号并控制更复杂的应用,例如风扇。这就像是微控制器板的 Hello World 项目!我们将使用各自的 IDE 在 Blue Pill 和 Curiosity Nano 微控制器板上运行此项目。
使用 Blue Pill 板运行闪烁的 LED 示例
这个小型项目演示了如何使 LED 亮 1 秒,然后熄灭 1 秒,重复进行。当然,它还演示了如何从 Blue Pill 中声明和使用 I/O 端口作为输出。
小贴士
在开始之前,当你操作 Blue Pill 和 Curiosity Nano 板时要小心。它们可能会被你身体上的静电损坏,所以在操作它们之前应该触摸一个大金属区域,如桌架。你也可以佩戴防静电腕带。通过这样做,你可以释放你的静电。一般来说,避免用裸手触摸排针。
我们现在将探讨如何将电子元件连接到无焊面包板和 Blue Pill:
- 
您需要将 Blue Pill 板插入面包板。请小心操作,因为引脚可能会弯曲。 
- 
将 LED 连接到面包板。现在,按照以下图示将 220 欧姆电阻的一个引脚连接到 LED 最长的引脚(腿),将电阻的另一个引脚连接到 Blue Pill 上标记为C13的引脚。 
- 
使用一根电线将 LED 最短的引脚连接到 Blue Pill 上标记为G或GND的接地引脚。记住,面包板每列的孔是内部相连的。 
- 
现在,按照以下方式将 ST-Link/V2 模块引脚连接到 Blue Pill 引脚。ST-Link/V2 引脚在其一侧标记。Blue Pill 的引脚在其底部标记。 
- 
将 Blue Pill 的 CLK 引脚连接到 ST-Link/V2 的 SWCLK 引脚。 
- 
将 Blue Pill 的 DIO 引脚连接到 ST-Link/V2 的 SWDIO 引脚。 
- 
将 Blue Pill 的 GND 引脚连接到 ST-Lin/V2 的 GND 引脚 
- 
将 Blue Pill 的 3V3 引脚连接到 ST-Link/V2 的 3.3 V 引脚。 
ST-Link/V2 和 Blue Pill 之间的连接关系如图1.12所示:

图 1.12 – Blue Pill、LED 和 ST-Link/V2 的连接
图 1.12显示了我们所做的连接。请注意,这里在 Blue Pill 和 ST-Link/V2 之间连接了四根杜邦线。图 1.13显示了 Blue Pill 和 ST-Link/V2 之间连接的图片:

图 1.13 – 包含 ST-Link/V2 的 Blue Pill 连接
一旦将 Blue Pill 连接到 ST-Link/V2,我们将继续以下步骤:
- 
将 ST-Link/V2 插入您的计算机。同时,从 Blue Pill 上断开 micro-USB 线缆(图片中的白色线缆)。在将程序上传到 Blue Pill 时不需要这个。 
- 
从书中 GitHub 仓库的“第一章”文件夹中下载名为 Blink_Blue_Pill.ino的程序。
- 
从 GitHub 下载 .ino文件,并使用 Arduino IDE 打开它,这将创建一个新的文件夹来存储程序。这是 Arduino IDE 的正常做法。如果您目前还不理解代码,请不要担心。我们将在下一章解释其 C 代码编程。
- 
点击 IDE 上的上传图标以编译并将程序上传到 Blue Pill。如果一切顺利,您将看到 Blue Pill 的板上 LED 和您连接的 LED 每秒闪烁一次。板上 LED 内部连接到 PC13 引脚。尝试通过更改 delay(1000)函数中的 1,000 毫秒值来改变闪烁速率。
- 
一旦你将程序上传到 Blue Pill,就不再需要将 ST-Link/V2 连接到它,所以如果你想的话可以断开连接。现在你可以将 Blue Pill 的 micro USB 线缆连接到你的电脑或一个 USB 电池组。你的编译后的程序将被保存在 Blue Pill 的内存中,每次你给它供电时都会运行。 
现在你已经完成了!你已经用 Blue Pill 完成了你的第一个电子电路。如果你的 LED 在闪烁,做得好!
此项目也可以使用 Arduino 微控制器板,如 Arduino Uno 完成。只需在 Arduino 代码中更改端口号,并使用 Arduino IDE 编译和上传程序。在代码中将端口号 13 替换为 PC13,并将电阻连接到 Arduino Uno 板的数字端口 13。
在 Curiosity Nano 板上运行闪烁 LED 示例
现在,让我们尝试在 Curiosity Nano 板上运行 LED 闪烁示例。我们不需要将接口编程器(如 ST-Link/V2)连接到 Curiosity Nano 上来上传你的程序,因为这个板已经具备了完成此操作所需的硬件和软件组件。以下是连接 Curiosity Nano 和 LED 的步骤:
- 
将 Curiosity Nano 板插入无焊点面包板。请小心操作,因为其腿可能会弯曲。此外,在处理 Curiosity Nano 之前,别忘了触摸一个大的金属物体以释放你身体上的静电。 将 LED 连接到面包板。现在,将 220 欧姆电阻的一个引脚连接到 LED 的最长引脚,如图 1.14 所示。将电阻的另一个引脚连接到 Curiosity Nano 上标有 RE0 引脚 的引脚。RE0 引脚内部连接到 Curiosity Nano 上的黄色 LED: ![图 1.14 – 显示 Curiosity Nano 和 LED 连接的示意图]() 图 1.14 – 显示 Curiosity Nano 和 LED 连接的示意图 
- 
使用线缆将 LED 的最短腿连接到 Curiosity Nano 上标有 GND 的地线引脚,如图 1.14 所示。Curiosity Nano 上的任何 GND 引脚都可以。记住,每个面包板列的孔是内部连接的。 带有 Curiosity Nano 的电子电路如图 1.15 所示。在此图中,你可以更详细地可视化 LED 和电阻如何连接到板上: ![图 1.15 – Curiosity Nano 和其 LED 连接图]() 图 1.15 – Curiosity Nano 和其 LED 连接图 
- 
使用 micro-USB 线缆将 Curiosity Nano 连接到你的电脑。 
- 
现在,让我们下载并运行包含使 LED 在 Curiosity Nano 上闪烁的 C 程序的演示项目。 
- 
从书中 GitHub 仓库中位于“第一章”文件夹的 16F15376_Curiosity_Nano_LED_Blink_Delay.zip文件下载。
- 
解压文件,并在 MPLAB X IDE 中打开项目。选择带有 main.c标签的选项卡。这就是你需要运行的 C 程序。现在,点击 MPLAB X 上的运行图标(绿色的三角形)。
在这一点上,IDE 将编译并将程序上传到板子上。几秒钟后,板上的黄色 LED 和面包板上的 LED 应该每秒闪烁一次。如果这是发生的,那么做得好!
一旦你将 LED 连接到 Curiosity Nano 并看到 LED 每秒闪烁一次,尝试在 IDE 中稍微修改一下代码,使 LED 闪烁更快或更慢。你可以通过更改__delay_ms(1000);函数中的毫秒值来实现这一点,并且别忘了该函数的值是以毫秒为单位的(一秒钟有 1,000 毫秒)。
摘要
在本章中,我们定义了什么是微控制器,以及它的功能和限制。我们还探讨了集成电路是什么(考虑到微控制器是集成电路的一种类型)以及它们的引脚如何在封装中排列。此外,我们还分析了微控制器板上的端口。了解这一点很重要,因为在未来的某个时候,你将需要识别这些引脚的顺序,以便将传感器或其他设备连接到它们。表 1.1显示了 Curiosity Nano 和 Blue pill 的硬件描述和操作电压,均为 5 伏。
然后,我们简要介绍了电子学以及在本章和其他章节中使用的主要电子元件。我们探讨了如何安装两个用于编程本书中使用的两个微控制器板的集成开发环境工具。这两个板有上传编译程序到它们的不同方式。比较两种不同的微控制器板的工作方式,分析它们的性能,并决定你在未来的项目中可以使用哪一个,这是很重要的。
最后,我们在两个微控制器板上展示了初始程序,演示了如何打开和关闭 LED,这可以作为更复杂和详细项目的基准。
下一章包含了一个简洁的 C 语言编程教程,这对于编程剩余章节的练习非常有用。
进一步阅读
- 
Ball, S. (2002). 嵌入式微处理器系统:现实世界设计. 马萨诸塞州伯灵顿:Newnes/Elsevier Science. 
- 
Gay, W. (2018). STM32 入门:使用 FreeRTOS、libopencm3 和 GCC 进行开发. 圣凯瑟琳斯:Apress. 
- 
Horowitz, P., Hill, W. (2015). 电子艺术. [第 3 版] 剑桥大学出版社:纽约,纽约。 
- 
Microchip (2019). PIC16F15376 Curiosity Nano 硬件用户指南. Microchip Technology, Inc. 可从: ww1.microchip.com/downloads/en/DeviceDoc/50002900B.pdf.
- 
Mims, F.M. (2000). 入门电子学. 伊利诺伊州林肯伍德:Master Publishing, Inc. 
第二章:第二章:微控制器板软件设置和 C 编程
在本章中,你将回顾用于编程 Blue Pill 和 Curiosity Nano 微控制器板的 IDE 的基本配置,以及学习为 Blue Pill 和 Curiosity Nano 编写应用程序所需的 C 编程语言基础知识。这绝对不是一份全面的 C 教程。它包含了理解和完成本书所有章节中解释的练习的重要信息。在本章中,我们将涵盖以下主要主题:
- 
介绍 C 编程语言 
- 
介绍 Curiosity Nano 微控制器板编程 
- 
介绍 Blue Pill 微控制器板编程 
- 
示例 – 编程和使用微控制器板内部 LED 
在本章结束时,你将获得对 C 编程语言的坚实基础介绍,包括一组编程指令,这些指令对于使用 Blue Pill 和 Curiosity Nano 微控制器板开发许多小型和中型微控制器项目非常有用。本章还涵盖了内部 LED 的使用,Blue Pill 和 Curiosity Nano 都具备这一功能。这可以非常方便地快速显示数字结果(例如,确认项目中的操作)。
技术要求
我们在本章中将使用的软件是用于编程 Blue Pill 和 Curiosity Nano 的 Arduino 和 MPLAB X IDE。它们的安装过程在第一章**, 微控制器和微控制器板简介中已有描述。我们还将使用之前章节中使用的相同代码示例。
在本章中,我们还将使用以下硬件:
- 
一个无焊点面包板。 
- 
Blue Pill 和 Curiosity Nano 微控制器板。 
- 
一条用于将微控制器板连接到计算机的微型 USB 线。 
- 
需要上传编译代码到 Blue Pill 的 ST-LINK/V2 电子接口。请记住,ST-Link/V2 需要四根公对公的杜邦线。 
这些是本章中描述的示例所需的基本硬件组件,它们也将证明在其他章节中解释的更复杂项目中非常有用。
本章中使用的代码可以在本书的 GitHub 仓库中找到:
github.com/PacktPublishing/DIY-Microcontroller-Projects-for-Hobbyists/tree/master/Chapter02
本章的“代码在行动”视频可以在此找到:bit.ly/3xwFvPA
下一节将简要介绍 C 编程语言。
介绍 C 编程语言
C 编程语言最初在七十年代初被创建,用于开发 UNIX 操作系统,但自那时起它已经被移植到几乎所有操作系统上。它是一种中级编程语言,因为它从高级语言(例如 Python)和低级语言(例如汇编语言)中共享属性。C 语言通常比低级语言更容易编程,因为它非常易于阅读,并且有许多库可用,这些库有助于软件开发,以及其他原因。它也非常适合编程嵌入式系统。C 是最受欢迎的编程语言之一,几乎所有微控制器都可以用 C 编译器编程——Blue Pill 和 Curiosity Nano 也不例外。
C 语言在不同微控制器系列和制造商之间并不完全可移植。例如,在 Blue Pill 和 Curiosity Nano 中,I/O 端口和中断的编程方式并不相同。这就是为什么需要两种类型的 C 编译器和不同的库来编程这两个微控制器板。实际上,用于编程 Blue Pill 的 Arduino IDE 使用的是 C 语言的变体,称为C++。C++是 C 编程语言的强大扩展,它结合了面向对象和低内存级编程等特性。
以下部分解释了 C 语言结构的基础知识。本节包括对#include指令的解释、编写注释、理解变量、使用常量、关键字列表、声明函数、评估表达式以及在 C 中编写循环。
C 语言的基本结构
与其他编程语言一样,C 语言使得可以在称为.h的单独文件中声明程序元素,如常量、类型、函数和变量。这有助于组织 C 指令并减少主 C 代码中的混乱。库是一个包含程序元素(如函数)的头文件,可以与其他 C 程序员共享或在不同的 C 程序中反复使用。C 语言编译器包含我们在本书中将使用的重要库。头文件可以通过#include指令(即链接和编译)与主程序一起包含;因此,在头文件中声明的编程元素将在 C 程序中被调用和使用。
有许多有用的标准和非标准库。我们将回顾并使用两者。#include指令是 C 编译器的特殊指令,而不是常规的 C 指令。它应该写在程序的开头,并且末尾没有分号。只有 C 语句在末尾有分号。有三种编写和应用#include指令的方法。具体如下:
- 
#include <file_name.h>:此类指令使用小于和大于符号,意味着头文件(.h)位于编译器路径中。你不需要写出头文件的完整路径。
- 
#include "file_name.h":此类指令使用双引号。头文件存储在项目目录中。
- 
#include "sub_directory_name/file_name.h":此类指令类型告诉编译器头文件位于子目录中。请注意,斜杠符号的使用取决于你使用的操作系统。例如,Windows 计算机使用反斜杠(\)符号作为目录分隔符。Linux 和 Mac 计算机使用正斜杠(/)符号。
下一个子节将展示如何定义和使用头文件。
#include 指令示例
以下程序示例展示了如何包含位于项目目录中的头文件:
#include "main_file.h"
int main(void)
{
    x = 1;
    y = 2;
    z = x+y;
}
在前面的例子中,x、y 和 z 变量是在 main_file.h 头文件中声明的,因此它们在主程序中没有声明。头文件 (file.h) 包含以下代码,声明了在主代码中使用的三个变量:
int x;
int y;
int z;
我们可以在主程序中声明变量,而不在头文件(.h)中声明变量。是否要在头文件中编写程序元素取决于你。我们将在本章后面学习更多关于变量的内容。
注意
C 语言是区分大小写的,因此在编写 C 代码时要小心。大多数 C 语言指令都是用非大写字母编写的。声明变量时也要小心。例如,C 中的变量 x 和 X 是不同的。
C 语言附带了一些标准库,许多程序员很好地利用了它们。stdio.h 库(存储为头文件)在 C 编程中被广泛使用。它定义了多个宏、变量类型,以及用于执行数据输入和输出的专用函数;例如,从键盘读取输入字母或将文本写入控制台。控制台是 IDE 提供的一个基于文本的区域,在这里从键盘读取数据或写入文本或特殊字符。
这是一个使用 <stdio.h> 指令的简短 C 程序示例:
// program file name: helloworld.c
#include <stdio.h>  
int main()  
{  // start main block of instructions
     printf("Hello world!"); 
     return 0;
} 
C 程序文件以 .c 扩展名存储(例如 mainprogram.c)。C++ 程序文件通常以 .cpp 扩展名存储(例如,mainprogram.cpp)。
printf() 函数用于在 IDE 的控制台上显示字符(例如,文本消息)。从前面的程序示例中可以看出,我们编写了一些注释来解释每一行代码。下一节将展示在 C 语言中编写注释的不同方式。
在 C 中使用注释
注释是不影响 C 程序功能的文本块或行。在 C 编程中编写注释很有用,因为它们可以用来解释和阐明指令、函数、变量等的含义或功能。我们编写的所有注释都会被编译器忽略。在 C 中编写注释有几种方法:
- 
使用双斜杠( //):这会创建单行注释。
- 
使用斜杠和星号( /* */):这会创建一个包含文本块的注释。
此代码示例演示了如何使用两种类型的注释:
/**********************************************************
Program: Helloworld.c 
Purpose: It shows the text "Hello, world!!" on the IDE's console. 
Author: M. Garcia.
Program creation date: September 9, 2020.
Program version: 1.0 
**********************************************************/
#include <stdio.h>  //standard I/O library
int main(void)
{
    int x; // we declare an integer variable
    printf("Hello, world!!"); 
    x=1; // we assign the value of 1 to variable x.
}
小贴士
在 C 程序的开头添加代码的目的、版本号和日期以及作者的姓名作为注释是一种良好的编程实践。
下一节将描述如何在 C 编程中声明和使用变量。变量非常有用,你将在本书的大部分章节中使用它们。
理解 C 语言中的变量
变量是一个通过编程分配给微控制器内存存储区域(也称为标识符)的名字,用于临时存储数据。在 C 语言中存在特定类型的变量,用于存储不同类型的数据。变量类型决定了分配给变量的微控制器内存的布局和大小(通常是其内部随机访问内存或 RAM)。
我们必须在 C 语言中首先声明一个变量,才能在代码中使用它。变量声明有两个部分——数据类型和标识符,使用以下语法:<数据类型> <标识符>。以下是对这两部分的解释:
- 数据类型(或简称类型)定义了要存储在变量中的数据类型(例如,整数)。有许多数据类型及其修饰符。以下表格描述了四种主要类型:

表 2.1 – C 语言中使用的四种主要数据类型
- 
表 2.1中的每种类型都有 unsigned、signed、short和long等修饰符。例如,我们可以声明一个存储无符号整数的变量,如unsigned int x;。
- 
还有一种名为 void的类型。这种类型没有值,通常用于定义返回无值的函数类型。
- 
标识符是唯一标识变量的名字。标识符可以用字母 a..z 或 A..Z、数字 0..9 和下划线字符:_ 来编写。标识符不能有空格,并且第一个字符不能是数字。记住,标识符是区分大小写的。此外,根据 ANSI C 标准,标识符的长度应少于 32 个字符。 
例如,让我们声明一个名为 x 的变量,它可以存储浮点数:
float x;
在前面的代码示例中,C 编译器将为变量x分配一个特定的内存分配,该分配仅包含浮点数。
现在,让我们在以下代码行中使用这个变量:
x=1.10;
如您所见,我们将浮点值 1.10 存储在名为x的变量中。以下示例演示了如何在 C 程序中使用变量:
/* program that converts from Fahrenheit degrees to Celsius degrees. Written by Miguel Garcia-Ruiz. Version 1.0\. Date: Sept. 9, 2020
*/
#include <stdio.h> // standard I/O library to write text
int main(void) // It won't return any value
{
    float celsius_degrees;
    float fahrenheit_degrees=75.0;
    // Calculate the conversion:
    celsius_degrees=(fahrenheit_degrees-32)*5/9;
    // printf displays the result on the console:
    printf("%f",celsius_degrees); 
}
您可以在声明变量时初始化其值,就像前面示例中的fahrenheit_degrees变量所示。
我们也可以使用字符串开头和结尾的双引号将字符串存储在变量中。以下是一个示例:
char name = "Michael";
上述示例展示了如何将字符串存储在字符变量类型中,它是一个字符数组。
声明局部和全局变量
在 C 语言中,根据变量的声明位置,存在两种类型的变量。它们可以有不同的值和用途:
- 
全局变量:这些是在您的代码的所有函数外部声明的。这些变量可以在任何函数和整个程序中使用。 
- 
局部变量:局部变量是在函数内部声明的。它们仅在声明它们的函数内部工作,因此它们的值不能在函数外部使用。请看以下包含全局和局部变量的示例: 
#include<stdio.h>
// These are global variables:
int y;
int m;
int x;
int b;
int straight_line_equation() {
    y=m*x+b;
    return y;
}
int main(){
    int answer;  // this is a local variable
    m=2;
    x=3;
    b=5;
    answer = straight_line_equation();
    printf(" %d\n  ",answer);
    return 0;  // this terminates  program
}
在前面的示例中,全局变量y、m、x和b在所有程序中工作,包括在straight_line_equation()函数内部。
使用常量
常量(也称为常量变量)可以用来定义一个在整个程序中值不会改变的变量。C 语言中的常量对于定义数学常数很有用。声明常量的语法如下:
const <数据类型> <标识符>=<值>;
在这里,数据类型可以是int、float、char或double,或者它们的修饰符,例如:
const float euler_constant=2.7183;
const char A_character='a';
您还可以使用#define指令声明变量。它位于程序的开头,紧随#include指令之后,行尾没有分号,使用以下语法:#define <标识符> <值>。
我们不需要声明常量的数据类型。编译器将动态确定。以下示例展示了如何声明常量:
#define PI 3.1416
#define value1 11
#define char_Val 'z'
下一节将处理在 C 程序中广泛使用的 C 语言关键字。
使用关键字
ANSI C 标准定义了多个在 C 编程中具有特定目的的关键字。这些关键字不能用于命名变量或常量。这些是在您的 C 代码中可以使用的关键字(语句):
auto, break, case, char, const, continue, default, do, double, else, enum, extern, float, for, goto, if, int, long, register, return, short, signed sizeof, static, struct, switch, typedef, union, unsigned, void, volatile, while.
用于编译 Blue Pill 和 Curiosity Nano 板程序的编译器具有额外的关键字。我们将在本章中列出它们。下一节将解释 C 语言中的函数是什么。
声明 C 语言中的函数
main() 函数。这个函数在 C 程序中编写,其他函数都从它调用。你可以逻辑地将代码划分为函数,使其更易于阅读,并将与同一任务相关的指令分组,为指令提供一些结构。C 语言中的函数定义大致类似于代数函数,其中包含函数名、函数定义和函数参数(s)。
在 C 语言中定义函数的一般形式如下:
<return_data_type> <function_name> (parameter list) {    <list of instructions>
    return <expression>; //optional
}
return语句允许从函数返回一个值,并且这个返回值被用于程序的其它部分。return语句是可选的,因为你可以编写一个不返回值的函数。
小贴士
在函数块中缩进包含的指令是一种良好的编程实践。这为函数提供了更多的视觉结构和可读性。
以下函数示例展示了如何使用参数以及如何从函数中返回数据,其中number1和number2是函数参数:
int maxnumber(int number1, int number2) {
    /* Declaring a local variable to store the result: */
    int result1;
    if (number1 > number2)
        result1 = number1;
    else
        result1 = number2;
    return result1; 
}
在前面的例子中,函数返回了两个数字比较的结果。
小贴士
确保函数的数据类型与return语句中使用的变量类型相同。
如果出于某种原因,你不需要从函数中返回值,你可以使用void语句而不是定义函数的数据类型,例如:
void error_message ()
{
    printf("Error.");
}
在前面的例子中,我们没有在函数中使用return 0语句,因为它没有返回任何值。然后我们可以error_message();。
调用函数
一旦我们声明了一个函数,我们就需要调用它,即在代码的另一个部分运行它。这会将程序控制权转移到被调用的函数,并执行其中的指令。执行完函数中的所有指令后,程序控制权恢复,继续运行主程序中的指令。
要调用一个函数,你需要写出函数名和参数所需的值。如果你的函数返回一个值,你可以将其存储在一个变量中。例如,让我们调用我们之前解释过的max()函数:
int result2;
result2=maxnumber(4,3);
在这个例子中,maxnumber()函数进行的数字比较的结果将被存储在result2变量中。
评估表达式(决策语句)
C 语言提供了一种声明一个或多个逻辑条件的方法,这些条件可以被程序评估(测试),以及一些根据评估结果需要执行的语句,即条件为真或假。
C 编程语言假定任何非空或非零值都是真值。如果值为零或空,则为假。C 语言有以下决策语句:
- 
if(expression_to_evaluate) {statements}: 这里的决策包含一个布尔表达式,后面跟着一个或多个语句,如果决策为真,则执行这些语句,例如:#include <stdio.h> void main(){ int x; x=11; if (x>10) { printf("yes, x is greater than 10"); } }
- 
if(决策) {语句}else{语句}:else部分可以在if语句之后使用,并且当决策为假时,运行一个或多个语句可能很有用,例如:#include <stdio.h> void main(){ int x; x=5; if (x>10) { printf("yes, x is greater than 10"); } else { printf("no, x is not greater than 10"); } }在上述示例中,分析了 x 变量,如果 x 大于 10,它将在 IDE 控制台打印出此消息: yes, x is greater than 10,否则它将打印出no, x is not greater than 10。小贴士 评估两个变量时请小心使用 if语句。为此请使用双等号()。如果你只使用一个等号,编译器将引发错误。请这样做:if(xy)
- 
switch语句将变量的值与多个可能的值进行比较,这些值称为情况。switch语句中的每个情况都有一个唯一的名称(标识符)。如果在情况列表中没有找到匹配项,则将执行默认语句,并且程序控制将离开switch,并带有情况列表。可选的break语句用于在switch块之外终止程序控制。这在某些原因导致你不想让switch语句继续评估其余情况时很有用。以下是switch语句的语法:
switch( expression_to_evaluate)
{
    case value1:
        <statement(s)>;
        break;
    case value_n:
        <statement(s)>;
        break;
}
上述代码显示了switch语句的语法,包括其break语句。以下代码是使用switch的示例,它将变量年龄与三个情况进行比较。如果变量的值为10,它将打印出以下文本:the person is a child:
#include <stdio.h>
void main(){
	int age;
	age=10;
	switch (age)
	{
		case 10:
			printf ("the person is a child");
			break;
		case 30:
			printf ("the person is an adult");
			break;
		case 80:
			printf ("the person is a senior citizen");
			break;
	}	
}
到目前为止,我们已经回顾了如何逻辑地评估一个表达式。下一节将解释如何重复运行一个或多个语句。这对于微控制器板的一些重复性任务可能很有用,例如连续从输入微控制器端口读取数据。
理解循环
for、while和do..while:
for 循环
for循环在其测试表达式变为假之前重复其块中的一个或多个语句。这是for循环的语法:
for (<initialization_variable>;         <test_expression_with_variable>; <update_variable>)
{
    <statement(s)_to_run>;
} 
在上述语法中,counter_variable的初始化只执行一次。然后,使用counter_variable评估表达式。如果测试的表达式为假,则循环终止。如果评估的表达式为真,则执行块语句,并更新counter_variable。counter_variable是局部变量,仅在for循环中有效。此示例在 IDE 控制台打印出从 1 到 10 的数字列表:
for (int x=1; x<=10; x++)
{
    printf("%d ", x);
}
请注意,x++语句与写作 x=x+1 相同。
while 循环
while循环在给定条件为真时重复其块中的一个或多个语句,在执行语句之前测试其条件。当条件测试为假时,循环终止。以下是while循环语句的语法:
while (<test_expression>) 
{
    statement(s); 
}
上述代码是while循环的语法。以下是一个使用while循环的示例代码,从 0 计数到 10:
int x = 0;
while (x <= 10)
{
    // \n it will display the next number in a new 
    // line of text:
    printf("%d \n", x); 
    x=x+1;
}
do..while 循环:
这种循环与while循环非常相似。do..while循环至少执行一次其块语句。表达式在块末尾评估。过程将继续,直到评估的表达式为假。
以下为do..while循环的语法:
do
{
    statement(s);
}
while (<test_expression>);
以下示例使用do..while循环,从 5 计数到 50,当总和小于 50 时:
int number=5;
do
{
    number=number+5;
    printf("%d ", number);
}
while (number < 50);
在前面的代码中,名为number的变量值增加了 5,并且该变量至少在 IDE 的控制台上打印一次,然后变量被评估。
无限循环
你也可以编写一个无限循环,当然,它将无限期地运行(循环不会终止)直到我们终止程序(或从微控制器板上断开电源!)无限循环可以用于持续显示微控制器的结果,连续从微控制器板上读取数据而不停止,等等。
你可以使用三种类型的循环中的任何一种来做这件事。以下是一些无限循环的示例:
for(; ;)
{
    printf("this text will be displayed endlessly!");
}
while(1) 
{
    printf("this text will be displayed endlessly!");
}
do
{
    printf("this text will be displayed endlessly!");
}
while (1);
如您从前面的代码中看到的,编写无限循环既简单又容易。
循环中的 break 和 continue 关键字
你可以使用break关键字。以下示例中的break语句将停止for循环,但该语句只会运行一次:
for (int x=1; x<=10; x++)
{
    printf("%d ", x);
    break;
}
你可以在三种类型的循环中的任何一种中使用break语句。
continue关键字。以下示例将不会打印出第二行文本:
for (int x=1; x<=10; x++)
{
    printf("%d ", x);
    continue;
    printf("this line won't be displayed.");
}
前面的代码由于continue语句而没有显示下一行文本,因为它将程序控制移动到for循环的开始。
下一节将处理一些专门为 Curiosity Nano 微控制器板创建的 C 语句和函数,这些语句和函数与 Blue Pill 板上的略有不同。
介绍 Curiosity Nano 微控制器板编程
如您在第一章中学习到的,微控制器和微控制器板简介,Curiosity Nano 可以使用本章中解释的 ANSI C 语言编程,使用 MPLAB X IDE。
Curiosity Nano 的 C 程序的基本结构与上述使用main()函数解释的类似,但其声明有所改变。你必须包含关键字 void,如下所示:
//necessary IDE's library defining input-output ports:
#include "mcc_generated_files/mcc.h"
void main(void) //main program function
{
    // statements
}
书籍的 GitHub 页面中的文件16F15376_Curiosity_Nano_IOPorts.zip包含了必要的IO_RD1_GetValue()函数,该函数将从 Curiosity Nano 的 RD1 端口读取模拟值。
以下是一些有用的函数,您可以在编程 Curiosity Nano 时使用,这些函数已经由 MPLAB X 编译器定义。请注意,xxx表示 Curiosity Nano 的端口名称。请阅读第一章,微控制器和微控制器板简介,以熟悉 Curiosity Nano 的 I/O 端口名称及其相应的芯片引脚:
- 
IO_xxx_SetHigh();: 这个函数在指定的引脚(端口)上写入逻辑高(3.3 V)值。
- 
IO_xxx_SetLow();: 这个函数在指定的引脚(端口)上写入逻辑低(0 V)值。
- 
IO_xxx_GetValue();: 这个函数返回从指定端口读取的逻辑(数字)值(要么是高要么是低)。高返回为 1,低返回为 0。
- 
ADC_GetConversion(xxx);: 这个函数从指定的端口读取模拟值,并返回一个从 0 到 1023 的值,该值对应于对读取值的模拟-数字转换。
- 
SYSTEM_Initialize();: 这个函数初始化微控制器端口。
- 
__delay_ms(number_milliseconds);: 这个函数使程序暂停一定数量的毫秒(一秒中有 1,000 毫秒)。
- 
IO_xxx_Toggle();: 这个函数将指定端口的值切换到其相反的状态。如果端口逻辑为高(1),则此函数将将其切换到 0,反之亦然。
我们将在本章后面解释的示例中用到一些前面的函数。
图 2.1显示了 Curiosity Nano 的引脚。请注意,其中许多是 I/O 端口:

图 2.1 – Curiosity Nano 的引脚配置
我们已经将以下端口从 Curiosity Nano 微控制器板配置为 I/O 端口。我们在本书的所有 Curiosity Nano 软件项目文件中做了这件事。端口的引脚可以在图 2.1中看到。其中一些在本书中被广泛使用:
RA0, RA1, RA2, RA3, RA4, RA5, RB0, RB3, RB4, RB5, RC0, RC1, RC7, RD0, RD1, RD2, RD3, RD5, RD6, RD7, RE0, RE1 和 SW0。
下一个部分解释了 Blue Pill 板微控制器板编程的基本编程结构和重要函数,这些函数与 Curiosity Nano 板略有不同。
介绍 Blue Pill 微控制器板编程
如您在第一章,微控制器和微控制器板简介中学习的那样,您可以使用 Arduino IDE 编程 Blue Pill 板,同时安装 IDE 中的特殊库。请记住,这个 IDE 使用 C++语言,它是 C 语言的扩展。在 Arduino IDE 编程中,程序也被称为 sketch。所有 sketch 都必须有两个函数,称为setup()和loop()。
setup()函数用于定义变量、定义输入或输出端口(板引脚)、定义和打开串行端口等,并且此函数将只运行一次。它必须在loop()函数之前声明。
loop()函数是您代码的主要块,将运行程序的主要语句。这个loop()函数将反复无限地运行。草图不需要main()函数。
这是您草图(程序)的主要结构:
void setup() 
{
    statement(s);
}
void loop() 
{
    statement(s);
}
这里是如何将引脚(微控制器板的端口)定义为输入或输出的示例:
void setup ( ) 
{
 // it sets the pin as output.
    pinMode (pin_number1, OUTPUT);
 // it sets the pin as input 
    pinMode (pin_number2, INPUT); 
}
输入端口将用于从传感器或开关读取数据,输出端口将用于向其他设备或组件发送数据,打开 LED 等。
提示
在 Arduino IDE 中编程时区分大小写。在编写函数名、定义变量等时请小心。
如前述代码所示,每个语句块都包含在大括号内,每个语句都以分号结束,类似于 ANSI C。这些是有用的函数,可用于编程 Blue Pill:
- 
digitalWrite(pin_number, value);:此函数在指定的引脚(端口)上写入高(3.3 V)或低(0 V)值;例如,digitalWrite(13,HIGH);将向引脚(端口)号 13 发送高值。注意 您必须在 setup()函数中先前声明pin_number为OUTPUT。
- 
digitalRead(pin_number);:此函数返回从指定引脚(端口)读取的逻辑高(3.3 V)或逻辑低(0 V)值,例如,val = digitalRead(pin_number);。注意 您必须在 setup()函数中先前声明pin_number为INPUT。
- 
analogWrite(pin_number, value);:此函数将(发送)一个模拟值(0..65535)到 Blue Pill 指定的 PIN(输出端口)。
- 
analogRead(pin_number);:此函数返回从指定 PIN 读取的模拟值。Blue Pill 有 10 个通道(可以用于模拟输入的端口或引脚),12 位的analogRead()函数将输入电压在 0 到 3.3 伏之间映射到 0 到 4095 的整数之间,例如:
- 
int val = analogRead(A7);
- 
delay(number_of_milliseconds);:此函数使程序暂停指定的时间,以毫秒为单位定义(记住一秒有一千毫秒)。提示 您还可以使用本节中解释的 C 语言结构来编程 Arduino 微控制器板,唯一的区别是 analogWrite()的值范围将是 0...255 而不是 0...65535,analogRead()的值范围将是 0 到 1023 而不是 0 到 4095。
图 2.2显示了 Blue Pill 的 I/O 端口和其他引脚:

图 2.2 – Blue Pill 的引脚配置
可以在 图 2.2 中看到端口的引脚。其中一些在本书的章节中被使用。Blue Pill 有以下模拟端口:A0, A1, A2, A3, A4, A5, A6, A7, B0 和 B1。以下为数字 I/O 端口:C13, C14, C15, B10, B11, B12, B13, B14, B15, A8, A9, A10, A11, A12, A15, B3, B4, B5, B6, B7, B8 和 B9。
只需记住,在代码中,端口被引用为 PA0、PA1 等,添加一个字母 P。
我们将在下一节的示例中使用一些前面的函数。
示例 – 编程和使用微控制器板内部 LED
在本节中,我们将使用 C/C++ 语言的常见语句来控制 Blue Pill 和 Curiosity Nano 板的内部 LED。内部 LED 可以非常方便地快速验证 I/O 端口的状态,显示传感器数据等,而无需将带有相应电阻的 LED 连接到端口。下一节将展示如何使用内部 LED 编译并发送代码到微控制器板。
编程 Blue Pill 的内部 LED
本节涵盖了编程内部 LED 的步骤。您不需要连接任何外部电子组件,例如外部 LED。使用 Blue Pill 的内部 LED 对于快速测试和显示程序的结果或变量值非常有用。您只需要使用微控制器板。以下步骤演示了如何上传和运行程序到 Blue Pill:
- 
按照在 第一章 “微控制器和微控制器板简介”中解释的步骤,将 ST-LINK/V2 接口连接到 Blue Pill。 
- 
将 USB 线缆连接到 Blue Pill 和您的计算机。将 Blue Pill 插入无焊点面包板。图 2.3 显示了 Curiosity Nano 和 Blue Pill 板的内部 LED: ![图 2.3 – Blue Pill(顶部)和 Curiosity Nano 的内部 LED]() 图 2.3 – Blue Pill(顶部)和 Curiosity Nano 的内部 LED 
- 
打开 Arduino IDE。在其编辑器中编写以下程序: /* Blink This program turns on the Blue Pill's internal LED on for one second, then off for two seconds, repeatedly. Version number: 1. Date: Sept. 18, 2020. Note: the internal LED is internally connected to port PC13. Written by Miguel Garcia-Ruiz. */ void setup() { pinMode(PC13, OUTPUT); } void loop() { digitalWrite(PC13, HIGH); delay(1000); digitalWrite(PC13, LOW); delay(2000); // it waits for two seconds }
- 
点击 PC13以选择LED_BUILTIN。
您可以将 Blue Pill 留在未插入无焊点面包板的状态,因为我们在此前的示例中没有将任何组件或线缆连接到 Blue Pill 的端口。
编程 Curiosity Nano 的内部 LED
与 Blue Pill 类似,您可以使用 Curiosity Nano 的内部 LED 快速显示传感器数据等,而无需将 LED 连接到端口。包含此示例和其他支持文件(这些文件对于在 MPLAB X IDE 上编译程序是必要的)的整个项目存储在 GitHub 页面上。它是一个名为 16F15376_Curiosity_Nano_LED_Blink_Delay.zip 的 zip 文件。
按照以下步骤在 MPLAB X IDE 上运行程序:
- 
将 USB 线缆连接到 Curiosity Nano 并将板插入无焊点面包板。解压 16F15376_Curiosity_Nano_LED_Blink_Delay.zip文件。
- 
在 MPLAB X IDE 中,点击文件/打开项目然后打开项目。 
- 
双击项目文件夹,然后点击 源文件文件夹。
- 
点击 main.c,你将看到以下源代码:/* This program makes the on-board LED to blink once a second (1000 milliseconds). Ver. 1\. July, 2020\. Written by Miguel Garcia-Ruiz */ //necessary library generated by MCC: #include "mcc_generated_files/mcc.h" void main(void) //main program function { // initializing the microcontroller board: SYSTEM_Initialize(); //it sets up LED0 as output: LED0_SetDigitalOutput(); while (1) //infinite loop { LED0_SetLow(); //it turns off the on-board LED __delay_ms(1000); //it pauses the program for //1 second LED0_SetHigh(); //it turns on on-board LED and //RE0 pin __delay_ms(1000); //it pauses the program for //1 second } }
- 
通过点击顶部的绿色运行图标来编译和运行代码,该图标位于菜单栏上。如果一切顺利,你将看到 Curiosity Nano 的内部 LED 闪烁。 
如前例所示,它具有专门为 Curiosity Nano 板创建的实用 C 函数,例如以下内容:
SetLow(), SetHigh() 和 __delay_ms()。
这些功能对于使用微控制器板制作项目是必不可少的,并且它们被用于本书的其他章节。
摘要
在本章中,我们学习了如何正确配置和设置 MPLAB X 和 Arduino IDE 以进行 C 微控制器板编程。我们介绍了 C 编程语言,特别是用于编程 Blue Pill 和微控制器板的 C 语言指令集。为了练习你学到的 C 语言知识,我们查看了一些使用板内和板外 LED 的实际电路。本章中学到的指令和结构可以应用于本书的其余部分。
第三章,使用按钮开关 LED,将重点介绍如何将按钮与上拉电阻连接到微控制器板上,以及在使用按钮时如何最小化电气噪声。它还将解释如何通过软件设置微控制器板的输入端口,以及按钮的可能应用。
进一步阅读
- 
Gay, W. (2018). 开始 STM32:使用 FreeRTOS、libopencm3 和 GCC 进行开发。St. Catharines, ON: Apress。 
- 
Microchip Technology (2019). MPLAB X IDE 用户指南. 从 ww1.microchip.com/downloads/en/DeviceDoc/50002027E.pdf获取。
第三章:第三章:使用按钮点亮或熄灭 LED
在本章中,我们将回顾和实践如何使用连接到微控制器板的按钮来点亮或熄灭 LED。按钮是一个实用的组件,其作用类似于开关,用于闭合或打开电子电路。我们可以使用它们来初始化或激活微控制器板上的一个过程。因此,按钮提供的输入数据对于许多需要人工干预的微控制器应用来说非常重要。具体来说,本章将涵盖以下主要内容:
- 
介绍按钮 
- 
理解来自按钮的电气噪声 
- 
将 LED 连接到微控制器板端口并使用内部上拉电阻 
- 
测试按钮 
到本章结束时,你将学会如何将按钮连接到 Curiosity Nano 和 Blue Pill 微控制器板,以及如何编程按钮的输入来点亮或熄灭 LED。你还将学会如何减少按钮中的电气噪声问题。正如我们将在本章中看到的那样,尝试解决这个问题并不简单。特别是,“理解来自按钮的电气噪声”部分解释说,并非所有按钮都能 100%无制造错误地工作,并且在使用时可能存在电气噪声。
技术要求
本章我们将使用的软件工具将是MPLAB-X和Arduino IDE。本章的代码可以在本书的 GitHub 存储库中找到,以下是 URL:
github.com/PacktPublishing/DIY-Microcontroller-Projects-for-Hobbyists/tree/master/Chapter03
本章的“代码在行动”视频可以在这里找到:bit.ly/3cXfZLM
本存储库中的代码示例将用于使用 Curiosity Nano 和 Blue Pill 微控制器板来点亮或熄灭 LED。IDE 的安装指南和使用方法在第一章,“微控制器和微控制器板简介”中已解释。在本章中,我们还将使用以下硬件:
- 
无焊面包板。 
- 
Blue Pill 和 Curiosity Nano 微控制器板。 
- 
用于将微控制器板连接到计算机的微型 USB 线。 
- 
需要上传编译代码到 Blue Pill 的 ST-Link/V2 电子接口。请注意,ST-Link/V2 需要四根公对公的杜邦线。 
- 
一个 LED。任何颜色都可以。我们更喜欢在练习中使用红色。 
- 
一个 220 欧姆、额定功率为四分之一瓦的电阻。 
- 
四根公对公的杜邦线,用于将电阻和按钮连接到板上。 
- 
一个普通的、常开按钮。 
下一节简要介绍了按钮开关,这些开关在电子电路中得到了应用。
介绍按钮开关
按钮开关是一种基本像机械开关一样工作的电子设备;它可以用来闭合或断开电路。它们也被称为瞬态按钮开关或按钮开关。按钮开关由硬质材料如塑料制成,内部有一个微小的金属弹簧,它与两根电线或触点接触,如果按下按钮(在通常开路按钮开关中)或按下时(在通常闭路按钮开关中),允许电流通过它们。当按钮开关关闭时,弹簧缩回,电气接触被中断,电流不会通过触点流动。按钮开关用于手动控制或初始化电路中的过程,包括包含微控制器板的应用。以下图像显示了通常闭路(左侧)和通常开路(右侧)的按钮开关:

图 3.1 – 通常闭路(左侧)和通常开路(右侧)按钮开关
如图 3.1所示,通常开路的按钮开关(在右侧)看起来是按下的。请注意,引脚连接到了微控制器板上。
注意
通常开路和通常闭路的按钮开关可能看起来完全相同,这取决于它们的制造商和型号。如果您不确定,请尝试使用微控制器板测试您的按钮,看看它是什么类型的按钮开关。如果按钮开关在不需要您按下它的情况下向微控制器板发送逻辑信号,这意味着它是一个通常闭路的按钮开关。在本章中,您将学习如何将按钮开关连接到微控制器板上。
在微控制器板项目中,按钮开关的一个典型应用是连接或断开微控制器板上的 I/O 引脚的接地或正电压。按钮开关产生的这种电压变化可以通过微控制器板的 I/O 引脚(端口)被微控制器板看到;这将在微控制器板上初始化一个过程。
按钮根据尺寸的不同,有多种类型。大而坚固的按钮通常用于一些工业应用,在这些应用中,操作员需要快速识别并按下它们。较小的按钮通常用于家用电器和设备,例如电脑键盘和固定电话。在本章中,我们将使用一种常见的小型按钮,这种按钮在许多电子套件和包含微控制器板的套件中都很常见。实际上,Blue Pill 和 Curiosity Nano 微控制器板在其电路中都有小型按钮。它们可以用于这两个板来重置其上运行的程序。主要有两种类型的按钮:常开和常闭按钮。让我们更详细地看看它们:
- 
常开按钮。在这种类型的按钮中,当未按下时,其开关始终保持开启状态;也就是说,它不会闭合电路。每次我们按下它时,它都会建立电气接触(闭合电路)。当我们按下按钮时,其内部开关关闭。这些是最常见的按钮类型。它们可以用于暂时激活或初始化一个过程;例如,短暂按下按钮以重置微控制器板。 
- 
常闭按钮。在其默认状态下,此按钮可以闭合电路,这意味着其开关在未按下按钮的情况下通常是闭合的。当我们按下这种类型的按钮时,我们打开开关(因此连接到电路的电路也被打开)。这些按钮在需要暂时关闭或中断电气/电子电路时非常有用。例如,如果我们想停止读取传感器,我们可以打开传感器与微控制器板之间的连接。 
下一节描述了许多按钮中存在的一个问题,称为电气噪声。这种类型的噪声有时可能非常难以(但并非不可能)最小化。
理解按钮产生的电气噪声
在许多按钮中都可以产生电气噪声。这可能会对按钮连接的电子电路的功能产生负面影响,并在微控制器板上产生不可预测的结果。
按钮的一个常见问题是它们并不完美。它们不会立即关闭开关,并且在许多情况下会产生电噪声。这可能是因为并非所有按钮都完全无制造错误。如果我们尝试将按钮直接连接到微控制器的 I/O 端口,每次按下按钮时,我们似乎都按对了。对我们来说,这似乎就像我们只按了一次。然而,对微控制器板来说,它看起来按钮被按了多次,而且时间非常短,这是由于按钮中产生的电噪声。电噪声可以定义为与电子电路耦合的随机电平或信号。这种电干扰或干扰可能变化很大,从非常小的电压到高电压水平,其频率也可能随机变化。有许多来源会产生电噪声,包括热量、有缺陷的电子元件、机械运动以及电路中的松散电气连接等。
来自按钮的不希望的电噪声几乎总是由一种称为抖动的现象引起的,这是由按钮内部金属部件和弹簧的摩擦和机械运动造成的。我们需要对按钮进行去抖动,以减少其电噪声,并因此以干净和高效的方式正确地闭合电路(如果我们使用的是常开按钮)。如果我们不对按钮进行去抖动,其内部开关可能会在每次按下按钮时无规律地闭合电路,这将影响整个电路或微控制器板的输入功能。按钮产生的数据信号应该是零伏特(逻辑低)或 3.3 伏特(逻辑高)。如果我们不对按钮进行去抖动,它将产生可能改变这些逻辑级别的电噪声,因此微控制器板可能无法将其识别为这样的信号。
重要
在 Blue Pill 和 Curiosity Nano 板上使用的高逻辑电平电压是 3.3 伏特。记住,在某些微控制器板上,它们的逻辑高电平是 5 伏特而不是 3.3 伏特,例如 Arduino 系列的微控制器板。
有几种技术可以处理按钮中的电噪声。例如,这种噪声可以通过连接一些电子元件到按钮,或者通过编码来大大减少,正如我们将在接下来的几节中看到的。
通过硬件去抖动按钮
减少按钮电噪声的一种方法是将一个电容器和两个电阻(这也可以称为RC 去抖动电路、电阻-电容器网络或 RC 滤波器)连接到按钮上,如图所示。当我们按下按钮时,电容器将被充电。当我们释放按钮时,电容器将保持其电荷一段时间,然后连接到它的电阻将在之后放电。这个电容器的电荷代表一个高逻辑电压,它可以在微控制器板上使用。在电容器充电期间发生的任何瞬态电噪声都可以忽略,因为在此期间电容器提供了一个高逻辑值:

图 3.2 – 连接到按钮的 RC 去抖动器
上述图示包含两个电阻,R1 和 R2,一个常开按钮,和一个电容器,C。电阻和电容器形成一个 RC 去抖动器。记住,Vcc 表示正电压,对于 Curiosity Nano 和 Blue Pill 来说,是 3.3 伏。通常,您可以从标记为 3.3V 或 Vcc 的微控制器板的一个引脚获得 Vcc。此外,您可以将 RC 去抖动器连接到标记为地的一个微控制器引脚。正如我们在前面的图示中看到的,这三个电子元件可以用来减少按钮中的电噪声。R1、R2 和 C 的典型值分别是 10K 欧姆、10K 欧姆和 0.1 微法拉,尽管如果 RC 去抖动器没有有效工作,您可能需要更改这些值,因为每个按钮中的电噪声并不总是相同的。RC 去抖动器的数学公式在 Ganssle, J.G. (2008)的《去抖动指南》中有详细解释。
我们在本节中包含了 RC 去抖动器作为参考,以防软件去抖动方法对您不起作用。下一节将向您展示如何仅使用软件去抖动按钮。
通过软件去抖动按钮
我们可以通过编码来最小化按钮产生的虚假电噪声。我们可以在代码中使用的一个技巧是在按下连接到我们电路的按钮后,立即忽略一段非常短时间的电噪声(通常是一些几十毫秒)。以下图示展示了如何将按钮直接连接到微控制器板的 I/O 端口,以通过软件进行去抖动:

图 3.3 – 带下拉电阻连接到 I/O 端口的按钮
前面的图中显示了一个下拉电阻,R,它迫使微控制器板的输入端口接收零伏(逻辑低),这连接到地,而按钮未被按下。下拉电阻,R,的典型值是 10k 欧姆。当我们需要不断向微控制器板的 I/O 端口输入低电平时,我们可以使用下拉电阻。当我们按下按钮时,只需将其切换到逻辑高电平。这可以用于瞬间启动一个过程,例如,打开连接到我们电路的灯。以下图示展示了如何将上拉电阻连接到微控制器端口,强制其输入为 3.3 伏(Vcc):

图 3.4 – 带有上拉电阻连接到 I/O 端口的按钮
前面图中的电阻值(R)通常是 10K 欧姆。
重要提示
您需要将下拉或上拉电阻连接到微控制器的输入端口,因为如果您不连接任何东西到端口(这可能在按钮未被按下时发生),端口将由于其内部电子排列而呈现未确定的(随机)电压。这被称为浮空输入电压。
前面的图中包含一个常开按钮。一旦按钮被按下,输入电压将变为逻辑高电平,或 3.3 伏。请记住,逻辑高电平可以是 5 伏,这取决于你使用的微控制器板。Vcc 电压和地线连接到微控制器板上。
幸运的是,许多微控制器提供了内部上拉和下拉电阻,这些电阻连接到它们的 I/O 端口,可以通过编码激活。Blue Pill 就包含这些!这意味着我们可以直接将按钮连接到其 I/O 端口,无需连接外部电阻,只需通过软件激活板上的内部上拉或下拉电阻。这可以加快需要使用按钮的原型开发,但这可能并不总是最佳解决方案。
以下图示展示了两种将按钮直接连接到 I/O 端口的方法。此端口已经通过软件激活了一个上拉或下拉电阻:

图 3.5 – 直接连接到 I/O 端口的按钮
如您所见,软件去抖动方法不使用连接到按钮的 RC 去抖动。这种方法大多数时候都有效,并且可以节省您的时间和精力。然而,如果您发现按钮的电气噪声持续存在,您应该进行实验并尝试两种方法。
每种去抖动方法都有其权衡。在基于硬件的方法中,你需要在按钮上连接一些电子元件。你还需要购买这些额外的元件。在基于软件的方法中,你将使用微控制器的内部上拉或下拉电阻,你不需要将任何额外的元件连接到按钮上,但你需要在程序中添加更多行代码来处理去抖动,这些指令可能会占用微控制器的一些宝贵的处理周期。尽管如此,我们仍然建议你使用基于软件的去抖动方法,因为它易于实现。
下一节将处理示例,展示如何将按钮连接到蓝色药丸和 Curiosity Nano 微控制器板,以及如何通过软件去抖动它。
将 LED 连接到微控制器板端口并使用内部上拉电阻
在本节中,你将学习如何将按钮连接到蓝色药丸和 Curiosity Nano 微控制器板。这对于这些微控制器板来说是一个简单的练习,它演示了如何使用按钮向微控制器板发送逻辑低电平信号来打开或关闭连接到它的 LED。如果我们想在我们的电子电路示例中使用按钮,我们需要将其连接到微控制器板的一个输入端口。此外,请记住,我们应该去抖动按钮以避免不希望的结果。
以下小节将展示如何通过编码来去抖动连接到蓝色药丸的按钮。这是去抖动按钮最简单的方法,你可以在本书的其他章节中使用这种方法。
通过软件连接蓝色药丸来去抖动按钮
在本节中,我们将展示一个 Fritzing 图,然后是一张显示所有连接的图片。我们还将查看一些代码,演示如何通过软件去抖动按钮。
以下是一个 Fritzing 图,展示了如何将按钮直接连接到一个已经使用其内部上拉电阻的 I/O 端口。LED 及其相应的电阻连接到蓝色药丸的端口号;即,B12:

图 3.6 – 使用内部上拉电阻的蓝色药丸与按钮
如你所见,每次我们按下按钮时,LED 都会打开或关闭。
请注意,在前面的图像中,按钮连接到面包板的中心,位于微控制器板的右侧。按照以下步骤将按钮和 LED 连接到蓝色药丸,如图所示:
- 
将蓝色药丸插入无焊面包板。 
- 
将按钮插入面包板,并使用杜邦线将其中一个引脚连接到蓝色药丸的地线引脚。 
- 
使用杜邦线将按钮的另一个引脚连接到 Blue Pill 的 B0端口。
- 
将一个 220 欧姆的电阻插入面包板,并使用杜邦线将其一个引脚连接到 Blue Pill 的 B12 端口。 
- 
将 LED 插入面包板,将其阳极连接到另一个电阻的引脚。 
- 
使用杜邦线将 LED 的阴极连接到 Blue Pill 的一个地线引脚。 
以下图像展示了如何根据之前显示的 Fritzing 图纸连接按钮到 Blue Pill:

图 3.7 – 将按钮连接到 Blue Pill 的阴极,然后使用杜邦线将其连接到 Blue Pill 的一个地线引脚
如您所见,Blue Pill 板在引脚的顶部和底部行都有地(G)引脚。这有助于电路中的组件连接。
记住,您需要将 ST-Link/V2 电子接口连接到 Blue Pill,以便从 Arduino IDE 上传程序,如第一章**,微控制器和微控制器板简介*中所述。
以下代码展示了如何在 Blue Pill 上通过软件进行按钮消抖。您可以在本书的 GitHub 仓库中找到此代码文件,其中包含注释。文件名为 internal_pullup_debounce_Blue_Pill.ino:
#define PinLED PB12
#define Pinpushbutton PB0
void setup() {
  pinMode(PinLED, OUTPUT);
  pinMode(Pinpushbutton, INPUT_PULLUP);
}
int reading_pushbutton;
int ledState = HIGH;
int buttonState;
int lastButtonState = LOW;   
unsigned long lastDebouncingTime = 0; 
unsigned long debouncingDelay = 50;  
void loop() {
reading_pushbutton=digitalRead(Pinpushbutton);
if (reading_pushbutton!= lastButtonState) {
    lastDebouncingTime = millis();
}
if ((millis() - lastDebouncingTime) > debouncingDelay) {
    if (reading_pushbutton!=buttonState) {
        buttonState = reading_pushbutton;
        if (buttonState == HIGH) {
            ledState = !ledState;
        }
    }
  }
digitalWrite(PinLED, ledState);
lastButtonState = reading_pushbutton;
}
以下代码在按钮按下后等待 50 毫秒,并切换 LED 的值。这个值是实验性的,所以如果你的按钮工作不稳定,你可能需要更改它。
重要提示
在 Arduino IDE 中,Blue Pill 的 I/O 端口用字母 P 表示。例如,端口 B12 在 IDE 中表示为 PB12。此外,端口标签(名称)必须用大写字母书写。
如前述代码所示,它持续读取 Blue Pill 的端口 B0。如果按下按钮,按钮将端口 B0 连接到地。然后,B12 输出端口发送高逻辑电平并打开连接到 B12 的 LED。如果未按下按钮,B12 端口发送低逻辑电平。
小贴士
如果您使用 Arduino 微控制器板,您也可以通过软件进行按钮消抖。实际上,我们在本章中使用的基于软件的消抖方法是基于 Arduino 板上使用的方法,如这里所述:
www.arduino.cc/en/Tutorial/BuiltInExamples/Debounce
如果您按下按钮时 LED 灯亮和灭,恭喜您!注意当您按下按钮时微控制器板如何反应。如果您在仅按下按钮时 LED 灯不规律地闪烁几次,如果您正在进行 RC 去抖动,您可能需要更改电阻或电容的值;如果您通过软件去抖动按钮,您可能需要更改毫秒等待值。
下一节描述了如何通过软件去抖动连接到 Curiosity Nano 微控制器板的按钮。
使用 Curiosity Nano 上的按钮开关 LED 灯
在本节中,我们使用 Curiosity Nano 通过等待一些毫秒来软件去抖动按钮。我们可以使用__delay_ms()函数来完成此操作。请记住,该函数是用两个下划线符号(__)编写的。
以下 Fritzing 图显示了如何将按钮连接到 Curiosity Nano:

图 3.8 – 直接连接到 Curiosity Nano 板的按钮
请注意,按钮连接到面包板的中心,位于微控制器板的右侧。
根据前面的图像,以下是连接所有组件的步骤:
- 
将 Curiosity Nano 插入无焊面包板。 
- 
将按钮插入面包板,并使用杜邦线将其中一个引脚连接到 Curiosity Nano 的地线引脚。 
- 
使用杜邦线将按钮的另一个引脚连接到 Curiosity Nano 的 RA0端口。
- 
将一个 220 欧姆的电阻插入面包板,并使用杜邦线将其中一个引脚连接到 Curiosity Nano 的 RD2端口。
- 
将 LED 插入面包板,将其阳极连接到另一个电阻的引脚。 
- 
使用杜邦线将 LED 的阴极连接到 Curiosity Nano 的一个地线引脚。 
以下图像显示了所有组件的连接方式:

图 3.9 – 连接到 Curiosity Nano 的按钮
在前面的图像中,您可以看到 Curiosity Nano 的上下行引脚都有地线(GND)引脚。这允许我们为电路中的组件布线。
我们为 MPLAB-X IDE 创建了一个项目,该项目可以在本书的 GitHub 仓库中找到。它包含解释每行代码的注释。您需要首先解压其 ZIP 文件,然后在 MPLAB-X IDE 中打开项目。此项目文件名为16F15376_Curiosity_Nano_pushbutton.X.zip。
以下项目中的代码展示了如何通过软件实现去抖动:
#include <xc.h>
#include <stdio.h>
#include "mcc_generated_files/mcc.h"
int reading_pushbutton=0;
void main(void)
{
    SYSTEM_Initialize();
    IO_RD2_SetDigitalOutput(); 
    IO_RA0_SetDigitalInput(); 
    IO_RA0_SetPullup(); 
    IO_RD2_SetLow(); 
    while (1) 
    {
        reading_pushbutton=IO_RA0_GetValue(); 
        __delay_ms(100);
        reading_pushbutton=IO_RA0_GetValue();
        if (reading_pushbutton==LOW){
            IO_RD2_Toggle(); 
        }
    }
}
之前的代码从按钮读取值并等待 100 毫秒;然后再次读取以查看按钮是否仍然被按下。我们通过实验找到了这个 100 毫秒的值,并且它似乎在大多数情况下都有效。记住,您可能需要根据您自己的按钮在电路中的表现进行调整。
这与我们之前在 Blue Pill 中使用的方法略有不同。我们编码了等待时间,试图忽略在此期间可能发生的某些电气噪声。如果你的 LED 在按下按钮时开启和关闭,恭喜!你现在能够连接并使用连接到微控制器板的按钮。记住,按钮可以用来在微控制器板上启动一个过程或活动。
下一节将展示如何检查按钮是否正常工作,以及它是否是常开或常闭按钮。
测试按钮
在本节中,我们将专注于测试按钮。在使用微控制器板之前,尝试一下以检查其机械工作情况是个好主意,测试还可以帮助我们确定按钮是常闭还是常开。以下图片显示了如何连接所有组件以测试按钮:

图 3.10 – 将按钮连接到 LED 和电池组
如您所见,我们不需要将按钮连接到微控制器板来测试它。以下是连接组件和测试按钮的步骤:
- 
将电池的正极 (+) 端连接到按钮的一个引脚上。 
- 
将另一个按钮引脚连接到 220 欧姆电阻。 
- 
将 220 欧姆电阻连接到 LED 的阳极引脚。 
- 
将 LED 的阴极引脚连接到电池的负极 (-) 端。在连接 LED 的引脚时要小心。如果反接,LED 将不会点亮。 
- 
一旦连接好所有组件,如果 LED 在不按下按钮的情况下点亮,这意味着按钮是常闭型的。如果按下按钮,LED 应该熄灭。如果每次按下按钮时 LED 都点亮,这意味着它是常开型的。 
- 
按下按钮几次。如果 LED 不规则地开启和关闭,或者 LED 完全不亮,按钮可能存在故障,您需要更换它,前提是电池有足够的电压。 
将电池连接到按钮和 LED 上,应该足以检查按钮是否工作。
概述
在本章中,我们学习了按钮是什么以及如何减少许多按钮都有的电气噪声问题,这个过程被称为消抖。这个过程可以通过软件或硬件来完成。我们还回顾了按钮在一些需要人工干预的电子项目中的重要性——例如,当我们按下其板载按钮时,如何手动重新启动微控制器板。在包含微控制器板的电子电路中使用按钮很重要,因为你在那里编程用户交互,所以用户可以启动微控制器板上的一个过程。
下一章将重点介绍如何连接光敏电阻(一种测量环境中光量的传感器)。
进一步阅读
- 
Ganssle, J.G. (2008). 消抖指南. 技术报告。马里兰州巴尔的摩:Ganssle Group。 
- 
Gay, W. (2018). STM32 入门:使用 FreeRTOS、libopencm3 和 GCC 进行开发. 圣凯瑟琳斯:Apress。 
- 
Horowitz, P., Hill, W. (2015). 电子艺术. [第 3 版] 剑桥大学出版社:纽约,纽约。 
- 
Microchip (2019). PIC16F15376 Curiosity Nano 硬件用户指南. Microchip Technology, Inc. 可从 ww1.microchip.com/downloads/en/DeviceDoc/50002900B.pdf获取
- 
Mims, F.M. (2000). 入门电子学. 伊利诺伊州林肯伍德:Master Publishing, Inc. 
- 
Ostapiuk, R. & Tay, I. (2020). C 编程语言基础. Microchip Technology, Inc. 从 microchipdeveloper.com/tls2101:start获取
- 
Ward, H.H. (2020). PIC 微控制器 C 编程. 纽约,纽约:Apress。 
第四章:第四章:使用光敏电阻测量光量
本章重点介绍如何将光敏电阻(一种测量环境光量的电子元件)连接到蓝牙板和 Curiosity Nano 微控制器板的输入端口。在本章的练习中,我们将使用光敏电阻来分析植物是否接收到了足够的光。
在本章中,我们将涵盖以下主要内容:
- 
理解传感器 
- 
介绍光敏电阻 
- 
将光敏电阻连接到微控制器板端口 
- 
编写光敏电阻值并设置端口 
- 
测试光敏电阻 
到本章结束时,你将学会如何将模拟传感器连接到微控制器板,以及如何分析从光敏电阻获得的分析数据。本章中获得的知识和经验将在其他需要使用传感器的章节中非常有用。
技术要求
本章中你将使用的软件工具是 Arduino IDE 和 MPLAB-X,分别用于编辑和上传程序到蓝牙板和 Curiosity Nano 板。
本章中使用的代码可以在本书的 GitHub 仓库中找到:github.com/PacktPublishing/DIY-Microcontroller-Projects-for-Hobbyists/tree/master/Chapter04
github.com/PacktPublishing/DIY-Microcontroller-Projects-for-Hobbyists/tree/master/Chapter04
本章的“代码在行动”视频可以在以下链接找到:bit.ly/3gNY4bt
在本章中,我们还将使用以下硬件设备:
- 
一个无焊面包板。 
- 
蓝牙板和 Curiosity Nano 微控制器板。 
- 
用于将微控制器板连接到计算机的微型 USB 线。 
- 
用于将编译后的代码上传到蓝牙板的 ST-Link/V2 电子接口。请注意,ST-Link/V2 需要四根公对公的杜邦线。 
- 
一个绿色、黄色和红色的 LED。 
- 
三个 220 欧姆电阻,额定功率为四分之一瓦。这些电阻用于 3 个 LED。 
- 
一个 220 欧姆电阻,额定功率为四分之一瓦,用于连接到 Curiosity Nano 的光敏电阻。 
- 
一个 10 K 欧姆电阻,额定功率为四分之一瓦。 
- 
光敏电阻传感器模块。 
- 
三根公对母的杜邦线,用于将传感器模块连接到无焊面包板。 
- 
一打公对公的杜邦线,用于将电阻和按钮连接到面包板和微控制器板。 
下一节将简要介绍光敏电阻、它们的电气特性和在电子项目中的应用。
理解传感器
在本节中,我们解释传感器是什么以及传感器模块的重要性。在您在实际微控制器板应用中使用它们之前,例如使用光敏电阻(这是一种有用的传感器类型),首先了解传感器及其用途是很重要的。有关传感器的信息对于后续章节至关重要。
定义传感器
传感器是一种电子组件、设备或模块,它测量来自环境或特定情况(例如,测量鱼缸中水温的传感器)的物理输入。传感器对于检测物理变量的变化很有用,例如湿度、温度、光、振动和运动等。这些物理变化通过传感器改变其电/电子特性来体现,例如传感器中电阻和导电性的变化。
存在着不同类型的传感器,具有不同的应用。例如,运动传感器可以在它们穿过传感器的视野时检测到人或宠物的移动。如果这个传感器检测到运动,它会向计算机或微控制器板发送信号,然后该板应该对此做出一些操作,例如打开自动门、触发警报、打开灯泡等。其他类型的传感器包括红外线、超声波、温度、压力和触摸传感器。
传感器模块是什么?
传感器可以是称为传感器模块的小型电子电路的一部分。它除了包含传感器外,还包含其他电子组件,如电阻器、晶体管、LED 和集成电路等。传感器模块中这些额外组件的目的是支持和简化来自传感器的信号读取、分析和传输。一些传感器模块将模拟信号转换为数字数据。模拟数据是电压变化,即从环境中的物理变量到模拟。例如,从温度传感器获得的 0.5 伏特可能相当于 25 摄氏度。来自传感器模块的数字数据可以包含逻辑电平 高 或逻辑电平 低 值。
注意
表示数字逻辑电平的电压取决于您使用的微控制器板。Blue Pill 和 Curiosity Nano 微控制器板的 I/O 端口都使用 3.3 伏,相当于逻辑电平高。逻辑电平低相当于 0 伏。
从传感器发出的模拟信号通过电线或无线通信介质(例如,蓝牙)电子方式发送到微控制器板,该板将对其进行处理,然后对其进行一些操作,如图 图 4.1 所示:

图 4.1 – 连接到微控制器板端口的温度传感器
来自传感器的数据(如图 图 4.1 中的图所示)由微控制器板的输入端口读取。这些数据可以调整并显示为人类可读的格式(例如,在显示屏上以摄氏度或华氏度显示温度)。来自传感器模块的模拟和/或数字信号也是如此。其数据通过有线或无线介质发送到微控制器板的端口或端口。
注意
通过编码,微控制器板的端口可以设置为输入或输出端口。请参阅 第二章,微控制器板的软件设置和 C 语言编程,了解如何编程它们。
下一节将重点介绍光敏电阻,这是一种常用的传感器类型,描述其功能、表示方法和应用。
介绍光敏电阻
本节向您介绍光敏电阻,它在许多应用中非常有用,例如,用于测量光量。在本章中,我们将定义光敏电阻是什么,它们的分类,以及它们如何连接到电子电路。
光敏电阻是一种由光敏材料制成的电子元件,根据其检测到的可见光量改变其电阻。光敏电阻有多种类型。其中一些检测 紫外线(UV)光,而另一些检测红外光。后者用于电视,其红外光传感器从遥控器接收数据。图 4.2 显示了本章示例中使用的常见光敏电阻。本章中使用的光敏电阻检测人类可见的光。它不检测红外光或紫外线。

图 4.2 – 典型的光敏电阻
从 图 4.2 中,您可以看到光敏电阻有两个引脚(也称为腿)。它们连接到与普通电阻类似的电子电路,因此光敏电阻没有极性。它们作为普通电阻工作,其电阻根据通过其透明盖板接收到的光量而变化。以下是光敏电阻的一些技术规格:
- 
尺寸:直径 5mm(宽度) 
- 
电阻范围:200 K 欧姆(暗态)到通常 5 K 到 10 K 欧姆,在接收到全亮度时几乎为 0 欧姆。 
- 
电源:最高 100V,平均电流小于 1 毫安,具体取决于电源电压。 
图 4.3 显示了一个包含光敏电阻的电气图以及如何将其连接到微控制器板。

图 4.3 – 含光敏电阻的电气图
如图 4.3所示,光敏电阻的电气符号用一个圆和一些指向圆的箭头表示,这表明光线正在照射光敏电阻的表面。光敏电阻连接到微控制器板的地(Ground)引脚,另一个引脚连接到电压引脚(Vcc)和微控制器板的输入端口。这是连接光敏电阻的一种方式。10K 欧姆电阻作为下拉电阻使用。这是因为当光敏电阻没有接收到任何光线时,连接到光敏电阻的输入端口将接收零伏特。请记住,我们不应该让输入引脚没有连接到任何东西,否则其状态将是浮动的(输入随机电压)。
注意
光敏电阻应该连接到微控制器板的一个模拟输入端口,因为该端口将接收来自光敏电阻的变化电压,因为光敏电阻呈现的电阻将根据光敏电阻接收到的光照量而变化。
下一节将解释如何连接和使用光敏电阻,以测量环境中的光照量,无论是在 Blue Pill 板还是在 Curiosity Nano 板上。
将光敏电阻连接到微控制器板端口
本节展示了如何将光敏电阻连接到 Blue Pill 和 Curiosity Nano 板,以读取环境中的光照量(例如,客厅)。
在本节中,我们还将解释如何使用三个 LED 灯来指示房间是否得到良好的照明:通过点亮绿色 LED 灯表示房间照明良好,通过点亮黄色 LED 灯表示光线较暗,或者通过点亮红色 LED 灯表示房间昏暗。带有光敏电阻传感器的电子电路可以放置在植物附近,该电路可以用来判断植物是否需要更多的光照。下一节将展示如何使用 Blue Pill 板构建电路。
将光敏电阻连接到 Blue Pill 板
将光敏电阻传感器连接到 Blue Pill 微控制器板的连接很简单。只要使用下拉电阻,就可以直接连接到输入模拟端口。图 4.4中所示的电路描述了如何进行连接,它基于图 4.3中的电气图。

图 4.4 – 连接到 Blue Pill 板的 LED 灯和光敏电阻
如图 4.4所示,三个 LED 灯将显示光敏电阻检测到的光照量。以下是连接组件到 Blue Pill 板的步骤:
- 
将 Curiosity Nano 的 GND 引脚连接到无焊面包板的上下轨,如图 4.4所示。 
- 
将光敏电阻的一个引脚连接到微控制器板标有3V3的接地引脚。 
- 
将光敏电阻的另一端连接到 Blue Pill 上标记为B1的引脚。B1将被用作模拟输入端口。 
- 
将一个10K 欧姆电阻连接到地以及连接到 Blue Pill 输入端口B1的光敏电阻的腿。 
- 
现在,将电阻连接到 Blue Pill 的输出端口B12、B14和B15。 
- 
作为最后一步,将绿色、黄色和红色 LED 的正极连接到三个电阻,然后将 LED 的负极连接到地。 
Blue Pill 的 3V3 引脚提供 3.3 伏,这对于施加电压(供电)到光敏电阻是足够的。
重要提示
不要将5 伏(5V)应用到 Blue Pill 的输入端口,因为这样可能会损坏 Blue Pill。这就是为什么你需要将 3V3 电压引脚连接到光敏电阻,这样它将提供高达 3.3 伏的模拟电压输出,而 Blue Pill 将使用这电压来测量光量。记住,来自光敏电阻的电压将根据其电阻而变化。
我们将一个10K 欧姆下拉电阻连接到 Blue Pill 的输入端口B1,如图图 4.4所示,强制端口在没有来自光敏电阻的电压时具有 0 伏输入。记住,输入端口应该接收一些电压,甚至 0 伏,以避免随机电压。
注意
根据你想要检测的光照水平范围,你可能想要尝试将图 4.4中连接到 Blue Pill 的下拉 10K 欧姆电阻的值改为不同的值。
图 4.5显示了所有组件如何连接到微控制器板。此电路基于图 4.4中显示的 Fritzing 图。

图 4.5 – 将光敏电阻和 LED 连接到 Blue Pill
如图 4.5所示,光敏电阻连接到 Blue Pill 的端口 B1。绿色 LED 亮起,意味着植物接收到的光量应该是正常的。记住,你需要将 ST-Link/V2 电子接口连接到 Blue Pill,以便从 Arduino IDE 上传程序,如第一章,微控制器和微控制器板简介中所述。
在本节中,你学习了如何将易于使用的光敏电阻连接到 Blue Pill 板,以及如何通过 LED 显示其值。
下一节描述了如何编写图 4.4和图 4.5中所示的光敏电阻示例的代码。
编写光敏电阻值和设置端口
本节展示了如何编写 Blue Pill 应用程序以从光敏电阻读取数据。
以下代码应在图 4.4和图 4.5所示的微控制器板电路中运行:
int photoresistorPin = PB1;
int photoresistorReading;
void setup(void) {
    pinMode(PB12, OUTPUT); 
    pinMode(PB14, OUTPUT); 
    pinMode(PB15, OUTPUT); 
}
void loop(void) {
    photoresistorReading = analogRead(photoresistorPin); 
    digitalWrite(PB12, LOW);
    digitalWrite(PB14, LOW);
    digitalWrite(PB15, LOW);
    if (photoresistorReading < 600) { 
        digitalWrite(PB15, HIGH);
    } else if (photoresistorReading < 1000) {  
        digitalWrite(PB14, HIGH);
    } else {
        digitalWrite(PB12, HIGH);  
  }
  delay(500);
}
如您从代码中看到的,其中最重要的功能之一是:analogRead(photoresistorPin);。内部,该函数将执行一个pinMode()函数来声明 PB12、PB14 和 PB15 端口为输出。
代码可以从本书的 GitHub 仓库下载。其文件名为photoresistor_bluepill.ino。仓库中的代码包含有用的注释,解释了其中使用的函数和变量。
注意
您可以在 Arduino Uno 等 Arduino 微控制器板上运行相同的 Blue Pill 代码。只需将 Blue Pill 的输入端口 PB1 更改为 Arduino 的模拟端口 0(在 Arduino Uno 上标记为 A0),并将 Blue Pill 的输出端口 PB12、PB14 和 PB15 更改为 Arduino 的数字端口 8、9 和 10。您可能还需要更改代码中的决策值(阈值)。
以下部分描述了如何根据 Blue Pill 板的示例将 LED 和光敏电阻连接到 Curiosity Nano 微控制器板。
将光敏电阻连接到 Curiosity Nano 板
按照上一节中的 Blue Pill 示例,我们可以通过使用 Curiosity Nano 微控制器板打开 LED 灯来显示环境中的光照量,如图图 4.6所示。

图 4.6 – 连接到 Blue Pill 板的 LED 和光敏电阻
如图 4.6所示,三个 LED 将被用来显示光敏电阻检测到的光照量。以下是连接组件到 Curiosity Nano 板的步骤:
- 
将 Curiosity Nano 的 GND 引脚连接到无焊面包板的上下轨,如图图 4.6所示。 
- 
将光敏电阻的一个引脚连接到 Curiosity Nano 上标记为 VTG 的引脚。此引脚提供 3.3 伏。 
- 
将光敏电阻的另一端连接到 Curiosity Nano 上标记为 RA0 的引脚。RA0 将被用作模拟输入端口。 
- 
将一个 220 欧姆电阻连接到地以及连接到 RA0 端口的 photoresistor 的腿。这将是一个下拉电阻。 
- 
现在,将 220 欧姆电阻分别连接到 RD1、RD2 和 RD3 端口以及 3 个 LED 的正极。 
- 
作为最后一步,将 LED 的负极连接到地。 
我们将一个 220 欧姆的下拉电阻连接到 Curiosity Nano 的输入端口,如图图 4.6所示,当光敏电阻没有电压输入时,强制端口具有 0 伏输入。记住,输入端口应该接收一些电压,甚至 0 伏,以避免随机电压。
注意
根据您希望检测的光照水平范围,您可能想尝试在图 4.6中显示的不同下拉 220 欧姆电阻的值。
图 4.6 中的光敏电阻将根据其从环境中接收到的光照量改变其电阻,因此通过它的电压将改变。这些电压差异将被微控制器板的输入端口读取。然后,运行在微控制器板上的我们的代码将比较模拟电压值,并通过分别开启黄色、绿色或红色 LED 来确定光照是极低、正常还是过亮。
下一段代码展示了如何通过模拟端口 RA0 读取光敏电阻值:
#include <xc.h>
#include <stdio.h>
#include "mcc_generated_files/mcc.h"
static uint16_t reading_photoresistor=0;
void main(void)
{
    SYSTEM_Initialize(); 
    ADC_Initialize();
    while (1)
    {
        IO_RD1_SetLow();
        IO_RD2_SetLow();
        IO_RD3_SetLow();
        reading_photoresistor =            ADC_GetConversion(channel_ANA0); 
        if (reading_photoresistor>=0 &&                 reading_photoresistor <=128)
        {
            IO_RD1_SetHigh();
        } else if (reading_photoresistor>= 129 &&                    reading_photoresistor<=512)
        {
            IO_RD2_SetHigh();
        } else
        {
            IO_RD3_SetHigh();
        }
        __delay_ms(200); 
    } 
}
请记住,上传到本书 GitHub 在线仓库的代码中包含许多注释,解释了几乎所有的指令。在前面代码中,最重要的函数之一是 ADC_GetConversion(channel_ANA0);,它读取光敏电阻的电压变化并执行这些值的模拟到数字转换。channel_ana0 是分配给端口 RA0 的标签。
代码可以从本书的 GitHub 仓库下载。其文件名为 Chapter4_Curiosity_Nano_code_project.zip。仓库中的代码包含有用的注释,解释了其中使用的函数和变量。
图 4.7 展示了光敏电阻和 LED 如何连接到 Curiosity Nano 的端口。图 4.7 中所示的电路基于 图 4.6 中的 Fritzing 图。

图 4.7 – 将光敏电阻和 LED 连接到 Curiosity Nano
如您在 图 4.7 中所见,光敏电阻连接到 Curiosity Nano 的端口 RA0。图中的绿色 LED 正在开启,这意味着植物接收到的光照量应该是正常的。
下一节将展示如何使用光敏电阻传感器模块获取关于环境光照量的模拟数据。
将光敏电阻传感器模块连接到微控制器板
本节解释了如何使用光敏电阻传感器模块来测量环境中的光照量。此模块可以从许多在线来源单独购买或作为传感器套件的一部分购买。光敏电阻传感器模块包含微小的电子组件,便于连接到微控制器板及其光敏电阻的使用。例如,本节中使用的模块包含额外的组件,如电阻和可变电阻,该可变电阻调整传感器模块发送的数字 高 值的阈值水平,如果它接收一定量的光。当然,这个数字值必须发送到微控制器板的数字输入端口。
下一节将展示如何将光敏电阻传感器模块连接到 Blue Pill。
将光敏电阻传感器模块连接到 Blue Pill 板
本节解释了如何仅使用三根线将光敏电阻模块连接到微控制器板。图 4.8中所示的光敏电阻传感器模块有四个连接器:GND(代表地),A0(代表模拟输出),D0(代表数字输出),和+5V。如果您的传感器模块来自不同的品牌,这些连接器的顺序可能会改变,但它们的作用是相同的。

图 4.8 – 连接到 Blue Pill 板的光敏电阻传感器模块
这里是如何将传感器模块连接到 Blue Pill 的步骤:
- 
将传感器模块的 GND 引脚(在某些传感器模块上,它标有-符号)连接到微控制器板的 GND 接地连接器。 
- 
将传感器模块的+5V(在某些模块上,它标有+符号)引脚连接到微控制器板的 3V3 电压引脚。尽管 3V3 引脚提供 3.3 伏,但对于向传感器模块供电(馈电)来说已经足够了。 重要提示 不要将5 伏(5V)应用到 Blue Pill 的输入端口,因为这可能会损坏 Blue Pill。这就是为什么你会将 3V3 电压引脚连接到传感器模块的+5V 引脚,这样模块将提供高达 3.3 伏的模拟电压输出,而 Blue Pill 将使用这部分电压来测量光量。 
- 
将模块的 A0 引脚连接到 Blue Pill 的 B1 引脚(它是一个输入端口)。 
- 
现在,将电阻连接到 Blue Pill 的 B12、B14 和 B15 端口。它们是输出端口。 
- 
作为最后一步,将绿色、黄色和红色 LED 的正极连接到这些电阻上,然后将 LED 的负极连接到地。 
如图 4.8所示,我们没有将下拉电阻连接到 Blue Pill 的输入端口,因为传感器模块已经包含下拉电阻。这允许我们在电路中节省一些空间,并节省连接额外组件的时间。
以下部分描述了如何使用传感器模块与 Curiosity Nano 配合。
将光敏电阻传感器模块连接到 Curiosity Nano 板
在本节中,我们将分析传感器模块的模拟引脚是如何连接到 Curiosity Nano 的,如图图 4.9所示。请记住,这个电路不需要下拉电阻。我们使用的是之前章节中描述的用于连接单个光敏电阻的相同输入端口。图 4.9显示了一个包含连接到 Curiosity Nano 板的传感器模块的 Fritzing 图。

图 4.9 – 连接到 Curiosity Nano 的 RA5 输入端口的光敏电阻模块
根据图 4.9中的 Fritzing 图,连接光敏电阻传感器模块到 Curiosity Nano 的步骤如下:
- 
将模块的 GND 引脚(在某些模块上,它标有-符号)连接到微控制器板的 GND 接地器,标记为 GND。 
- 
将模块的+5V 引脚(在某些模块上,它标有+符号)连接到微控制器板的 VTG 引脚。尽管 VTG 引脚提供 3.3 伏,但它可能足以向传感器模块供电。 重要提示 不要将 5V 应用到 Curiosity Nano 的输入端口,因为这可能会损坏微控制器板。这就是为什么你会将 Curiosity Nano 的 VTG 电压引脚连接到传感器模块的+5V 引脚,这样传感器模块将提供高达 3.3 伏的输出,Curiosity Nano 将使用该电压来测量光量。 
- 
将传感器模块的 A0 引脚连接到 Curiosity Nano 的 RA5 引脚(这是一个输入端口)。 
- 
现在,将保护 3 个 LED 灯的电阻连接到 RD1、RD2 和 RD3 端口。它们是输出端口。 
- 
作为最后一步,将绿色、黄色和红色 LED 灯的正极连接到这些电阻,然后将 LED 灯的负极连接到地。 
如图 4.9所示,与 Blue Pill 的示例类似,我们不会将下拉电阻连接到 Curiosity Nano 的输入端口,因为传感器模块已经包含下拉电阻。
你可以使用与图 4.6和图 4.7中使用的光敏电阻相同的代码,从图 4.9中所示的光敏电阻传感器模块获取模拟值。如果需要,你可能需要调整代码中的值。你可以通过在多种环境中进行实验(例如,在客厅或卧室中使用传感器)来观察微控制器板从传感器获得的模拟值的变化,并相应地调整代码。
下一个部分将描述如何测试光敏电阻,如果它有问题,例如 LED 灯不亮,作为故障排除的方法。
在本节中,你学习了如何将光敏电阻模块和 LED 灯连接到 Curiosity Nano 的端口。本节很重要,因为它展示了光敏电阻模块的实用性和易用性,这有助于微控制器板项目中的连接。
测试光敏电阻
本节重点介绍如何测试光敏电阻,以查看它是否正常工作。首先,记住本章中使用的光敏电阻没有极性,因此你可以安全地将它的任何引脚(腿)连接到微控制器板的输入端口。
你还需要确保连接到光敏电阻的拉低电阻具有正确的值。例如,图 4.4中的 Blue Pill 示例中使用的拉低电阻是 10K 欧姆,而图 4.6中的 Curiosity Nano 示例中我们使用了 220 欧姆的电阻。我们通过实验找到了这些电阻值。你可以尝试将不同的电阻连接到光敏电阻,看看通过光敏电阻的电压是否变化很大。理想情况下,该电压应在 0 到 3.3 伏特之间变化,或接近这些值,因为在本章的电路示例中,我们将光敏电阻的一个引脚连接到了 3.3 伏特。
为了检查光敏电阻是否正常工作,你可以使用万用表。按照以下步骤使用万用表测试光敏电阻:
- 
将万用表的红表笔(测试线)连接到光敏电阻的一个引脚。 
- 
将万用表的黑表笔连接到光敏电阻的另一端。 
- 
打开万用表并设置为测量电阻(欧姆)。 
- 
用手覆盖光敏电阻并揭开它。由于光敏电阻接收到的光线发生变化,其电阻应该在万用表中发生变化。 
如果你没有万用表,你可以使用电压源(如电池)和 LED(任何颜色都可以)来测试光敏电阻。图 4.10显示了如何将光敏电阻连接到 LED:

图 4.10 – 测试光敏电阻
如图 4.10所示,当光敏电阻接收到的光线量不同时,LED 的光线应该发生变化(例如,从暗到亮),所以试着用手覆盖它并看看会发生什么。如果 LED 的光线没有变化,那么很可能是光敏电阻损坏了,因此你需要更换它。以下是连接组件的步骤:
- 
将正极( +)电池端连接到光敏电阻的一个引脚。
- 
将光敏电阻的另一引脚连接到 LED 的正极引脚。 
- 
将 LED 的负极引脚连接到负极( -)电池端。
在连接 LED 的引脚时要小心。如果反向连接,LED 将不会点亮。
摘要
在本章中,我们学习了传感器及其在电子项目中的应用。这很重要,因为我们将在本书的其他章节继续应用传感器。我们还定义了光敏电阻,以及它们的分类。我们还学习了如何将光敏电阻传感器模块连接到 Blue Pill 和 Curiosity Nano 板的输入端口,以及如何分析和使用光敏电阻的模拟数据。
在本章中,你学习了重要信息。我们定义了什么是传感器和光传感器。你现在可以使用微控制器板从它们中读取数据。本章还描述了如何将光传感器模块连接到微控制器板。
第五章, 湿度和温度测量,将解释什么是湿度和温度传感器,以及我们如何使用 Blue Pill 和 Curiosity Nano 微控制器板获取和使用其模拟数据。这可以应用于多种场合,例如测量温室的温度和湿度。
进一步阅读
- 
Horowitz, P., Hill, W. (2015), 电子艺术 [第 3 版],剑桥大学出版社:纽约,纽约。 
- 
Microchip (2019), PIC16F15376 Curiosity Nano 硬件用户指南, Microchip Technology, Inc. 可从: ww1.microchip.com/downloads/en/DeviceDoc/50002900B.pdf
- 
Mims, F.M. (2000), 电子入门, 林肯伍德,伊利诺伊州:Master Publishing, Inc. 
第五章:第五章: 湿度和温度测量
本章描述了如何在环境中实际测量湿度和温度,以及如何将专用传感器连接到微控制器板。你将了解到如何使用常用的传感器 DHT11 和 LM35。在本章中,你将获得有关从温度和湿度传感器以及传感器模块获取数据以及如何将其显示给用户的有价值信息。
在本章中,我们将涵盖以下主要内容:
- 
介绍 DHT11 湿度温度传感器模块 
- 
将 DHT11 和 LM35 传感器连接到微控制器板 
- 
编码从传感器模块获取数据 
- 
在串口监视器上显示湿度和温度数据结果 
到本章结束时,你将学会如何正确地将 DHT11 湿度温度传感器和 LM35 温度传感器连接到 Curiosity Nano 和 Blue Pill 微控制器板。你还将学会如何分析和显示从这些传感器获得的数据。
技术要求
本章中你将使用的软件工具是MPLAB X和Arduino IDE,分别用于编辑和上传你的程序到 Curiosity Nano 和 Blue Pill 微控制器板。
本章将使用的代码可以在本书的 GitHub 仓库中找到:github.com/PacktPublishing/DIY-Microcontroller-Projects-for-Hobbyists/tree/master/Chapter05
本章的“代码在行动”视频可以在以下链接找到:bit.ly/2UiRHVP
在本章中,我们将使用以下硬件:
- 
一个无焊面包板。 
- 
Blue Pill 和 Curiosity Nano 微控制器板。 
- 
一根 Micro USB 线,用于将你的微控制器板连接到电脑。 
- 
上传编译后的代码到 Blue Pill 所需的 ST-LINK/V2 电子接口。请注意,ST-LINK/V2 需要四根女性到女性的杜邦线。 
- 
绿色和黄色 LED。 
- 
两个 220 欧姆、额定为四分之一瓦特的电阻。这些电阻是为 LED 准备的。 
- 
一个 4.7 千欧姆、额定为四分之一瓦特的电阻。它是为 DHT11 传感器准备的。 
- 
一个 2.2 千欧姆、额定为四分之一瓦特的电阻。它是为液晶显示器(LCD)准备的。 
- 
一个 DHT11 湿度温度传感器模块。 
- 
一个 LM35 温度传感器。 
- 
三根男性到女性的杜邦线,用于将传感器模块连接到无焊面包板。 
- 
一打男性到男性的杜邦线。 
- 
一个 1602 16x2 液晶显示器。 
下一节简要介绍了 DHT11 传感器模块,其电气特性以及该模块在电子项目中的应用。
介绍 DHT11 湿度温度传感器模块
在本节中,我们将回顾 DHT11 传感器模块。本节还描述了传感器引脚是什么,以及如何将它们连接到微控制器板。DHT11 是一个易于使用、实用且低成本的传感器模块,可以测量 0 到 50 摄氏度范围内的温度,误差率为 +-2%。它还可以测量 20% 到 90% 范围内的环境相对湿度(RH),精度为 +-5%。这些值可能因传感器模块的制造商而略有不同。下一节将描述 RH 是什么,这是一个由 DHT11 传感器读取的环境值。
什么是相对湿度?
相对湿度是基于水蒸气和环境温度的组合。它是在一定温度下空气中存在的水蒸气量的比例,以百分比表示。一般来说,水蒸气的量在冷空气中比热或温暖空气中的相对湿度(RH)要高。一个相关的参数是露点,这是空气从某个地方或环境中冷却到必须达到的温度,以便它能够被水蒸气饱和。
测量相对湿度很重要,因为它与人们在环境中的不适程度有关,以及其他应用。RH 测量可以有一些有用的应用,例如在温室中,有些植物需要一定程度的 RH 才能生长。
DHT11 引脚及其值
以下是一个 DHT11 传感器模块的 Fritzing 图。请注意,DHT11 模块可能有一个第四个引脚,具体取决于其制造商。第四个引脚没有连接到任何东西(有时标记为 not connected 或 NC):

图 5.1 – DHT11 传感器模块
如我们所见,DHT11 的 v 引脚(它也可以标记为 VCC 或 +,具体取决于制造商)可以连接到 3 到 5.5 伏的直流(DC)电源。在本章中,我们将 DHT11 连接到 3.3 伏的电压,这可以由 Curiosity Nano 和 Blue Pill 板提供。引脚 s 是提供传感器生成的温度和湿度数据的信号。它也可以标记为 OUT 或 DATA,具体取决于 DHT11 制造商。引脚 g(有时标记为 G、GND 或 -)将连接到微控制器板的地线。大多数 DHT11 模块的测量温度和湿度时的运行电流为 0.3mA,待机时为 60 微安,使其成为一个功耗非常低的传感器。
以下图片显示了由两家不同制造商制造的两种 DHT11 传感器模块:

图 5.2 – DHT11 传感器模块
请注意,DHT11 模块之间略有差异。例如,两个 DHT11 模块的引脚顺序不同。左侧的模块按照顺序有地线(标记为 GND)、信号(标记为 data)和电压(标记为 VCC)引脚,而右侧的模块按照顺序有信号(data)、电压和地线引脚。此外,引脚的标签也不同。然而,两个 DHT11 模块的工作方式相同,可以用于本章中显示的电路。传感器本身被封装在带有网格的蓝色塑料盒中。DHT11 模块有额外的电子元件,便于连接到传感器。
在本节中,您将了解 DHT11 传感器模块、其引脚以及不同制造商制造的 DHT11 传感器之间的相似之处和不同之处。您还回顾了相对湿度是什么,这是 DHT11 可以读取的重要环境值。
下一节将向您展示如何将 DHT11 模块连接到 Blue Pill 的数字端口,以便您可以读取其值。
将 DHT11 传感器模块连接到微控制器板
本节处理本章中所有硬件组件。我们将首先将 DHT11 连接到 Blue Pill 板。将 DHT11 连接到微控制器板很容易,因为它只需要三根线。
将 DHT11 连接到 Blue Pill 板
在本节中,我们将连接 DHT11 到 Blue Pill,如图所示:

图 5.3 – DHT11 连接到 Blue Pill 微控制器板
如我们所见,DHT11 的连接很简单。在一些 DHT11 模块中,其制造商建议将一个 5K 欧姆的上拉电阻连接到S(信号)引脚。然而,由于 5K 欧姆电阻在商业上不可用,一个 4.7K 欧姆的电阻已经足够接近推荐值。在我们项目中使用的 DHT11 模块中,其电子电路已经有一个类似的电阻,所以我们不需要连接一个 4.7K 欧姆的电阻。
注意
根据制造商的不同,许多 DHT11 模块已经包括一个上拉电阻,因此 4.7k 欧姆的上拉电阻不是必需的。值得检查一下。只需将 DHT11 连接到微控制器板。如果它给出不规则的温度测量值,或者根本无法进行测量,您可能需要将上拉电阻连接到它。
按照以下步骤将 DHT11 连接到 Blue Pill:
- 
将 Blue Pill 的GND(也标记为G)引脚连接到无焊面包板轨道。 
- 
将标记为(提供 3.3 伏特)的 Blue Pill 的3.3引脚连接到上面包板轨道。请注意,在某些 Blue Pill 板上,此引脚标记为3V3。 
- 
将 DHT11 的s引脚连接到 Blue Pill 的B12引脚。 
- 
将 DHT11 的v引脚连接到连接到3V3引脚的上面包板轨道。 
- 
将 HDT11 的g引脚连接到地线引脚(下面包板轨道)。 
- 
将 USB 线缆连接到 Blue Pill,然后连接到您的计算机。 
以下图像显示了所有连接应该如何连接:

图 5.4 – DHT11 连接到 Blue Pill
在这里,我们可以看到我们只需要几根杜邦线就可以将 DHT11 连接到 Blue Pill 板。您需要将 ST-LINK/V2 接口连接到您的计算机以上传其代码,如在第 1 章 中所述,微控制器和微控制器板简介。在上传程序到 Blue Pill 之前,请务必先断开 USB 线缆(如前一张图像所示左侧)。请注意,前一张图像中显示的引脚顺序是 GND、DATA 和 VCC,这与 图 5.3 中显示的 DHT11 的引脚顺序不同。再次强调,这是因为一些 DHT11 制造商改变了 DHT11 的引脚顺序。
注意
所有 Blue Pill 的 地(GND)引脚都是相同的;它们是内部连接的。这块微控制器板有多个 GND 引脚,这样我们就可以将电子组件连接到板上。
温度和湿度值将从 IDE 的计算机串口监视器中显示。这将在 为 Blue Pill 板编程 DHT11 传感器 部分进行解释。
以下图像显示了一个带有 DHT11 和 4.7k-ohm 上拉电阻的 Fritzing 图表连接到信号(S)引脚。在此示例中使用的 DHT11 模块没有内置上拉电阻,因此我们需要连接一个:

图 5.5 – 带有上拉电阻的 DHT11
上一张图像显示了 4.7 k-ohm 电阻作为上拉电阻的工作情况。下一节将描述如何连接 LCD 来显示从 DHT11 获得的温度和湿度数据。
将 LCD 连接到 Blue Pill
本节展示了显示从 DHT11 传感器获得的温度和湿度数据的一种有趣且实用的方法,将其显示在低成本 1602 LCD 上。以下是一个显示所有连接的 Fritzing 图表:

图 5.6 – 连接到 Blue Pill 板的 1602 LCD
前图展示了 1602 LCD,它可以显示两行(16x2)的 16 个字母和特殊字符(例如%,$等)。每个字符由一个 5x8 点阵形成。LCD 有 16 个引脚,从左到右标记为VSS、VDD、V0、RS、RW、E、D0、D1、D2、D3、D4、D5、D6、D7、A和K。这是一种流行的 LCD,也可以与 Arduino 微控制器板一起使用。连接到V0 LCD 引脚的 2.2k 欧姆电阻调整 LCD 的对比度。VSS和VDD引脚连接到电源。D0到D7引脚用于向 LCD 发送数据以形成字符,但在这里,我们只使用 4 位(引脚D4到D7)来显示 LCD 上的字母和数字。1602 LCD 连接到5 伏(+5V)电源,该电源由 Blue Pill 的 5V 引脚提供。
请记住,前图中显示的上部和下部面包板电压轨连接到 Blue Pill 的 5V 引脚,为 LCD 提供 5 伏电压。DHT11 连接到 Blue Pill 的 3.3V 引脚,因为该传感器使用 3.3 伏电压。其结果数据将通过 3.3 伏的数字电压级发送到 Blue Pill 的输入数据引脚B12。
按照以下步骤连接 DHT11 和 LCD 到 Blue Pill,同时参考前图:
- 
将 Blue Pill 的GND(也标记为G)引脚连接到无焊面包板轨。 
- 
将 Blue Pill 的5V引脚(提供 5 伏电压)连接到面包板轨。 
- 
将 DHT11 的s引脚连接到 Blue Pill 的B12引脚。 
- 
将 DHT11 的v引脚连接到 Blue Pill 的3V3引脚。 
- 
将 HDT11 的g引脚连接到地线引脚(上部面包板轨)。 
- 
将 USB 线连接到 Blue Pill,然后连接到您的电脑或 USB 移动电源。 
- 
将 LCD 的 16 个引脚插入无焊面包板。 
- 
将 LCD 的VSS引脚连接到地线引脚(下部面包板轨)。 
- 
将 LCD 的VDD引脚连接到 5 伏(下部面包板轨)。 
- 
将 2.2K 欧姆电阻连接到 LCD 的V0引脚和地线引脚(上部面包板轨)。 
- 
将 LCD 的RS引脚连接到 Blue Pill 的B11引脚。 
- 
将 LCD 的RW引脚连接到地线引脚(下部面包板轨)。 
- 
将 LCD 的E引脚连接到 Blue Pill 的B10引脚。 
- 
将 LCD 的D4引脚连接到 Blue Pill 的B0引脚。 
- 
将 LCD 的D5引脚连接到 Blue Pill 的A7引脚。 
- 
将 LCD 的D6引脚连接到 Blue Pill 的A6引脚。 
- 
将 LCD 的D7引脚连接到 Blue Pill 的A5引脚。 
- 
将 LCD 的A引脚连接到 5 伏(上部面包板轨)。 
- 
将 LCD 的K引脚连接到地线引脚(上部面包板轨)。 
- 
LCD 的D0、D1、D2和D3引脚未连接。 
以下图像展示了所有部件的连接方式:

图 5.7 – 连接到 Blue Pill 微控制器板的 1602 LCD
在这里,您可以看到 LCD 正在工作,因为 Blue Pill 连接到 USB 移动电源(前图未显示)。LCD 显示当地温度(摄氏度),湿度以百分比显示。编程 LCD 和 DHT11 的代码将在本章后面展示。
下一节将向您展示如何将 LM35 温度传感器连接到 Curiosity Nano 板,演示如何从该传感器读取温度值并将它们发送到 Curiosity Nano 的模拟输入端口。
将 LM35 温度传感器连接到 Curiosity Nano 板
在本节中,我们将描述如何在 Curiosity Nano 上测量由 LM35 传感器获取的温度值。为了演示目的,当温度在 23 到 26 摄氏度的舒适温度范围内时,将分析温度。LM35 是一个低成本且易于连接的传感器,可测量从-55 到 150 摄氏度的广泛温度范围。以下是 LM35 传感器引脚排布图:

图 5.8 – 显示引脚 1、2 和 3 的 LM35 传感器
如您所见,LM35 有三个引脚:引脚 1(Vs)、引脚 2(Vout)和引脚 3(GND)。引脚 1 是来自电源的电压。Curiosity Nano 的VBUS引脚提供 5 伏,因此 LM35 的引脚 1 可以连接到它。引脚 2 是输出电压(Vout),以毫伏(mV)的形式提供测量温度值,使用线性比例因子。这个比例因子每增加 1 摄氏度增加+10 mV(+10 mV/C)。引脚 3 连接到微控制器板的接地(GND)。
LM35 传感器信号引脚(引脚 2)提供 mV 的温度值,将被 Curiosity Nano 转换为数字值。为此,我们需要将 LM35 的引脚 2 连接到 Curiosity Nano 的一个输入模拟端口。温度值计算为温度=(5.0/1023)millivolts_from_LM35*,其中 5.0 是连接到 LM35 引脚 1 的 5 伏,1023 是 Curiosity Nano 的 10 位 ADC,这意味着它的 ADC 可以检测(2¹⁰)个离散的模拟级别。该公式将 LM35 的输出(以 mV 计)转换为等效的摄氏度值。以下图像显示了 LM35 传感器:

图 5.9 – LM35 温度传感器
前面的图像展示了 LM35 温度传感器及其三个引脚。由于它和普通晶体管一样都采用 TO-92 半导体封装类型,因此它们的大小相同。然而,LM35 不是一个晶体管——它是一个温度传感器。
我们必须将其两个 LED 连接到其输出端口以显示温度和湿度范围,如图所示:

图 5.10 – 将 LM35 传感器和 LED 连接到 Curiosity Nano 板
如你所见,我们必须连接一个绿色 LED 来显示由 LM35 传感器读取的环境温度在 23 到 26 摄氏度的舒适温度范围内;如果温度超出这个范围,黄色 LED 将被点亮。本章中使用的舒适温度区间的温度值由加拿大标准协会确定,与其他国家机构定义的值相似。舒适温度区间的值可以在以下位置找到:www.ccohs.ca/oshanswers/phys_agents/thermal_comfort.html。
按照以下步骤将 LM35 和 LED 连接到 Curiosity Nano 板:
- 
将 Curiosity Nano 的GND引脚连接到无焊面包板轨道的下轨。 
- 
将 LM35 的Vout(信号)引脚(2)连接到 Curiosity Nano 的RA0引脚。它将被用作模拟输入端口。 
- 
将 LM35 的Vs引脚(1)连接到 Curiosity Nano 的VBUS引脚。此引脚提供 5 伏特。 
- 
将 LM35 的g引脚(3)连接到 Curiosity Nano 的GND引脚,从其上方的引脚行。 
- 
现在,将两个 220 欧姆电阻连接到 Curiosity Nano 的RD2和RD3端口,以及两个 LED 的阳极。 
- 
将 LED 的阴极连接到地线引脚。 
- 
最后,将 USB 线缆连接到 Curiosity Nano,然后连接到你的电脑或 USB 移动电源。 
以下图像显示了所有连接应该如何连接:

图 5.11 – LM35 传感器连接到 Curiosity Nano 板
前面的图像显示了 LM35 连接到 Curiosity Nano 的 RA0 上方的引脚行。
注意
Curiosity Nano 的所有 GND 引脚都是相同的;它们是内部连接的。这个微控制器板有多个 GND 引脚,这样我们就可以将电子组件连接到板上。
在本节中,你了解了 LM35 温度传感器、其引脚以及如何将其连接到微控制器板。你还学习了如何使用 LED 显示温度信息。下一节将展示如何编写程序从 DHT11 传感器读取湿度和温度值。
从传感器模块获取数据的编码
本节描述了如何为 Blue Pill 和 Curiosity Nano 板编写程序,以便它们可以读取 DHT11 的值。你还将学习如何使用 Blue Pill 编程 LM35 温度传感器。让我们先为 Blue Pill 板编程 DHT11 传感器。
为 Blue Pill 板编程 DHT11 传感器
在本节中,你将回顾使用特殊库从 DHT11 传感器获取数据的代码。该代码还将展示如何在串行端口上显示温度和湿度数据,从而在 Arduino IDE 的串行监视器上显示。以下代码从连接到 Blue Pill 数字输入端口B12的 DHT11 传感器模块中读取温度和湿度:
#include <DHT.h> 
#define DHT11_data_pin PB12 
DHT dht(DHT11_data_pin, DHT11); 
void setup() {
    Serial.begin(9600); 
    while (!Serial);
    Serial.println("Opening serial comm.");
    dht.begin();
}
void loop() {
    float humidity = dht.readHumidity(); 
    float temperature=dht.readTemperature(); 
    Serial.println("Humidity: "+String(humidity)); 
    Serial.println("Temperature: "+String(temperature)); 
    delay(1000); 
}
在前述代码中,你可以看到第一行包含一个名为DHT.h的库。这是一个非常实用的库,用于从 DHT11 读取值。此代码可在本书的 GitHub 仓库中找到,其中包含解释其主要部分的注释。要在 Arduino IDE 上安装DHT.h库,请按照以下步骤操作:
- 
从 IDE 的主菜单中选择工具 | 管理库。 
- 
在库管理器的搜索框中输入 DHT11。
- 
将列出几个库。选择并安装由 Adafruit 制作的 DHT 传感器库的最高版本。 
- 
等待库安装完成。然后,关闭库管理器。现在,DHT11 库应该可以在你的代码中使用了。 
请注意,dht.readTemperature()函数返回摄氏度的温度值,而dht.readHumidity()函数返回相对湿度的百分比值。
以下截图显示了 Arduino IDE 的库管理器显示名为DHT 传感器库的库,由 Adafruit 提供:

图 5.12 – Arduino IDE 的库管理器
在这里,你可以看到在搜索框中输入DHT11,你可以找到 Adafruit 的 DHT 传感器库。点击安装按钮。
小贴士
你也可以将 DHT11 传感器连接到 Arduino Uno 微控制器板上。只需连接前述代码中显示的 DHT11 的DHT11_data_pin。此外,将 DHT11 的 GND 和 VCC 引脚分别连接到 Arduino Uno 的 GND 和 3V3 引脚。
下一个部分将展示如何在 1602 LCD 上显示湿度和温度数据。
编程传感器模块和 1602 LCD
以下代码描述了如何从 DHT11 传感器获取温度和湿度数据,以及如何在 1602 LCD 上显示这些数据:
#include <DHT.h>
#include <math.h>
#include <LiquidCrystal.h>
const int rs = PB11, en = PB10, d4 = PB0, d5 = PA7,    d6 = PA6, d7 = PA5;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7); 
#define DHT11_data_pin PB12
DHT dht(DHT11_data_pin, DHT11); 
void setup() {
    dht.begin(); 
    lcd.begin(16, 2); 
}
void loop() {
    float humidity = dht.readHumidity(); 
    float temperature=dht.readTemperature();
    lcd.setCursor(0, 0);
    lcd.print("Humidity: "+String(round(humidity))+"%   ");
    lcd.setCursor(0,1);
    lcd.print("Temp.: "+String(temperature)+"C   "); 
    delay(1000); 
}
请记住,上传到本书 GitHub 仓库的代码包含许多注释,解释了前述代码的主要部分。LiquidCrystal.h是用于控制 1602 LCD 的库。math.h库包含round()函数,用于四舍五入湿度值。这两个库都属于 Arduino IDE 的原始安装文件,因此我们不需要单独下载或安装它们。DHT.h是一个用于读取 DHT11 值的库;其安装在本章中已解释过。
下一个部分将描述如何将 LM35 温度传感器编程到 Curiosity Nano 微控制器板上。
在 Curiosity Nano 板上编程 LM35 传感器
以下代码从连接到 Curiosity Nano 的模拟输入端口 RA0 的 LM35 传感器读取温度:
#include "mcc_generated_files/mcc.h"
static uint16_t LM35read=0;
float temp=0.0;
void main(void)
{
    // initialize the device
    SYSTEM_Initialize();
    ADC_Initialize();
    while (1)
    {
        IO_RD2_SetLow();
        IO_RD3_SetLow();
        LM35read=ADC_GetConversion(channel_ANA0);
        temp=(5.0/1023)*LM35read;
        if (temp>=23.0 && temp<=26.0)
        {
            IO_RD3_SetHigh();
        } else {
          IO_RD2_SetHigh();
        }
        __delay_ms(500);
    }
}
如您所见,Curiosity Nano 使用 ADC_GetConversion() 函数将读取自 LM35 传感器的值进行模拟到数字转换。我们还使用了根据从 LM35 读取的 mV 计算摄氏度的公式;即 temp=(5.0/1023)*LM35read;。
通过这样,您已经学会了如何通过编码 Blue Pill 和 Curiosity Nano 来获取 DHT11 传感器模块和 LM35 传感器的数据。下一节将向您展示如何在 Arduino IDE 的串行监视器上显示 DHT11 数据。
在串行端口监视器上显示湿度和温度数据结果
本节描述了如何使用 Blue Pill 和 Curiosity Nano 在串行端口监视器上显示 DHT11 数据,并讨论了如何处理从 DHT11 传感器模块获得的数据。
打开并运行 Arduino IDE 上的 Blue Pill 代码。您可以通过点击 Arduino IDE 主菜单中的 工具 | 串行监视器 来读取从 DHT11 获得的数据。以下截图显示了这一过程:

图 5.13 – Arduino IDE 的串行监视器截图
在这里,您可以看到从 DHT11 获得的湿度和温度值以小数点显示,从而显示了更精确的温度。请记住,存储这些值的变量是用 float 类型声明的。
小贴士
如果您无法打开 IDE 的串行监视器,并且 IDE 显示一条消息告诉您找不到 USB 端口,那么可能是您连接到 Blue Pill 和电脑的 USB 线缆有故障。此外,一些 USB 线缆只能用于充电设备,这些线缆您不应与 Blue Pill 一起使用。
请注意,前面截图中的温度是以摄氏度显示的,而相对湿度以百分比显示。
绘制数据
Arduino IDE 的串行端口监视器有一个有趣的选项,可以将从 DHT11 读取并发送到串行端口的值以图形方式绘制。这些值以实时方式绘制。
点击 Arduino IDE 主菜单中的 工具 | 串行绘图器,查看数据是如何以图形方式显示的,如下所示:

图 5.14 – HDT11 串行绘图器截图
在这里,您可以查看 DHT11 数据是如何以图形方式绘制的。y 轴表示湿度量,而 x 轴表示时间(秒)。图表显示了一个峰值,因为当时环境湿度发生了变化。要测试 DHT11 传感器湿度测量的变化,只需对着传感器吹气。
在本节中,你学习了如何打开 Arduino IDE 的串行监视器以及如何将 DHT11 传感器模块的数据显示在上面,包括如何以图形方式绘制这些数据。
摘要
在本章中,我们学习了 DHT11 湿度和温度传感器以及 LM35 温度传感器的基础知识,包括它们的操作范围以及这些传感器如何将这些数据发送到微控制器板。这些是实用且低成本的传感器,Blue Pill 和 Curiosity Nano 可以轻松处理。本章展示了两种显示湿度和温度结果的方法。Blue Pill 直接在计算机监视器和 LCD 上显示湿度和温度值,而 Curiosity Nano 则使用 LED 显示温度和湿度范围。本章很有益,因为你学习了如何使用微控制器板从传感器获取环境数据以及如何有效地显示它,使用微控制器板的输入和输出端口。本章还强调了使用 LCD 显示温度和湿度数据的使用。
第六章,使用明亮的 LED 的 Morse Code SOS 视觉警报,将回顾如何创建一个实用的视觉警报。
进一步阅读
- 
Horowitz, P., Hill, W. (2015). 《电子艺术》 [第 3 版]。剑桥大学出版社:纽约,纽约。 
- 
LM35 (2017). LM35 精密摄氏度温度传感器数据表。德州仪器。可从: www.ti.com/lit/ds/symlink/lm35.pdf
- 
Microchip (2019). PIC16F15376 Curiosity Nano 硬件用户指南。Microchip 技术公司。可从: ww1.microchip.com/downloads/en/DeviceDoc/50002900B.pdf
- 
Mouser (2020). DHT11 湿度和温度传感器数据表。Mouser 公司。可从: www.mouser.com/datasheet/2/758/DHT11-Technical-Data-Sheet-Translated-Version-1143054.pdf
第六章:第六章:使用亮 LED 的摩尔斯电码 SOS 视觉警报
本章描述了如何构建一个非常显眼的视觉警报器,该警报器通过连接到微控制器板的超级亮 LED来显示 SOS 信息(当有人或一群人处于危险或困境时使用)。在本章中,你将学习如何使用微控制器板控制超级亮 LED。我们之所以在本章中使用超级亮 LED,是为了增加 SOS 信息的可见性。本章将有益于未来的电子项目,因为你将学习如何使用晶体管作为开关来控制 LED。本章中制作的应用程序可以在徒步旅行、海上和类似场景中使用的困难人群中使用。
本章我们将涵盖以下主要内容:
- 
理解摩尔斯电码和 SOS 信息 
- 
介绍超级亮 LED 及其所需电阻的计算 
- 
将电阻和超级亮 LED 连接到微控制器板 
- 
编写 SOS 摩尔斯电码信号 
- 
测试视觉警报 
到本章结束时,你将能够正确地将超级亮 LED 连接到 Curiosity Nano 和 Blue Pill 微控制器板,并使用微控制器板生成摩尔斯电码信息。
技术要求
本章中你将使用的软件工具是 MPLAB-X 和 Arduino IDE,分别用于编辑和上传你的程序到 Curiosity Nano 和 Blue Pill 微控制器板。
本章中使用的代码可以在本书的 GitHub 仓库中找到:
github.com/PacktPublishing/DIY-Microcontroller-Projects-for-Hobbyists/tree/master/Chapter06
本章的“代码在行动”视频可以在以下链接找到:bit.ly/3iXDlEP
本章中,我们将使用以下硬件设备:
- 
一个无焊面包板。 
- 
Blue Pill 和 Curiosity Nano 微控制器板。 
- 
用于将微控制器板连接到计算机的微型 USB 线。 
- 
需要上传编译后的代码到 Blue Pill 的 ST-Link/V2 电子接口。请注意,ST-Link/V2 需要四根公对公的杜邦线。 
- 
一个 5 毫米的槽孔 625 纳米橙色-红色,超级亮 LED,制造商编号 BL-BJU334V-1,由美国光电子公司制造,或者类似的产品。 
- 
两个 1 千欧姆、四分之一瓦特的电阻。这些电阻用于 LED 和晶体管。 
- 
一个 220 欧姆、四分之一瓦特的电阻。这是为 LED 准备的。 
- 
一个2N2222晶体管,TO-92 封装。 
- 
一打男性到男性的杜邦线。 
以下部分描述了摩尔斯电码是什么以及为什么在这个项目中使用它。
理解摩尔斯电码和 SOS 信息
摩尔斯电码是一种电信技术,通过应用不同持续时间的信号序列来编码、接收和发送 字母数字 和 特殊字符。摩尔斯电码是以电报发明家塞缪尔·摩尔斯的名字命名的。这种代码很重要,因为它在长距离的无线电和有线通信中普遍使用,特别是用于发送和接收电报。如今,摩尔斯电码在业余 (ham) 无线电通信中仍然被使用,因为当电磁大气条件不利时,人们可以可靠地解码它。更重要的是,摩尔斯电码可以通过发送 SOS 信息以光、音频或电磁信号的形式在紧急情况下使用。摩尔斯电码有时在航空中作为无线电导航辅助工具使用。
摩尔斯电码中的每个字符都是由 - 符号和 . 符号组成的。一个点是一个信号单元,一个破折号是三个信号单元。每个字母、数字和特殊字符都是通过点与/或破折号的组合进行编码的。字母之间的空格是一个信号单元(一个点),单词之间的空格是七个信号单元。此代码通常在信息载体上传输,例如,可见光和电磁无线电波。以下是一个使用国际摩尔斯电码编码的字母和数字列表:
- 
A ( .-)
- 
B ( -...)
- 
C ( -.-.)
- 
D ( -..)
- 
E ( .)
- 
F ( ..-.)
- 
G ( - -.)
- 
H ( ....)
- 
I ( ..)
- 
J ( .---)
- 
K ( -.-)
- 
L ( .-..)
- 
M ( - -)
- 
N ( -.)
- 
O ( - - -)
- 
P ( .- -.)
- 
Q ( - -.-)
- 
R ( .-.)
- 
S ( . . .)
- 
T ( -)
- 
U ( ..-)
- 
V ( ...-)
- 
W ( .- -)
- 
X ( -..-)
- 
Y ( -.--)
- 
Z ( - -..)
- 
1 ( .- - - -)
- 
2 ( ..- - -)
- 
3 ( ...- -)
- 
4 ( . . . . -)
- 
5 ( . . . . .)
- 
6 ( -. . . .)
- 
7 ( - - . . .)
- 
8 ( - - - . .)
- 
9 ( - - - -.)
- 
0 ( - - - - -)
特殊字符,如 $ 和 # 以及来自非英语语言的字符,也已被摩尔斯电码编码,但展示这些内容超出了本章的范围。例如,这是我们将单词 PARIS 用摩尔斯电码编码的方式:.- -.   .-   .-.   ..   ...
这是另一个例子。单词“HELP”可以编码为 …. . .-.. .--.
另一个更长的例子是单词 ALIVE:.- .-.. .. ...- .
常用的 distress 消息,用摩尔斯电码编码,由字母 SOS 组成。它由三个点、三个破折号和三个点组成(. . .  ---  . . .)。这个信息已被国际条约应用和认可,最初用于海上紧急情况。其起源不确定,但流行用法将 SOS 与诸如 Save Our Ship 或 Save Our Souls 这样的短语联系起来。尽管如此,SOS 容易记忆,在紧急情况下使用,并且比用摩尔斯电码编码其他单词,如 HELP,要短。
在本章中,我们将使用 SOS 信息制作一个视觉警报,通过使用 Blue Pill 和 Curiosity Nano 板通过开启和关闭一个超级明亮的 LED 来显示信息中的点和破折号。
下一节简要介绍了超亮 LED,以及为了我们的摩尔斯电码目的,可以连接到它们的是什么类型的电阻。
介绍超亮 LED 及其所需电阻的计算
超亮 LED是一种发光二极管(LED),以高亮度发光,比常规 LED 亮度更高。LED 亮度(光强度)以毫坎德拉(mcd)计算。请注意,1,000 mcd 等于 1 坎德拉。坎德拉通常用来衡量光源产生的光量,在这种情况下,是一个 LED,但坎德拉也可以用来衡量其他光源,如灯泡。我们在这章中使用的超亮 LED 额定为 6,000 mcd,发出一种漂亮且强大的橙色光芒,当连接到适当的限流电阻时相当明亮。相比之下,典型的 LED 额定值在约 50 到 200 mcd 之间。
超亮 LED 通过使用透明玻璃涂层和反射材料来增加光扩散的特殊设计。然而,一些超亮 LED 的观看角度(LED 光观察的角度看起来更亮)减少了约 35 度,例如我们在这章中使用的那种,而其他常规和超亮 LED 的观看角度为 120%。这个观看角度取决于它们的成本、效率和用途。
与常规 LED 一样,超亮 LED 需要一定的电压来供电,通常在 2 到 3 伏之间。这就是为什么我们需要将限流电阻连接到 LED 以降低其电压。我们可以使用公式 R=(Vs-Vf)/If 来计算以下情况下 LED 的限流电阻:
- 
Vs = 供电电压。Blue Pill 和 Curiosity Nano 输出端口提供 3.3 伏。 
- 
Vf = 正向电压,即通过电阻器下降的电压。 
- 
If 是正向 电流(amps)。 
- 
R 是我们想要计算的电阻值。 
连接到 LED 时常用的电阻值是 1 k 欧姆。当施加 3.3 伏的电源电压,电流为 1.5 毫安(或 0.0015 安)时,该电阻器的下降电压为 1.8 伏。让我们应用前面的公式来确认这个电阻值:

连接到超亮 LED 的电阻器将决定其吸取的电流数量。当使用 3.3 伏或 5 伏作为许多微控制器板提供的电源电压时,常用的电阻值用于连接 LED 是 220、330 和 1 k 欧姆。在大多数 LED 应用中(除非你将 LED 连接到 Blue Pill 微控制器板,如下一节所示),电阻值不是关键因素,因此我们可以使用其他具有相似值的电阻。首先,你可以确定超亮 LED 是否工作。前往本章末尾的测试视觉警报部分。
重要注意事项
当超级明亮的 LED 开启(发光)时,不要直接盯着它看,因为这可能会伤害你的眼睛。你可以暂时从侧面看它。
图 6.1展示了本章中使用的超级明亮的 LED:

图 6.1 – BL-BJU334V-1 超级明亮的 LED
图 6.1描绘了一个 BL-BJU334V-1 5 mm 通孔 LED,在 625 nm 波长下发出明亮的橙色光。其左侧引脚是阳极(正极),右侧引脚是阴极(负极),这是较短的。还有其他类型的超级明亮的 LED,亮度更高,尺寸更大。我们决定特别使用这个 LED,因为它成本低,适合插入无焊面包板,并连接到微控制器板。下一节将处理超级明亮的 LED 连接到 Blue Pill 和 Curiosity Nano 板。
将电阻和超级明亮的 LED 连接到微控制器板
本节展示了如何使用连接到微控制器板的超级明亮的 LED 来显示摩尔斯电码信息。我们首先解释如何将超级明亮的 LED 连接到 Blue Pill 的一个输入端口,以及如何使用晶体管作为开关来控制超级明亮的 LED。然后,我们描述如何将超级明亮的 LED 连接到 Curiosity Nano 板。
图 6.2显示了一个包含超级明亮的 LED 的 Fritzing 图:

图 6.2 – 一个超级明亮的 LED 连接到 Blue Pill 的 I/O 端口
如图 6.2所示,超级明亮的 LED 的阳极连接到一个 1 k 欧姆限流电阻。该电阻连接到输出端口 B12,每次发送摩尔斯电码字符的点或划时,都会向其提供 3.3 V 电压。以下是将图 6.2中显示的所有组件连接的步骤:
- 
将 1 k 欧姆电阻连接到 Blue Pill 的 B12 端口。 
- 
将电阻连接到超级明亮的 LED 的阳极引脚(其最长的腿,如图 6.1中所示,为左侧)。 
- 
将超级明亮的 LED 的阴极引脚(其最短的腿)连接到较低的无焊面包板的行接地。 
- 
将 Blue Pill 的 GND 引脚连接到无焊面包板的下轨。 
在执行这些步骤时,请确保连接正确的 LED 极性。
重要提示
不要将超级明亮的 LED 直接连接到电源,因为这会损坏它。你应该在其阳极(长 LED 腿)上连接一个限流电阻。
每个 Blue Pill I/O 端口可以处理高达 6 mA(毫安)的电流。请注意,在某些情况下和配置中,一个超级明亮的 LED 可能会消耗超过 6 mA 的电流。这就是为什么我们将其阳极连接到一个 1 k 欧姆电阻上,以限制到达 LED 的电流(及其电压)。如果连接到 Blue Pill 端口的任何设备消耗超过 6 mA 的电流,你将会损坏 Blue Pill 板。
在我们将所有东西连接到 Blue Pill 微控制器板端口之前,我们需要知道 I/O B12 端口消耗了多少安培,以查看它是否低于端口可以处理的最大安培数。LED 从 图 6.2 消耗的安培(电流)使用以下公式计算:

以下是对符号的描述:
- 
Vs = 3.3 V,这是在生成摩尔斯电码的点划线时由输出端口提供的供电电压。 
- 
Vf = 1.8 V,这是通过 1 k 欧姆电阻的导通电压(我们用万用表测量了它)。 
- 
R 是电阻值(1 k 欧姆)。 
因此, ,或 1.5 毫安,远低于每个 Blue Pill 端口可以处理的 6 mA 最大值,所以如果我们将其连接到产生 3.3 V 的端口,我们可以安全地使用 1 k 欧姆电阻为我们的超级明亮 LED 提供电源。
,或 1.5 毫安,远低于每个 Blue Pill 端口可以处理的 6 mA 最大值,所以如果我们将其连接到产生 3.3 V 的端口,我们可以安全地使用 1 k 欧姆电阻为我们的超级明亮 LED 提供电源。
重要的是要注意,电阻值和从端口到达电阻的电压将决定 LED 的亮度。我们可以使用具有较低值的电阻来使 LED 发光更亮。例如,我们可以使用 220 欧姆电阻。其降压电压为 1.9 V(我们用万用表测量了它)。让我们使用 Vs = 3.3 V 来计算其电流(安培):I=(Vs-Vf)/R=(3.3-1.9)/220=6 mA,这是 Blue Pill 端口可以处理的极限电流。如果我们使用 220 欧姆(或更低值)的电阻将其连接到超级明亮 LED,我们应该使用一个作为开关工作的晶体管来保护 Blue Pill 端口,避免直接从它那里吸取电流。图 6.3 展示了一个带有 2N2222 晶体管的 Fritzing 图,当它收到基极(晶体管引脚编号 2)的电压时,它会关闭 开关,即内部连接其集电极和发射极,从而将 LED 的阴极连接到地:

图 6.3 – 由 2N2222 晶体管开关的超级明亮 LED
如图 6.3所示,LED 连接到一个 220 欧姆电阻,该电阻连接到 Blue Pill 的 3.3 V 引脚。这个电阻从 Blue Pill 的 3.3 V 引脚吸取电流,该引脚可以处理高达 300 mA 的电流,而不是从处理高达 6 mA 的 B12 端口。因此,晶体管控制着流向电路另一部分的电流,切换 LED 的地线。每当晶体管在其基极接收到一定电压时,它就会饱和,并在其集电极和发射极引脚之间创建开/关的开关效果。我们需要在其基极连接一个电阻来降低其电压,从而正确地饱和它。在本章中,当施加 3.3 V 电压时,用于饱和晶体管的典型值是 1 k 欧姆。图 6.3中使用的低成本且流行的晶体管零件号为 2N2222(在 TO-92 封装中)。这个晶体管可以处理高达 600 mA 的电流,足以驱动我们的超亮 LED。以下是将图 6.3中显示的所有组件连接起来的步骤:
- 
将 Blue Pill 的 GND 引脚连接到面包板的上面一行。 
- 
将 1 k 欧姆电阻连接到 Blue Pill 的 B12 端口。 
- 
将 1 k 欧姆电阻连接到 2N2222 晶体管的基极(引脚编号2)。 
- 
将 2N2222 晶体管的发射极(引脚编号1)连接到地(面包板的上面一行)。 
- 
将 LED 的负极引脚(其最短的一端)连接到 2N2222 的集电极(引脚编号3)。 
- 
将 220 欧姆电阻连接到 LED 的正极引脚(其最长的一端)。 
- 
将 220 欧姆电阻连接到 Blue Pill 的 3V3(3.3)引脚。 
图 6.4显示了 2N2222 的引脚图:

图 6.4 – 2N2222 晶体管引脚编号
图 6.4显示了 2N2222 晶体管在 TO-92 封装中的样子,显示了其三个引脚。引脚 1 是其发射极,引脚 2 是其基极,引脚 3 是其集电极。晶体管上的 N 表示 2N2222 是 NPN 型晶体管,其内部配置由负-正-负层组成。那个大的 N 字母实际上并没有在商业晶体管上显示;它只出现在图 6.4中显示的 Fritzing 图上。相反,商业晶体管在其上显示它们的零件号。
图 6.5显示了晶体管的电子符号:

图 6.5 – 晶体管的电子图(NPN 型)
如图 6.5所示,符号显示了 2N2222 的引脚编号。这种引脚顺序在其他类型的晶体管中会改变。
图 6.6显示了所有连接方式:

图 6.6 – 将超亮 LED 连接到 2N2222 晶体管
图 6.6 展示了 2N2222 晶体管连接到 BluePill 的接地和 3.3(3.3 V)引脚。晶体管连接在超亮 LED 的左侧。下一节将介绍如何使用电阻和晶体管将超亮 LED 连接到 Curiosity Nano 板。
将超亮 LED 连接到 Curiosity Nano
本节解释了如何从 Curiosity Nano 板控制超亮 LED 来显示 SOS 摩尔斯电码信息。
图 6.7 是一个 Fritzing 图表,展示了如何将超亮 LED 连接到 Curiosity Nano:

图 6.7 – 超亮 LED 连接到 Curiosity Nano 的 I/O 端口
如 图 6.7 所示,我们使用 1 k 欧姆电阻连接超亮 LED,这与之前章节中解释的 Blue Pill 微控制器板的类似电路。以下是连接 图 6.7 中所示组件的步骤:
- 
将 Curiosity Nano 的 RD3 引脚连接到 1 k 欧姆电阻。 
- 
将电阻连接到超亮 LED 的阳极引脚(其最长的一端)。 
- 
将超亮 LED 的阴极引脚(其最短的一端)连接到 Curiosity Nano 的 GND 引脚。 
请注意,在理论上,Curiosity Nano 的每个 Nano I/O 端口可以处理高达 12.8 毫安(500 毫安/39 个端口),Curiosity Nano 的电压调节器(VBUS)可以处理高达 500 毫安。根据制造商的说法,这可能会因环境温度而略有变化。我们可以通过连接一个低值电阻来使 LED 发光更亮,或者我们可以将多个 LED 连接到一个端口上,但这将消耗更多电流,可能会损坏微控制器板。由于每个端口不能支持太多电流,我们需要连接一个晶体管来切换 LED 的接地。图 6.8 展示了所有组件的连接方式:

图 6.8 – 通过晶体管开关,连接到 Curiosity Nano 板的超亮 LED
如 图 6.8 所示,连接到 LED 阳极引脚的电阻连接到 Curiosity Nano 的 VTG 端口,该端口提供 3.3 V。以下是连接所有组件的步骤:
- 
将 Curiosity Nano、2N2222 晶体管和超亮 LED 插入无焊面包板。 
- 
将晶体管的引脚 1 连接到 Curiosity Nano 的接地(GND)引脚。 
- 
将 1 k 欧姆电阻连接到 Curiosity Nano 的 RD3 端口。 
- 
将 1 k 欧姆电阻连接到晶体管的引脚 2。 
- 
将超亮 LED 的阴极(其最短的引脚)连接到晶体管的引脚 3。 
- 
将 220 欧姆电阻连接到超亮 LED 的阳极(其最长的引脚)。 
- 
将 220 欧姆电阻连接到 Curiosity Nano 的 VTG 引脚。 
图 6.9 展示了所有组件的连接方式:

图 6.9 – Curiosity Nano 上连接的晶体管和 LED
如图 6.9所示,2N2222 晶体管正在切换超亮 LED 的地线。
下一个部分描述了如何在 Blue Pill 和 Curiosity Nano 板上编程 SOS 信号。
编码 SOS 莫尔斯代码信号
本节描述了用于在 Blue Pill 板上开关 LED 以显示 SOS 莫尔斯信号的代码,该代码运行在 Blue Pill 板上。以下代码显示了用于定义 SOS 莫尔斯代码消息并将其发送到板输出端口的主体函数。下一个代码段定义了必要的点、划线和空间值,以及端口标签:
int led=PB12;
int dot_duration=150; 
int dash_duration=dot_duration*3; 
int shortspace_duration=dot_duration; 
int space_duration=dot_duration*7;
下一个函数设置了输出端口(B12)以控制 LED 的开关:
void setup() {
       pinMode (led,OUTPUT);
} 
这些函数定义了 SOS 消息中使用的字母 S 和 O:
void S() {
          dot();
          dot();
          dot();
          shortspace();
}
void O() {
          dash();
          dash();
          dash();
          shortspace();
}
以下函数定义了字母之间和每个发送到输出端口的 SOS 消息之间的时间空间:
void shortspace() {
          delay(shortspace_duration);
} 
void space() {
          delay (space_duration);
} 
void dot() {
          digitalWrite(led,HIGH); 
          delay (dot_duration); 
          digitalWrite(led,LOW); 
          delay(dot_duration); 
}
void dash() {
          digitalWrite(led,HIGH); 
          delay(dash_duration); 
          digitalWrite(led,LOW); 
          delay(dash_duration); 
}
以下为main函数,它定义了 SOS 消息及其前导时间空间:
void loop() {
          S(); O(); S();  
          space();  
}
上述代码显示,Blue Pill 的B12端口被用作输出,用于开关超亮 LED。在此示例代码中,每个点持续时间为 150 毫秒(存储在dot_duration变量中),每个划线持续时间为每个点持续时间的三倍。每个字母之间有一个短的时间间隔,由shortspace()函数生成。此外,每个 SOS 单词之间也有一个时间间隔,由space()函数生成。SOS 电报中的字母 S 和 O 分别由S()和O()函数编码。
请记住,上传到 GitHub 仓库的代码中有许多注释,解释了前面代码中的大多数指令。
注意
您可以在 Arduino 微控制器板上运行前面的代码。只需将输出端口编号PB12更改为任何 Arduino 数字端口。例如,Arduino Uno 微控制器板有数字端口2到13。
以下部分展示了如何在 Curiosity Nano 板上编写 SOS 消息示例代码。
Curiosity Nano 的 SOS 消息代码
Curiosity Nano 微控制器板的 SOS 消息代码与在 Blue Pill 板上运行的代码类似。下一个代码段定义了必要的点、划线和空间值:
#include "mcc_generated_files/mcc.h"
const int dot_duration=150; 
const int dash_duration=dot_duration*3; 
const int shortspace_duration=150; 
const int space_duration=dot_duration*7;         
以下函数定义了字母之间和每个发送到输出端口的 SOS 消息之间的时间空间:
void shortspace() {
          __delay_ms(shortspace_duration);
} 
void space() {
         __delay_ms(space_duration);
} 
void dot() { 
          IO_RD3_SetHigh(); 
          __delay_ms(dot_duration); 
          IO_RD3_SetLow(); 
          __delay_ms(dot_duration); 
}        
void dash() { 
          IO_RD3_SetHigh();  
          __delay_ms(dash_duration); 
          IO_RD3_SetLow();
          __delay_ms(dash_duration); 
}
这些函数定义了 SOS 消息中使用的字母 S 和 O:
void S() { 
          dot();
          dot();
          dot();
          shortspace();
}
void O() { 
          dash();
          dash();
          dash();
          shortspace();
}
以下为main函数,它定义了 SOS 消息及其前导时间空间:
void main(void)
{
    SYSTEM_Initialize();
    IO_RD3_SetLow(); 
    while (1) 
    {
      S(); O(); S(); 
      space();
    }
}
如前述代码所示,RD3被用作驱动 2N2222 晶体管并因此开关 LED 的输出端口。
请记住,上传到 GitHub 仓库的代码中包含许多注释,解释了其主要部分。
下一个部分将描述如何测试超亮 LED 以查看其是否正常工作,以及如何测试 LED 显示的 SOS 信息的速度。
测试视觉警报
在本节中,我们将重点介绍如何测试超亮 LED,以及如何测试 LED 显示的 SOS 信息的速度。
你可以通过图 6.10来测试超亮 LED 是否与电源正常工作:

图 6.10 – 将超亮 LED 连接到电池组
以下是根据图 6.10连接所有部件的步骤:
- 
将超亮 LED 的阳极(其最长的腿)连接到一个 1 k 欧姆的电阻上。 
- 
将电阻连接到电池组的正极。电池组应提供大约 3 V 的电压(由两节 AA 电池提供),这对于测试我们的超亮 LED 来说已经足够了。 
- 
将电池组的负极连接到超亮 LED 的阴极(其最短的腿)。 
按照前面的步骤连接好所有部件后,LED 应该会发光。如果不会发光,请检查 LED 的正负极,以及电池是否有足够的电量。同时检查连接。如果 LED 不发光,则说明它无法工作,需要丢弃。
如果你将本章中使用的普通 LED 与我们使用的超亮 LED 的亮度进行比较,你会注意到普通 LED 发光更均匀,且更全向,而超亮 LED 的视角为 35 度,这意味着它从顶部发出的光会比从侧面发出的光更亮。试试看!从侧面非常短暂地观察两个 LED。记住,你不应该垂直(顶部视角)盯着超亮 LED 看,因为它可能会伤到你的眼睛。
你还可以测试 SOS 信息的速度。在前面代码中,将dot_duration变量原本声明的值对 Blue Pill 和 Curiosity Nano 都进行更改。较小的值会使 SOS 信息在超亮 LED 上发光更快。
摘要
在本章中,我们学习了什么是超亮 LED 以及如何将其连接到微控制器板上。我们还回顾了如何使用超亮 LED 作为强大的视觉警报,因为它比传统 LED 发光更亮。我们还总结了摩尔斯电码是什么,它在全球的使用情况,以及如何通过开启和关闭连接到 Blue Pill 和 Curiosity Nano 微控制器板上的超亮 LED 来显示 SOS 摩尔斯电码信息,这在视觉警报中用作求救信号。连接超亮 LED 并不简单,因为我们需要知道它将消耗多少电流,因为微控制器板的输出端口只能处理非常有限量的电流,大约是几毫安。本章对希望在其他电子项目中控制 LED 的读者有益。它还指出,仔细计算超亮 LED 所消耗的安培数,并使用正确的电阻或晶体管将其连接起来,以避免损坏微控制器板的重要性。
下一章将重点介绍如何使用连接到微控制器板的小型麦克风检测连续的两次拍手声以激活微控制器板上的一个过程。
进一步阅读
- 
Choudhuri, K. B. R. (2017). Learn Arduino Prototyping in 10 days. Birmingham, UK: Packt Publishing Ltd. 
- 
Gay, W. (2018). Beginning STM32: Developing with FreeRTOS, libopencm3, and GCC. New York, NY: Apress. 
- 
Horowitz, P., Hill, W. (2015). The Art of Electronics. [3rd ed.] Cambridge University Press: New York, NY. 
- 
Microchip (2019). PIC16F15376 Curiosity Nano 硬件用户指南. Microchip Technology, Inc. 可从: ww1.microchip.com/downloads/en/DeviceDoc/50002900B.pdf.
- 
2N2222 (2013). P2N2222A 晶体管数据表。Semiconductor Component Industries, LLC. 可从: 
- 
LED (n.d.) BL-BJ33V4V-1 超亮 LED 数据表。Bright LED Electronics Corp. 可从:http://www.maxim4u.com/download.php?id=1304920&pdfid=446ED6935162B290D3BC0AF8E0E068B8&file=0168\bl-bj33v4v-1_4138472.pdf. 
第七章:第七章:创建拍手开关
当涉及到家庭自动化时,最希望的功能之一通常是远程开关电子设备的能力(Colon,2020)。为了解决这个问题,在本章——涵盖本书的第五个项目——我们将学习如何构建一个无线电子遥控器,当检测到简单的麦克风(拍手开关)的两个连续拍手声音时,它会打开 LED。检测到的下一个两个连续拍手声音将关闭 LED。拥有一个拍手开关遥控器的重要性在于,电子设备可以从房间的任何地方打开或关闭。这种特性使得它对老年人或肢体残疾人特别感兴趣。
本章将涵盖以下主要主题:
- 
将麦克风连接到微控制器板端口 
- 
编写拍手开关草图 
- 
编写具有两个拍手声音的拍手开关代码 
- 
编写具有拍手间隔计时器的拍手开关代码 
- 
提高项目性能 
完成本章后,你将能够将所学知识应用于需要从模拟源读取数据、将数据转换为数字数据的项目,从而能够使用它来自动化流程。
技术要求
开发拍手开关所需硬件组件如下:
- 
一个面包板 
- 
一个驻极体麦克风 FC-04 模块 
- 
七根公对公跳线 
- 
一个 LED 
- 
一个 220 欧姆电阻 
- 
一个 5 伏电源 
这些组件非常常见,而且很容易获得。在软件方面,你需要 Arduino IDE 和本章的 GitHub 仓库:github.com/PacktPublishing/DIY-Microcontroller-Projects-for-Hobbyists/tree/master/Chapter07
本章的“代码在行动”视频可以在这里找到:bit.ly/3h2xjQu
为了提供电源,你可以使用适合面包板轨道的电源适配器(图 7.1),这些电源适配器或面包板电源在网店中很常见,可以跳线提供 3.3 或 5 伏,并包含一个开关按钮:

图 7.1 – 电源
此外,你可以使用 9 伏电池。使用这些电池是最常见的选项之一,因为 9 伏电压适合为带有微控制器如 Blue Pill STM32 的项目供电。
将麦克风连接到微控制器板端口
在本节中,我们将学习如何使用STM32 Blue Pill和麦克风 FC-04 模块构建拍手开关所需的硬件组件。
然而,在我们开始连接组件之前,我们必须了解麦克风的基本知识。
理解驻极体麦克风模块
拍手开关使用麦克风来感知环境,同时等待触发动作的事件。在本节中,我们将了解如何将此功能应用于项目中。
我们将使用一个通用的麦克风模块,它是一个带有驻极体电容麦克风的扩展板(如图图 7.2所示):

图 7.2 – 驻极体麦克风板
电容式麦克风由一个放置在板上的振膜膜片组成,两者都是导体。电容器本质上是由导体和它们之间的绝缘体形成的。因此,当这两个导体之间的距离较小时,可以获得更高的电容。
重要提示
电容是电子组件收集和存储电能的能力或容量。
麦克风接收声音,使振膜振动。振动改变导体之间的距离,并改变其电容以产生电压电荷,这反过来又需要大量的电压来维持,使得传统的麦克风在降低微控制器板(如 Blue Pill 或 Curiosity Nano)的功耗方面无效。为了解决大量功耗的问题,开发了驻极体麦克风。驻极体麦克风使用在制造过程中充电的独特极化材料,因此不需要外部电压(Fox, 2020)。在了解麦克风基础知识后,我们现在将进入将麦克风连接到微控制器板的步骤。
连接组件
现在我们将连接电子组件到面包板,进行布线,最后将所有东西连接到 STM32 Blue Pill:
- 
在连接组件时,将驻极体麦克风、电阻、LED 和 STM32 Blue Pill 放置在面包板上,留有足够的空间添加布线层,如图图 7.3所示。本项目的硬件连接非常简单: ![图 7.3 – 面包板上的组件]() 图 7.3 – 面包板上的组件 
- 
接下来,为了使用外部电源启动拍手开关,将 5 伏引脚连接到面包板上的红色轨道,并将地线引脚连接到蓝色轨道,如图所示(图 7.4): ![图 7.4 – 连接到电源]() 图 7.4 – 连接到电源 
- 
将传感器的地(GND)引脚连接到面包板的蓝色轨道(蓝色线条旁边的孔)或 SMT32 Blue Pill 的GND端子。接下来,你需要将电压(VCC)引脚连接到面包板的红色轨道(红色线条旁边的孔),或 Blue Pill 的5V总线,如图所示。传感器产生模拟输出,因此必须连接到 Blue Pill 卡的模拟输入,并将声音传感器的输出引脚连接到 Blue Pill 的A0引脚,如图图 7.5所示: ![Figure 7.5 – 麦克风连接]() 图 7.5 – 麦克风连接 这样,就可以实现从传感器来的模拟信号的采集,微控制器将其转换为数字信号。 
- 
要配置 LED,将 LED 的阴极连接到 Blue Pill 的GND引脚,将阳极连接到 Blue Pill 的13号引脚。电阻必须位于这两个引脚之间,因为这是一个数字输出引脚(见图 7.6): 

图 7.6 – LED 设置
最后,你需要使用电池或连接到计算机 USB 端口的 ST-LINK 等电源为板子供电。ST-LINK 还将用于将脚本上传到微控制器板。图 7.7总结了所有硬件连接:

图 7.7 – 麦克风传感器连接电路
上一图显示了 STM32 Blue Pill 和电子组件之间的所有连接。此图总结了我们刚刚完成的连接步骤。
图 7.8展示了本项目的电路图:

图 7.8 – 麦克风传感器连接的电路图
电路图显示了整个项目的电气图。图 7.9展示了我们在自己动手做(DIY)的拍手开关中所有部件的连接方式:

图 7.9 – 拍手开关设备
图 7.9显示了所有完成的硬件连接将如何看起来。
现在,让我们进入下一节,该节将详细说明 C 代码的必要部分,以完成拍手开关的功能。
编写你的拍手开关草图
在本节中,我们将开发程序以从麦克风识别拍手声。这个声音将使 LED 开关。让我们开始吧:
- 
作为第一步,我们需要定义 Blue Pill 卡片引脚的哪些引脚将被用于输入和输出。然后,我们需要为麦克风分配声音阈值水平以检测声音;这个值在 0-1023范围内。我们使用300这个值,所以麦克风捕捉到的声音足够大,可以识别拍手声而不是任何背景噪音(我们将在改进项目性能部分展示如何选择合适的阈值)。如以下代码片段所示,模拟读取引脚将是 0(标记为PC13),使用const关键字来分配其值。另一种方法是使用预处理宏#define,如下面的代码片段所示:#define MicAnalogPin 0 #define LedDigitalPin PC13 #define ClapThreshold 300两者之间的区别在于,使用 #define时,编译器会在编译前替换所有出现的位置,以避免在微控制器中使用内存,并且始终具有全局作用域。相比之下,const是一个存储在微控制器内存中的常量值变量,具有有限的作用域。基于最佳编程实践,推荐使用常量变量来确保类型安全,因为 #define指令会替换宏值而不考虑作用域,这可能导致数据类型问题。相比之下,const将始终是其声明中定义的相同数据类型。
- 
接下来,在 setup()部分,我们需要启动串行数据传输并分配传输速度(以9600bps 作为标准值):void setup() { Serial.begin(9600); }
- 
我们还需要配置微控制器将使用哪些引脚作为输入和输出。这些值之前已在常量中定义。在以下代码中,赋值是针对微控制器卡的: void setup() { Serial.begin(9600); pinMode(LedDigitalPin, OUTPUT); pinMode(MicAnalogPin, INPUT); }
- 
现在是草图中的 loop()部分。它包含两个主要部分:读取模拟输入引脚和检测拍手声以点亮 LED。
- 
analogRead()函数读取先前定义的输入引脚的值:void loop() { int SoundValue = analogRead(MicAnalogPin); Serial.print("Sound value: "); Serial.println(SoundValue); }
- 
现在我们有了麦克风中的 SoundValue变量中的读数值;下一步将是将其值与定义的阈值进行比较。如果麦克风输入的声音高于阈值,LED 灯将亮起,并且将发生 1 秒的暂停,在这段时间内你可以观察到 LED 灯是亮着的。如果检测到的声音不超过阈值值,LED 灯将被指令保持关闭。在两种情况下,串行控制台将显示正在运行的脚本的状态:void loop() { int SoundValue = analogRead(MicAnalogPin); Serial.print("Sound value: "); Serial.println(SoundValue); if (SoundValue > ClapThreshold) { Serial.println("A clap was detected"); digitalWrite(LedDigitalPin, HIGH); delay(1000); } else { Serial.println("No clap detected"); digitalWrite(LedDigitalPin, LOW); } }
现在我们有了第一个草图检测拍手声并点亮 LED 的完整代码。接下来,我们可以看到完整的草图,该草图位于 GitHub 仓库的Chapter7/clap_switch文件夹中。
现在草图已经完成,你可以将其上传到 Blue Pill 板。为了测试我们的项目是否工作,只需拍手看看 LED 灯是如何亮起的。别忘了面包板必须供电,无论是通过电池还是连接到电脑。
到目前为止,我们已经学习了如何使用微控制器从麦克风读取模拟值(声音)。在主循环期间,设备持续监听麦克风以检测是否有任何声音(我们将假设检测到的声音是拍手声)比定义的阈值更大;如果是这样,LED 灯就会亮起。如果不是,微控制器将保持 LED 灯关闭。
接下来,我们将修改草图,让我们的拍手开关在 LED 灯开启之前等待两次拍手。为了更好的组织,我们将创建代码的副本以与原始草图进行比较,或者在我们遇到新代码问题时需要回滚到上一个版本。
编写带有两个拍手声的拍手开关
在本节中,我们将修改我们的程序以从麦克风识别两个拍手声。这将使我们能够在激活遥控器之前更加精确:
- 
一旦我们定义了常量,我们定义两个变量:整数类型,用于计数拍手的次数,布尔类型,用于知道 LED 的状态(开启或关闭)。为了更好的阅读,我们已突出显示草图中原变量声明的更改: const int MicAnalogPin = 0; const int LedDigitalPin = PC13; const int ClapThreshold = 300; 0, and the LED status to false (off), which means that true will be on.
- 
我们将保持 setup()部分不变,继续到loop()部分,那里有最重要的逻辑更改。我们将修改位于验证麦克风记录的声音是否比定义的阈值更大的条件语句中的指令:void loop() { int SoundValue = analogRead(MicAnalogPin); if (SoundValue > ClapThreshold) { else sentence. Also, the instruction to turn on the LED has been removed. If a clap is detected, the clap counter will be incremented by 1 and will wait for a half-second pause before the Blue Pill re-senses the microphone.
- 
我们需要知道拍手的总次数是否为 2,因此我们必须在我们的草图中编写另一个条件,询问ClapNumber变量是否已经记录了两次拍手;如果是这样,它必须开启 LED:void loop() { int SoundValue = analogRead(MicAnalogPin); if (SoundValue > ClapThreshold) { ClapNumber++; delay(500); } if (ClapNumber == 2) { digitalWrite(LedDigitalPin, HIGH); } }现在我们已经准备好在我们的设备上测试新的草图,编译它,并加载它。我们可以通过两次连续的拍手来测试代码,两次拍手之间有一个短暂的停顿(记住我们编程的延迟)。 
- 
如你所见,LED 灯亮了,但它没有熄灭。为了再次熄灭 LED,我们将编程功能,当用户再拍两次手时熄灭 LED。为此,我们需要另一个我们定义的变量: LedState。在其中,我们将存储 LED 是开启还是关闭的状态:void loop() { int SoundValue = analogRead(MicAnalogPin); if (SoundValue > ClapThreshold) { ClapNumber++; delay(500); } if (ClapNumber == 2) { if (LedState) { digitalWrite(LedDigitalPin, HIGH); } else { digitalWrite(LedDigitalPin, LOW); } ClapNumber = 0; LedState = !LedState; } }
当微控制器检测到连续两次掌声时,它将首先使用下一个条件语句if (LedState)检查存储 LED 状态的变量的状态。由于它是一个布尔类型变量,可以直接将其分析到if语句中,无需额外的运算符。如果变量具有TRUE值,它将触发if块,如果它是FALSE,则执行else块。因此,前面的代码在变量为TRUE时打开 LED,在变量为FALSE时关闭它。最后,在检测到两次掌声的同一条件下,ClapNumber变量被重置为0次掌声以重新启动计数器并等待两次新的掌声。LedState变量的值是通过使用否定运算符来改变的,反转布尔变量的值;如果状态是ON,命令将把它变成OFF,反之亦然。
通过这个先前的步骤,我们检测两次连续掌声并打开 LED 的项目就完成了。完整的草图如下所示,也位于 GitHub 仓库的Chapter7/double_clap_switch文件夹中。有了检测两次连续掌声的完整草图,我们就可以测试其新的功能。一开始,LED 将是关闭的。当你两次掌声,它们之间有短暂的停顿时,它会亮起;再次连续拍两次手,它会关闭。
最后,我们将向我们的草图添加一个计时器,以指示我们的掌声开关在打开 LED 之前只等待 30 秒。与这个部分相同,我们将创建代码的副本并使用新的代码进行工作。
编写带有掌声之间计时器的掌声开关代码
现在,我们将添加一个计时器来限制第一次和第二次掌声之间的等待时间框架:
- 
定义两个新的变量,都是 unsigned long类型,用于存储每次掌声的时间。对之前草图的更改如下所示:const int MicAnalogPin = 0; const int LedDigitalPin = PC13; const int ClapThreshold = 300; int ClapNumber = 0; bool LedState = false; unsigned long FirstClapEvent = 0; unsigned long SecondClapEvent = 0;这两个突出显示的变量将存储检测到掌声时的毫秒数:一个用于第一次,另一个用于第二次。 
- 
setup()部分保持不变,我们将继续到loop()部分来介绍计时器的更改。我们将在条件语句内添加一个条件来检测掌声:void loop() { int SoundValue = analogRead(MicAnalogPin); if (SoundValue > ClapThreshold) { ClapNumber++ delay(500); FirstClapEvent variable value to the millis() function. This function returns the milliseconds since the STM32 Blue Pill executed the sketch. Otherwise, the variable value remains the same.
- 
在我们识别出两次掌声后,我们将 millis()赋值给SecondClapEvent变量。现在,我们需要在我们的脚本中编写另一个条件来询问两次掌声之间的时间是否少于 30 秒:void loop() { int SoundValue = analogRead(MicAnalogPin); if (SoundValue > ClapThreshold) { ClapNumber++; delay(500); FirstClapEvent = (ClapNumber == 1) ? millis() : FirstClapEvent; } if (ClapNumber == 2) { SecondClapEvent = millis(); if (SecondClapEvent - FirstClapEvent < 30000) { if (LedState) { digitalWrite(LedDigitalPin, HIGH); } else { digitalWrite(LedDigitalPin, LOW); } ClapNumber = 0; LedState = !LedState; FirstClapEvent = 0; SecondClapEvent = 0; } } }
现在,我们可以通过两次连续的掌声来测试代码,它们之间有 30 秒的时间框架。完整的草图如下所示,也位于 GitHub 仓库的Chapter7/double_clap_switch_timer文件夹中:
现在我们已经完成了具有所有功能的草图,只需加载并执行草图以测试和验证其功能。
在下一节中,我们将学习如何测试系统并提供一个有用的技巧来提高处理模拟数据的工作效率。
提高项目性能
我之前提到过,我们将讨论阈值值。一般来说,具有模拟读取的项目将阈值值设置为 200,但如您所记得,我们正在使用 300 的值以确保我们读取的是拍手声,而不是背景噪音。
如果您想更精确地知道您拍手声的值,那么您可以使用 IDE 提供的示例脚本。要访问此草图,我们必须转到 文件 菜单,然后转到 示例,并选择 基础。在该部分中,我们将找到 AnalogReadSerial 草图,如图 7.10 所示:

图 7.10 – 模拟串行读取示例
选择该菜单选项将打开 AnalogReadSerial.ino 草图:
void setup() {
  Serial.begin(9600);
}
void loop() {
  int sensorValue = analogRead(0);
  Serial.println(sensorValue);
  delay(1);
}
之前的代码引入了一个我们在此项目中尚未使用的指令,即 Serial.println()。此代码在名为串行端口的控制台中显示数据,以便人们可以理解,并且它包括一个换行符。
通过加载和执行脚本,我们可以打开 Arduino IDE 的串行监视器,以查看麦克风生成的值(在 0-1023 范围内)。您只需尝试一些测试拍手声,以找出您拍手声的值,并将其用作更个性化的阈值。
之前的代码块检测麦克风以检测两个拍手声并打开或关闭一个 LED。系统在每次拍手声之间等待 30 秒的时间框架,然后打开或关闭 LED。
恭喜,您现在已经构建了一个无线电子遥控器!
摘要
那么,我们在本项目中学到了什么?首先,我们学习了如何将麦克风模块、LED 和电阻连接到由 STM32 微控制器控制的 STM32 Blue Pill 微控制器板。然后,我们编写了一段代码来读取模拟值并在我们的微控制器中分析它。随后,我们发送了一个数字信号,根据我们 STM32 中的嵌入式规则打开或关闭 LED。最后,我们物理测试了该设备,以了解其真实世界的操作。
此项目使我们能够开始创建一个遥控器来自动化家用电器,并根据我们的需求使用它们。例如,您可以添加一个继电器模块并将其连接到灯具,这样您就可以在您所在的地方舒适地打开和关闭灯具,而无需触及灯具开关。
在下一章中,我们将学习如何使用串行监视器功能来分析我们的草图在运行时生成的输出。我们将通过使用 STM32 微控制器构建一个气体传感器项目来实现这一点。
进一步阅读
- Colon, A. (2020). 2020 年最佳智能家居设备. PCMAG: www.pcmag.com/news/the-best-smart-home-devices-for-2020
)
- Fox, A. (2020). 《电容器麦克风完全指南》. 我的新麦克风:mynewmicrophone.com/the-complete-guide-to-electret-condenser-microphones/
)
第八章:第八章:气体传感器
良好的室内空气质量对于保证健康的环境至关重要(Marques 和 Pitarma,2017)。MQ-2 气体传感器可以是一种测量室内空气质量参数或作为早期火灾探测系统的极好方式。在本章中,你将学习如何构建一个用于检测环境中气体的实用系统(我们将其称为气体传感器)并将 MQ-2 气体传感器连接到蓝色药丸微控制器卡。
本章将涵盖以下主要内容:
- 
介绍 MQ-2 气体传感器 
- 
将气体传感器连接到 STM32 微控制器板 
- 
编写程序读取传感器板上的气体浓度 
- 
测试系统 
在本章结束时,你将了解 MQ-2 气体传感器的操作,并能够正确将其连接到 STM32 微控制器卡并查看从传感器获得的数据。你将能够在需要使用传感器检测易燃气体或酒精或测量空气质量的项目中应用你所学的知识。
技术要求
开发气体传感器所需的硬件组件如下:
- 
一个无焊面包板 
- 
一块蓝色药丸板 
- 
ST-Link/V2 
- 
一个 MQ-2 分线模块 
- 
七根公对公跳线 
- 
一个 8x8 LED 矩阵 
- 
一块 7219 分线板 
- 
一个 5V 电源 
这些组件很常见,很容易就能买到。在软件方面,你需要 Arduino IDE 和本章的 GitHub 仓库:github.com/PacktPublishing/DIY-Microcontroller-Projects-for-Hobbyists/tree/master/Chapter08
本章的“代码在行动”视频可以在此找到:bit.ly/2UpGDGs
让我们先描述一下 MQ-2 气体传感器的特性。
介绍 MQ-2 气体传感器
在本节中,我们将了解构建我们的气体传感器的主要硬件组件的详细信息:MQ-2 传感器。该传感器推荐用于检测 LPG、丙烷、酒精和烟雾,主要浓度在 300 到 10,000 百万分之一(ppm)之间。因此,我们可以称它为检测烟雾和易燃气体的传感器。
浓度指的是空气中的气体量,以 ppm(百万分之一)为单位。也就是说,如果你有 2,000 ppm 的 LPG,这意味着在一百万个气体分子中,只有 2,000 ppm 是 LPG,其余 998,000 ppm 是其他气体。
MQ-2 气体传感器是一种电化学传感器,当暴露于某些气体时,其电阻会发生变化。它包括一个小加热器,用于提高电路的内部温度,这为检测物质提供了必要的条件。通过引脚上的 5V 连接,传感器保持足够的热量以正确工作。
重要提示
传感器可能会非常热,因此在操作过程中不应触摸。
MQ 系列气体传感器是模拟的,这使得它们很容易与任何微控制器卡(如 STM32 Blue Pill)实现。在扩展模块中找到 MQ-2 传感器非常常见,这有助于连接和使用,因为它只需要供电并开始读取其数据。这些扩展模块有一个 数字输出(DO),我们可以将其解释为传感器检测到的任何气体的存在(低电平)或不存在(高电平)。图 8.1 显示了带有扩展板的 MQ-2 气体传感器:

图 8.1 – 带有扩展板的 MQ-2 气体传感器
在下一节中,我们将学习如何通过数字和模拟方式将 MQ-2 传感器连接到我们的无焊面包板,以获取其读数数据。
将气体传感器连接到 STM32 微控制器板
在本节中,我们将构建一个使用 STM32 Blue Pill 微控制器板和气体传感器模块的气体传感器设备,该设备使用 技术要求 部分中列出的硬件组件。气体传感器扩展板通过四个引脚连接到 STM32 Blue Pill:
- 
模拟输出(AO):此引脚生成模拟信号,必须连接到微控制器的模拟输入。 
- 
DO:此引脚生成数字信号,必须连接到微控制器的数字输入。 
- 
VCC:为传感器供电的引脚(5 V)。 
- 
GND:接地连接。 
对于这个项目,您将学习如何将 MQ-2 模块与 STM32 板进行接口连接,以数字和模拟方式获取数据。让我们从数字选项开始。
数字读取接口
现在我们将电子元件连接到面包板上,进行布线,并将所有东西连接到 STM32 Blue Pill 上:
- 
在连接元件时,将传感器模块和 STM32 Blue Pill 放在足够空间添加布线层的无焊面包板上,如图 图 8.2 所示。本项目的硬件连接非常简单: ![图 8.2 – 面包板上的元件]() 图 8.2 – 面包板上的元件 
- 
接下来,使用外部电源为 Blue Pill 提供电力。将 5 V 引脚连接到面包板上的红色轨道,并将一个 G 引脚连接到蓝色轨道,如图 图 8.3 所示: ![图 8.3 – 与电源的连接]() 图 8.3 – 与电源的连接 
- 
将 MQ-2 传感器的 GND 引脚连接到 STM32 Blue Pill 的 GND 端口。接下来,您需要将 VCC 引脚连接到 Blue Pill 的 5 V 总线,如图所示。在本节中,我们将读取 DO,因此它必须连接到 Blue Pill 卡上的一个数字输入。将 MQ-2 传感器的 DO 连接到 Blue Pill 的 B12 引脚,如图 图 8.4 所示: 

图 8.4 – 用于数字读取的 MQ-2 传感器连接
最后,你需要使用电池等电源来为电路板供电。图 8.5总结了所有硬件连接:

图 8.5 – 用于数字读取的 MQ-2 传感器连接电路
前面的图示显示了 STM32 Blue Pill 和电子部件之间的所有连接。图 8.6展示了本项目的原理图:

图 8.6 – 用于数字读取的 MQ-2 传感器连接图
图 8.7展示了我们的 DIY 气体传感器设备中所有部件的连接方式:

图 8.7 – 数字读取的气体传感器设备
在本小节中,我们学习了如何连接电子设备以创建具有数字读取功能的气体传感器设备。接下来,我们将看到如何将其连接为模拟读取。
模拟读取接口
只需要一步就可以将我们的硬件设备从读取传感器的数字数据改为模拟读取:
- 将跳线从 DO 引脚断开,并将其连接到 MQ-2 传感器的 AO 引脚。此外,不要连接到 B12 引脚,而是连接到 Blue Pill 的 AO 引脚,如图图 8.8所示:

图 8.8 – 用于模拟读取的 MQ-2 传感器连接
图 8.9总结了所有硬件连接:

图 8.9 – 用于模拟读取的 MQ-2 传感器连接电路
图 8.10展示了模拟读取设备的原理图:

图 8.10 – 用于模拟读取的 MQ-2 传感器连接图
让我们回顾一下。在本节中,我们学习了如何连接硬件组件以创建我们的气体传感器设备。你学习了如何将 MQ-2 传感器连接到 STM32 Blue Pill 微控制器板,以两种方式获取其数据:数字形式和模拟形式。
在下一节中,我们将创建 C 代码,从 STM32 Blue Pill 微控制器获取 MQ-2 传感器数据。
编写读取传感器板上气体浓度的程序
在本节中,我们将学习如何编写程序从我们的气体传感器读取数据,并在环境中检测到气体时在串行监视器上显示它。
如前所述,我们首先学习如何以数字和模拟形式读取数据。
数字读取的编码
让我们开始编写代码:
- 
定义 STM32 Blue Pill 微控制器哪个引脚将用作从传感器读取数据的输入。以下是展示如何做到这一点的代码: const int sensorPin = PB12; boolean sensorValue = true;选定的引脚是 PB12(在 Blue Pill 板上标记为 B12)。声明并初始化了一个布尔变量为true。这个变量将用于存储传感器数据。
- 
接下来,在 setup()部分,我们需要启动串行数据传输并分配传输速度(以9600bps 作为标准值):void setup() { Serial.begin(9600); }
- 
向微控制器指示分配给 PB12的引脚类型:void setup() { Serial.begin(9600); pinMode(sensorPin, INPUT); }
- 
现在是 loop()部分,其余的代码。前几行读取输入引脚的数据传感器,并在串行控制台中显示其值:void loop() { sensorValue = digitalRead(sensorPin); Serial.print("Sensor value: "); Serial.println(sensorValue); if (sensorValue) { Serial.println("No gas present"); delay(1000); } else { Serial.println("Gas presence detected"); delay(1000); } }从传感器读取的值可以是 TRUE或FALSE;记住,我们正在读取一个数字值。如果值为TRUE,则环境中没有气体存在;否则,检测到气体。这种行为发生是因为 MQ-2 传感器的输出是取反的;在此状态下,模块的 LED 也必须点亮,因为它是内部带有 5 V 电阻的。当没有气体存在时,LED 熄灭,输出是逻辑 1(5 V)。数字读取的代码现在已完成。您可以在 GitHub 仓库的 Chapter8/gas_digital文件夹中找到完整的草图。
现在我们有了读取 MQ-2 传感器 DO 的完整代码。您可以将其上传到 STM32 微控制器。现在您可以在串行监控器中看到如图图 8.11所示的传感器读数。最正常的情况是读数指示没有气体存在:

图 8.11 – 无气体存在的传感器 DO 的串行监控读取
现在,非常注意防火安全,将点燃的火柴拿到传感器旁,并在靠近传感器时吹灭以产生烟雾。当烟雾浸入传感器时,串行监控器会立即改变(如图图 8.12所示):

图 8.12 – 有气体存在的传感器 DO 的串行监控读取
如我们所见,它就像读取任何数字输入一样。传感器的灵敏度是通过断出模块中包含的可变电阻来配置的。向右转动使其更加敏感,并且需要更少的气体存在来激活输出。同样,如果我们向左转动,则需要更多的气体存在来激活输出。
到目前为止,我们已经学会了如何以数字形式读取气体传感器。在接下来的小节中,我们将从 AO 获取其读数。
编码模拟读取
当使用 AO 时,可以获得不同水平的气体存在。该模块有一个加热室,气体进入其中。这种气体将继续被检测,直到室空。传感器的电压输出将与室内的气体浓度成正比。
简而言之,气体浓度越高,电压输出越高,气体浓度越低,电压输出越低。
让我们从代码开始:
- 
复制 Chapter8/gas_digital项目并重命名为Chapter8/gas_analog。请记住重命名文件夹和 INO 文件。
- 
将传感器引脚改为 0(在 Blue Pill 上标记为 A0),移除布尔变量,并为传感器读取分配一个阈值级别。我们将使用800的值,以确保传感器在其室内有气体:const int sensorPin = 0; const int gasThreshold = 800;
- 
保持 setup()不做修改:void setup() { Serial.begin(9600); pinMode(sensorPin, INPUT); }
- 
loop()中的代码将使用相同的逻辑,但有一些变化:void loop() { int sensorValue = analogRead(sensorPin); Serial.print("Sensor value: "); Serial.println(sensorValue); if (sensorValue > gasThreshold) { Serial.println("Gas presence detected"); } else { Serial.println("No gas present"); } delay(1000); }
- 
要读取传感器值,我们使用 analogRead()函数。读取的值存储在sensorValue变量中;下一步将是将其值与阈值进行比较。如果传感器值高于阈值,这意味着检测到了气体。
现在我们已经完成了草图,请将其上传到 Blue Pill 板上。为了测试我们的项目是否工作,就像数字读取版本一样,只需将点燃的火柴拿到传感器旁,当靠近传感器时吹灭以产生烟雾。请务必非常小心地注意防火安全。图 8.13 展示了当开始检测到烟雾时的串行监视器:

图 8.13 – 有气体存在的传感器 AO 串行监视器读取
这一部分帮助我们学习如何用 C 语言编写代码来读取 MQ-2 传感器的数据,以了解环境中是否有气体或烟雾浓度。此外,还掌握了读取模拟和数字形式的传感器值的技术。在下一节中,我们将创建一种简单的方法,直接在硬件设备上知道是否有气体或烟雾浓度,而无需在计算机上的串行监视器中查看。
系统测试
在本章的最后部分,我们将连接一个 8x8 LED 矩阵,如果传感器检测到环境中存在气体,则显示警报。
LED 矩阵是一组按行和列分组排列的 LED。通过打开这些 LED,可以创建图形或文本,这些在广告牌和交通标志中得到了广泛应用。
有一种用于小型项目的电子组件,称为 8x8 LED 矩阵。它由 64 个 LED 组成,排列成八行八列(见 图 8.14):

图 8.14 – 8x8 LED 矩阵
如前图所示,8x8 LED 矩阵有控制行和列的引脚,因此不可能独立控制每个 LED。
这种限制意味着必须使用 16 个数字信号并持续刷新图像或文本。因此,已经创建了集成的 MAX7219 和 MAX7221 电路来简化这项任务;这些电路几乎相同且可使用相同的代码互换。
除了这些集成电路之外,还创建了集成 8x8 LED 矩阵和 MAX7219 电路的开关模块,此外还提供了输出连接器,可以将多个模块级联。图 8.15 展示了 8x8 LED 矩阵开关模块:

图 8.15 – LED 矩阵 8x8 开关模块
模块的输入引脚如下:
- 
VCC: 模块电源 
- 
GND: 地线连接 
- 
DIN: 串行数据输入 
- 
CS: 芯片选择输入 
- 
CLK: 串行时钟输入 
输出引脚几乎相同,只是 DIN 被替换为 DOUT,这将允许与其他模块级联,但我们在本章中不会学习这个功能。
图 8.16 展示了如何将 MAX7219 8x8 LED 矩阵模块连接到我们的 STM32 Blue Pill 板上:

图 8.16 – LED 矩阵 8x8 开关模块与 STM32 Blue Pill 的接口
现在是时候创建代码来在我们的 LED 矩阵上显示警报了。我们将更新 Chapter8/gas_digital 草图。让我们开始编码!
- 
为了使过程更容易,我们将使用名为 LedControlMS的库,该库简化了 8x8 LED 矩阵模块的使用。要开始安装,请从我们的 GitHub 下载库:Chapter8/library。
- 
安装时,请转到草图菜单 | 包含库 | 添加 .ZIP 库…(见 图 8.17)并选择下载的文件,然后它就准备好使用了: ![图 8.17 – 添加 LedControlMS 库]() 图 8.17 – 添加 LedControlMS 库 
- 
在我们的脚本中,我们将添加库: #include "LedControlMS.h";
- 
我们必须指出我们正在使用的显示模块数量;在我们的情况下,是一个。我们将初始化库,指出模块将连接到 STM32 Blue Pill 板上的引脚,以及带有模块数量的变量: const int numDisplays = 1; const int sensorPin = PB12; boolean sensorValue = true; LedControl lc = LedControl(7, 8, 5, numDisplays);
- 
默认情况下,矩阵处于省电模式,因此需要唤醒它。如果有多个模块,则需要一个循环,但在这个例子中只有一个,所以我们直接操作: void setup() { Serial.begin(9600); pinMode(sensorPin, INPUT); 0 in the code refers to the first array of a possible set of interconnected arrays.
- 
最后,我们写入我们想要显示的字符。我们将使用 writeString()函数在else语句中指示 LED 矩阵中有气体;我们将显示字母A来表示警报:void loop() { sensorValue = digitalRead(sensorPin); Serial.print("Sensor value: "); Serial.println(sensorValue); if (sensorValue) { Serial.println("No gas present"); delay(1000); } else { Serial.println("Gas presence detected"); lc.writeString(0, "A"); delay(1000); } }我们准备将我们的脚本上传到微控制器并测试系统是否正常工作。与上一节类似,为了测试它,将点燃的火柴拿到传感器旁,当接近传感器时吹灭以产生烟雾。再次提醒,不要忘记非常注意消防安全。图 8.18显示了完整的气体感应装置,包括传感器和连接到 STM32 微控制器的 LED 矩阵模块: 

图 8.18 – 气体感应装置
到目前为止,在本节中,我们学习了如何处理 8x8 LED 矩阵并使用它来在我们的气体感应装置上设置视觉警报。
在本章中,我们学习了如何读取代码程序以数字和模拟方式读取气体传感器。这使我们能够加强我们对不同形式输出中传感器数据采集的知识。这些知识将使我们能够创建更复杂的嵌入式系统,例如使用环境中的传感器自动化家庭。
摘要
在本章中,我们学到了很多!首先,我们学习了如何将 MQ-2 气体传感器连接到 STM32 Blue Pill 微控制器板,无论是通过数字方式还是通过 AO 读取。然后,我们编写了两段代码来读取数字和模拟传感器值。最后,我们测试了设备以了解其操作,在串行控制台中显示传感器数据。
这个项目让我们掌握了读取不同类型传感器数据并根据自己的需求使用这些知识的技能。例如,你可以在房间里显示一些传感器来实时监控环境。
在下一章中,我们将进入所谓的物联网的迷人世界。通过我们将获得的知识,我们将创建连接到互联网并远程访问我们信息的项目。
进一步阅读
Marques G. & Pitarma R. (2017). 使用物联网监测室内居住环境中的健康因素. 见:Rocha Á., Correia A., Adeli H., Reis L., & Costanzo S. (eds) Recent Advances in Information Systems and Technologies. WorldCIST 2017. Advances in Intelligent Systems and Computing, vol. 570. Springer, Cham. doi.org/10.1007/978-3-319-56538-5_79
第九章:第九章:物联网温度记录系统
近年来,互联网的使用量有所增加。这种相同的增加使得互联网得以进化。现在我们谈论的是连接到这个网络的事物;原本未设计为具有连接性的日常使用设备。这种进化创造了物联网(IoT)的概念,正如摩根在《福布斯》杂志(2014 年)中定义的,“将常用设备连接到互联网,以自动完成任务。”
物联网几乎存在于日常生活的所有领域,从健康到教育,分别被称为物联网医疗(IoMT)和物联网教育(IoET)。
在本章中,您将了解到如何使用ESP8266 Wi-Fi 模块为 STM32 Blue Pill 板创建一个温度记录应用,从而进入物联网应用的创造世界。有了这些知识,您将能够构建可以连接到互联网并从传感器等来源远程展示数据的工程项目。
在本章中,我们将涵盖以下主要主题:
- 
将温度传感器连接到 Blue Pill 板 
- 
编写温度读取系统代码 
- 
学习连接 ESP8266 模块 
- 
编写程序将感应到的温度发送到互联网 
- 
将 STM32 Blue Pill 板连接到互联网 
到本章结束时,您将能够理解创建物联网应用中最受欢迎的 Wi-Fi 模块之一 ESP8266 的操作,并且熟悉如何将 STM32 微控制器板连接到互联网并发送从温度传感器获得的数据。
技术要求
开发温度记录系统所需的硬件组件如下:
- 
1 个无焊面包板。 
- 
1 块 Blue Pill STM32 微控制器板。 
- 
1 个 ST-Link/V2 电子接口,用于将编译后的代码上传到 Blue Pill 板。请注意,ST-Link/V2 需要 4 根公对公跳线。 
- 
1 个 DS18B20 温度传感器模块。 
- 
1 个 ESP8266 Wi-Fi 模块。 
- 
1 块 FTDI 适配器板。 
- 
1 个 LED。 
- 
1 个 220 欧姆电阻。 
- 
7 根公对公跳线。 
- 
5 根公对公跳线。 
- 
1 个 5V 电源。 
如往常一样,这些组件非常常见,获取它们不会有任何问题。在软件方面,您将需要 Arduino IDE 和本章的 GitHub 仓库:github.com/PacktPublishing/DIY-Microcontroller-Projects-for-Hobbyists/tree/master/Chapter09
本章的“代码在行动”视频可以在这里找到:bit.ly/3vSwPSu
以下部分介绍了温度传感器模块及其主要特性。
将温度传感器连接到 Blue Pill 板
在本节中,我们将学习构建温度记录传感器所需的硬件组件,使用STM32 Blue Pill和温度模块。
要构建一个测量温度的电子设备,你需要一个监控环境并记录温度数据的传感器。还需要一个微控制器卡,以便能够从传感器读取数据,并将信息显示给用户。我们将首先查看温度传感器模块。
介绍 DS18B20 温度传感器模块
让我们了解构建温度记录所需的主要硬件组件的详细信息:DS18B20 传感器。它是一种数字温度传感器,可以测量空气温度、液体(使用防水版本)和土壤。
重要提示
DS18B20 温度传感器有一个独特的 64 位串行代码,允许通过 STM32 微控制器卡上的一个数字引脚(单线协议)连接多个传感器。
我们将使用一个通用的分线模块,该模块已经包含一个电压 LED 和所需的 4.7 kΩ上拉电阻(如图图 9.1所示):

图 9.1 – DS18B20 数字温度传感器分线板
它是一个单线传感器,这意味着传感器只需要一个引脚端口与控制器进行通信。温度以摄氏度为单位测量,从-55°C 到+125°C,精度为±0.5°C(在-10°C 和 85°C 之间)。使用此传感器而不是热敏电阻(热敏电阻)的主要优点是,我们从传感器接收一个数字引脚上的位流,而不是在模拟引脚上接收电压。
现在我们已经了解了温度传感器,让我们继续下一小节,学习如何将其连接到无焊面包板上的 STM32 Blue Pill。
连接组件
我们将把电子元件连接到无焊面包板上,进行布线,最后将所有东西连接到 STM32 Blue Pill。以下是需要执行的步骤:
- 
将温度传感器和 STM32 Blue Pill 放置在无焊面包板上,留有足够的空间添加布线层,如图图 9.2所示: ![图 9.2 – 面包板上的组件]() 图 9.2 – 面包板上的组件 
- 
接下来,我们将使用外部电源为温度记录系统供电。为此,将 STM32 Blue Pill 的 5 V 引脚连接到无焊面包板上的红色轨道,并将地线引脚连接到蓝色轨道,如图下照片所示(图 9.3): ![图 9.3 – 与电源的连接]() 图 9.3 – 与电源的连接 
- 
将传感器的地(GND)引脚连接到无焊面包板的蓝色轨道或 STM32 Blue Pill 的 GND 端子。接下来,您需要将电压(VCC)引脚连接到无焊面包板的红色轨道,或 STM32 Blue Pill 的 5V 总线,如下面的照片所示。温度传感器产生数字输出,因此必须连接到 STM32 Blue Pill 卡上的数字输入。将温度传感器的信号引脚(S)连接到 Blue Pill 的 B12 引脚,如图 9.4所示: ![图 9.4 – 温度传感器连接到 Blue Pill]() 图 9.4 – 温度传感器连接到 Blue Pill 
- 
最后,您需要使用电池或连接到计算机 USB 端口的 STLink 等电源为板子供电。像往常一样,我们将使用 STLink 将脚本上传到微控制器板。图 9.5总结了所有硬件连接: 

图 9.5 – 温度传感器连接电路
之前的图示显示了 STM32 Blue Pill 和电子组件之间的所有连接,并总结了我们刚刚完成的连接步骤。
图 9.6展示了本项目的原理图:

图 9.6 – 温度传感器连接原理图
原理图显示了整个项目的电路图。图 9.7展示了我们温度记录系统中所有组件的连接方式:

图 9.7 – 温度记录系统
本节向您介绍了 DS18B20 温度传感器。我们发现了它的规格以及与其他类型温度传感器的优势。然后您学习了如何将其连接到面包板并与 STM32 Blue Pill 接口相连。
现在是时候进入下一节了,该节将展示用于完成物联网温度记录第一功能的 C 代码。
编写温度读取系统代码
在本节中,我们将开发程序从传感器读取温度值。如前所述,DS18B20 传感器使用 1 线协议,因此我们将使用 Arduino IDE 库来编程它。让我们开始吧:
- 
作为第一步,我们将安装OneWire库。打开 Arduino IDE,然后进入工具菜单,接着选择管理库(见图 9.8): ![图 9.8 – 库管理器]() 图 9.8 – 库管理器 
- 
接下来,我们将在搜索框中输入单词 OneWire来搜索库。我们将安装由 1 线协议开发者创建的库,因此请安装 Jim Studt 及其同事创建的库(见图 9.9):![图 9.9 – 安装 OneWire 库]() 图 9.9 – 安装 OneWire 库 
- 
接下来,我们将添加 Dallas 温度库。为此,我们在搜索框中输入 ds18b20并安装由 Miles Burton 和合作者开发的库(如图 图 9.10 所示)。此库也可从传感器生产商 Dallas Semiconductor(现 Maxim)获得:![图 9.10 – 安装 Dallas 温度库]() 图 9.10 – 安装 Dallas 温度库 另一种不使用 Arduino IDE 内置功能安装库的方法是从 GitHub 上的存储库手动下载库。下载后,请将它们放置在 Arduino/Libraries文件夹中。接下来,在以下链接中找到库的存储库。OneWire: github.com/PaulStoffregen/OneWire。Maxim(前身为 Dallas)温度: github.com/milesburton/Arduino-Temperature-Control-Library。
- 
让我们编写代码。我们需要包含之前安装的库,并定义 STM32 Blue Pill 卡的哪个引脚将被用于输入: #include <DallasTemperature.h> #define PIN_1_WIRE PB12 OneWire pinWire(PIN_1_WIRE); DallasTemperature sensors(&pinWire);如前文片段所示,单总线将使用 PB12(在 Blue Pill 上标记为 P12)。此外,已创建一个实例以执行通信,并将实例的引用传递给温度传感器。 
- 
接下来,在 setup()部分中,我们需要启动串行数据传输并分配传输速度(通常,我们将使用 9,600 bps 作为标准值):void setup() { Serial.begin(9600); }
- 
我们还需要开始读取传感器: void setup() { Serial.begin(9600); sensors.begin(); }
- 
现在是草图中的 loop()部分。requestTemperatures()函数在读取控制台显示的值后读取温度传感器的值:void loop() { sensors.requestTemperatures(); int temp = sensors.getTempCByIndex(0); Serial.print("Temperature = "); Serial.print(temp); Serial.println(" °C"); delay(1000); }重要提示 如果 DS18B20 温度传感器的读取值为 -127,这意味着连接存在问题。验证所有接线。也许引脚连接错误,或者只是松散的电缆。 
我们已经有了读取温度的完整代码。接下来,我们可以看到完整的草图,位于 GitHub 仓库的 Chapter9/temperature_reading 文件夹中。
现在草图已经完成,您可以将其上传到 Blue Pill 板。您可以在 串行监视器 中看到传感器正在测量的温度(如图 图 9.11 所示):

图 9.11 – 串行监视器温度读数
到目前为止,我们已经学会了从传感器测量环境温度。在主循环期间,设备持续感应传感器并显示在串行监视器上收集的数据。
接下来,我们将学习关于 ESP8266 传感器模块以及如何连接它来加载所需的互联网连接脚本。
学习连接 ESP8266 模块
如我们在本章开头所学的,一个要被视为物联网设备的电子设备必须具备互联网连接,并通过这种媒介提供其数据。
由于上述要求,我们将使用一个模块,将使我们的温度记录系统具备连接到互联网的能力。这个组件是 ESP8266 Wi-Fi 模块。
现在,我们将学习连接 STM32 Blue Pill 到互联网所需的硬件组件,首先要知道和理解 Wi-Fi 模块。
ESP8266 Wi-Fi 模块的简介
ESP8266 是一个集成了 Wi-Fi 通信的微控制器,其主要优势是与其他具有类似特性的芯片相比成本非常低。它本身可以作为微控制器工作,如 Arduino 或 Blue Pill,但它广泛用作没有内置互联网连接的其他微控制器的 Wi-Fi 模块。本项目将使用它作为主要微控制器来管理互联网连接和温度测量。ESP8266 收到来自互联网的远程交互后,将连接到 STM32 Blue Pill 以展示两个微控制器之间的连接。
本章将使用 ESP-01 模块,该模块包含 ESP8266 芯片、Wi-Fi 天线、闪存、LED 和引脚,无需焊接即可连接到无焊点面包板(如图 9.12 所示),只需几根跳线:

图 9.12 – 带有 ESP8266 Wi-Fi 接入点 (AP) 的 ESP-01 扩展板。
ESP-01 默认情况下通过串行端口使用 AT 命令通过 TCP/IP 堆栈进行 Wi-Fi 通信。
ESP8266 模块有三种操作模式:
- 
Station (STA)。 
- 
接入点 (AP)。 
- 
两者都。 
- 
在 AP 模式下,该模块在 Wi-Fi 网络上充当接入点,以连接其他物联网设备。在 STA 类型中,我们的模块可以连接到网络的 Wi-Fi 接入点。后一种模式允许 SP-01 同时作为 AP 和 STA 运行。在本章中,我们将覆盖 SP-01 的 AT 固件,以使用我们自己编写的 C 脚本作为固件。 
在了解 ESP8266 的基本功能,包括 ESP-01 模块后,让我们继续学习如何将其连接到 STM32 Blue Pill。
连接 ESP8266 Wi-Fi 模块
在本小节中,我们将学习如何将 ESP-01 连接起来以上传我们的 C 脚本。最终,我们将拥有一个能够连接到 Wi-Fi 网络的电子设备。
在使用 SP-01 进行原型设计时,最关键的问题之一是其引脚与无焊点面包板在物理上不兼容,因此我们需要跳线来完成连接。
SP-01 的引脚配置如下:
- 
GND 对应地线。 
- 
GPIO2 是通用输入输出引脚。它是数字引脚编号 2。 
- 
GPIO0 是通用输入输出引脚。它是数字引脚编号 0。 
- 
RXD 是串口数据接收的引脚。它工作在 3.3 V 电压下。它也可以用作 GPIO 数字引脚。这将编号为 3。 
- 
TXD 是串口数据传输的引脚。它工作在 3.3 V 电压下。它也可以用作 GPIO 数字引脚。这将编号为 1。 
- 
CH_PD 是用于开启和关闭 ESP-01 的引脚。如果我们将其设置为 0 V(低电平),则关闭,在 3.3 V(高电平)时开启。 
- 
RESET 是用于重置 ESP-01 的引脚。如果我们将其设置为 0 V(低电平),则重置。VCC 是我们为 ESP-01 提供电源的地方。它工作在 3.3 V 电压下,支持最大 3.6 V。提供的电流必须大于 200 mA。 
如您所见,SP-01 没有模拟引脚,但它有四个数字引脚可供使用:GPIO0、GPIO2、RXD(GPIO3)和 TXD(GPIO1)。要编程 SP-01,我们需要一个 USB-串行适配器(也称为 FTDI 或 TTL),同时我们还可以为其供电。
图 9.13 展示了 SP-01 和 FTDI 适配器之间的连接:

图 9.13 – 连接到 Blue Pill 的 ESP8266
以下是将 ESP8266 连接到 FTDI 的步骤,根据之前的图示:
- 
将 ESP8266 的 RXD 引脚连接到 FTDI 的 TXD 引脚。 
- 
将 ESP8266 的 TXD 引脚连接到 FTDI 的 RXD 引脚。 
- 
将 ESP8266 的 GND 引脚连接到 FTDI 的 GND 引脚。 
- 
将 ESP8266 的 CH_PD 引脚连接到 FTDI 的 3.3 V 引脚。 
- 
将 ESP8266 的 3.3 V 引脚连接到 FTDI 的 3.3 V 引脚。 
要完成 步骤 4 和 步骤 5,您需要一个无焊点面包板。图 9.14 展示了连接完成后 FTDI 和 ESP-01 模块之间的连接情况:

图 9.14 – Wi-Fi 模块连接
重要提示
要在 ESP-01 中加载程序,我们必须将 GPIO0 引脚置于低电平(低电平 = GND)并将 GPIO2 引脚置于高电平(高电平 = VCC)。我们必须记住,ESP8266 使用 3.3 V 逻辑电平,因此 GPIO2 引脚默认为高电平,因为它具有内部上拉。因此,它可以保持未连接状态。
最后,图 9.15 展示了所有完成的硬件连接,包括温度传感器:

图 9.15 – 物联网温度记录系统
回顾本章所学内容,我们现在知道如何使用 DS18B20 温度传感器和 STM32 微控制器获取环境温度。我们遇到了 Wi-Fi 模块 SP-01,并通过 FTDI 适配器进行编程和供电。
是时候进入下一节了,该节将展示使用 SP-01 将温度传感器连接到互联网的 C 代码。
编写程序将感应到的温度发送到互联网
现在,我们需要使用 ESP8266 Wi-Fi 模块开发将温度传感器连接到互联网的软件。让我们开始:
- 
打开 Arduino 菜单并选择 Preferences。 
- 
将 arduino.esp8266.com/stable/package_esp8266com_index.json添加到 Additional Boards Manager URLs 字段。您需要用逗号与我们在第一章中安装的 STM32 模块的链接分开文本。
- 
安装 esp8266 平台。转到 Tools 菜单并选择 Board,然后选择 Boards Manager(见 图 9.16): ![图 9.16 – 安装 esp8266 平台]() 图 9.16 – 安装 esp8266 平台 
- 
在代码中包含库将是第一步: #include <DallasTemperature.h> #include <ESP8266WiFi.h> #include <ESP8266WebServer.h>
- 
setup()将包含所有编程逻辑。我们需要启动串行数据传输并分配传输速度(这次我们将使用 115,200 bps)。同时,我们将初始化传感器读取:void setup() { Serial.begin(115200); sensors.begin(); }
- 
接下来,我们将添加 Wi-Fi 凭据并启动一个网络服务器。当服务器接收到读取请求时,这将调用名为 read_sensor的函数:void setup() { Serial.begin(115200); sensors.begin(); WiFi.softAP(ssid, password); Serial.print("Connected, IP address: "); Serial.println(WiFi.localIP()); server.on("/", [](){ Serial.println("Incomming connection to server"); server.send(200, "text/html", strFrm); }); server.on("/read", read_sensor); server.begin();; }
- 
当网络服务器启动时,将显示一个 HTML 按钮,作为用户读取传感器温度的命令。 String strFrm = "<form action='read'><input type='submit' value='Read sensor'></form>";
- 
最后,在用户按下按钮后,服务器将执行 read_sensor()函数。此函数将读取传感器值并通过互联网将其显示给用户:void read_sensor() { Serial.print("Reading the sensor: "); sensors.requestTemperatures(); int temp = sensors.getTempCByIndex(0); Serial.println(temp); server.send(200, "text/plain", String("Temperature: ") + String(temp)); }
- 
草图中 loop()部分将保持互联网连接等待用户命令:void loop(void) { server.handleClient(); }
现在,您可以将其上传到 ESP8266。为了测试程序,只需打开任何网页浏览器并打开分配给我们的设备的 IP 地址。图 9.17 显示了使用 ESP8266 Wi-Fi 模块通过互联网读取温度读数:

图 9.17 – 通过互联网读取温度传感器
这次,我们有了将温度传感器连接到互联网的完整代码。我们可以在 GitHub 仓库的 Chapter9/wifi 文件夹中找到完整的草图。
在下一节中,我们将为 STM32 Blue Pill 微控制器提供从互联网获取数据的第一种方法。
将 STM32 Blue Pill 板连接到互联网
之前的代码片段感应传感器以测量温度并将感应数据发送到互联网。
当用户通过网页浏览器请求温度时,STM32 微控制器将接收到一个请求闪烁 LED 的请求,从而将其与使用 ESP8266 Wi-Fi 模块创建的 IoT 环境相连接。
图 9.18 展示了连接 STM32 和 SP-01 所需的连接:

图 9.18 – 将 STM32 连接到互联网
图 9.19显示了 STM32 和 SP-01 之间的实际设备连接:

图 9.19 – STM32 和 SP-01 之间的物理连接
要完成 STM32 和 SP-01 之间的连接,我们需要在Chapter09/wifi脚本中添加几行代码:
const int toInternetPin = 0;
在上一行中,添加一个常量来存储用于接收来自互联网的数据的输入引脚。然后,在read_sensor()函数中,添加以下行以在用户请求温度时发送值 1(HIGH):
digitalWrite(toInternetPin, HIGH);
最后,将Chapter09/internetblink脚本上传到 STM32 Blue Pill 微控制器,以便读取数字输入并发送数字输出以闪烁 LED。这个脚本在这里不会解释,因为它使用的是读者已经熟悉的指令集。
打开网页浏览器并访问我们的服务器 IP 地址,然后按读取传感器按钮。你会看到温度和 LED 闪烁。
恭喜!你已经完成了如何使用 ESP8266 Wi-Fi 模块 ESP-01 将温度传感器连接到互联网,以及如何打开 STM32 Blue Pill 和互联网请求之间连接的学习。
摘要
在这个项目中我们学到了什么?首先,我们学习了如何将温度传感器连接到 STM32 Blue Pill 微控制器板。然后,我们编写了读取温度并将其发送到我们的微控制器的代码。随后,我们学习了如何将 Wi-Fi 模块连接到我们的 STM32,并编写一个草图将板子连接到互联网。
这个项目让我们获得了开始创建物联网应用的能力,在这个高度互联的世界里这是一个了不起的技能。在接下来的章节中,你将能够应用你所学的知识,因为它们包括需要互联网连接的项目。在第十章 物联网植物花盆湿度传感器中,你将学习如何通过传感器测量花盆的湿度并将其发送到云端。我们将在网页上可视化传感器数据。
进一步阅读
- 摩根,J. “物联网”的简单解释。《福布斯》。2014: www.forbes.com/sites/jacobmorgan/2014/05/13/simple-explanation-internet-things-that-anyone-can-understand/
第十章:第十章:物联网花盆湿度传感器
随着物联网(IoT)的出现,我们沉浸在新的工业革命中——所谓的工业 4.0。从这些技术中受益最多的行业之一是农业(Chalimov,2020)。农业物联网应用范围从自主收割到识别害虫和疾病或测量湿度的传感器。我们可以利用这些进步在家中——例如,监测我们的观赏植物以获得更有效的护理。
在本章中,你将应用在第九章“物联网温度记录系统”中学到的信息,关于如何连接和编程互联网连接,但这次我们将介绍一个NodeMCU 微控制器来简化 ESP8266 编程。你将学习如何创建一个数字设备来监测花盆,从土壤湿度传感器读取数据并确定是否需要浇水,然后发送警报通知它太干了。
本章将涵盖以下主要内容:
- 
将土壤湿度传感器连接到 Blue Pill 板 
- 
从土壤湿度传感器模块读取数据 
- 
编写程序将感应数据发送到互联网 
- 
在互联网上显示传感器数据结果 
通过完成本章,你将发现如何通过连接到 STM32 Blue Pill 板的传感器读取土壤的湿度量。你还将学习如何通过 NodeMCU 开发板将此信息发送到互联网,并通过响应式网页可视化传感器值。
技术要求
开发花盆湿度系统所需的硬件组件如下所示:
- 
一个无焊面包板。 
- 
一个 Blue Pill 微控制器板。 
- 
一个 NodeMCU 微控制器。 
- 
一个 ST-Link/V2 电子接口,用于将编译后的代码上传到 Blue Pill 板。请注意,ST-Link/V2 接口需要四根公对公跳线。 
- 
一个土壤湿度传感器。 
- 
一个 ESP8266 Wi-Fi 模块。 
- 
公对公跳线。 
- 
电源。 
这些组件可以从你喜欢的供应商那里轻松获得。此外,你还需要本章的 Arduino集成开发环境(IDE)和 GitHub 仓库,可以在github.com/PacktPublishing/DIY-Microcontroller-Projects-for-Hobbyists/tree/master/Chapter10找到。
本章的“代码在行动”视频可以在这里找到:bit.ly/3d9CmNM
下一节将介绍土壤湿度传感器及其如何与 STM32 Blue Pill 微控制器板一起使用。
将土壤湿度传感器连接到 Blue Pill 板
我们将从这个部分开始学习如何使用传感器测量花盆中的土壤湿度,你将后来学习如何将其连接到STM32 Blue Pill板以构建花盆湿度监控系统。
介绍土壤湿度传感器
土壤湿度传感器由两个测量土壤中水分量的焊盘组成。通过允许电流通过土壤流动来获取感应值,根据电阻,这显示了花盆中的湿度水平。
你可以找到一个通用的扩展模块,它非常容易使用。以下照片展示了这一点:

图 10.1 – 土壤湿度传感器扩展板
这些焊盘通过包含的公对公跳线连接到扩展板。扩展板通过四个引脚连接到 STM32 Blue Pill 板,如下所述:
- 
模拟输出(AO):此引脚生成模拟信号,必须连接到微控制器的模拟输入。 
- 
数字输出(DO):此引脚生成数字信号,必须连接到微控制器的数字输入。 
- 
VCC:为传感器供电的引脚(3.3 伏特(V)-5 V)。 
- 
地(GND):地连接。 
为了简化我们项目的开发,我们将使用 DO 引脚来构建我们的系统,因为它只根据湿度生成二进制数据。
连接组件
我们将使用无焊点面包板连接传感器和 STM32 Blue Pill 微控制器,最后用线连接组件。按照以下步骤操作:
- 
将土壤湿度传感器和 STM32 Blue Pill 板放置在无焊点面包板上,留出足够的空间以添加布线层。 
- 
将传感器的地(GND)引脚连接到 SMT32 Blue Pill 板的地(GND)端子。 
- 
接下来,你需要将电压(VCC)引脚连接到 STM32 Blue Pill 板的 3V3 总线上。传感器的 DO 必须连接到 STM32 Blue Pill 板上的数字输入,因此将传感器的 DO 引脚连接到 Blue Pill 的 B12 引脚,如下照片所示: ![图 10.2 – 土壤湿度传感器连接到 Blue Pill]() 图 10.2 – 土壤湿度传感器连接到 Blue Pill 
- 
最后,你需要一个电源来为板供电。使用 ST-LINK 将脚本上传到 STM32 Blue Pill 微控制器板。以下截图总结了所有硬件连接: 

图 10.3 – 土壤湿度传感器连接电路
以下截图展示了本项目的原理图:

图 10.4 – 土壤湿度传感器连接原理图
图 10.4显示了该项目的这部分电路图。传感器的地线引脚连接到 Blue Pill 的 GND 引脚,而 VCC 引脚连接到 Blue Pill 的 3V3 总线。最后,传感器的 DO 插头插入到 STM32 微控制器的 B12 引脚。以下照片显示了植物花盆湿度系统:

图 10.5 – 植物花盆湿度系统
在上一张照片中,我们可以看到湿度监控系统部署的过程。正如我们所见,我们构建了一个紧凑的电子电路来监测植物花盆中土壤的湿度。
在本节中,我们了解了湿度传感器的概念及其组件。此外,我们学习了如何通过面包板将传感器连接到微控制器,并最终学习了如何将整个系统连接到植物花盆上。
现在是进入下一部分的时候了,这部分将向您展示如何编写 C 代码来完成物联网湿度监控系统的基础功能。
从土壤湿度传感器模块读取数据
您现在将学习如何编写一个程序,该程序读取湿度传感器的信息,并在串行监视器上显示植物花盆是否需要浇水或已经足够湿润。
让我们开始开发从 STM32 Blue Pill 收集传感器数据的程序,如下所示:
- 
让我们开始编写代码。这次,我们不需要任何额外的库。定义 STM32 Blue Pill 卡上哪些引脚将被用作读取传感器数据的输入。同时,声明一个变量来保存从传感器读取的数据,如下所示: const int PB12 pin (labeled B12 on the Blue Pill). Also, we initialize the sensorValue variable to a value of 0.
- 
接下来,在 setup()部分,我们需要启动串行数据传输并分配传输速度(像往常一样,我们将使用 9,600 比特/秒(bps)作为标准值)。以下是执行此操作的代码:void setup() { Serial.begin(9600); }
- 
通过运行以下代码向微控制器指示分配给 PB12的引脚类型:void setup() { Serial.begin(9600); pinMode(sensorPin, INPUT); }
- 
剩余的代码在 loop()部分。前几行读取输入引脚的数据传感器,并在串行控制台中显示其值。代码如下所示:void loop() { sensorValue = digitalRead(sensorPin); Serial.print("Sensor value: "); Serial.println(sensorValue); if (sensorValue == 1) { Serial.println("Soil is too dry"); delay(1000); } else { Serial.println("Soil is moist enough"); delay(1000); } }从传感器读取的值可能是 1或0;记住,我们正在读取一个数字值。如果值是1,那么植物花盆需要浇水;否则,它已经足够湿润。代码现在已完成。您可以在 GitHub 仓库的 Chapter10/moisture文件夹中找到完整的草图。
- 
现在草图已完成,您可以将其上传到 Blue Pill 板,并将传感器垫插入植物花盆中。现在,您可以在串行监视器中看到土壤太干燥,如下面的截图所示: ![图 10.6 – 干土壤的串行监视器读取]() 图 10.6 – 干土壤的串行监视器读取 
- 
现在,向花盆中加水,注意不要让任何电子组件受潮。一旦土壤变湿,串行监视器的信息就会立即改变,如下面的截图所示: 

图 10.7 – 浇水后串行监视器的读数
重要提示
在最近的 macOS 版本中,Arduino IDE 中可能不会显示 通用串行总线 (USB) 端口,因此可能无法看到串行监视器。为了解决这个问题,需要从 www.silabs.com/developers/usb-to-uart-bridge-vcp-drivers 安装 USB-UART 驱动程序(其中 UART 代表 通用异步收发传输器)。
让我们回顾一下到目前为止我们已经学到的内容。我们学习了用于测量土壤湿度的传感器。我们在 将土壤湿度传感器连接到 Blue Pill 板 部分学习了如何将其连接到我们的 STM32 Blue Pill 微控制器。在本节中,我们编写了获取其数据并在串行监视器上显示的代码。
你在本章中已经掌握的技能将允许你创建其他需要从传感器中读取数据的数字电子系统,使你能够在需要测量土壤湿度的额外项目中使用这个传感器。
接下来,我们将学习 NodeMCU 微控制器,它将借助其集成的 ESP8266 模块方便地连接到互联网。
编写程序将感应数据发送到互联网
如果你记得,在 第九章 的 物联网温度记录系统 中,我们发现使用了 ESP-01 模块,因为它通过 ESP8266 集成了 Wi-Fi 通信。该模块通过 STM32 Blue Pill 微控制器(其中 AT 代表 Attention)使用 AT 命令进行编程。如本章开头所述,我们将使用 NodeMCU 开发板,如下面的照片所示:

图 10.8 – NodeMCU 开发板
该板也基于 ESP8266 微控制器。然而,与 SP-01 模块不同,它可以直接通过其微型 USB 端口使用不同的开发 IDE 和各种编程语言(如 Lua 和 C)进行编程。它还包括 通用输入/输出 (GPIO) 引脚,可以根据开发者的需求进行编程。这些特性使得 NodeMCU 微控制器成为当今最受欢迎的物联网平台之一。
NodeMCU 与固件和开发板兼容,联合提供最流行的开源物联网平台。开发板基于 ESP-12 模块,与 ESP-01 模块一样,为我们提供了 Wi-Fi 连接功能,并增加了开发板的功能,具有以下特点:
- 
微型 USB 端口和串行-USB 转换器 
- 
通过微型 USB 进行简单编程 
- 
通过 USB 端子(引脚)供电,便于连接 
- 
集成复位按钮和发光二极管(LED) 
使用其引脚,我们可以轻松地将它放置在无焊面包板上,连接我们将在项目中需要的电子元件。NodeMCU 通过传输控制协议/互联网协议(TCP/IP)堆栈启用 Wi-Fi 通信。
重要提示
要编程 NodeMCU,必须已经执行了在第九章“通过互联网显示传感器数据结果”部分中指示的添加此类板子的步骤,即IoT 温度记录系统。
让我们创建一个程序将 NodeMCU 连接到互联网。按照以下步骤操作:
- 
首先,包含 ESP8266 的 Wi-Fi 库。您需要两个字符串类型的变量用于 Wi-Fi 网络的 0: 潮湿
- 
1: 干燥
- 
2: 未读取。这里硬编码,不是来自传感器代码如下所示: #include <ESP8266WiFi.h> const char* ssid = "Your_SSID"; const char* password = "Your_Password"; const int fromStm32Pin = 4; int sensorValue = 2;
- 
我们将创建一个网络服务器来接收传感器数据。服务器将监听端口 80。以下是实现此功能的代码:WiFiServer server(80);
- 
在 setup()部分中,我们需要启动串行数据传输并分配传输速度(这次我们将使用 115,200 bps)。代码如下所示:void setup() { Serial.begin(115200); }
- 
向 NodeMCU 板指示读取 STM32 的引脚类型,如下所示: void setup() { Serial.begin(115200); pinMode(fromStm32Pin, INPUT); }
- 
setup()部分的其余部分将配置 Wi-Fi 网络,在成功连接后,将 IP 地址发送到串行监视器。代码如下所示:void setup() { Serial.begin(115200); pinMode(fromStm32Pin, INPUT); Serial.print("Connecting to WiFi network: "); Serial.println(ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected."); Serial.println("IP address: "); Serial.println(WiFi.localIP()); server.begin();}loop()部分被构建为三个功能。首先,启动网络服务器。然后,从 STM32 读取传感器数据。最后,显示一个响应式 Web 应用程序来可视化传感器监控。对于完整的草图,请参阅 GitHub 仓库中的 Chapter10/webserver文件夹。
- 
网络服务器将监听来自客户端的连接请求。客户端连接后,我们通过 if条件捕获它,如下面的代码片段所示:void loop() { WiFiClient client = server.available(); if (client) { // Code to serve the responsive webapp. } }
- 
客户端连接后,代码将验证是否接收到了带有读取传感器数据命令的 GET请求,如下面的代码片段所示:void loop() { WiFiClient client = server.available(); if (client) { if (header.indexOf("GET /4/read") >= 0) { Serial.println("Reading the sensor"); sensorValue = digitalRead(fromStm32Pin); } } }
- 
如果客户端收到的请求要求读取传感器值,NodeMCU 将从 STM32 Blue Pill 读取传感器的读数。 为了在 NodeMCU 和 STM32 之间建立这座桥梁,需要添加以下截图所示的额外连接: ![图 10.9 – 微控制器互连电路]() 图 10.9 – 微控制器的互联电路 下面是微控制器互联的示意图: ![图 10.10 – 微控制器互联的原理图]() 图 10.10 – 微控制器互联的原理图 从 NodeMCU 的 GPIO 4(D2)连接一根公对公跳线到 STM32 的 GPIO PC13 引脚。 以下照片显示了实际系统中所有组件的连接方式: ![图 10.11 – STM32 和 NodeMCU 连接]() 图 10.11 – STM32 和 NodeMCU 连接 
- 
现在,为了完成 NodeMCU 和 STM32 之间的连接,需要在 Chapter10/moisture草图中添加几行新代码。添加一个新的常量来存储用于将数据发送到 NodeMCU 的输出引脚,如下所示: const int sensorPin = PB12; int sensorValue = 0; PC13 pin (labeled C13 on the Blue Pill).
- 
在 setup()部分,指示PC13的引脚类型,如下所示:void setup() { Serial.begin(9600); pinMode(sensorPin, INPUT); pinMode(toInternetPin, OUTPUT); }
- 
修改 loop()部分的if条件,如下所示:void loop() { if (sensorValue == 1) { 1 (HIGH) or 0 (LOW) according to the humidity sensor. Now, we can upload Chapter10/moisture to the STM32 and close the sketch and continue working in Chapter10/webserver.
- 
完成我们的 Web 服务器的最后一步是在客户端请求后提供响应式 Web 应用。这样,任何连接到同一 Wi-Fi 网络和 Web 浏览器的设备都将能够远程访问传感器读数。 但首先,我们将学习一些具有 viewport值的<meta>标签的name属性的概念。这个标签将负责根据我们浏览的设备调整我们的应用布局,因此我们可以从桌面 PC 到移动设备进行操作。为了给它一个期望的视觉风格,我们可以有两种方式:在 <head>标签内导入<style></style>标签,如下面的代码片段所示:<link rel="stylesheet" href="styleFile.css"> <style>Some styles</style>对于我们的 Web 应用,我们需要一个按钮。如果我们对提供 CSS 视觉风格不太了解,我们可以使用互联网上免费提供的工具,例如 www.bestcssbuttongenerator.com/,它将视觉生成我们按钮的 CSS 样式。要在我们的草图中包含 HTML 代码,我们将使用以下句子: client.println("<html tags>");在我们的 Web 应用上可视化传感器值的代码打印了一个段落,指示用户土壤是否干燥,以及一个图形指示器以更好地理解我们的花盆状态,如下面的代码片段所示: if (sensorValue == 1) { client.println("<p>Soil is too dry</p>"); client.println("<p><img width=\"50\" height=\"60\" src=\"https://raw.githubusercontent.com/ PacktPublishing/Creative-DIY-Microcontroller- Projects/master/Chapter10/images/ dry_plant.png\"></p>"); } else if (sensorValue == 0) { client.println("<p>Soil is moist enough</p>"); client.println("<p><img width=\"50\" height=\"60\" src=\"https://raw.githubusercontent.com/ PacktPublishing/Creative-DIY-Microcontroller- Projects/master/Chapter10/images/ green_plant.png\"></p>"); } else { client.println("<p>Press the button to read the sensor</p>"); } client.println("<p><a href=\"/4/read\"> <button class=\"sensorButton\"><i class=\"fas fa- satellite-dish\"></i> Read sensor</button> </a></p>");为了允许用户收集传感器读数,我们包含了一个按钮,每次需要知道他们的植物状态时都需要按下。记住——这个项目部分的完整代码可在 Chapter10/webserverGitHub 文件夹中找到。重要提示 如果你需要使用免费图片和图标,你可以在以下互联网存储库中找到它们: 
现在草图已经完成,所以将其上传到 NodeMCU 板,并在上传完成后重置它。现在,你可以在串行监视器中看到连接我们的客户端的 IP 地址,如下面的截图所示:

图 10.12 – 串行监视器上的 IP 地址
现在是时候进入下一节了,该节将向您展示如何在网上可视化数据。
在互联网上显示传感器数据结果
将物体连接到互联网将允许您从任何连接到该网络的地点访问它们的数据。
这就是为什么我们给我们的项目赋予了成为 Web 服务器的功能,从而能够从任何 Web 浏览器访问花盆的状态。
对于这个项目,访问只能从我们的 Wi-Fi 网络进行。为了测试其操作,我们将从任何移动或桌面 Web 浏览器访问开发的 Web 应用。按照以下步骤操作:
- 
打开 Web 浏览器,访问我们的服务器 IP 地址(见图 10.12)。您应该看到我们的着陆页,用于监控我们的花盆,如下面的截图所示: ![图 10.13 – Web 应用着陆页]() 图 10.13 – Web 应用着陆页 
- 
在着陆页面上,每次您想要测量花盆的湿度时,都可以简单地按下按钮。如果土壤干燥,我们会看到一个代表性的图像和说明为土壤过于干燥的图例,如下面的截图所示: ![图 10.14 – 干土壤的 Web 应用屏幕]() 图 10.14 – 干土壤的 Web 应用屏幕 
- 
否则,如果土壤湿度适中,我们会看到一个说明为土壤湿度足够的图例以及一个代表性的图像,如下面的截图所示: 

图 10.15 – 湿土壤的 Web 应用屏幕
只要您连接到您的本地 Wi-Fi 网络,您就可以从家中任何地方使用这个物联网设备和应用来监控您的花盆。
我们已经到达了本章的结尾。做得好!让我们看看在这个项目中我们学到了什么。
摘要
在项目开始时,您看到了如何将土壤湿度传感器连接到您的 STM32 板。然后,我们创建了一个简单的草图来收集传感器读数,并测试它以确保其正常工作。
我们还学习了如何将 NodeMCU 卡连接到互联网并从 STM32 读取传感器数据。最后,在项目的最后一部分,我们构建了一个 Web 应用,可以从任何 Web 浏览器(无论是移动还是桌面)控制物联网设备。
物联网领域正在快速发展,因此在这个技术领域拥有正确技能的人才可以轻松进入这个令人兴奋的领域的职位。考虑到这一点,完成本章后,我们现在为创建物联网设备和应用有了更坚实的基础。
在下一章中,我们将学习如何将我们的电子设备连接到互联网,并使它们在我们的本地 Wi-Fi 网络之外可用。
进一步阅读
Chalimov, A, 农业中的物联网:智能农业的 8 个技术应用案例(以及需要考虑的挑战). Eastern Peak, 2020: easternpeak.com/blog/iot-in-agriculture-technology-use-cases-for-smart-farming-and-challenges-to-consider/
第十一章:第十一章:物联网太阳能(电压)测量
面对全球变暖的挑战,太阳能被认为是可再生能源中最有希望的一种。它被认为是在减少对化石燃料的依赖和满足不断增长的电力需求方面最好的替代品之一(Ryan,2005)。为了实现这一点,阳光被转化为电能,而阳光是通过太阳能板收集的。
在本章中,您将继续为 STM32 Blue Pill 微控制器板创建物联网软件,使用电压传感器来测量太阳能板收集的太阳能。该应用将通过 NodeMCU ESP8266 微控制器板将感应数据发送到互联网。
在本章中,我们将涵盖以下主要主题:
- 
将太阳能板连接到 Blue Pill 板 
- 
从电压传感器模块读取数据 
- 
编写程序将感应数据发送到互联网 
- 
在互联网上显示传感器数据结果 
在本章之后,您将具备开发物联网应用和提升您的简历的扎实技能,因为它是工业 4.0 的核心元素。您将学习的第一个技能是从连接到 STM32 Blue Pill 的传感器读取太阳能板电压。此外,您将学习如何通过 NodeMCU 8266 开发板将读取的信息发送到互联网。最后,您将了解如何在移动物联网应用上可视化传感器值。
技术要求
开发太阳能能量测量系统所需的硬件组件如下:
- 
一个无焊面包板。 
- 
一个 Blue Pill 微控制器板。 
- 
一个 NodeMCU 微控制器。 
- 
一个 ST-Link/V2 电子接口,用于将编译后的代码上传到 Blue Pill 板。请注意,ST-Link/V2 需要四根公对公跳线。 
- 
一个 B25 电压传感器。 
- 
一个太阳能板。 
- 
公对公跳线。 
- 
公对母跳线。 
- 
电源。 
所有组件都可以在您偏好的电子供应商处轻松找到。记住,您将需要 Arduino IDE 和 GitHub 仓库来完成本章:github.com/PacktPublishing/DIY-Microcontroller-Projects-for-Hobbyists/tree/master/Chapter11
本章的“代码在行动”视频可以在这里找到:bit.ly/2U4YMsT
下一节将介绍太阳能板和 B25 电压测量传感器,以及如何将它们与 STM32 Blue Pill 微控制器板接口连接。
将太阳能板连接到 Blue Pill 板
首先,我们需要了解两个组件:太阳能板和电压测量传感器。在了解基础知识后,我们可以构建我们的太阳能能量测量系统。
介绍太阳能板
太阳光携带能量。当阳光与半导体碰撞时,部分能量会转化为移动的电子,从而产生电流。太阳能电池(也称为光伏板或 PV 板)是为了利用到达我们星球的所有阳光而设计的。当阳光反射在 PV 板上时,电流输出保持恒定;这被称为直流(DC)电。这种直流电可以用来给电池充电并为微控制器如 STM32 Blue Pill 提供电力。
以下截图显示了用于电子组件(如我们的太阳能演示系统)的太阳能板:

图 11.1 – 太阳能板
为了方便与该太阳能板连接和操作,我们将焊接一个引脚头到板上,这样我们就可以直接连接跳线到它。以下图显示了引脚头和焊接后的 PV 板的外观:

图 11.2 – 将引脚头焊接至太阳能板
您还可以在市场上找到已经集成电缆的太阳能板,以方便使用,如下图所示:

图 11.3 – 带集成线的太阳能板
在了解了太阳能板的外观和功能后,让我们继续下一小节,我们将探讨我们将用来测量电压的传感器。
B25 电压传感器
如果我们需要测量电压,我们可以使用 STM32 Blue Pill 板的模拟输入。这些输入的电压限制为 5V,因此如果需要测量更高的电压,就必须使用外部传感器来完成。B25 传感器(见 图 11.4)测量 5V 至 25V 范围的电压,使其成为这项任务的非常受欢迎的传感器:

图 11.4 – B25 电压传感器扩展板
如所示,该模块有两个终端,外部电源将连接到这两个终端,一个连接到 GND,另一个连接到 VCC,必须用螺丝调整。
此外,扩展板通过 3 个引脚头连接到 STM32 Blue Pill。它们如下:
- 
S:此引脚产生模拟信号,必须连接到微控制器的模拟输入。 
- 
+:未连接。 
- 
-:接地连接。 
在这个信息的基础上,我们将在下一小节学习如何将电压传感器连接到 STM32 Blue Pill 板上。
连接组件
我们将使用无焊面包板连接传感器和 STM32 Blue Pill 微控制器,并最终用电线连接组件。以下是我们的接线方式和组件连接方法:
- 
将电压传感器和 STM32 Blue Pill 放在无焊面包板上。留出一些空位以添加电线。 
- 
将传感器的地(GND)引脚连接到 STM32 Blue Pill 的 GND 端子。 
- 
接下来,你需要将传感器的模拟输出连接到 STM32 Blue Pill 卡上的模拟输入,并将传感器的 S 连接到 Blue Pill 的A0引脚,如图图 11.5所示: ![图 11.5 – 电压传感器连接到 Blue Pill]() 图 11.5 – 电压传感器连接到 Blue Pill 
- 
最后,你需要一个电源连接来将太阳能板连接到板上。使用 STLink 将脚本上传到 STM32 Blue Pill 微控制器板。图 11.6总结了所有硬件连接: 

图 11.6:电压传感器连接电路
以下截图展示了本项目的原理图:

图 11.7 – 电压传感器连接的原理图
原理图显示了电气连接。光伏板的 VCC 和地端子连接到传感器的 VCC 和 GND 引脚。为了将 Blue Pill 与传感器接口,其地引脚连接到 Blue Pill 的 GND 总线,最后,传感器的模拟输出(S)插入到 STM32 微控制器的 A0 引脚。图 11.8显示了太阳能测量系统:

图 11.8 – 太阳能测量系统
现在我们已经完成了组件的连接,我们创建了一个简单的电路用于我们的电压测量系统,如前图所示。
在本节中,我们了解了太阳能板,并遇到了电压传感器及其组件。我们还学习了如何将太阳能电池连接到电压传感器,以及如何将电压传感器连接到 STM32 Blue Pill。
是时候进入下一节了,该节将展示如何编写 C 代码来完成我们的物联网太阳能监测系统的第一个功能。
从电压传感器模块读取数据
是时候学习如何编写一个程序来读取电压传感器的信息并在串行监视器上显示其读数了。
让我们编写程序来接收 STM32 Blue Pill 的传感器数据:
- 
声明 STM32 Blue Pill 卡上哪个引脚将用作传感器数据的输入: 0 (labeled A0 on the Blue Pill).
- 
接下来,在 setup()部分,开始串行数据传输,并将传输速度设置为 9600 bps,并告知微控制器分配给 A0 的引脚类型:void setup() { Serial.begin(9600); pinMode(sensorPin, INPUT); }
- 
现在,在 loop()中,首先读取输入引脚的传感器数据,将其值发送到串行端口,并等待一秒钟:void loop() { int sensorValue = analogRead(sensorPin); Serial.print("Voltage: "); Serial.println(sensorValue); delay(1000); }
- 
我们将程序加载到 STM32 板上,并查看 Arduino IDE 的串行绘图器,以了解我们从传感器读取的模拟信号的波形,结果可见于 图 11.9: ![图 11.9 – 串行绘图器中的传感器信号波形]() 图 11.9 – 串行绘图器中的传感器信号波形 形成传感器信号的波形可以取 0到1023的值。然后,需要将此值转换为电压。
- 
我们将在脚本中添加两行来显示电压值,并对将信号值发送到串行端口的行进行注释: void loop() { int sensorValue = analogRead(sensorPin); map() function transforms a number from one range to another:map(value, fromLow, fromHigh, toLow, toHigh) The first parameter that `map()` receives is the value to be converted. In our program, it is the value read from the sensor. The value of `fromLow` will be mapped to `toLow`, and `fromHigh` to `toHigh`, and all values within the range.Now, upload it to the Blue Pill board. Now you can see in the **serial monitor** the voltage value as shown in *Figure 11.10*:

图 11.10 – 串行监视器读数
对于完整的草图,请参阅 GitHub 仓库中的 Chapter11/voltage 文件夹。
我们到目前为止学到了什么?我们介绍了 B25 传感器来测量电压,并了解了太阳能板。我们学习了如何将它们连接到我们的 STM32 Blue Pill 微控制器,编写代码读取传感器数据,在串行监视器上显示它,并在串行绘图器中绘制它。
在本节中,我们获得了一些新技能,这些技能将帮助您构建需要监测电压水平的电子系统。
接下来,我们将使用 NodeMCU 微控制器将感应数据发送到互联网。
编写程序将感应数据发送到互联网
在本节中,我们将继续使用 NodeMCU 开发板从 STM32 接收数据并将其发送到互联网。然而,与 第十章 中的 IoT 植物花盆湿度传感器 不同,其中两个微控制器之间直接发送数字值(1 或 0),我们现在需要在这些微控制器之间使用串行通信发送电压值。
串行传输是通过使用 RX/TX 引脚发送数据来完成的。
让我们创建连接 NodeMCU 和 STM32 的程序:
- 
在 setup()中,我们需要添加新的串行数据传输到 115200 bps。这是 NodeMCU 板的推荐速度:void setup() { serial.begin(9600); Serial1.begin(115200); }
- 
loop()实例需要在读取传感器和电压转换后添加新的一行。write()函数将数据作为整数值发送:void loop() { int sensorValue = analogRead(sensorPin); double voltageValue = map(sensorValue, 0, 1023, 0, 25); Serial.print("Voltage: "); //Serial.println(sensorValue); Serial.println(voltageValue); Serial1.write((int)voltageValue); delay(1000); }
- 
要完成 NodeMCU 和 STM32 之间的通信,需要添加 图 11.11 和 图 11.12 中显示的附加连接: ![图 11.11 – 微控制器串行通信电路]() 图 11.11 – 微控制器串行通信电路 图 11.12 显示了 STM32 和 NodeMCU 微控制器之间电路接口的原理图: ![图 11.12 – 微控制器串行通信原理图]() 图 11.12 – 微控制器串行通信原理图 将 NodeMCU 的 RX 引脚连接到 STM32 的 TX 引脚(B6),并将 NodeMCU 的 TX 引脚连接到 STM32 的 RX 引脚(B7)。 图 11.13显示了实际系统中所有连接的方式,包括电压传感器: ![图 11.13 – STM32 和 NodeMCU 串行连接]() 图 11.13 – STM32 和 NodeMCU 串行连接 
- 
现在,为了完成 NodeMCU 和 STM32 之间的串行连接,我们将创建一个新的草图, Chapter11/voltage_iot.
- 
在 setup()中,指示串行数据传输:void setup() { Serial.begin(115200); }
- 
最后一步是 loop():void loop() { double data = Serial.read(); Serial.print("Voltage: "); Serial.println(data); delay(1000); }使用前面的代码,NodeMCU 将从 STM32 接收传感器值,并将其显示在串行监视器上。 
草图现在已完成。将其上传到 NodeMCU 板,并在上传完成后重置它。现在您可以看到,在串行监视器中,传感器值,如下面的截图所示:
现在是时候进入下一节了,该节将向您展示如何在网上可视化数据。
在互联网上显示传感器数据结果
在第九章,“物联网温度记录系统”,和第十章,“物联网植物花盆湿度传感器”中,我们学习了如何在本地网络内编程物联网应用。在本章的这一节中,我们将学习如何将数据发送到本地网络之外的云。
众多云平台允许我们将我们的物联网设备连接到它们的服务。大多数平台允许我们免费使用基本服务。如果需要更完整的服务,则可能需要付费,通常是每月支付。这次我们将使用 Blynk 平台,它有几个免费选项,我们将使用这些选项。
Blynk 为 Android 和 iOS 都提供了应用程序,这将使我们能够监控太阳能电池板上的电压值。
让我们看看如何使用移动应用程序从互联网发送和查看我们的信息:
- 
下载 Blynk 应用程序。 对于 Android,从 play.google.com/store/apps/details?id=cc.blynk&hl=en_US下载。对于 iOS,从 apps.apple.com/us/app/blynk-iot-for-arduino-esp32/id808760481下载。
- 
创建一个新账户: ![图 11.14 – Blynk,主页屏幕]() 图 11.14 – Blynk,主页屏幕 
- 
一旦创建账户,创建一个新的项目。输入名称,选择 ESP8266 作为设备,并将 WiFi 设置为连接类型。然后点击创建项目: ![图 11.15 – Blynk,创建新账户]() 图 11.15 – Blynk,创建新账户 
- 
您将收到一封包含应用程序所需令牌的电子邮件,您也可以在设置中找到: ![图 11.16 – Blynk,菜单屏幕]() 图 11.16 – Blynk,菜单屏幕 
- 
输入一个名称,选择ESP8266作为设备,并选择WiFi作为连接类型。点击创建项目: ![图 11.17 – Blynk,创建新项目]() 图 11.17 – Blynk,创建新项目 
- 
你将收到一封包含应用程序所需令牌的电子邮件,你也可以在设置中找到它。 
- 
按压屏幕,Widget 工具箱将出现: ![图 11.18 – Blynk,小部件框]() 图 11.18 – Blynk,小部件框 
- 
添加一个仪表组件。配置它并按下确定按钮: ![图 11.19 – Blynk,太阳能应用]() 图 11.19 – Blynk,太阳能应用 
- 
最后,将 Chapter11/voltage_iot程序上传到 NodeMCU 并执行它。
我们已经到达了 第十一章 的结尾,“物联网太阳能(电压)测量”。恭喜!
摘要
在本章专门介绍物联网的章节中,我们学习了一些基本主题。首先,我们了解了用于为小型电子设备供电的太阳能电池。接下来,我们学习了 B25 电压传感器以及如何将其连接到 STM32。
之后,我们学习了如何创建一个程序来读取电压传感器的数据。有了电压读数,我们通过串行通信将 STM32 连接到 NodeMCU 板。我们创建了一个程序,在微控制器之间发送电压值。最后,我们使用一个应用程序在云端可视化传感器数据。
在物联网主题的结尾,你拥有了创建连接到互联网和内网的程序和设备的扎实技能。你的项目组合得到了加强,这将使你更容易在这个增长领域找到工作机会。
在下一章中,你将开始开发项目,这些项目将帮助你创建电子支持设备,以协助应对 COVID-19 大流行。
进一步阅读
Ryan, V., 什么是太阳能? 技术学生,2005: technologystudent.com/energy1/solar1.htm
第十二章:第十二章:COVID-19 数字体温测量(体温计)
本章描述了一个有趣的项目,你将开发一个非接触式体温计来测量人体温度。这种数字体温计可能对支持 COVID-19 患者的诊断有所帮助。本章中解释的电子项目涉及使用一个非常强大的红外(IR)温度传感器来检测体温。此外,你将学习和练习如何使用集成电路间(I2C)数据传输协议将红外温度传感器连接到微控制器板。
重要提示
本章中描述的体温测量项目不应作为确定一个人是否患有 COVID-19 的最终和准确方法。它仅用于演示和学习目的。
在本章中,我们将涵盖以下主要主题:
- 
编程 I2C 接口 
- 
将红外温度传感器连接到微控制器板 
- 
在 LCD 上显示温度 
- 
测试体温计 
到本章结束时,你将学会如何从红外温度传感器获取有用的数据,以及如何有效地在连接到微控制器板的 LCD 上显示体温数据。你还将了解 I2C 数据传输协议是如何从红外传感器获取数据,以及如何正确测试红外温度传感器。
技术要求
本章中你将使用的软件工具是Arduino IDE,用于编辑和上传你的程序到 Blue Pill 微控制器板。本章中使用的代码可以在本书的 GitHub 仓库中找到:
github.com/PacktPublishing/DIY-Microcontroller-Projects-for-Hobbyists/tree/master/Chapter12
本章的“代码在行动”视频可在此处找到:bit.ly/2SMUkPw
在本章中,我们将使用以下硬件设备:
- 
一个无焊面包板。 
- 
一个 Blue Pill 微控制器板。 
- 
一条 micro-USB 电缆,用于将微控制器板连接到计算机和移动电源。 
- 
一个 Arduino Uno 微控制器板。 
- 
一个 USB 2.0 A 到 B 电缆,用于 Arduino Uno 板。 
- 
两个 USB 移动电源。 
- 
一个 ST-Link/V2 电子接口,用于将编译后的代码上传到 Blue Pill。请注意,ST-Link/V2 需要四条公对公的杜邦线。 
- 
一个 MLX90614ESF-DCA-000 温度传感器(它适用于 3.3 伏特)。 
- 
一个 0.1 微法拉电容器。它通常有一个 104 的标签。 
- 
一个 1602 16x2 I2C LCD。 
- 
一打公对公和一打公对母的杜邦线。 
下一个部分将描述如何编写 I2C 协议以及将在 Blue Pill 和 Arduino Uno 微控制器板上运行的代码。Arduino Uno 用于从红外传感器获取数据。
编程 I2C 接口
在本节中,我们将回顾如何从 MLX90614 温度传感器获取有用的数据,并使用 I2C 协议(也称为 IIC)进行传输。这是一个实用的串行数据通信协议,适用于将传感器、LCD 和其他设备连接到支持 I2C 的微控制器板。下一节将定义 I2C 是什么。
I2C 协议
I2C 是一种同步串行通信协议,允许通过一个共同的 总线(总线作为主要的数字道路)在短距离内连接传感器、微控制器、显示器、模数转换器(ADCs)等设备。I2C 总线由几条所有设备共享并用于传输和交换数据的线路(电线)组成。I2C 协议实用且有益,因为它仅使用两条电线进行数据通信。I2C 的另一个好处是,从理论上讲,它可以支持多达 1,008 个设备连接到同一个 I2C 总线!也值得提到的是,可以连接多个微控制器到同一个总线,尽管它们必须轮流从 I2C 总线访问数据。图 12.1 展示了 I2C 总线配置的概述:

图 12.1 – I2C 总线概述
如 图 12.1 所示,总线允许连接两种主要类型的设备:一个 控制器(也称为 主设备)和一个 外围设备(也称为 从设备)。控制器通常是微控制器板,但它也可以是个人计算机或其他类型的设备,它将从外围设备(s)接收、发送、处理和使用数据。外围设备可以是提供数据给控制器的传感器,或者是一个显示设备(如 LCD),其中控制器发送的数据将被显示。还可以连接其他类型的设备到 I2C 总线。
注意
并非所有液晶显示器(LCDs)都可以直接连接到 I2C 总线。为了做到这一点,LCD 必须连接一个 I2C 适配器,通常称为 I2C 背包 或 I2C 模块。这是一个处理 I2C 通信的小型电子电路,通常附着在一些 LCD 的背面。
I2C 总线包含两条数据线(电线),称为 SDA 和 SCL。SCL 线传输总线上传送数据所需的时钟信号,而 SDA 线是数据信号,负责在控制器(s)和外围设备(s)之间传输所有数据。
连接到 I2C 总线的设备还有两根额外的线。其中一根是地线(有时标记为GND或Vss)。这根线应该连接到电子电路的公共地,其中微控制器板连接到,并且一根电压线(标记为Vdd)。这根线连接到 5 伏,但有时也可以用 3.3 伏。I2C 协议相当健壮,允许最高达到 5 Mbit/s 的比特率。通常,微控制器板为连接到 I2C 总线的设备提供 5 伏或 3.3 伏。
许多微控制器板支持 I2C 协议。幸运的是,Blue Pill 包含用于此目的的 I2C 引脚。实际上,Blue Pill 有三组引脚,可以直接连接三个 I2C 设备。在本章中,我们将使用 Blue Pill 的 B6(SCL)和 B7(SDA)引脚进行 I2C 通信。
注意
Arduino 微控制器板也支持 I2C 协议。例如,Arduino Uno 板的 A4 和 A5 引脚分别提供 SDA 和 SCL 线的连接。
值得注意的是,I2C 协议由Wire.h库处理,该库默认位于 Arduino IDE 配置中。您不需要安装此库。
在下一节中,我们将回顾如何使用 Arduino Uno 微控制器板编写 I2C 协议以获取红外传感器的温度数据。
I2C 编码
在本节中,我们回顾了通过 Arduino Uno 微控制器板作为外围设备(从设备)读取 MLX90614 红外传感器温度数据的代码。该板将通过 I2C 总线将温度数据发送到 Blue Pill,而 Blue Pill(作为控制器)将在 LCD 上显示它。这个 LCD 也连接到 I2C 总线。关于 Blue Pill 和 Arduino Uno 连接的完整描述可以在将红外温度传感器连接到微控制器板部分找到。
下一节将解释在 Arduino Uno 板上运行的必要代码。
编写 Arduino Uno 软件(外围设备)
为了在 Arduino Uno 上编写读取 MLX90614 红外传感器数据的程序,我们将使用一个库,该库将包含在我们的 Arduino IDE 程序中,称为Adafruit_MLX90614.h。您可以从 Arduino IDE 安装此库:
- 
转到工具 | 管理库。 
- 
将类型设置为所有,将主题设置为所有。 
- 
在搜索框中,输入 Adafruit MLX90614。
安装Adafruit MLX90614库的最新版本(不要安装 Mini 版本)。Wire.h库控制 I2C 协议,该库已安装在 Arduino IDE 的文件中。
以下是在 Arduino Uno 上运行的代码(其文件名为peripheral.ino;您可以在 GitHub 页面上找到它)。0X8是分配给 Arduino Uno 板作为 I2C 协议的从设备(外围设备)的十六进制地址。我们任意分配了 0x8;它可以是任何十六进制地址,但请确保主设备和从设备使用相同的地址:
#include <Wire.h> 
#include <Adafruit_MLX90614.h> 
Adafruit_MLX90614 mlx = Adafruit_MLX90614(); 
#define SLAVEADDRESS 0x8  
float AmbientobjC=0.0; 
此函数将 Arduino Uno 设置为从设备,分配给它 0x8 地址。Blue Pill 将使用此地址识别 Arduino Uno。此函数还设置了处理来自控制器(主设备)的请求的中断,即 Blue Pill。Blue Pill 将从传感器获取温度数据:
void setup() {  
  Wire.begin(SLAVEADDRESS);
  Wire.onRequest(requestEvent); 
}
此函数将连续从传感器读取温度。delay函数使传感器有机会获取新的温度读数:
void loop() {
  AmbientobjC=mlx.readObjectTempC();
  delay(100);
}
此函数每次控制器(主设备)从外围设备(从设备)请求数据时都会运行:
void requestEvent() { 
  union floatToBytes {
    char buffer[4];
    float objtempReading;
  } converter;
  converter.objtempReading = AmbientobjC+3;
  Wire.write(converter.buffer, 4); 
}
从之前的代码片段中,我们可以看到write()函数用于将温度数据发送到控制器(Blue Pill)。
我们将3的值添加到AmbientobjC变量中,以补偿环境温度。重要的是要明确,温度读数不是绝对的,并且会因多种因素略有变化,包括环境温度、是否有人在外面。因此,您可能需要多次测试温度读数,并相应地调整AmbientobjC变量,也许可以将传感器读数与医疗体温计读数进行比较。
注意
上传到 GitHub 平台的代码包含大量注释,解释了大多数代码行。
下一个部分解释了运行 Blue Pill 作为控制器所需的代码。
编写 Blue Pill 软件(控制器)
以下代码(其文件名为controller.ino;您可以在 GitHub 页面上找到它)将在 Blue Pill 微控制器板上运行(控制器)。此代码将用于获取由 Arduino Uno 板发送的温度数据,并将其显示在连接到 I2C 总线的 LCD 上:
#include <LiquidCrystal_I2C.h> 
LiquidCrystal_I2C lcd(0x27, 16, 2);
#include <Wire.h> 
#define SLAVEADDRESS 0x8  
之前的代码片段展示了用于通过 I2C 协议控制 LCD 的LiquidCrystal_I2C.h库。其下一行将 LCD 地址设置为0x27,用于 16 字符和 2 行(16x2)LCD。该库可以从github.com/fdebrabander/Arduino-LiquidCrystal-I2C-library下载。下载LiquidCrystal_I2C.h文件并将其复制到 Arduino 库文件夹中,通常为Arduino/libraries。
下一代码片段开始使用外围(从设备)地址启动 I2C 连接,初始化串行监视器和 LCD:
void setup() {
  Wire.begin(SLAVEADDRESS); 
  Serial.begin(9600); 
  lcd.begin();  
  lcd.backlight(); 
}
此loop()函数连续读取由外围设备(Arduino Uno)发送的温度数据:
void loop() {
   Wire.requestFrom(8, 4);
   uint8_t index = 0;
   union floatToBytes {
       char buffer[4];
       float objtempReading; 
   } converter;
   while (Wire.available()){ 
      converter.buffer[index] = Wire.read(); 
      index++;
   }
   Serial.println(converter.objtempReading); 
   lcd.setCursor(0, 0);  
   lcd.print("Body Temp.:"); 
   lcd.print(converter.objtempReading);
   delay(500);
}
之前的代码片段展示了如何从 Arduino Uno 读取字节数据。请记住,我们无法直接通过 I2C 总线传输浮点值。运行在 Arduino Uno 上的代码将每个浮点温度数据读数转换为四个字符的字节。运行在 Blue Pill 上的代码将这四个字节转换回浮点数。
提交给 GitHub 页面的代码包含许多注释,解释了代码行。
以下部分解释了如何将红外传感器连接到 Blue Pill 微控制器板。
将红外温度传感器连接到微控制器板
本节解释了 MLX90614 温度传感器的主要技术特性,并展示了如何使用I2C 协议将其连接到 Blue Pill 微控制器板。
首先,让我们解释 MLX90614 传感器的主要特性。
MLX90614 红外传感器
MLX90614 传感器由 Melexis 公司制造,是一款功能强大且紧凑的红外传感器。该传感器使用红外线来测量人体或任何物体产生的热量。作为一种非接触式体温计,它减少了在检查体温时传播疾病的机会,并且不需要清洁。
MLX0-614 在技术上是一个包含在集成电路(IC)中的传感器,因为它具有额外的电子组件和较小的电路,包括 ADC、电压调节器和数字信号处理器(DSP)。
以下是一些传感器的技术特性:
- 
体温范围为-40 至+125 摄氏度。 
- 
环境温度范围为-70 至 382.2 摄氏度。 
- 
医疗(高)精度校准。 
- 
测量分辨率接近 0.02 摄氏度。 
- 
该传感器有 3 伏和 5 伏两种版本。 
- 
一种方便的睡眠模式,可降低功耗。 
MLX90614 系列传感器的数据表可以从以下链接下载:
www.melexis.com/-/media/files/documents/datasheets/mlx90614-datasheet-melexis.pdf
MLX90614 红外传感器生成两种类型的温度测量:环境温度和物体温度读数。环境温度是传感器红外敏感部分(内部组件)上记录的温度,接近室温。物体温度测量物体发出的红外光量,可用于测量体温。在本章中,我们将仅使用物体温度测量。
图 12.2显示了 MLX90614 传感器:

图 12.2 – 显示其四个引脚的 MLX90614 传感器
在图 12.2中,请注意传感器上有一个圆形透明窗口,红外光线通过该窗口,击中内部敏感部分。这个部分将红外光转换为电脉冲。
图 12.3显示了 MLX90614 传感器图引脚图的顶部视图:

图 12.3 – MLX90614 红外传感器引脚图
在图 12.3中,你会注意到传感器顶部有一个小缺口。这个缺口有助于你识别哪个引脚是哪个。
MLX90614 的 SCL 和 SDA 引脚分别连接到微控制器板的 SCL 和 SDA,地线引脚连接到微控制器板的地线,电压引脚连接到 3.3 伏或 5 伏。
MLX90614 传感器以不同的类型或版本制造。其中最重要的区别之一是其供电电压。验证其零件号非常重要:
- 
MLX90614ESF-Axx,MLX90614KSF-Axx:它们的供电电压为 5.5 伏。 
- 
MLX90614ESF-Bxx,MLX90614ESF-Dxx:它们的供电电压为 3.6 伏。 
例如,我们本章使用的红外传感器是 MLX90614ESF-DCA-000,根据制造商的数据表,它需要 3.6 伏才能工作。因此,你可以使用许多微控制器板提供的 3.3 伏电压来使用这种类型的传感器。
重要提示
总是检查红外传感器的零件号以确定其所需的供电电压。如果你施加高于其所需供电电压的电压,可能会损坏传感器。
另一个你应该考虑的技术方面是传感器的视野范围。这是指传感器与被测物体之间的距离关系。这将决定传感器观察到的感应区域。每当物体从传感器表面移动 1 厘米,感应区域就会增加 2 厘米。理想情况下,传感器与被测物体(例如,人体皮肤)之间的距离应该在 2 到 5 厘米之间。
下一个部分将解释 GY-906 模块,其中包含一个红外传感器。
GY-906 传感器模块
本节描述了 GY-906 传感器模块的主要特性和引脚配置。MLX90614 传感器(见图 12.4)也以模块形式出售,称为GY-906:

图 12.4 – GY-906 模块
如图 12.4所示,GY-906 模块有四个专用引脚用于 I2C 通信。VIN 引脚连接到电压,具体为 3.3 伏或 5 伏,这取决于它所包含的 MLX90641 传感器的类型。请参考MLX90614 红外传感器部分以帮助识别模块中嵌入式传感器的所需电压。你还需要查阅模块的数据表。例如,一个 GY-906 模块可能内置了 MLX90614ESF-DCA-000 红外传感器,需要 3.3 伏才能工作。因此,GY-906 模块可能内置了任何 MLX90614 传感器类型。模块的 GND 引脚连接到微控制器板的地线。SCL 引脚用于传输时钟信号,SDA 引脚用于传输数据信号。
除了 MLX90614 传感器外,GY-906 模块还包含其他电子元件,例如上拉电阻。
使用 MLX90614 传感器或 GY-906 模块的决定取决于多个因素,包括成本、应用类型和尺寸。请注意,GY-906 模块比 MLX90614 传感器略大。在本章中,我们将使用 MLX90614 传感器而不是模块,因为单独的传感器是一个经济实惠的选择,并且可以展示如何直接将传感器连接到 I2C 总线。然而,GY-906 模块和 MLX90614 传感器具有相同的功能。
下一节将展示如何将 MLX90614 传感器连接到微控制器板。
红外传感器与 Arduino Uno 的连接
在本节中,我们描述了如何将 MLX90614 传感器连接到 Arduino Uno 微控制器板上的 I2C 引脚,该板将作为外围设备(从设备)。Blue Pill 板将是控制器(主设备),通过 I2C 总线接收 Arduino Uno 发送的温度数据,如图12.5所示:

图 12.5 – 控制器和外围设备
如图 12.5所示,Blue Pill 和 Arduino Uno 板都连接到 I2C 总线。
我们将 MLX90614 连接到 Arduino Uno 板,作为外围设备(从设备),以下是一些原因:
- 
为了利用 I2C 数据传输协议,该协议只需要两条数据线。 
- 
为了练习使用控制器(主设备)和外围设备(从设备)实现 I2C 协议。 
- 
为了使用与 Arduino 系列等其他微控制器板(例如)完全兼容的 MLX90614 软件库,但不与 Blue Pill 板兼容。这就是为什么我们使用相应的库将红外传感器连接到 Arduino Uno 板。这样,我们可以使用 Arduino Uno 作为外围设备(从设备),它与红外传感器 100%兼容。 
- 
为了让 Blue Pill(控制器)从直接处理传感器数据中解放出来,以便 Blue Pill 可以用于执行其他处理密集型任务。此外,Blue Pill 可以专门用于获取传感器数据并在 LCD 上显示。 
首先,我们将解释如何将 MLX90614 红外传感器连接到 Arduino Uno 微控制器板。连接图示在图 12.6中:

图 12.6 – Arduino Uno 和红外传感器的连接
如图 12.6所示,传感器连接到模拟端口 A4 和 A5,这些也是 Arduino Uno 的 I2C 引脚。传感器数据手册建议使用 0.1 微法拉电容器来平滑掉传感器中可能存在的任何高频或超高频电气噪声,这些噪声可能会影响温度读数。以下是连接所有设备的步骤:
- 
如果您使用的是 MLX90614ESF-DCA-000 或 MLX90614ESF-BAA-000 传感器,请将其电压(VDD)引脚连接到 Arduino Uno 的 3.3 伏特引脚。如果您使用的是 MLX90614ESF-AAA-000 或 MLX90614KSF-ACC-000 传感器,请将其连接到 Arduino Uno 的 5 伏特引脚。 
- 
将传感器的地线(VSS)引脚连接到 Arduino Uno 的地线(GND)引脚。 
- 
将传感器的 SDA 引脚连接到 Arduino Uno 的 A4 模拟端口。 
- 
将传感器的 SCL 引脚连接到 Arduino Uno 的 A5 模拟端口。 
- 
将 0.1 微法拉电容的一端连接到传感器的电压引脚,另一端连接到传感器的地线引脚。 
连接好电线和组件后,将代码上传到名为peripheral.ino的 Arduino Uno 板,该代码在编程 I2C 接口部分中解释。它应该在 Arduino IDE 的串行监视器上显示温度数据。按照以下步骤打开 Arduino Uno 的串行监视器:
- 
从 IDE 的主菜单中打开工具。 
- 
选择串行监视器选项。 
- 
从串行监视器中,确保选择9600波特率。 
- 
不要忘记从工具 | 板中选择Arduino Uno。 
- 
选择 Arduino Uno 连接的正确 USB 端口,从 Arduino IDE 中点击工具 | 端口。 
下一节描述了如何使用 I2C 总线将 Blue Pill 连接到 Arduino Uno,以及如何从 Arduino Uno 传输温度数据到 Blue Pill。
将 Blue Pill 连接到 Arduino Uno
本节展示了如何通过 I2C 总线连接 Arduino Uno 和 Blue Pill。Arduino Uno 将发送红外温度数据到 Blue Pill。请记住,Blue Pill 作为控制器(主设备)工作,而 Arduino Uno 是外围设备(从设备)。图 12.7显示了两个微控制器板的 Fritzing 图。

图 12.7 – Blue Pill 和 Arduino Uno 的 I2C 连接
如图 12.7所示,以下是连接 Blue Pill 到 I2C 总线的步骤:
- 
将 Arduino Uno 的地线(GND)连接到 Blue Pill 的地线(G 或 GND)。
- 
将 Blue Pill 的 B7 引脚连接到 MLX90614 的 SDA 引脚。 
- 
将 Blue Pill 的 B6 引脚连接到 MLX90614 的 SCL 引脚。 
如图 12.7中所示的所有连接,Blue Pill、红外传感器和 Arduino Uno 板都通过 SDA 和 SCL 引脚连接。这是我们应用中的 I2C 总线。
重要提示
确保将 Blue Pill 的地线(G或GND)连接到 Arduino Uno 的地线(GND)。这将允许两个微控制器板之间通过 I2C 总线正确传输数据。
以下部分描述了如何使用 I2C 总线在 LCD 上显示红外温度测量值。
在 LCD 上显示温度
本节描述了如何通过 I2C 总线在 LCD 上显示红外温度测量值。温度数据由 Arduino Uno 发送到 Blue Pill,如前所述。图 12.8 展示了一个包含微控制器板、LCD 和红外温度传感器的 Fritzing 图:

图 12.8 – LCD 连接到 I2C 总线
如 图 12.8 所示,LCD 的连接很简单。它只需要四根线,因为本章使用的 LCD 是 I2C 兼容的,后面有一个 I2C 接口。以下是连接 LCD 到 Blue Pill 的步骤:
- 
将 LCD 的接地( GND)引脚连接到 Blue Pill 的接地(G或GND)引脚。
- 
将 LCD 的电压( VCC)引脚连接到 Blue Pill 的 5 伏(5V)引脚。
- 
将 LCD 的 SDA 引脚连接到 Blue Pill 的 B7 引脚。 
- 
将 LCD 的 SCL 引脚连接到 Blue Pill 的 B6 引脚。 
图 12.9 描述了 LCD 的背面,显示了其 I2C 接口背板连接到它:

图 12.9 – LCD 的背面
从 图 12.9 中,你可以看到 LCD 的 I2C 接口有一个小可变电阻,位于大 IC 的右侧。你可以旋转它来调整 LCD 的对比度。
LCD 的每行可以显示多达 16 个字符。这足以以两位精度和两位小数显示红外传感器的温度。
重要提示
确保将 LCD 的电压(VCC)连接到 Blue Pill 的5V。如果你将其连接到 3.3 伏引脚,它可能无法正常工作。
图 12.10 展示了所有连接方式:

图 12.10 – 微控制器板、传感器和 LCD
图 12.10 显示 LCD 显示的温度为 28.53 摄氏度,因为当拍照时,红外传感器无意中测量了 LED 灯的温度!然而,这个电路的目的是用于测量体温。下一节将展示如何通过检查人体不同部位的温度来测试传感器。我们使用了两个连接到 Blue Pill 和 Arduino Uno 的移动电源来尝试。如果你已经完成了温度传感器和微控制器板的连接,并且如果你的 LCD 正在显示温度值,恭喜你!你学会了如何使用非接触式红外温度传感器。
测试温度计
在本节中,我们将测试红外传感器作为温度计的工作情况,通过测量人体温度。似乎不同的身体部位会得到略微不同的温度测量值。你应该通过测量不同部位的温度,如人的额头和耳垂,进行多次测试。记住,传感器和皮肤之间的距离应在 2 至 5 厘米之间,尽管你应该尝试不同的距离并观察结果。
在测试温度计之前,确保皮肤干燥、清洁且无遮挡。此外,确认此人没有暴露在高温环境中,例如在炎热的阳光下,因为这会改变你的测量结果。如果你使用温度计测量皮肤温度,确保此人不在直射阳光下,否则你会得到错误的读数。
医学研究显示,人体平均皮肤表面温度在 36.3 至 36.6 摄氏度之间。这被认为是正常的。然而,高于 37 摄氏度的温度提示可能是发烧。
在考虑了这些提示之后,让我们看看我们的温度计是如何工作的。图 12.11显示了一个正在测试红外传感器的个人:

图 12.11 – 测量温度
如图 12.11所示,测量的温度为 36.55 摄氏度,这是成年人的正常范围。测试者需要将她的额头靠近红外传感器以获得可靠的测量值。可以通过在传感器上方放置一个镜子管来增加额头和传感器之间的距离,以引导红外光通过它。
现在我们已经测试了本章,并意识到温度计工作得非常完美,让我们在摘要中回顾一下我们学到了什么。
摘要
在本章中,你学习了使用 I2C 串行数据传输协议将红外温度传感器连接到微控制器板的基本知识。正如你所见,I2C 总线是我们本章构建的红外温度计的一个重要部分。这种红外温度计可以有效地检查人体温度,就像普通温度计一样。由于温度测量是非接触式的,这可以防止人体接触传感器,从而避免传播如 SARS-CoV-2 等病毒。
这种非接触式温度计可以帮助检查一个人是否发烧,从而确定(与其他测量结果一起)此人是否感染了 COVID-19。然而,本章中解释的红外温度测量不应作为确定一个人是否患有 COVID-19 的最终数据。
下一章解释了另一个与 COVID-19 相关的项目,即使用超声波传感器测量两人之间推荐的 2 米距离。
进一步阅读
- 
体温 (2020)。体温:什么是(以及什么不是)正常的?可从 health.clevelandclinic.org/body-temperature-what-is-and-isnt-normal/获取
- 
Gay, W. (2018) I2C, 《STM32 入门》,Apress,加利福尼亚州伯克利 
- 
I2C (2021),I2C 教程。可从 learn.sparkfun.com/tutorials/i2c/all获取
- 
Mankar, J., Darode, C., Trivedi, K., Kanoje, M. 和 Shahare, P. (2014), I2C 协议综述,国际研究前沿技术杂志,2(1) 
第十三章:第十三章:COVID-19 社交距离警报
当世界庆祝 2020 年的到来时,一场由于一种新疾病:COVID-19 而引发的流行病正在兴起。随着这种大流行的出现,所有的人类活动都受到了不同程度的影响。
在这个意义上,教育部门是最受影响的之一。全球所有学校都暂时停止了活动,因为这些环境中的感染风险可能非常高。经过几个月的封锁后,全球各地的学校逐渐开始恢复面对面活动,遵循严格的消毒标准和确保学生与学校工作人员之间保持物理距离的协议(Global Education Cluster, 2020)。
世界卫生组织(WHO)推荐的物理距离是人与人之间至少保持 1 米(m)(3 英尺(ft))的距离,2 m(6 ft)是最一般的推荐,以最大限度地减少儿童(KidsHealth, 2021)感染的风险。这一措施被称为社交距离。此外,技术有时可以作为强制执行这些措施的一种很好的方式。
在这一章中,你将学习如何创建一个使用微控制器技术来强制执行社交距离的设备,以帮助孩子们养成保持安全物理距离的习惯。当他们的距离不是安全的物理距离时,他们会从设备那里收到声音警报。你将创建的设备可以作为孩子们日常使用的可穿戴设备,将其放入一个盒子里,用作项链,如下面的截图所示:

图 13.1 – 儿童可穿戴社交距离设备
在这一章中,我们将涵盖以下主要主题:
- 
编程压电蜂鸣器 
- 
将超声波传感器连接到微控制器板 
- 
编写一个从超声波传感器获取数据的程序 
- 
测试距离计 
通过完成这一章,你将了解如何使用STM32 Blue Pill 板编程电子距离范围测量。你还将学习如何在距离测量为小于 2 m 时播放警报。
重要提示
这个项目仅用于演示和学习目的。请勿将其用作预防 COVID-19 感染风险的初级社交距离警报。
技术要求
开发社交距离警报所需的硬件组件列表如下:
- 
一个无焊面包板。 
- 
一个 Blue Pill 微控制器板。 
- 
需要 1 个 ST-LINK/V2 电子接口将编译后的代码上传到 Blue Pill 板。请注意,ST-LINK/V2 接口需要四根母对母跳线。 
- 
一个 HC-SR04 超声波传感器。 
- 
一个蜂鸣器。 
- 
公对公跳线。 
- 
母对公跳线。 
- 
一个电源。 
- 
用于盒子的纸板。 
如往常一样,你需要 Arduino 集成开发环境(IDE)和本章的 GitHub 仓库,该仓库可在github.com/PacktPublishing/DIY-Microcontroller-Projects-for-Hobbyists/tree/master/Chapter13找到。
本章的“代码在行动”视频可在以下链接找到:bit.ly/3gS2FKJ
让我们开始吧!
编程压电 buzzer
在本节中,你将学习 buzzer 是什么,如何将其与 STM32 Blue Pill 接口,以及如何编写程序来构建警报声音。
压电 buzzer 是一种产生音调和蜂鸣声的设备。它使用压电效应,即压电材料将机械应力转换为电,并将电转换为机械振动。压电 buzzer 包含一个具有这些特性的晶体,当施加电压时,它会改变形状。
如本章其他章节常见,你可以找到一个通用的开发模块,使用起来相当简单,如下截图所示:

图 13.2 – 马达 buzzer 开发板
此开发板通过三个引脚连接到 STM32 Blue Pill 微控制器板,如下所述:
- 
输入/输出(I/O):此引脚必须连接到微控制器的数字输出。 
- 
电压公共收集器(VCC):为传感器供电的引脚(5 伏,或 5V)。 
- 
地(GND):地连接。 
接下来,你将学习如何将这些引脚与 Blue Pill 微控制器板接口。
连接组件
你需要一个无焊点面包板来将 buzzer 连接到 STM32 Blue Pill 微控制器板,以及一根线来连接组件。按照以下步骤操作:
- 
你需要将 STM32 Blue Pill 和 buzzer 放入无焊点面包板,并在面包板上留出空间以连接跳线。 
- 
将传感器的 GND 引脚连接到 STM32 Blue Pill 的 GND 端口。 
- 
接下来,你需要将 VCC 引脚连接到 STM32 Blue Pill 的 5V 总线。 
- 
最后,将 buzzer 的 I/O 引脚连接到 Blue Pill 的 B12 引脚。以下截图显示了所有连接到无焊点面包板的组件: 

图 13.3 – 马达 buzzer 与 Blue Pill 的接口
以下截图展示了 STM32 Blue Pill 和马达 buzzer 之间的所有连线,并汇总了我们刚刚进行的步骤:

图 13.4 – 压电 buzzer 连接电路
到目前为止,我们已经探讨了压电蜂鸣器和它们的组件及功能。你还学习了如何使用无焊面包板将它们连接到 STM32 Blue Pill 微控制器板。
现在,你准备好用 C 语言编写程序,在蜂鸣器中重现可听警报。不要忘记使用STLink将脚本上传到 STM32 Blue Pill 微控制器板。
让我们开始开发一个程序,使用 STM32 Blue Pill 播放可听警报,如下所示:
- 
让我们开始定义 STM32 Blue Pill 卡引脚中哪个引脚将被用于在蜂鸣器中播放声音。运行以下代码: const int PB12 pin (labeled B12 on the Blue Pill).
- 
接下来,我们将留空 setup()部分。你不需要为此脚本初始化代码。
- 
完整的代码位于 loop()部分,如下代码片段所示:void loop() { tone(pinBuzzer, 1200); delay(250); noTone(pinBuzzer); delay(500); tone(pinBuzzer, 800); delay(250); noTone(pinBuzzer); delay(500); }我们正在使用两个新函数: tone()和noTone()。让我们看看它们的功能是什么。tone()函数从一个引脚生成特定频率的方波。其语法是tone(pin, frequency, duration),其中pin参数是连接蜂鸣器的 Blue Pill 引脚。frequency是音调的频率,以unsigned int类型表示。duration参数是音调的持续时间,以unsigned long类型表示。noTone()停止使用tone()启动的方波生成。如果没有先前生成音调,则不会生成错误。其语法是noTone(pin),其中pin是生成音调的引脚。因此,前面的代码使用 delay()函数启动一个 1,200 Hz 的音调并保持 250 ms。随后,它停止音调并等待 500 ms,在 250 ms 内生成一个新的音调,现在为 800 Hz,并再次使用相同的 500 ms 暂停停止它。这些步骤在程序运行期间重复,以模拟警报声音。
此功能的代码现在已完成。你可以在 GitHub 仓库的Chapter13/buzzer文件夹中找到完整的草图。
让我们查看我们如何进步我们的学习。我们发现了一个播放音调的组件,学习了如何将其连接到 STM32 Blue Pill 微控制器,并编写了播放可听警报的代码。
在本节中你获得的所有技能将使你能够创建其他需要播放和可听警报的电子系统。接下来,我们将学习超声波传感器。
将超声波传感器连接到微控制器板
在继续前进之前,我们需要了解 HC-SR04 超声波传感器的功能,如何将其与STM32 Blue Pill连接,以及如何编写程序来测量传感器与另一个物体之间的距离。
该传感器发出超声波。当这波与物体碰撞时,波被反射并被传感器接收。当接收到反射信号时,传感器可以计算反射所需的时间,从而测量碰撞物体的距离。
传感器可以在以下屏幕截图中看到:

图 13.5 – 超声波传感器
此传感器板通过四个引脚连接到 STM32 Blue Pill 微控制器板,如下所述:
- 
触发:此引脚启用超声波。 
- 
回声:此引脚接收反射波。 
- 
VCC:为传感器供电的引脚(5V)。 
- 
GND:接地连接。 
接下来,是时候将这些引脚与 Blue Pill 微控制器进行接口连接了。
连接组件
需要使用无焊点面包板将蜂鸣器连接到 STM32 Blue Pill 微控制器,并使用电线连接组件。按照以下步骤进行:
- 
您需要将 STM32 Blue Pill 和传感器放入无焊点面包板,并留出空间连接跳线。 
- 
将传感器的 GND 引脚连接到 SMT32 Blue Pill 的 GND 端子。 
- 
接下来,您需要将 VCC 引脚连接到 STM32 Blue Pill 的 5V 总线。 
- 
最后,将蜂鸣器的触发引脚连接到 C14 引脚,将回声引脚连接到 Blue Pill 的 C13 引脚。以下截图显示了所有连接到无焊点面包板上的组件: 

图 13.6 – 钛锌电蜂鸣器与 Blue Pill 的接口
以下截图显示了 STM32 Blue Pill 和超声波传感器之间的所有连线:

图 13.7 – 超声波传感器连接电路
到目前为止,您已经学习了如何使用无焊点面包板将传感器连接到 STM32 Blue Pill 微控制器板。
现在,您将学习如何用 C 语言编写程序,在蜂鸣器中产生可听见的警报。别忘了使用STLink将脚本上传到 STM32 Blue Pill 微控制器板。
编写用于获取超声波传感器数据的程序
在本节中,您将学习如何编写程序以从超声波传感器收集数据。让我们开始,如下所示:
- 
首先,我们将定义 STM32 Blue Pill 卡上哪些引脚将用于读取传感器数据。同时,我们将声明两个变量来保存声波传播的持续时间,另一个用于计算传播的距离,如下所示: const int pinTrigger = PC14; const int pinEcho = PC13; long soundWaveTime; long distanceMeasurement;选择的引脚是 PC13 和 PC14 引脚(在 Blue Pill 上标记为 C13 和 C14)。 
- 
接下来,在 setup()函数中,开始串行通信。您需要将触发引脚设置为输出引脚,将回声引脚设置为输入引脚。我们需要将触发引脚初始化为LOW值。代码如下所示:void setup() { Serial.begin(9600); pinMode(pinTrigger, OUTPUT); pinMode(pinEcho, INPUT); digitalWrite(pinTrigger, LOW); }
- 
现在,我们将编写 loop()函数。我们需要启动超声波,等待 10 秒(sec),然后关闭超声波。代码如下所示:void loop() { digitalWrite(pinTrigger, HIGH); delayMicroseconds(10); digitalWrite(pinTrigger, LOW); ... }
- 
下一步是读取传感器的回声引脚,以了解波的往返总时间。我们使用 pulseIn()函数来完成此操作,并将其存储在最初声明的变量中,为此目的。为了计算距离,我们将返回脉冲的值除以 59,以获得厘米(cm)距离,如下面的代码片段所示:void loop() { digitalWrite(pinTrigger, HIGH); delayMicroseconds(10); digitalWrite(pinTrigger, LOW); soundWaveTime = pulseIn(pinEcho, HIGH); distanceMeasurement = soundWaveTime/59; ... }
- 
最后,你将在串行控制台中显示传感器与设备前方任何物体之间的距离值,如下所示: void loop() { digitalWrite(pinTrigger, HIGH); delayMicroseconds(10); digitalWrite(pinTrigger, LOW); soundWaveTime = pulseIn(pinEcho, HIGH); distanceMeasurement = soundWaveTime/59; Serial.print("Distance: "); Serial.print(distanceMeasurement); Serial.println("cm"); delay(500); }
此功能的代码现在已完成。你可以在 GitHub 仓库的Chapter13/ultrasonic文件夹中找到完整的草图。
在本节结束时,你学习了如何用 C 语言编写程序来测量连接到 STM32 的超声波传感器与物体之间的距离。
通过这些技能,你将能够开发需要距离测量的电子项目,例如汽车倒车防撞。
测试距离计
在测试距离计之前,我们需要将蜂鸣器和超声波传感器连接到无焊点面包板上的 SMT32 Blue Pill。以下截图展示了包括 STM32、超声波传感器和蜂鸣器在内的完整电路图:

图 13.8 – 我们社交距离设备的完整电路图
下面的截图显示了实际系统中所有组件的连接方式:

图 13.9 – 蜂鸣器和超声波传感器的连接
现在,为了完成完整社交距离设备的连接,我们需要编写一个新的脚本,该脚本结合了Chapter13/buzzer和Chapter13/ultrasonic脚本。新脚本将命名为Chapter13/distance_meter。按照以下步骤操作:
- 
我们需要声明两个脚本的常量和变量,并添加一个新的脚本以定义传感器设备与另一个物体之间的安全距离。以下代码片段展示了如何实现此操作: const int pinTrigger = PC14; const int pinEcho = PC13; const int pinBuzzer = PB12; const int distanceSafety = 200; long soundWaveTime; long distanceMeasurement;对于 COVID-19 社交距离,我们将使用 200 厘米(2 米)。 
- 
setup()函数与超声波脚本相同,如下面的代码片段所示:void setup() { Serial.begin(9600); pinMode(pinTrigger, OUTPUT); pinMode(pinEcho, INPUT); digitalWrite(pinTrigger, LOW); }
- 
最后,在 loop()函数中,我们将包含一个条件来验证我们的社交距离设备是否与另一个人(物体)物理上分离少于 2 米。如果是这种情况,播放声音警报。以下是实现此功能的代码:void loop() { digitalWrite(pinTrigger, HIGH); delayMicroseconds(10); digitalWrite(pinTrigger, LOW); soundWaveTime = pulseIn(pinEcho, HIGH); distanceMeasurement = soundWaveTime/59; Serial.print("Distance: "); Serial.print(distanceMeasurement); Serial.println("cm"); delay(500); if (distanceMeasurement < distanceSafety) { Serial.println("Sound alert"); tone(pinBuzzer, 1200); delay(250); noTone(pinBuzzer); delay(500); tone(pinBuzzer, 800); delay(250); noTone(pinBuzzer); delay(500); } }
现在,你可以测量社交距离,并且我们的设备可以作为学校中的项链使用,以保持安全的物理距离,仅作为官方安全指南的补充。
为了实现这一点,我们可以创建一个纸盒外壳,并将我们的设备插入其中。打印以下截图所示的模板——您可以从Chapter13/cardboard GitHub 文件夹中下载此模板:

图 13.10 – 我们设备的纸盒模板
为了更好地将我们的电子设备放入外壳中,建议将用于构建原型的跳线(公对公)更换为公对母跳线,并使用 5V 电池供电,如下面的截图所示:

图 13.11 – 适应纸盒模板的连接
最后,剪下并粘贴外壳,将我们刚刚创建的设备放入外壳中,以创建一个可穿戴设备,如下面的截图所示:

图 13.12 – 我们设备的纸盒模板
使用这个设备,您将知道您是否处于安全距离,以避免可能的通过飞沫传播的 COVID-19 感染。
我们已经到达了第十三章的结尾。恭喜!
摘要
在这个项目中我们学到了什么?首先,我们学习了如何将压电蜂鸣器连接到我们的 Blue Pill 微控制器板,并编写程序以播放可听警报。然后,我们编写了一个程序来测量我们的电子设备与另一个物体之间的距离。
我们还学习了如何将两个项目结合起来,创建一个可以用于在 COVID-19 大流行期间保持安全物理距离的社交距离设备——例如,在学校,因为孩子们更容易分心,而且更友好、更社交。
重要的是要提醒您,这个项目是为了学习目的,不应在任何情况下用作预防 COVID-19 传播风险的初级警报。这主要是因为,目前我们知道主要风险是空气传播的。
在下一章中,我们将学习如何构建一个 20 秒的手部清洗计时器。
进一步阅读
- 
全球教育集群. 安全返校:实践者指南. 联合国教科文组织. 2020: healtheducationresources.unesco.org/library/documents/safe-back-school-practitioners-guide
- 
KidsHealth. 冠状病毒(COVID-19):与儿童保持社交距离. 2021: kidshealth.org/en/parents/coronavirus-social-distancing.html
第十四章:第十四章:COVID-19 20 秒洗手计时器
本章描述了一个有用的项目,您将通过在超声波传感器前挥手来制作一个非接触式计时器。这个计时器将计算卫生部门推荐的至少 20 秒的洗手时间,以防止由 SARS-CoV-2 病毒引起的 COVID-19 症状。该项目涉及一个价格低廉的超声波传感器,该传感器通过测量用户与电路之间的距离来检测用户是否在挥手,从而触发计数。此应用必须封装在一个防水容器中,以避免用户洗手时电路进水并损坏。我们在本章末尾解释了如何做到这一点。
在本章中,我们将涵盖以下主要主题:
- 
编程计数器(计时器) 
- 
在 LCD 上显示计时器 
- 
将超声波传感器连接到微控制器板 
- 
将所有部件组装在一起——想想为这个项目设计一个保护壳! 
- 
测试计时器 
到本章结束时,您将学会如何正确地将超声波传感器和 LCD 连接到微控制器板上。此外,您还将学习如何从传感器读取输入值以激活 20 秒倒计时。您还将学习如何编写在微控制器板上运行的效率高且有效的计时器代码。
技术要求
本章中您将使用的软件工具是 Arduino IDE,用于编辑并将程序上传到 Blue Pill 微控制器板。
本章中使用的代码可以在本书的 GitHub 仓库中找到:
github.com/PacktPublishing/DIY-Microcontroller-Projects-for-Hobbyists/tree/master/Chapter14
本章的“代码在行动”视频可以在这里找到:bit.ly/3gQZdPf
在本章中,我们将使用以下硬件设备:
- 
一个无焊面包板。 
- 
一个 Blue Pill 微控制器板。 
- 
一根微 USB 线,用于将微控制器板连接到计算机和移动电源。 
- 
一个 USB 移动电源。 
- 
一个 ST-INK/V2 电子接口,用于将编译后的代码上传到 Blue Pill。请注意,ST-LINK/V2 需要四根公对公的杜邦线。 
- 
一个 HC-SR04 超声波传感器。 
- 
一个 1602 16x2 LCD。 
- 
一个 2.2k 欧姆、1/4 瓦的电阻。这是用于 LCD 的。 
- 
一打公对公和一打公对母的杜邦线。 
下一个部分将解释如何编写在 Blue Pill 微控制器板上运行的 20 秒计时器代码。
编程计数器(计时器)
本节展示了如何编写 20 秒计时器的代码。编写这样的计时器程序并不简单,因为用户可能会在计数器开启时通过超声波传感器多次挥手来激活计时器。如果 20 秒的计数正在进行,程序不应考虑这些多次激活;否则,计数器将多次重新启动,计数将不准确。我们还需要考虑在不使用时关闭 LCD 以节省能源。
我们应该按照以下步骤编写我们的 20 秒计时器应用程序:
- 
从超声波传感器读取值。 
- 
检查用户是否在距离传感器 15 厘米内挥手。如果发生这种情况,执行以下操作: a) 打开 LCD 背光。 b) 显示打湿双手的消息,并在 LCD 上显示 20 秒的计数。 c) 当计数器完成时,在 LCD 上显示此消息:洗手。 d) 等待 4 秒后关闭 LCD 以节省能源。 e) 返回到步骤 1。 
以下是在 Blue Pill 上运行的 Arduino IDE 代码,按照前面的步骤编程。以下代码片段显示了变量和常量的定义。HC-SR04 的回声数字值从端口A9(标记为PA9)获取并存储在echo变量中。同样,触发值通过端口A8(PA8)发送到超声波传感器,并存储在trigger变量中。请注意,dist_read变量存储了物体(例如,挥手的手)与超声波传感器之间的距离,单位为厘米:
#include "elapsedMillis.h" 
elapsedMillis timeElapsed;
#include <LiquidCrystal.h> 
const int rs = PB11, en = PB10, d4 = PB0, d5 = PA7, d6 =    PA6, d7 = PA5;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7); 
#define backLight PB12    
#define trigger PA8 
#define echo PA9   
const int max_dist=200; 
float duration,dist_read=0.0;  
如您从前面的代码中可以看到,它使用了一个名为elapsedMillis.h的库来计算计数过程中经过的毫秒数。这个库也可以从www.arduino.cc/reference/en/libraries/elapsedmillis/获取。您可以在上传到书籍 GitHub 仓库的代码文件夹中找到这个库。它很有用,因为通过使用这个库,我们避免了在 20 秒计数中使用delay()函数。如果我们使用delay()函数,Blue Pill 的计数和从端口读取传感器值可能会出错。请注意,库被写在了双引号中,因为在 C++中这意味着库与源代码在同一文件夹中,这是一个不属于原始 Arduino IDE 安装的库。代码还使用了LiquidCrystal.h库,用于控制 1602 LCD。这个库已经包含在标准的 Arduino IDE 安装中,因此不需要单独安装。
此代码片段设置了 LCD 和 Blue Pill 端口:
void setup() {
  lcd.begin(16, 2); 
  pinMode(trigger, OUTPUT);
  pinMode(echo,INPUT);
  pinMode(backLight, OUTPUT);
}
以下代码段显示了代码的主循环,它读取超声波传感器的值并计算用户挥手的手与传感器之间的距离:
void loop() {
  digitalWrite(trigger, LOW); 
  delayMicroseconds(2); 
  digitalWrite(trigger, HIGH); 
  delayMicroseconds(10); 
  digitalWrite(trigger, LOW); 
  duration = pulseIn(echo, HIGH);
  dist_read = (duration*.0343)/2;
以下代码段来自主循环函数,用于计算用户与传感器之间的距离是否等于或小于 15 厘米,然后激活 20 秒计数器并在 LCD 上显示:
  if ((dist_read<=15) & (dist_read>0)) 
  {
    lcd.display();
    digitalWrite(backLight, HIGH); 
    timeElapsed=0;
    lcd.setCursor(0, 0);
    lcd.print("lather hands :) ");
    lcd.setCursor(0, 1);
    lcd.print("  ");
    while (timeElapsed < 21000)
    { 
        lcd.setCursor(0, 1);
        lcd.print(timeElapsed / 1000);
     }
     lcd.setCursor(0, 0);
     lcd.print("rinse hands :)  ");   
     delay(4000);
  }
   lcd.noDisplay();
   digitalWrite(backLight, LOW);
}
小贴士
您也可以在 Arduino 微控制器板上运行前面的代码。您只需更改用于 LCD 和传感器连接的端口编号。例如,如果您使用 Arduino Uno 板,将此行更改为const int rs=12,en=11,d4=5,d5=4,d6=3,d7=2;,分别使用 Arduino 板数字端口12、11、5、4、3和2。您还需要将这些行更改为以下内容:
#define backLight 6
#define trigger 7
#define echo 8
因此,您将使用 Arduino 数字端口 6、7 和 8 来连接超声波传感器。
请记住,上传到 GitHub 仓库的代码包含许多注释,解释了其最重要的部分。
下一个部分将解释如何将 1602 LCD 连接到 Blue Pill,以显示 20 秒计数:
在 LCD 上显示计时器
在本节中,我们解释如何连接和使用 1602 LCD 来显示计时器。图 14.1显示了类似于在第五章中解释的 Fritzing 图,湿度和温度测量:

图 14.1 – 连接到 Blue Pill 微控制器板的 LCD
以下是将 LCD 连接到 Blue Pill 的步骤,按照图 14.1中的图解进行:
- 
将 Blue Pill 的GND(也标记为G)引脚连接到无焊面包板轨道。 
- 
将 Blue Pill 的5V引脚(提供 5 伏)连接到面包板轨道。 
- 
将 USB 线连接到 Blue Pill,然后连接到您的电脑或 USB 移动电源。 
- 
将 LCD 的 16 个引脚插入无焊面包板。 
- 
将 LCD 的VSS引脚连接到地(下方的面包板轨道)。 
- 
将 LCD 的VDD引脚连接到 5 伏(下方的面包板轨道)。 
- 
将 2.2k 欧姆电阻连接到 LCD 的V0引脚和地(下方的面包板轨道)。 
- 
将 LCD 的RS引脚连接到 Blue Pill 的B11引脚。 
- 
将 LCD 的RW引脚连接到地(下方的面包板轨道)。 
- 
将 LCD 的E引脚连接到 Blue Pill 的B10引脚。 
- 
将 LCD 的D4引脚连接到 Blue Pill 的B0引脚。 
- 
将 LCD 的D5引脚连接到 Blue Pill 的A7引脚。 
- 
将 LCD 的D6引脚连接到 Blue Pill 的A6引脚。 
- 
将 LCD 的D7引脚连接到 Blue Pill 的A5引脚。 
- 
将 LCD 的A引脚连接到 Blue Pill 的端口B12。 
- 
将 LCD 的K引脚连接到地(下方的面包板轨道)。 
- 
LCD 的D0、D1、D2和D3引脚未连接。 
完成前面的步骤后,您已经完成了将 LCD 连接到 Blue Pill 板的工作。LCD 将用于显示 20 秒计数。做得好!
图 14.2显示了所有连接方式:

图 14.2 – 连接到 LCD 的 Blue Pill 微控制器板
如您从图 14.2中可以看到,1602A 液晶显示屏很容易连接到 Blue Pill。连接到 LCD 的引脚V0的 2.2k 欧姆电阻设置了 LCD 的对比度。
小贴士
您可以使用 50k 欧姆可变电阻器(也称为电位器)代替连接到 LCD 引脚V0的 2.2k 欧姆电阻,以调整显示对比度。只需将电位器的中间引脚连接到V0,一个引脚连接到地,另一个引脚连接到5V。
请注意,LCD 引脚A(引脚编号 15)连接到 Blue Pill 的B12端口,通过编码通过打开或关闭背光来控制 LCD。
小贴士
在 Blue Pill 和其余电子组件(LCD、超声波传感器等)之间在无焊面包板上留出足够的空间,以便于将 ST-Link/V2 接口连接到 Blue Pill。
下一个部分将解释如何使用超声波传感器来判断用户是否在向传感器挥手以触发 20 秒定时器。
将超声波传感器连接到微控制器板
本节解释超声波传感器的工作原理,并描述如何将 HC-SR04 传感器连接到 Blue Pill 微控制器板,描述如何使用其四引脚功能。超声波传感器将用于检查用户是否向其挥手以启动 20 秒计数。
什么是超声波传感器?
超声波是频率高于大多数人类能听到的频率(即高于 20,000 Hz)的声波。超声波或超声波可以有不同的应用,包括被称为回声定位的技术,这种技术被诸如蝙蝠等动物使用,通过反射声波来确定猎物距离。同样的原理也应用于超声波传感器。
超声波传感器是一种专用电子组件,通常包含多个电子部件,如电阻器、晶体管、二极管、晶振时钟、特殊麦克风和扬声器。许多超声波传感器在技术上属于模块,因为它们集成了多个电子部件,这种集成作为模块有助于与其他设备(如微控制器板)的连接。超声波传感器通过使用超声波测量物体(例如,挥动的手)与传感器之间的距离。传感器通过扬声器发射超声波,并通过麦克风接收撞击物体的反射超声波。传感器测量声波发射和接收之间的时间。
超声波传感器是如何工作的?
超声波传感器(如HC-SR04)通过发射和接收超声波(类似于声纳)来确定物体距离。声纳是一种回声定位设备,用于水下检测物体,发射声脉冲(通常使用超声波频率),测量这些脉冲的反射时间,并计算物体与声纳设备之间的距离。本章中使用的超声波传感器不是为了水下使用,我们稍后会看到。
一些超声波传感器(如本章中使用的 HC-SR04)使用频率为 40 kHz 的声波,这远高于人类耳朵平均能感知的声音频率范围,即 20 Hz 到 20 kHz。
这就是 HC-SR04 超声波传感器的工作原理:
- 
微控制器板向传感器的 Trig引脚发送数字信号,通过传感器的扬声器触发(启动)超声波发射。
- 
当高频声波击中物体时,它会反射回传感器,并被传感器的麦克风捕捉到。 
- 
传感器通过其 Echo引脚向微控制器板发送数字信号。
- 
微控制器板从 Echo引脚接收该数字信号,编码声波发射和接收之间的持续时间。
传感器与物体之间的距离计算如下:
D=(T*C) / 2
符号表示以下内容:
- 
D:距离 
- 
T:超声波发射和接收之间的时间(持续时间) 
- 
C:空气中的声速(干燥空气中的声速为 343 m/s) 
距离被除以 2,因为我们只需要声波的返回距离。
图 14.3展示了超声波传感器的 Fritzing 图:

图 14.3 – HC-SR04 超声波传感器引脚图
从图 14.3中,你可以看到传感器的引脚图。VCC引脚连接到 5 伏电源。Trig和Echo引脚连接到微控制器板的数字端口。GND引脚连接到地。
这里是 HC-SR04 传感器的技术特性:
- 
工作电压:直流 5 伏 
- 
工作频率:40 kHz 
- 
工作电流:15 mA 
- 
最大工作范围:4 米 
- 
最小工作范围:2 厘米 
- 
分辨率:0.3 厘米 
- 
测量角度:30 度(传感器的视野) 
图 14.4展示了本章中使用的 HC-SR04 超声波传感器:

图 14.4 – HC-SR04 超声波传感器
从图 14.4中,你可以看到该传感器有两个类似扬声器的组件。其中一个是实际上发出超声波信号的小扬声器,另一个是捕捉这些信号在物体上反射后的麦克风。图 14.5展示了 HC-SR04 超声波传感器的背面:

图 14.5 – HC-SR04 传感器的背面
如图 14.5所示,传感器的背面包含支持超声波信号生成和接收的电子组件,如电阻器、晶体管和集成电路。
还有其他类型的超声波传感器,例如 Maxbotix MaxSonar 超声波传感器。其 Fritzing 图示在图 14.6中显示:

图 14.6 – Maxbotix MaxSonar 超声波传感器
图 14.6中所示的传感器可以用于微控制器板。Maxbotix MaxSonar 是一个准确且长距离的超声波传感器(它可以测量高达 6.45 米的距离),但它很昂贵,需要连接七根线到它的七个引脚。HC-SR04 传感器足以满足我们 20 秒计时器的应用。它成本低,易于连接,只需四根线。
当超声波传感器检测到用户向其挥手时,计时器开始,因此传感器将触发计时器。
图 14.7展示了如何将 HC-SR04 超声波传感器连接到 Blue Pill:

图 14.7 – 超声波传感器连接到 Blue Pill 微控制器板
从图 14.7中,你可以看到面包板的一个低轨连接到 Blue Pill 的5V引脚。另一个轨连接到 Blue Pill 的地。以下是将 HC-SR04 传感器连接到 Blue Pill 的步骤,除了遵循图 14.1中的步骤外,还需要按照图 14.7中的图示进行以下步骤:
- 
将传感器的VCC引脚连接到面包板的低轨,该低轨连接到5V。 
- 
将传感器的Trig引脚连接到 Blue Pill 的A8引脚。 
- 
将传感器的Echo引脚连接到 Blue Pill 的A9引脚。 
- 
将传感器的GND引脚连接到面包板的低轨,该低轨连接到地。 
图 14.8展示了所有连接方式:

图 14.8 – Blue Pill 连接到 LCD 和超声波传感器
请注意从图 14.8中,所有从超声波传感器来的连接都是在它的背面完成的。这是为了避免任何电缆阻碍传感器前部的发送和接收超声波信号。另外,注意 1602 LCD 的电源(引脚VDD)连接到 Blue Pill 的5V引脚。如果你用 3.3 伏供电 LCD,它可能无法工作。
小贴士
确保没有电线阻碍 HC-SR04 超声波传感器的视野;否则,它们将产生不规律或错误的测量和结果,以及 20 秒计数。
还请注意,从 图 14.8 可以看出,面包板的上方轨道连接到 Blue Pill 的 G 引脚(在某些 Blue Pill 上标记为 GND),它用于连接液晶显示屏的地线和用于预置液晶显示屏对比度的 2.2k 欧姆电阻。
下一个部分将解释如何将整个项目封装起来,以保护其免受灰尘、水等侵害,并便于在洗手的地方使用。
将所有东西组合在一起——想想为项目做一个保护壳吧!
本部分展示了如何将带有超声波传感器的电子电路放置在保护壳内。本部分还提供了一些如何在塑料或玻璃容器中放置所有部件的建议,因为如果您在浴室或靠近洗手池的地方使用 20 秒计数器,您将需要保护电路免受水溅和肥皂斑点的损害,这些斑点可能会损坏本 20 秒计数器项目中使用的电子组件。出于安全考虑,我们不推荐您将 Blue Pill 板连接到墙壁 USB 适配器。最好将 Blue Pill 连接到 USB 移动电源。
如果您无法将整个 20 秒倒计时电路(包括其无焊面包板)放入塑料或玻璃容器中,请尝试将 Blue Pill 连接到一个更小的无焊面包板,例如半面包板。从面包板上拆下超声波传感器和液晶显示屏,并用强力胶带将它们定位并固定在容器内部。关于这个较小电路的 Fritzing 图表显示在 图 14.9 中:

图 14.9 – 在小型无焊面包板上连接所有部件
如您从 图 14.9 所见,通过使用半面包板,您可以使所有连接更加紧凑,这样您就可以使用一个小的容器,如空速溶咖啡罐或任何带盖的塑料容器。您可以将超声波传感器安装在盖子上,并将其余部分放在容器或罐子内部。您需要使用公对母杜邦线将液晶显示屏和超声波传感器连接到半面包板。
图 14.10 展示了一个带有定制外壳的原型设计,这为您提供了如何封装所有组件并保护电子设备免受水溅的思路:

图 14.10 – 包含整个项目的 3D 原型设计
如您从 图 14.10 所见,该外壳可能是一个放置 1602A 液晶显示屏的塑料盒。HC-SR04 传感器放置在盒子的前面。盒子的内部可以包含小型面包板、电线、Blue Pill、电阻、移动电源和 USB 线。不要将整个项目放置在洗手池附近,以防万一。
测试计时器
本部分展示了如何测试 20 秒计时器。
一旦将带有传感器的电子电路、Blue Pill 和 LCD 放入保护壳中,尝试在浴室中使用它。如果可能,小心地将它放置在洗手池附近,以便在洗手时激活它并看到计数。看看你是否能将其固定在墙上或表面上,这样它就不会移动,也不会有人在挥手时意外将其碰倒。安全第一!
你应该将 Blue Pill 连接到一个带有 USB 接口的便携式充电宝。这是为了避免将 Blue Pill 连接到墙壁 USB 适配器,使其在如浴室等环境中使用更安全,如图 14.11 所示:

图 14.11 – 连接到 Blue Pill 微控制器板的充电宝
你可以用一个小型充电宝测试所有这些,如图 14.11 所示。
通过多次在传感器前挥手来尝试激活计时器。你会发现有时电路会计数到 21。这是因为大多数微控制器板(包括 Blue Pill)计算时间并不非常准确。尝试在代码中添加一个变量和决策,以显示计数到 20。提示:当计数达到 20 时停止显示计数。当你洗手试图破坏导致 COVID-19 的病毒时,计数到 21 并不关键。计数时间越长越好。
如果你觉得用户需要在不同的距离挥手来检测传感器,你可以调整检测的距离。尝试更改此行代码中的值:
if ((dist_read<=15) & (dist_read>0))
15这个值意味着如果你在距离传感器 15 厘米或更近的地方挥手,LCD 会激活并显示计数。尝试将这个值改为更大的数字,比如 20 厘米。
如果你认为 LCD 上显示的文本和数字需要更高的对比度,尝试将 2.2k 欧姆电阻更换为更小的电阻,例如 1k 欧姆。这可能发生在你的浴室或你打算使用计数器的场所过于明亮的情况下。
这是一个有趣的测试:尝试用不同年龄段的人进行 20 秒计数器的测试,看看超声波传感器是否能检测到不同大小的手。例如,看看传感器是否能检测到小孩和成人的挥手动作。
摘要
在本章中,我们学习了编写易于阅读的 20 秒计数器的基础知识。许多卫生机构推荐使用这个计数来正确洗手,以试图消灭一些病毒,例如导致 COVID-19 的病毒。本章还解释了 HC-SR04 超声波传感器是如何激活计数器的。在完成本章的项目后,你获得的一项主要技能是学会了如何将实用的 LCD 连接到微控制器板上,以及如何在 LCD 上显示计数。你可以在其他需要从微控制器板上显示数字或文本数据的项目中使用 LCD。
在本章中,我们介绍了一种从传感器获取数据、在微控制器板上处理数据以及对其进行操作(如显示在 LCD 上)的实用方法。从传感器获取数据并处理是微控制器的主要应用之一,利用其简单性将传感器连接到其输入/输出端口。
进一步阅读
- 
Choudhuri, K. B. R. (2017),10 天内学习 Arduino 原型设计,英国伯明翰:Packt 出版社有限公司 
- 
Gay, W. (2018),STM32 入门:使用 FreeRTOS、libopencm3 和 GCC 进行开发,纽约,纽约:Apress 出版社 
- 
HC-SR04(2013),HC-SR04 用户手册 V1.0,Cytron 技术公司,可在 docs.google.com/document/d/1Y-yZnNhMYy7rwhAgyL_pfa39RsB-x2qR4vP8saG73rE/edit?usp=sharing获取
- 
Horowitz, P. 和 Hill, W. (2015),电子艺术,[第 3 版],剑桥大学出版社:纽约,纽约 
- 
LCD1602(2009),LCM 模块数据表 TC1602A-01T,Tinsharp 工业有限公司,可在 cdn-shop.adafruit.com/datasheets/TC1602A-01T.pdf获取
- 
Microchip (2019),PIC16F15376 Curiosity Nano 硬件用户指南,Microchip 技术公司,可在 ww1.microchip.com/downloads/en/DeviceDoc/50002900B.pdf获取

订阅我们的在线数字图书馆,全面访问超过 7,000 本书和视频,以及行业领先的工具,帮助你规划个人发展并提升职业生涯。欲了解更多信息,请访问我们的网站。
第十五章:为什么订阅?
- 
使用来自超过 4,000 位行业专业人士的实用电子书和视频,节省学习时间,增加编码时间 
- 
通过为你量身定制的技能计划提高你的学习效果 
- 
每月免费获得一本电子书或视频 
- 
完全可搜索,便于轻松访问关键信息 
- 
你可能还会喜欢这些书籍 
你知道 Packt 为每本书都提供电子书版本,并提供 PDF 和 ePub 文件吗?你可以在 packt.com 升级到电子书版本,并且作为印刷书客户,你有权获得电子书副本的折扣。如需了解更多详情,请联系我们 customercare@packtpub.com。
在 www.packt.com,你还可以阅读一系列免费技术文章,订阅各种免费通讯,并享受 Packt 书籍和电子书的独家折扣和优惠。
你可能还会喜欢的其他书籍
如果你喜欢这本书,你可能还会对 Packt 的其他书籍感兴趣:
](https://github.com/OpenDocCN/freelearn-c-cpp-zh/raw/master/docs/diy-mctrl-proj-hby/img/Hands-On_RTOS.jpg)](https://www.packtpub.com/product/hands-on-rtos-with-microcontrollers/9781838826734)
动手实践基于微控制器的实时操作系统
Brian Amos
ISBN: 978-1-83882-6-734
- 
从 RTOS 的基础知识开始,并在 STM32 上应用它们 
- 
提升你的编程技能,以设计和构建现实世界的嵌入式系统 
- 
掌握实现嵌入式系统的先进技术 
构建高性能嵌入式系统
Jim Ledin
ISBN: 978-1-78995-5-965
- 
学习嵌入式系统和实时操作系统的基本知识 
- 
了解 FPGA 如何在硬件中实现处理算法 
- 
使用 KiCad 从零开始设计、构建和调试自定义数字系统 
Packt 正在寻找像你这样的作者
如果你对成为 Packt 的作者感兴趣,请访问 authors.packtpub.com 并今天申请。我们已经与成千上万的开发人员和科技专业人士合作,就像你一样,帮助他们将见解分享给全球科技社区。你可以提交一般申请,申请我们正在招募作者的特定热门话题,或者提交你自己的想法。
分享你的想法
现在您已经完成了《DIY Microcontroller Projects for Hobbyists》,我们非常想听听您的想法!如果您在亚马逊购买了这本书,请点击此处直接跳转到该书的亚马逊评论页面,并分享您的反馈或在该购买网站上留下评论。
您的评论对我们和科技社区都非常重要,它将帮助我们确保我们提供的是高质量的内容。

 
                    
                     
                    
                 
                    
                



































 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号