想学嵌入式?要不一起玩 Arduino 吧

作者:HelloGitHub-Anthony
这里是 HelloGitHub 推出的《讲解开源项目》系列,本期介绍的是如何用开源硬件开发平台 Arduino,自己动手做一个温湿度显示器。
书接上回,上一章我们知晓了什么是 Arduino、能用它来做什么,以及 Hello World 的实现,内容十分简单和容易上手。没看过的小伙伴可以点击阅读,从而做到无缝连接本章的内容。
接下来,我们将更进一步学习 Arduino 的知识,为避免枯燥的文字教程,本文将结合实际的开发进行讲解。首先会介绍 温湿度传感器 和 OLED 屏幕 的开发,接着将这两部分的知识进行组合,最后你将得到一个有意思的温湿度显示器。
不要担心,本文所有内容均已脱“难”,只要跟着文章一步步进行下去,肯定就能做出来!
下面,就让我们一起开始制作你的第一个 Arduino 成品吧!
一、温湿度传感器
本节我们会用到名为 DHT 11 的温湿度传感器,DHT 11 是一款常用的温湿度数字传感器,它虽然精度不是很高但价格低廉,只用到三根线 VCC、GND、DATA 即可工作(简单),是我们学习使用传感器的不二之选!
这里我使用的是进行过二次封装的 DHT 11 传感器,它长这个样子:

1.1 连接传感器
根据购买的店铺不同,最终实物可能会有所不同。如果你无法分辨每个引脚具体含义,一定要先咨询卖家再进行接线,防止烧坏传感器!
我这里的三个引脚从左到右依次为 DATA、VCC、GND,连接方式为:
- GND -- GND
- VCC -- 5V
- DATA -- Digital 8
1.2 读取数据
读取 DHT 11 传感器的数据方式也非常简单,我们可以根据 数据手册 中 4、串行接口 一节提供的信息自行编写数据解析的程序。
但我认为这已经超出了初学者的能力范围而且实现起来也会花不少功夫,所以这时候我们就需要 Arduino 的 Libraries 功能上场了!
Arduino 官方提供了一个 Library 平台,收集了很多开发者提供的开源支持库,灵活使用这些库进行开发,可以节省我们大量的时间以及头发。
下面将介绍如何使用 Arduino IDE 的 Libraries 功能。
1.3 DHT 11 支持库
在这里我们选择 Adafruit 提供的 DHT sensor library 支持库,它还依赖 Adafruit Unified Sensor 库,下面我们详细操作:
安装
点击左侧 Libraries 栏目,在搜索框中输入 DHT11 找到 DHT sensor library by Adafruit,点击 INSTALL 进行安装,然后会提示我们需要安装一些依赖项目:


这里 Arduino IDE 自动提示我们想要使用 DHT sensor library 还需要安装 Adafruit Unified Sensor,我们直接点击 Install all 让它自动安装,成功后可以在输出界面看到这样的提示:

使用
安装好之后我们找到 Arduino IDE 上方选项卡打开:File->Examples->DHT sensor library->DHTtester 即可打开 DHT sensor library 使用例程。

这里我们只需要根据实际情况修改开头几行配置,就能直接编译到开发板上进行测试啦!
上传到开发板后打开我们的 Serial Monitor 即可看到 Arduino 正在回传温湿度信息:

1.4 传感器小结
本节我们简单学习了如何安装 Arduino 的支持库、如何查看支持库提供的例程,以及 DHT11 库的使用方法。
下一节,我们将学习如何使用 LCD 屏幕显示内容。
二、OLED 屏幕
本节我们会用到名为 SH1106 的 1.3寸 OLED 显示屏,我用的是 SH1106 使用 I2C 方式进行操作,只用到四根线 VCC、GND、SDA、SCL 分辨率为 128x64 ,它长这个样子:

1.1 接线
使用时接线为:
- GND -- GND
- VCC -- 5V
- SDA -- A4
- SCL -- A5
根据使用方式和屏幕不同,实际接线可能会有出入。如果不懂可以搜索关键词:“Arudino+屏幕型号+通信方式”(I2C 或 SPI)
对于显示屏如果直接进行操作使用起来非常复杂,但好在开源社区为其提供了强大的支持库。
1.2 开源库 U8g2
U8g2 是一个单色显示屏的开源库,支持市面上绝大多数单色显示屏,能非常方便地从库管理器进行安装。
安装
上一节的支持库安装方式相同,在 Libraries 页面进行搜索后安装即可。
但由于其体积较大或是网络问题,可能会存在下载缓慢或者失败等问题。如果一直无法安装成功,可以手动下载官方版本进行安装
使用
U8g2 同样提供了丰富的例程供我们学习,打开 examples 文件夹可以看到如下结构:

需要注意的是 U8g2 提供了两个版本:U8g2 本身(例程中 full_buffer 与 page_buffer)和 u8x8(例程中 u8x8)。前者支持完整绘图功能,但是速度一般且需要额外的内存支持,后者只支持显示字库中图形但是速度快不需要额外的内存。
full_buffer 与 page_buffer 的区别在于:
full_buffer:会在内存中维护全部的图形缓存会占用大量内存。渲染速度快,但在 UNO 上只有部分例程能够成功运行。page_buffer:一次只维护一小部分缓存并分批次进行更新。渲染速度稍慢,在 UNO 上全部例程都可成功运行。
大家可以自行运行例程中的代码,进行一个粗略的了解。
每段脚本只需要解除相应屏幕的注释就能运行,比如我用的 SH1106 128x64 使用 I2C 通信,用到的代码片段如下:

具体规范只要有屏幕型号、分辨率、连接方式(I2C 还是 SPI)就能轻松找到
三、温湿度显示器
前面我们已经了解了如何分别使用温湿度传感器和 OLED 屏幕,现在我们只需将它们组合起来。
下面就变得非常非常简单了,我们只需要将传感器数据搬运到屏幕上显示即可。
完整的代码如下:
#include <Arduino.h>
#include <U8g2lib.h>
#include "DHT.h"
// DHT11 DATA 引脚连接的数字引脚编号
#define DHT_DATA_PIN 8
DHT dht11(DHT_DATA_PIN, DHT11, 1);
U8G2_SH1106_128X64_NONAME_1_HW_I2C oled(U8G2_R0, U8X8_PIN_NONE);
float t, f, h;
float head_index;
const char URL[] = "http://www.HelloGitHub.com";
int url_width = 0;
bool Fahrenheit = false;
void update_data()
{
h = dht11.readHumidity();
t = dht11.readTemperature();
f = dht11.readTemperature(true);
head_index = dht11.computeHeatIndex(t, h, false);
}
void setup()
{
t = f = h = 0;
dht11.begin();
oled.begin();
oled.enableUTF8Print();
oled.setFontMode(0);
url_width = oled.getUTF8Width(URL); # 符号需要启动
update_data();
}
void loop()
{
static int url_x_pos = -url_width;
oled.firstPage();
do
{
if (millis() % 200 == 0) // 每 200ms 更新一次
update_data();
oled.setFont(u8g2_font_t0_11_mr);
oled.drawBox(0, 0, 128, 17);
oled.setDrawColor(0);
oled.setCursor(url_x_pos, 14);
oled.print(URL);
oled.setDrawColor(1);
oled.setCursor(0, 32);
oled.setFont(u8g2_font_7x13_mf);
oled.print("Temp: ");
if (Fahrenheit) // 每隔一段时间自动切换单位显示
{
oled.print(f);
oled.print("°F");
}
else
{
oled.print(t);
oled.print("°C");
}
oled.setCursor(0, 47);
oled.print("Humi: ");
oled.print(h);
oled.print(" %");
oled.setCursor(0, 62);
oled.print("HeadIndex: ");
oled.print(head_index);
oled.print("°C");
} while (oled.nextPage());
Fahrenheit = (millis() % 4000 == 0) ? (!Fahrenheit) : Fahrenheit; // 每 4s 更换一次单位
url_x_pos += 3;
if (url_x_pos > 128)
url_x_pos = -url_width;
}
最终效果如下:

结语
如果你跟着本文一步步走下来,到这里应该已经收获了自己第一个 Arduino 成品,恭喜你!
其实,本文更侧重的是“授人以渔”!毕竟再好的教程也做不到面面俱到,解决你所有的问题,所以解决问题的方法最重要。文中对于如何上手开源库、查阅文档、查看代码示例、搜索资料等方面做了详尽步骤的讲解。相信有了这些知识,你可以打开新的世界,而不是仅限于本文所讲的例子。
下面你就可以发挥想象力,结合所学到的知识和方法,自己动手做出好玩的电子产品啦!如果你做出了好玩的东西可以发给我,如果作品够多的话我可以做一期 Arduino 作品秀!把你做的让人眼前一亮的作品,让更多的人发现和喜欢。
本期的内容就是这些,这里是 HelloGitHub 分享 GitHub 上有趣、入门级的开源项目。
感谢您的阅读!您的每个点赞、留言、分享,都是对我们最大的鼓励~我们下期再见!
想学嵌入式?要不一起玩 Arduino 吧的更多相关文章
- 2014年9月21日_随笔,jdic,ETL,groovy,Nutz好多东西想学
(1)老妈十一要回老家,才突然发现买票好难啊.有亲朋很重要 (2)这周我做了什么.jdic,ETL,groovy, Nutz好多东西想学. Nutz开发成员专访.Nutz优酷视频(演讲).Nutz 入 ...
- 最近想学Json,请问大家有没有什么好的Json教程介绍一下?
最近想学json,请问大家有没有什么好的Json教程介绍一下? 最近学完java的框架了,想了解一下json,可是找不到相关视频,请大家有这方面的Json教程好资料就介绍下啦,最后有网址链接啦. {} ...
- 少年,想学带修改主席树吗 | BZOJ1901 带修改区间第k小
少年,想学带修改主席树吗 | BZOJ1901 带修改区间第k小 有一道题(BZOJ 1901)是这样的:n个数,m个询问,询问有两种:修改某个数/询问区间第k小. 不带修改的区间第k小用主席树很好写 ...
- 为什么43%前端开发者想学Vue.js
根据JavaScript 2017前端库状况调查 Vue.js是开发者最想学的前端库.我在这里说明一下我为什么认为这也是和你一起通过使用Vue构建一个简单的App应用程序的原因. 我最近曾与Evan ...
- 结合jquery的前后端加密解密 适用于WebApi的SQL注入过滤器 Web.config中customErrors异常信息配置 ife2018 零基础学院 day 4 ife2018 零基础学院 day 3 ife 零基础学院 day 2 ife 零基础学院 day 1 - 我为什么想学前端
在一个正常的项目中,登录注册的密码是密文传输到后台服务端的,也就是说,首先前端js对密码做处理,随后再传递到服务端,服务端解密再加密传出到数据库里面.Dotnet已经提供了RSA算法的加解密类库,我们 ...
- APP爬虫(1)想学新语言,又没有动力,怎么办?
最近Python和GO语言很火,想学但是只能看得懂21天精通这种级别的教程.公司的项目暂时不会上py或go的技术栈,给的薪资福利待遇还可以,暂时又不想辞职.没有项目实战经验,完全看不懂大神写的干货,怎 ...
- 给想学python但还没有接触过的你,python代码的书写规则,小白入门
Python 文件结构 变量命名 注释 单行注释 多行注释 缩进 Python 文件结构 #!/usr/bin/env python3 # 指定python解释器 # -*- coding: utf- ...
- 汇编语言基于8086CUP(想学操作系统的前奏!!!)
汇编语言基于8086CUP(想学操作系统的前奏!!!) 1.汇编语言的产生 1.1.思维图 1.2.单位转换 1B=8bit 1KB=1024B 1MB=1024KB 1GB=1024MB 1TB=1 ...
- 单片机和Linux都想学_换个两全的方法学习单片机
本节教你如何学习单片机,如何选择合适的开发板和开发工具. 现在我们知道单片机是要学习的,那么怎么去学习单片机?在上一课我们说不要使用老一套的方法学习,实际上是指的两个问题. 第一:选择什么开发板: 第 ...
随机推荐
- windows+ubuntu双系统时间同步问题
windows+ubuntu双系统时间同步问题 给Ubuntu更新时间,在终端输入: sudo apt-get install ntpdate sudo ntpdate time.windows.co ...
- linux磁盘分区fdisk命令操作(实践)
写这篇的目的,还是要把整个过程完整的记录下来,特别是小细节的地方,通常很多情况是一知半解,平时不实践操作只凭看是没有用的,所以做这个行业就是要多动手,多学习,多思考慢慢你的思路也会打开.练就自己的学习 ...
- LinkedList实现
LinkedList源码实现: public class LinkedList<E> { private class Node{ public E e; public Node next; ...
- Go xmas2020 学习笔记 06、Control Statements、Declarations & Types
06-Control Statements. If-then-else. Loop. for. range array. range map. infinite loop. common mistak ...
- Python学习阵痛期
Python和之前学习的Java语法上有较大的区别,例如Java中for循环常使用++自增符,在Python中是没有++的. 因为Python中整型.字符型等都是不可变的,一改变值就重新分配了新的内存 ...
- 微信小程序 因文件大小不能使用本地背景图片解决方法
因微信文件只允许2m,所以不能给图片太多空间.所以出现背景图片的坑 解决方案1: 把背景图片放到服务器文件件下,直接将路径给url. 得是https开头的路径才可以 解决方案2:将图片转换成base6 ...
- Java语言学习day11--7月10日
今日内容介绍1.自定义类型的定义及使用2.自定义类的内存图3.ArrayList集合的基本功能4.随机点名器案例及库存案例代码优化 ###01引用数据类型_类 * A: 数据类型 * a: java中 ...
- 2021.11.11 P4052 [JSOI2007]文本生成器(AC自动机+DP)
2021.11.11 P4052 [JSOI2007]文本生成器(AC自动机+DP) https://www.luogu.com.cn/problem/P4052 题意: JSOI 交给队员 ZYX ...
- ubuntu16.04安装MATLAB R2017b步骤详解(附完整文件包)
摘要:介绍在ubuntu16.04中从下载到安装成功的完整步骤.本文给出MATLAB R2017b(Linux系统)的完整安装包百度云盘下载地址,逐步介绍一种简单易行的安装方法,在桌面创建快捷方式,最 ...
- MySQL 回表
MySQL 回表 五花马,千金裘,呼儿将出换美酒,与尔同销万古愁. 一.简述 回表,顾名思义就是回到表中,也就是先通过普通索引扫描出数据所在的行,再通过行主键ID 取出索引中未包含的数据.所以回表的产 ...