动手玩转Arduino

978-7-115-33596-8
作者: 【澳】John Boxall
译者: 翁恺
编辑: 傅道坤
分类: Arduino

图书目录:

详情

本书精心整合了65个Arduino项目,而且其难易程度依次递增,旨在让读者掌握更多的Arduino知识和经验。读者除了学到基础的电子学知识之外,还将学习如何创建更为复杂的项目。本书每章内容都以之前章节为基础,它采用步骤式讲解,让读者理解并构建不同的项目。当读者学完本书之后,将学会如何创建闪烁的灯光、RFID标签打卡钟,以及使用电视遥控器来控制的电动坦克等内容。

图书摘要

版权信息

书名:动手玩转Arduino

ISBN:978-7-115-33596-8

本书由人民邮电出版社发行数字版。版权所有,侵权必究。

您购买的人民邮电出版社电子书仅供您个人使用,未经授权,不得以任何方式复制和传播本书内容。

我们愿意相信读者具有这样的良知和觉悟,与我们共同保护知识产权。

如果购买者有侵权行为,我们可能对该用户实施包括但不限于关闭该帐号等维权措施,并可能追究法律责任。


Copyright © 2013 by John Boxall. Title of English-language original: Arduino Workshop, ISBN 978-1-59327-448-1, published by No Starch Press. Simplified Chinese-language edition copyright © 2013 by Posts and Telecom Press. All rights reserved.

本书中文简体字版由美国No Starch出版社授权人民邮电出版社出版。未经出版者书面许可,对本书任何部分不得以任何方式复制或抄袭。

版权所有,侵权必究。


Arduino是当今世界上最流行的开源硬件,具有价格低廉、便捷灵活、容易上手等特点,在机器人、艺术、科学实验等领域受到了广泛关注。

本书精心整合了65个Arduino作品,而且其难易程度依次递增,旨在让读者以感性的方式,来掌握更多的Arduino知识和经验。通过这65个动手实践,读者除了学到基础的电子学概念、巩固已有的Arduino知识之外,还将学会如何创建功能更为强大复杂的Arduino作品。

本书适合对Arduino感兴趣的硬件DIY爱好者、电子爱好者阅读,也非常适合学生进行电子制作使用。


谨将本书献给一直给予我深深信任的两位家人——我的妈妈和我亲爱的Kathleen。


首先,向Arduino团队致以深深的谢意:Massimo Banzi、David Cuartielles、Tom Igoe、Gianluca Martino和David Mellis,没有你们的视野、思想和艰苦的努力,一切都不会发生。

非常感谢我的技术评审Marc Alexander,为他的付出、专业、建议、支持、思想和长期的交流,更是为他坚持做完这么大的一个计划。

我还要感谢以下机构,他们提供了图片,还有鼓励:adafruit工业、Agilent技术、Gravitech、Freetronics、Oomlout、Seeed Studio(深圳硒递)、夏普公司和SparkFun。还要非常感谢Freetronics让本书使用它们杰出的元器件。感谢所有贡献了宝贵时间来做Arduino库的人们,他们让大家的生活都变得轻松了。

荣誉和感谢还要献给Fritzing团队,他们做出了很棒的开源电路图设计工具,我在整本书中都用了他们的软件。

还要感谢以下给予我鼓励、灵感和支持的人士(排名不分先后):Iraphne Childs、Limor Fried、Jonathan Oxer、Philip Lindsay、Nicole Kilah、Ken Shirriff、Nathan Kennedy、David Jones和Nathan Seidle。

最后,感谢No Starch出版社的诸位,包括Sondra Silverhawk对出书的建议,Serena Yang专业的编辑、无限的耐心和不断的建议,以及Bill Pollock的支持和指导,他有时会说服我用更好的方式来解释事情。


本章我们将研究Arduino板和IDE软件,我们要用IDE软件创建和上传Arduino程序到Arduino板(Arduino用草图表示程序,我们还是继续用程序这个传统术语)。我们会学到程序的基本框架和程序里可以实现的基本功能,我们要创建和上传我们的第一个程序。

Arduino到底是什么?根据Arduino网站(http://www.arduino.cc/)的介绍,它是一个开源的电子原型平台,这个平台是由灵活易用的硬件和软件所组成的。它是面向艺术家、设计师、爱好者和任何对创造交互对象或交互环境有兴趣的人士的。

简而言之,Arduino是一个微小计算机系统,可以由你编程来和各种形式的输入和输出做交互。最新型号的Arduino板,和普通人的手比起来是相当小的,如图2-1所示。

图2-1 一块Arduino Uno是相当小的

第一次见到这块板子你也许不会想到,Arduino系统可以做出能与周围环境交互的装置。用上各种可能的输入输出器件:传感器、指示灯、显示器、电机等,就可以编程实现精确的交互要求,创造出具有特定功能的装置来。比如,艺术家可以做出一个装置,当有人经过时,灯能以一定的模式闪烁;高中生可以做出自动机器人,能监测到火苗然后熄灭它;地理学家可以设计一个系统,能监视温度和湿度,并把数据以短信的方式回传到他们的办公室。实际上,在互联网上简单搜索一下,就能找到数量无穷的例子。

现在,我们继续来详细研究Arduino Uno这个硬件(换句话说,就是那个“物理的部分”),看看那上面都有些什么。别太担心不知道看到了什么,所有这些都是要在后面的章节里详细讨论的。

我们快速浏览一下Uno这块板子。从板子的左侧开始,首先会看到两个插座,如图2-2所示。

图2-2 USB和电源插座

在图最左边的是通用串行总线(USB)插座。它把板子和计算机连起来,起到3个作用:给板子供电、把你的程序上传到Arduino和在板子和计算机之间双向传递数据。在图右边的是电源插座,通过这个插座,可以用常见的电源变压器给Arduino供电。

在板子的中间偏下的,是这个板子的心脏:单片机,如图2-3所示。

图2-3 单片机

单片机是Arduino的“大脑”。它是一个小型计算机,包含有执行指令的处理器、分别保存数据和程序的不同类型的内存,它还具有多种发送和接收数据的方式。在单片机正下方有两排小型插座,如图2-4所示。

图2-4 电源和模拟插座

左边那排提供了电源连接,并能接一个外部的RESET(重启)按钮。右边那排有6个模拟输入端,可以测量电信号的电压变化。另外,A4和A5引脚还被用作和其他器件发送和接收数据的引脚。在板子的顶端还有另外两排插座,如图2-5所示。

图2-5 数字输入/输出引脚

标有数字0~13的插座(或者叫作引脚)是数字输入/输出(I/O)引脚。它们既可以检测电信号有还是没有,也可以根据指令产生信号。引脚0和1也是串口,用来和其他器件发送和接收数据,和计算机之间就是由它们通过USB连接电路进行通信的。标有一个波浪号(~)的引脚可以产生变化的电信号,这种电信号可以用来做出灯光效果或控制电机。

接下来介绍板上的一些非常有用的元件,它们叫做发光二极管(LED),这种非常小的元件在有电流流过时会发光。Arduino板上有4个LED。最右边的那个标有ON,是板子的电源指示灯,另外3个排在一起,如图2-6所示。

图2-6 板上的LED

在Arduino与通过串口或USB连接的设备之间发送或接收数据时,标有TX和RX的LED会亮。标有L的LED是给你自己用的(它连接在数字输入输出引脚13上)。在这个LED左边的小的黑色方块是一个微型单片机,它控制USB接口,让你的Arduino可以和计算机之间收发数据,不过,你不需要操心这个小芯片。

最后,如图2-7所示的是RESET按钮。

图2-7 RESET按钮

和普通的计算机一样,有时候Arduino也可能出问题,当一切都失效了的时候,可能要重置系统、重启Arduino。板上这个简单的RESET按钮(见图2-7)就是用来重启系统解决问题的。

Arduino系统最大的优势是它易于扩展,就是说,可以方便地加上更多的硬件功能。Arduino板两侧的插座,能够插上一块盾板(shield),盾板是一块电路板,它的引脚能直接插到Arduino板上。比如,如图2-8所示的盾板上有一个以太网接口,使Arduino可以通过网络和互联网通信,这样就能做出各种各样的电子设备。

图2-8 Arduino以太网接口盾板

注意看,这个以太网盾板也有两行插座,这样就可以在它上面插更多的盾板。比如,如图2-9所示,在一个以太网盾板上插了另一块盾板,上面有大型数字显示器、温度传感器、额外的数据存储器和一个大型LED。

图2-9 数字显示器和温度传感器盾板

要小心,你需要记住每块盾板用了哪些输入/输出引脚,以避免多块盾板插在一起时产生冲突。也可以买到完全空白的盾板,在上面搭建自己的电路。第8章会详细解释这个事情。

伴随着Arduino硬件的是软件,软件是指令的集合,这些指令告诉硬件要做什么、怎么去做。需要用到两种类型的软件,第一种是集成开发环境(IDE),本章会讨论IDE,另一种是要我们自己来写的Ardiuno程序。

IDE软件装在个人电脑上,用来编写程序、发送程序到Arduino板。

如图2-10所示,Arduino IDE里有一个简单的文本编辑器。IDE的界面可以分成3个主要的区域:命令区、文字区和消息窗口区。

图2-10 Arduino IDE

IDE界面的上部是命令区,包括标题栏、菜单项和图标。标题栏显示程序的文件名(如sketch_mar22a),以及IDE的版本(如Arduino 1.0)。在它下面是菜单项包括File(文件)、Edit(编辑)、Sketch(程序)、Tools(工具)和帮助,以及图标,下面逐一解释。

1.菜单项

和任何字处理软件或文本编辑器一样,点击某个菜单项就可以展开它的菜单,看到各种具体选项。

File(文件),包含保存、打开和打印程序的功能,可以打开的完整的例子程序集以及Preferences()子菜单。

Edit(编辑),包括任何字处理软件中常见的拷贝、粘贴和搜索功能。

Sketch(程序),包括在上传到板子之前检查程序的功能,还有一些程序目录以及引入库的选项。

Tools(工具),包括各种功能,以及选择Arduino板类型和USB端口的选项。

Help(帮助),包括到各种话题的链接,以及IDE的版本说明。

2.图标

菜单条下面是6个图标,将鼠标在每个图标上停留可以显示出图标的名字。自左向右,这些图标是:

Verify(检查),点击这个按钮检查Arduino程序是否有效,没有任何程序错误。

Upload(上传),点击这个按钮会检查程序,然后上传到Arduino板。

New(新建),点击这个按钮会在一个新窗口打开一个新的空程序。

Open(打开),点击这个按钮打开一个已保存的程序。

Save(保存),点击这个按钮保存当前打开的程序,如果程序还没有文件名,就会被要求给出一个文件名。

Serial Monitor(串口监视器),点击这个按钮打开一个新窗口,用来在Arduino和IDE之间收发数据。

如图2-10所示,IDE界面中间的是文字区,这是写程序的地方。当前程序的文件名显示在文字区左上方的页眉上(默认的文件名是当天的日期)。在文字区可以输入程序,这和任何文字编辑器一样。

如图2-10所示,IDE界面的底部是消息窗口区,从IDE来的消息会显示在这个黑色的区域里。你可以看到各种消息,包括程序检查的结果、程序上传的状态等。

在消息区的右下角,应该能看到Arduino板子的型号以及所连接的串口,这里显示的是在COM6上的Arduino Duemilanove w/ATmega328(采用ATMega328芯片的Arduino Duemilanove)。

一个Arduino程序就是用来实现一个特定任务的一组指令。本节我们要创建和上传一个简单的程序,能让Arduino的LED(见图2-11)亮一秒、灭一秒,形成不断的闪烁。

图2-11 Arduino板上的LED,在大写字母L的旁边

注意:

别太操心所建立的这个程序里的具体指令。这个程序是为了说明要让Arduino做点什么事情是很容易的,继续读下去会遇到更难的部分。

首先,用USB线把Arduino板连到计算机上,然后打开IDE,选择Tools->Serial Port,确认正确的串口已经被勾选上,这样就能确认Arduino板已经被正确地连接了。

首先,输入一条注释,说明程序的用途。注释是程序里任意长度的说明,是为了程序的用户而写的。程序里的注释用来给你自己或其他人加些说明,这是很有用的。注释可以是说明指令,也可以是说明各种细节。在给Arduino编程(写程序)的时候,把你的想法写成注释是个好主意,将来修改程序的时候,这些注释能提供有用的信息。

在一行里加上注释,需要输入两个斜杠,然后写注释,就像下面这样。

// Blink LED sketch by Mary Smith, created 09/09/12(闪烁LED程序,作者Mary Smith,创建于2012年9月9日) 

这两个斜杠告诉IDE在检查程序的时候忽略后面跟着的内容(前面提过,在检查程序的时候,你要求IDE检查程序书写正确没有错误)。

输入占据两行或多行的注释,需要在注释开始之前输入/*,然后在注释结束的地方输入*/,就像下面这样。

/* 
Arduino Blink LED Sketch (Arduino 闪烁LED程序) 
by Mary Smith, created 09/09/12 (作者Mary Smith,创建于2012年9月9日) 
*/ 

和两个斜杠开头的单行注释一样,/*和*/告诉IDE忽略它们所括起来的文字。

用以上两种方法之一输入一条描述你的Arduino程序的注释,然后选择File->Save As保存程序。给你的程序输入一个简短的文件名(比如blinky),然后点击OK。

Arduino程序的默认文件名后缀是.ino,IDE应该会自动加上这个后缀。所以,你的程序的文件名就应该是blinky.ino,在菜单的Sketchbook(素描本)里可以看到它。

创建任何程序,接下去的事情都是加上void setup()函数。这个函数里是Arduino每次重启或开机时只执行一次的指令。要创建这个setup函数,在程序的注释后面,加入下面的行。

void setup() 
{ 

} 

我们的程序要让Arduino板上的用户LED闪烁,用户LED连接在Arduino的13号数字引脚上。数字引脚可以检测电信号,也可以根据指令产生信号。在这个作品中,我们要产生一个电信号来点亮LED。这也许看上去有点复杂,数字引脚更多的细节会在后续的章节中介绍,此刻,只要继续写程序就好。

在程序的大括号({})之间输入下面的内容。

pinMode(13, OUTPUT); // 设置数字引脚13为输出 

程序里的数字13就是我们用的数字引脚的编号,设置这个引脚为输出,就表示要在这个引脚上产生(输出)一个电信号。如果你想在引脚上检测所受的电信号,就需要用INPUT。注意这个函数的调用pinMode()以分号(;)结尾。Arduino程序里的每个函数调用都要以分号结尾。

再次保存你的程序,确保你不会丢失了你的辛苦劳作。

我们的目标是让LED不停地闪烁。为此,需要写一个loop(循环)函数来让Arduino不断地重复执行一些指令,直到断电或是有人按了RESET按钮。

输入下面代码中在void setup()后面加粗的部分,就有了一个空的loop函数。别忘了这个新的部分要以另一个大括号(})结束,然后再保存一次程序。

/* 
Arduino Blink LED Sketch (Arduino 闪烁LED程序) 
by Mary Smith, created 09/09/12 (作者Mary Smith,创建于2012年9月9日) 
*/ 

void setup() 
{ 
  pinMode(13, OUTPUT); // 设置数字引脚13为输出 
} 
void loop() 
{ 
// 你的主循环代码要放在这儿:
} 

警告:

Arduino IDE不会自动保存程序,所以要经常自己保存一下。

下面,输入实际的要在loop()里让Arduino执行的代码。

在loop函数的大括号之间输入下面的内容,然后点击Verify按钮来确认输入的一切都是对的。

digitalWrite(13, HIGH); // 打开数字引脚13 
delay(1000); // 暂停一秒 
digitalWrite(13, LOW); // 关闭数字引脚13 
delay(1000); // 暂停一秒 

我们分开来逐一说明。digitalWrite()函数控制在数字引脚上输出的电压,在这个程序里,就是控制连接了LED的13引脚上的电压。设置这个函数的第2个参数为HIGH,这就输出了“高”电平,会有电流从引脚流出,LED就会被点亮。如果设置这个参数为LOW,流经LED的电流就会停止。

LED亮了以后,用deay(1000);让它保持1秒。delay()函数可以使程序在一段时间内什么也不做。这里是1000毫秒,或者说1秒,程序什么也不做。

然后,用digitalWrite(13,LOW);把LED上的电压取消掉。最后,再用delay(1000);让LED保持1秒的熄灭状态。

完整的程序如下:

/* 
 Arduino闪灯程序 
 作者Mary Smith,创建于2012年9月9日 
*/ 

void setup() 
{ 
  pinMode(13, OUTPUT); // 设数字引脚13为输出 
} 
void loop() 
{ 
  digitalWrite(13, HIGH); // 点亮数字引脚13 
  delay(1000); // 暂停1秒 
  digitalWrite(13, LOW); // 熄灭数字引脚13 
  delay(1000); // 暂停1秒 
} 

在做任何事情之前,保存程序。

检查程序是确保程序以Arduino理解的方式书写。要检查整个程序,点击IDE的Verify按钮,然后等待一会儿。一旦程序被检查完毕,就会在消息窗口显示一条消息,如图2-12所示。

图2-12 程序被检查好了

“Done compiling”消息告诉你程序已经OK了,可以上传到Arduino板。它还告诉你程序用了多少内存(这里是1 076字节),这块Arduino上总的可用内存是32 256字节。

不过,如果你的程序不对呢?比如,你忘了在第二个delay(1000)函数的后面加上一个分号。如果程序有问题,那么在点击了Verify按钮之后,消息窗口会显示检查错误消息,如图2-13所示。

图2-13 检查错误时的消息窗口

这条消息告诉你,错误出在void loop函数里,并且列出了它认为你的错误所在的程序行号(blinky:16,是blinky程序的第16行),然后是错误的描述,即error: expected ';' before '}' token(错误:在 '}'符号之前应该有一个';')。另外,IDE还会把错误的地方用黄色高亮显示,或是在错误的地方打一个点。这样能让你方便地找到并修改错误。

一旦程序已经正确输入了,保存好,确认Arduino板已经连接,然后点击IDE的Upload(上传)按钮。IDE可能会再次检查程序,然后再上传到Arduino板。在此过程中,板上的TX/RX LED(见图2-6)会不时地闪烁,说明数据正在Arduino和计算机之间来回传递。

现在,Arduino应该开始运行程序了。如果一切都做对了,LED应该闪烁,亮一秒灭一秒!

恭喜你,现在,你已经基本了解如何输入、检查和上传Arduino程序了。

运行程序之后,可能想要改变它的动作,比如,调节LED亮或灭的时间。因为IDE很像一个文字处理软件,所以可以打开之前保存的程序,修改其中的内容,然后保存、上传到Arduino。比如,要提高闪烁的频率,改变两次delay函数的调用,调整延迟的数值为250,就可以让LED每1/4秒闪烁一次,如下所示。

delay(250); // 暂停1/4秒 

然后再次上传程序,LED就会闪烁得快点儿了,每1/4秒变化一次。

掌握新学到的如何输入、编辑、保存和上传Arduino程序之后,就可以阅读下一章了。在下一章会学到如何使用更多的函数,实现良好的作品设计,构造基本的电路等。


在本章,我们将:

今天触摸屏到处可见,如智能手机、平板电脑和手持游戏机。所以,为什么不用触摸屏来接受用户的输入呢?

触摸屏非常贵,不过我们要用SparkFun提供的廉价型号(元件编号LCD-08977和BOB-09170),它们原本是为任天堂的DS游戏终端设计的。

这个触摸屏的尺寸大约为5厘米× 7厘米,图10-1是它插在面包板上的样子。

注意触摸屏用一条排线连到右上角的一块小电路板上(见图10-1中画圈的地方)。这块小板是用来把Arduino和面板连到触摸屏上用的,图10-2所示是这个小板的特写。

图10-1 安装在面包板上的触摸屏

图10-2 触摸屏的连接板

按照表10-1连接触摸屏的小板到Arduino。

表10-1  触摸屏小板连线

小板引脚

Arduino引脚

Y1

A0

X2

A1

Y2

A2

X2

A3

在上层的塑料膜和下层的玻璃层之间,触摸屏有两层电阻性的镀膜。一层镀膜是x轴,另一层是y轴。当电流流经每层镀膜,镀膜的阻值会由于不同地方的触摸而不同。这样,测量了每层的电流,就能得到所触摸区域的X和Y坐标。

在这个作品中,我们要用Arduino记录屏幕上触摸的位置,然后把这种触摸转换成能够指出屏幕上的区域的整数。

需要如下的元件:

按照表10-1连接触摸屏,然后按照7.1节“字符LCD模块”的描述和图7-2的样子连接LCD模块。

输入并上传下面的程序。程序中重要的地方已经加上了注释。

  // 作品34 - 触摸屏上的定位 

  #include <LiquidCrystal.h> 
  LiquidCrystal lcd(4,5,6,7,8,9); 

  int x,y = 0; 
  void setup() 
  { 
    lcd.begin(16,2); 
    lcd.clear(); 
  } 

 int readX()          // 返回触摸屏的x轴 
  { 
    int xr=0; 
    pinMode(A0, INPUT);    
    pinMode(A1, OUTPUT);   
    pinMode(A2, INPUT);  
    pinMode(A3, OUTPUT);   
    digitalWrite(A1, LOW);    // 设A1为GND  
    digitalWrite(A3, HIGH);   // 设A3为5V 
    delay(5); 
   xr=analogRead(0);       // 保存x轴的值 
    return xr; 
  } 

 int readY()             // 返回触摸屏的y轴 
  { 
    int yr=0; 
    pinMode(A0, OUTPUT);    // A0 
    pinMode(A1, INPUT);     // A1 
    pinMode(A2, OUTPUT);    // A2 
    pinMode(A3, INPUT);     // A3 
    digitalWrite(14, LOW);   // 设A0为GND  
    digitalWrite(16, HIGH);   // 设A2为5V 
    delay(5); 
    yr=analogRead(1);        // 保存y轴的值 
    return yr; 
  } 

  void loop() 
  { 
    lcd.setCursor(0,0); 
   lcd.print(" x = "); 
    x=readX(); 
    lcd.print(x); 
    y=readY(); 
    lcd.setCursor(0,1); 
   lcd.print(" y = "); 
    lcd.print(y); 
   delay (200);  
  }

处的函数readX()readY()读入触摸屏的电阻层的电压,用analogRead()函数读到电压,然后返回读数。程序不断地执行这两个函数来得到屏幕上被触摸区域的实时位置,然后在处把这个数据显示在LCD上(每个函数里的delay(5)是给输入/输出引脚足够的时间来响应变化)。

测试这个程序的时候,一边触摸屏幕一边看着LCD模块,观察在屏幕的不同位置触摸时的x和y的值。同时还要注意不触摸屏幕时显示的数值,如图10-3所示。

图10-3 触摸屏没被触摸时出现的值

这些值很重要,程序中要用这些值判断屏幕是否被触摸到。

触摸屏幕的四角,记录下返回值,就能给屏幕定坐标,如图10-4所示。这也就是要画出每个角的坐标。一旦决定了这些值,就可以把整个触摸屏划分成较小的区域,以此作为控制用的区域了。

图10-4 触摸屏坐标

建立了触摸屏的坐标系后,可以把整个屏幕分成较小的区域,用readX()readY()函数在屏幕上定义出一些控制区域,然后就可以用if语句在某些区域被触摸的时候采取对应的动作了。作品35就是这样做的。

在这个作品中,我们用触摸屏坐标系做出了一个开关。把屏幕垂直地分成两部分,如图10-5所示,左边的区域表示“on”,而右边的区域表示“off”。

图10-5 开/关映射

Arduino通过比较触摸点的坐标和屏幕两部分的边界来判断触摸屏上哪个区域被触摸了。判断出区域之后,就可以向一个数字输出发送开或关的信号了,不过这个程序只是简单地在串口监视器上显示哪个区域被触摸了,是开了还是关了。

输入并上传下面的程序。

  // 作品35 - 做一个两区域触摸开关 

  int x,y = 0; 

  void setup() 
  { 
    Serial.begin(9600); 
    pinMode(10, OUTPUT); 
  } 

  void switchOn() 
  { 
    digitalWrite(10, HIGH); 
    Serial.print("Turned ON at X = "); 
    Serial.print(x); 
    Serial.print(" Y = "); 
    Serial.println(y); 
    delay(200); 
  } 

  void switchOff() 
  { 
    digitalWrite(10, LOW); 
    Serial.print("Turned OFF at X = "); 
    Serial.print(x); 
    Serial.print(" Y = "); 
    Serial.println(y); 
    delay(200);  
  } 

  int readX()  // 返回触摸屏x轴的值 
  { 
    int xr=0; 
    pinMode(A0, INPUT);    
    pinMode(A1, OUTPUT);   
    pinMode(A2, INPUT);  
    pinMode(A3, OUTPUT);   
    digitalWrite(A1, LOW);    // 设A1为GND  
    digitalWrite(A3, HIGH);   // 设A3为5V 
    delay(5); 
   xr=analogRead(0);
    return xr; 
  } 

  int readY()             // 返回触摸屏y轴的值
  { 
    int yr=0; 
    pinMode(A0, OUTPUT);    // A0 
    pinMode(A1, INPUT); 
    pinMode(A2, OUTPUT); 
    pinMode(A3, INPUT); 
    digitalWrite(A0, LOW);   // 设A0为GND
    digitalWrite(A2, HIGH);   // 设A2为5V
    delay(5);
    yr=analogRead(1);
    return yr;
  } 

  void loop() 
  { 
    x=readX(); 
    y=readY(); 

 // 检查是否按下(ON) 

    if (x<=900 && x>=500) 
    { 
     switchOn(); 
    } 

 // 检查是否按下(OFF) 
    if (x<500 && x>=100) 
    { 
     switchOff(); 
    } 
  }

void loop()里的两个if语句检查屏幕的左边或右边有没有发生触摸。如果左边被触摸了,这个触摸在处被认为是一个“ON”;而如果右边被触摸了(按下了“OFF”),这个触摸会在处被检测出来。

注意:

y轴上的数值被忽略了,因为触摸屏是被垂直分成左右两半的。如果水平分成上下两半,那么就需要用y轴的数值来做检测了,作品36就是这么干的。

图10-6所示是串口监视器上的这个程序的输出结果。每次触摸屏幕,就显示开关的状态和触摸的坐标。

图10-6 作品35的输出

在这个作品中,我们要做一个三区域的触摸开关,可以控制数字引脚3上的一个LED,让这个LED点亮、熄灭,还可以通过PWM调节它的亮度(第3章的知识)。

触摸屏的坐标系设计如图10-7所示。

图10-7 作品36的触摸屏坐标系

这个触摸屏的坐标系分成“OFF(关)”、“ON(开)”和“brightness(亮度)”控制区域,程序测量触摸屏返回的数值来判断哪个部分被按下了,然后做相应的动作。

输入并上传下面的程序。

  // 作品36 - 做一个三区域触摸开关 

  int x,y = 0; 

  void setup() 
  { 
    pinMode(3, OUTPUT); 
  } 

  void switchOn() 
  { 
   digitalWrite(3, HIGH); 
    delay(200); 
  } 

  void switchOff() 
  { 
    digitalWrite(3, LOW); 
    delay(200);  
  } 

  void setBrightness() 
  { 
    int xx, bright; 
    float br; 
    xx=x-100; 
   br=(800-xx)/255; 
    bright=int(br); 
    analogWrite(3, bright); 
  } 

  int readX()             // 返回触摸屏x轴的值
  { 
    int xr=0; 
    pinMode(A0, INPUT);    
    pinMode(A1, OUTPUT);   
    pinMode(A2, INPUT);  
    pinMode(A3, OUTPUT);   
    digitalWrite(A1, LOW);    // 设A1为GND  
    digitalWrite(A3, HIGH);   // 设A3为5V 
    delay(5); 
    xr=analogRead(0); 
    return xr; 
  } 

  int readY()             // 返回触摸屏y轴的值
  { 
    int yr=0; 
    pinMode(A0, OUTPUT);    // A0 
    pinMode(A1, INPUT);     // A1 
    pinMode(A2, OUTPUT);    // A2 
    pinMode(A3, INPUT);     // A3 
    digitalWrite(A0, LOW);   // 设A0为GND  
    digitalWrite(A2, HIGH);   // 设A2为5V 
    delay(5); 
    yr=analogRead(1); 
    return yr; 
  } 

  void loop() 
  { 
    x=readX(); 
    y=readY(); 

  // 检查是否按下(ON) 

   if (x<=500 && x>=100 && y>= 150 && y<375) 
    { 
     switchOn(); 
   } 

  // 检查是否按下(OFF) 

   if (x>500 && x<=900 && y>= 150 && y<375) 
    { 
     switchOff(); 
    } 

  // 检查亮度 

   if (y>=375 && y<=900) 
    { 
     setBrightness(); 
    } 
  }

和分成两区域的程序类似,这个程序在处判断触摸是否发生在“ON”和“OFF”区域,以及在处判断是否有在水平分割线之上的触摸,那是表示亮度调节的。如果在亮度区域触摸了屏幕,在处,x轴的位置会被转换成相应的PWM值,然后用setBrightness()调节LED的亮度。

我们可以使用这些基础函数,用这个简单廉价的触摸屏做出任意数量的开关或滑动控制。

本章我们介绍了另一种接收用户数据、控制Arduino的手段。下一章,我们要关注Arduino板本身,学习不同的版本,然后在面包板上做出自己的版本来。


在本章,我们将:

我们要把整个Arduino分解成若干个元件,然后在面包板上搭出自己的Arduino电路来。自己搭电路可以省钱,在作品和原型都在不断变化时特别有用。我们还会学习一些新的元件和电路知识。然后研究如何能不借助额外的硬件把程序上传到自己做的Arduino上去。最后,我们要尝试Arduino Uno以外的常见的版本,找出它们的不同。

随着作品和实验在复杂度和数量上逐渐加大,为每个任务购买Arduino板的成本很容易会失去控制,特别是当你希望同时做不止一个作品的时候。因此,如果在面包板上搭一个Arduino电路,然后再扩展来搭出整个电路,以这样的方式把Arduino板组合进整个电路,会更便宜也更方便。在面包板上把基本的Arduino电路搭出来所需的元件成本应该低于10美元,而且如果没有损坏,这些元件通常还可以再用于其他作品。如果作品需要大量外部电路,自己做会更容易,这样可以省下大量在Arduino板和面包板之间来来回回的导线。

要做一个最小集的Arduino,需要以下的元件:

有些元件可能你还没见过。在下面的小节里,我会解释每个元件,给你看每个元件的样子和电路图符号。

1.7805线性稳压器

线性稳压器里有一个简单的电路,能把一个电压转换成另一个。元件清单里的稳压器的型号是7805,它能把7~30V的电压转换成固定的5V,最大的电流是1A,所以用它来给面包板Arduino供电是很合适的。图11-1所示是一种TO-220封装的7805,封装是指它的外形。

图11-1 7805线性稳压器

图11-2所示是7805的电路图符号。把7805标字的一面朝向自己,左边的管脚是输入电压,中间的管脚是地,而右边的管脚是5V输出。顶部的金属层钻了个孔,这样它就可以和一个更大的金属固定在一起,那片金属就成了散热器。当电流接近它的最大能力1A的时候要用散热器,因为那样使用的话,7805会变得非常热。金属层也是接在地上的。我们的电路需要一个7805稳压器。

图11-2 7805的电路图符号

2.16MHz晶体振荡器

这东西一般就叫做晶振,晶体振荡器能产生非常准确频率上的电信号。这里用的频率是16MHz,图11-3所示是我们要用的晶振的样子。

图11-3 晶体振荡器

和你的Arduino板上的晶振比较一下,它们的形状和尺寸应该都是相同的。

晶振是没有极性的,它的电路图符号如图11-4所示。

晶振决定了单片机的运行速度。比如,我们要组装的单片机电路运行在16MHz,意思是它每秒能执行1600万条处理器指令。不过,这并不是说它能那么快地运行一行程序或是一个函数,因为一行代码要用很多处理器指令来执行。

图11-4 晶体振荡器的电路图符号

3.Atmel ATmega328-PU单片机集成电路

单片机是一台微型计算机,里面有执行指令的处理器、不同类型的存放数据和程序指令的存储器,还能以各种方式收发数据。第2章讲到,单片机是面包板Arduino的大脑。图11-5所示就是一片ATmega328P。图中这样的集成电路的1脚,是在集成电路的左下角,标着一个小点的那个脚。

图11-5 ATmega328P

这个单片机的电路图符号如图11-6所示。

图11-6 单片机电路图符号

Arduino引导装载程序是一个软件,能将程序写入Arduino,不是所有的单片机芯片都有这样的引导装载程序的。自己做Arduino的时候,要购买已经烧录了引导装载程序的芯片。一般卖Arduino板的店家也会卖这样的芯片,比如adafruit、Freetronics和SparkFun。

图11-7所示是电路图。

图11-7 面包板Arduino电路图

这个电路图由两个部分组成。首先,左边是电源部分,能把电压降到稳压的5V。当有电的时候,一个LED就会亮。右边的部分,包括单片机、重启按钮、编程引脚和另一个LED。这个LED接到ATmega328上用在Arduino引脚13的那个管脚上。按照这个电路图接好Arduino。别忘了接线到那个6位插针(见图11-8),这个6位插座就是电路图中底部的6个圆圈。本章后面我们会用这个插针来上传程序到自己做的Arduino。

图11-8 6位插针

这个电路只是用一个9V电池和对应的电池扣供电,如图11-9所示。左边电路的正极(+)接电池扣的红色线,而负极(−)接黑色线。

图11-9 9V电池和电池扣

在自制的Arduino上,那些Arduino的引脚在哪里?普通Arduino板上有的那些模拟、数字和其他用途的引脚在我们的面包板版本上也都是有的,只要直接接到单片机上就行。

在面包板Arduino上,R2和LED2是接在数字引脚13上的。表11-1的左边列出了Arduino引脚,而右边是对应的ATmega328的管脚。

表11-1 ATmega328的管脚

Arduino引脚名称

ATmega328管脚

Arduino引脚名称

ATmega328管脚

RST

1

D10

16

RX/D0

2

D11

17

TX/D1

3

D12

18

D2

4

D13

19

D3

5

(只能接5V)

20

D4

6

AREF

21

(只能接5V)

7

GND

22

GND

8

A0

23

D5

11

A1

24

D6

12

A2

25

D7

13

A3

26

D8

14

A4

27

D9

15

A5

28

为避免混淆,像adafruit和Freetronics这样的厂家卖一种贴在单片机芯片上的不干胶标签,如图11-10所示的这个单片机(在http://www.freetronics.com/mculabel/可以购买)。

图11-10 引脚标签

现在可以上传一个程序了。我们用一个简单的闪烁LED的程序开始。

// 作品37 - 做自己的面包板Arduino 

void setup() 
{         
 pinMode(13, OUTPUT);   
} 

void loop() 
{ 
 digitalWrite(13, HIGH); 
 delay(1000);      
 digitalWrite(13, LOW); 
 delay(1000);      
} 

有3种方法上传这个程序。

1.用交换单片机的方法

上传程序最便宜的方法,是把已有的Arduino里的单片机拔出来,插上我们自制的Arduino里的单片机,上传程序,然后再插回自制的Arduino里。

要从Arduino里安全地拔出单片机,要用到集成电路拔取钳,如图11-11所示。

图11-11 用集成电路拔取钳来拔出单片机

在拔出单片机的时候,要保证慢慢地同时均衡地拔两端,别心急。拔出来可能不那么容易,但是最终单片机会出来的。

把单片机插进面包板或Arduino的时候,可能先得把管脚稍微向内弯一下,这样就能比较容易插进去。为此,把芯片的一边放在一个平面上,小心地按下,然后重复另一边,如图11-12所示。

图11-12 矫正单片机的管脚

最后,把原来的单片机插回到Arduino板的时候,要注意有标记的那端应该在右侧,如图11-13所示。

图11-13 在Arduino上的单片机的正确方向

2.连接到另一块Arduino板

我们可以用Arduino Uno的USB接口上传程序给面包板上的Arduino的单片机。用这个方法既不会磨损Arduino板上的集成电路插座,又可以省钱,因为不需要另外购买USB编程线了。

以下是使用Arduino板的USB接口电路给另一块单片机上传程序的步骤。

(1)拔掉USB线,取下单片机芯片。

(2)断开面包板Arduino电路的电源。

(3)从Arduino的数字引脚0接一根线到面包板上的ATmega328P的管脚2,另一根线从Arduino的数字引脚1接到ATmega328的管脚3。

(4)把Uno的5V和GND接到面包板上对应的地方。

(5)从Arduino的RST接一根线到ATmega328的管脚1。

(6)给Arduino Uno板插上USB线。

这样,这个系统就好像是一个普通的Arduino Uno一样,我们就可以正常地把程序上传到面包板电路去了,需要的时候也可以使用串口监视器。

3.用FTDI编程线

最后的方法也是最简单的,但是需要购买一根USB编程线,叫做FTDI线(这个名字是因为里面用的接口电路的芯片是一家叫做FTDI的公司生产的)。在购买FTDI线的时候,要确认是5V型号的,因为3.3V型号的不能正常工作。这种线(见图11-14)的一头有一个USB插头,另一头是6线的插头。线的USB那头有等价于Arduino Uno板上的USB接口的电路。6线的插头是连到图11-7和图11-8所示的插针那里的。

图11-14 FTDI线

连接这根线的时候,要确保插头的黑线这边插在面包板的插针的GND上。一旦这根线接好,它也会给电路供电,就像普通的Arduino板子一样。

在上传程序或使用串口监视器之前,要选择Tool -> Board确定板子类型为“Arduino Duemilanove”或“Nano(ATMega328)”,然后选择正确的单片机型号(见图11-15)。

一旦选择了一种上传的方法,就上传作品37的程序来做测试。现在,我们应该可以只用一块面包板来设计更复杂的电路了,这样我们能用更少的钱做出更多的作品来。如果学会了如何做自己的印刷电路板,甚至可以做出更长久的作品来。

图11-15 在IDE里修改板子型号

虽然在这本书中,我们只会使用Arduino Uno板,不过你可以自己选择很多另外的板子。这些板子具有不同的外形尺寸、输入和输出引脚的数量、程序存储空间的大小,以及购买的价格。

板子之间最关键的不同是所用的单片机。目前的板子主要是使用ATmega328或ATmega2560单片机,Due用的是另外的更强大的版本。这些单片机(包括ATmega328的两个版本)的主要区别总结在表11-2中。

表11-2 单片机对照表

ATmega328P

Atmega328P SMD

Atmega2560

SAM3X8E

用户可替换

处理速度

16 MHz

16 MHz

16 MHz

84 MHz

工作电压

5 V

5 V

5 V

3.3 V

数字引脚的数量

14(6个支持PWM)

14(6个支持PWM)

54(14个支持PWM)

54(12个支持PWM)

模拟输入的数量

6

8

16

12

每个I/O引脚的直流电流

40 mA

40 mA

40 mA

3~15 mA

可用的flash存储空间

31.5KB

31.5KB

248KB

512KB

EEPROM大小

1KB

1KB

4KB

没有EEPROM

SRAM大小

2KB

2KB

8KB

96KB

用来比较不同的Arduino兼容的板子的主要参数是板上存储器的类型以及每种类型的大小。以下是3种类型的存储器。

注意:

除了Uno还有很多Arduino的板子,这里所介绍的只是冰山一角。规划大的或是复杂的作品的时候,别害怕扩大使用更大的Mega板。同样的道理,如果一个更长久的作品只需要不多的几个I/O引脚,应该考虑Nano甚至是LilyPad。

我们来看几个买得到的板子。

Uno现在被认为是Arduino的标准板。目前所有的Arduino盾板都应该和Uno是兼容的。因为有板上的USB接口,而且单片机是可以插拔的,所以Uno被认为是最容易使用的Arduino板。

市面上的很多板子都模仿了Arduino Uno的功能,有些在标准设计的基础上做了一些改进。其中一种板子就是Freetronics的Eleven,如图11-16所示。

图11-16 Freetronics的Eleven

尽管Eleven与Arduino Uno完全兼容,但它做出了一些改进,使得它更有用。首先是在数字输入/输出引脚下方的一大块原型区域,这块区域让你可以直接在主板上做自己的电路,这样可以节约空间和成本,因为不需要另外购买原型盾板了。

另外,指示发送/接收(TX/RX)、电源和D13的4个LED排列在板子的最右侧边上,这样的布置,即使上面盖了盾板也能看见它们。最后,它用了一个micro USB插座,比Uno用的标准USB插座小很多。这样就使得设计自己的盾板要容易很多,因为不需要担心盾板上的焊点被USB插座的外壳短路了。这种板子在http://www.freetronics.com/products/eleven/可以买到。

Freeduino板来自一个合作的开源项目,这个项目撰写并发布文件,让人们可以做自己的Arduino兼容的板子。其中最流行的设计是一块Duemilanove兼容的板子套件,如图11-17所示。

这块Freeduino板子可以运行本书所有的作品。用Freeduino的两大好处是它便宜,而且自己动手组装一块板子是一种自我满足。Freeduino套件在http://www.seeedstudio.com/可以买到。

图11-17 一块组装好的Duemilanove兼容的Freeduino板

Boarduino是一种最小化的Arduino设计,它能直接插在面包板上。它以套件的形式提供,需要自己把元件焊起来。图11-18所示是组装好的样子。

图11-18 一块组装好的Boarduino

Boarduino套件在http://www.adafruit.com/可以买到。它实现了Freeduino套件所有的功能,但是在需要超过500mA电流的时候需要用到另外的电源。

如果需要一个紧凑的组装好的Arduino兼容板,Nano应该能满足要求。Nano被设计成可以插入面包板,虽然小巧但是功能强大。

Nano的尺寸只有18mm×43mm,但是它提供了Boarduino和Freeduino所有的功能。而且,它使用了ATmega328的贴片封装版本,所以还具有额外的两个模拟输入引脚(A6和A7)。Nano可以在http://www.gravitech.us/arna30wiatp.html买到。

图11-19 一个Arduino Nano

LilyPad是用来集成在如可穿戴电子这样的创意作品内的。实际上,LilyPad真的是可以用水和中性洗衣液来洗的,所以很适合用来装扮衣服,比如给运动衫亮灯。这种板子的设计很独特,如图11-20所示。

图11-20 一个Arduino LilyPad

LilyPad的输入输出引脚需要导线焊到板上,所以LilyPad更适合用作长久的作品。作为一种最小设计,它没有稳压电路,所以由用户决定给它提供2.7V~5.5V之间的电源。LilyPad还没有USB接口,所以需要一个5V的FTDI线才能给它上传程序。在大多数Arduino销售商那里都能买到Arduino LilyPad。

如果Arudino Uno上的输入输出引脚用完了,或者需要存储空间存放更大的程序,就可以考虑Mega 2560。它的外形比Arduino Uno大很多,尺寸是10.9cm×5.3cm,如图11-21所示。

尽管Mega 2560板子比Uno大了许多,不过还是可以配上大多数的Arduino盾板,也有Mega大小的原型盾板可以用来做Uno做不了的较大的作品。因为Mega用了ATmega2560单片机,它的存储空间和输入输出能力(如表11-2所列)都比Uno要大大改善了。另外,它的4条独立的串口通信线提升了它的通信能力。在大多数Arduino销售商那里都能买到Mega 2560。

图11-21 Arduino Mega 2560

如果需要一块Arduino Mega 2560、一个microSD卡盾板和一块连接到互联网的以太网盾板,最好的选择是一个EtherMega。它把所有这些功能集成在一块板上,比单独买每块板子要便宜。EtherMega可以在http://www.freetronics.com/ethermega/买到。

图11-22 Freetronics的EtherMega

装备有84MHz的处理器,能以非常快的速度运行程序,Due恐怕是目前最强大的Arduino板。从图11-23可以看到,这块板子和Arduino Mega 2560非常像,但是多了一个USB端口来接外部设备,引脚的标签也是不同的。

图11-23 Arduino Due

而且,Due的内存是Uno板的16倍,所以真的可以做复杂细致的程序。不过,Due只能工作在3.3V,所以任何连到模拟或数字引脚的电路、盾板或其他器件,都不能具有超过3.3V的电压。除了这些限制,使用Due的好处远远超过硬件上的这点变化。

说明:

购买Arduino板或附件的时候,一定要从能提供售后服务的有声誉的经销商那里购买。尽管互联网上充斥着廉价的替代品,尽管总有地方能生产超低价格的产品,但是你可能在买到坏的或是标示错误的产品的时候,没办法寻求赔偿。


开源硬件

Arduino硬件设计是公开给大众的,所以任何人都可以自由地制造、修改、分发和使用它。这种发布的类型属于开源硬件,这是最近的一场反对版权和知识产权法律保护的运动[1]。Arduino团队决定让它的设计开放,以利于更大的硬件圈子,做出更好的东西来。

遵循开源硬件的精神,许多生产附件或对原始Arduino板做了修改的组织都以相同的许可方式公开了他们的设计。以这样的方式,产品就能比单一组织开发更快地得到发展。

本章描述了各种类型的硬件的总体情况,包括自己做的一种面包板Arduino。我们了解了做Arduino要用的元件,学习了如何用面包板自己做一个Arduino,这样我们就不用再购买新的板子做基于多个Arduino板的原型了。我们还了解了市场上各种Arduino板的情况,这样就能选择最适合需要的板子了。最后,我们还对Arduino开源运动本身有了一点了解。

下一章我们要学习如何使用几种电机,开始做自己的Arduino控制的电动坦克。

[1]译者著:开源运动不是反对版权和知识产权,而是对现有版权和知识产权体系的改进和扩展。


相关图书

Arduino实战
Arduino实战

相关文章

相关课程