1、 第1章 进入Arduino的世界 欢迎来到Arduino的世界!Arduino是一个开源的开发平台,在全世界范围内成千上万的人正在用它开发制作一个又一个电子产品,这些电子产品包括从平时生活的小物件到时下流行的3D打印机,它降低了电子开发的门槛,即使是从零开始的入门者也能迅速上手,制作有趣的东西,这便是开源Arduino的魅力。通过本书的介绍,读者对Arduino会有一个更全面的认识。 本章知识点: Arduino的起源与发展 Arduino的特点 Arduino开发板简介 Arduino的未来展望 1.1 什么是Arduino 什么是Arduino?相信很多读者会有这个疑问,也需要一个全面而
2、准确的答案。不仅是读者,很多使用 Arduino 的人也许对这个问题都难以给出一个准确的说法,甚至认为手中的开发板就是Arduino,其实这并不准确。那么,Arduino究竟该如何理解呢? 1.1.1 Arduino不只是电路板 Arduino 是一种开源的电子平台,该平台最初主要基于 AVR 单片机的微控制器1和相应的开发软件,目前在国内正受到电子发烧友的广泛关注。自从2005年Arduino腾空出世以来,其硬件和开发环境一直进行着更新迭代。现在 Arduino 已经有将近十年的发展历史,因此市场上称为Arduino的电路板已经有各式各样的版本了。Arduino开发团队正式发布的是Ardui
3、no Uno和Arduino Mega 2560,如图1-1和图1-2所示。 1 关于AVR单片机的内容会在第3章进行介绍。 Arduino开发从零开始学 2 图1-1 Arduino Uno R3 图1-2 Arduino Mega 2560 R3 图1-1和图1-2所示的开发板就是所谓的Arduino I/O印刷电路板(Printed Circuit Board, PCB)。 Arduino项目起源于意大利,该名字在意大利是男性用名,音译为“阿尔杜伊诺”,意思为“强壮的朋友”,通常作为专有名词,在拼写时首字母需要大写。其创始团队成员包括:Massimo Banzi、David Cuarti
4、elles、Tom Igoe、Gianluca Martino、David Mellis和Nicholas Zambetti 6人。Arduino的出现并不是偶然,Arduino最初是为一些非电子工程专业的学生设计的。设计者最初为了寻求一个廉价好用的微控制器开发板从而决定自己动手制作开发板,Arduino一经推出,因其开源、廉价、简单易懂的特性迅速受到了广大电子迷的喜爱和推崇。几乎任何人,即便不懂电脑编程,利用这个开发板也能用Arduino做出炫酷有趣的东西,比如对感测器探测做出一些回应、闪烁灯光、控制马达等。 Arduino 的硬件设计电路和软件都可以在官方网站上获得,正式的制作商是意大利的
5、SmartProjects(), 许多制造商也在生产和销售他们自己的与Arduino兼容的电路板和扩展板,但是由Arduino团队设计和支持的产品需要始终保留着Arduino的名字。所以,Arduino更加准确的说法是一个包含硬件和软件的电子开发平台,具有互助和奉献的开源精神以及团队力量。 1.1.2 Arduino程序的开发过程 由于Arduino主要是为了非电子专业和业余爱好者使用而设计的,所以Arduino被设计成一个小型控制器的形式,通过连接到计算机进行控制。Arduino开发过程是: (1)开发者设计并连接好电路; (2)将电路连接到计算机上进行编程; (3)将编译通过的程序下载到控
6、制板中进行观测; (4)最后不断修改代码进行调试以达到预期效果。 进入Arduino的世界 第1章 3 1.2 为什么要使用Arduino 在嵌入式开发中,根据不同的功能开发者会用到各种不同的开发平台。而Arduino作为新兴开发平台,在短时间内受到很多人的欢迎和使用,这跟其设计的原理和思想是密切相关的。 首先,Arduino无论是硬件还是软件都是开源的,这就意味着所有人都可以查看和下载其源码、图表、设计等资源,并且用来做任何开发都可以。用户可以购买克隆开发板和基于Arduino的开发板,甚至可以自己动手制作一个开发板。但是自己制作的不能继续使用Arduino这个名称,可以自己命名,比如Rob
7、otduino。 其次,正如林纳斯本纳第克特托瓦兹的Linux操作系统一样,开源还意味着所有人可以下载使用并且参与研究和改进Arduino,这也是Arduino更新换代如此迅速的原因。全世界各种电子爱好者用Arduino开发出各种有意思的电子互动产品。有人用它制作了一个自动除草机,去上班的时候打开,不久花园里的杂草就被清除干净了!有人用它制作微博机器人,配合一些传感器监测植物的状态,并及时发微博来提醒主人,植物什么时间该浇水、施肥、除草等,非常有趣。 图1-3所示为日本一开发者用Arduino和Kinect制作的可以自己接住丢掉垃圾的智能垃圾桶。 图1-3 智能垃圾桶 Arduino可以和LE
8、D、点阵显示板、电机、各类传感器、按钮、以太网卡等各类可以输出输入数据或被控制的任何东西连接,在互联网上各种资源十分丰富,各种案例、资料可以帮助用户迅速制作自己想要制作的电子设备。 在应用方面,Arduino突破了传统的依靠键盘、鼠标等外界设备进行交互的局限,可以更方便地进行双人或者多人互动,还可以通过Flash、Processing等应用程序与Arduino进行交互。 Arduino与Flash、Processing的交互将在第6章介绍。 1.3 Arduino硬件的分类 在了解Arduino起源以及使用Arduino制作的各种电子产品之后,接下来对Arduino硬件和开Arduino开发从
9、零开始学 4 发板,以及其他扩展硬件进行初步的了解和学习。 1.3.1 Arduino开发板 Arduino开发板设计得非常简洁,一块AVR单片机、一个晶振或振荡器和一个5V的直流电源。常见的开发板通过一条 USB 数据线连接计算机。Arduino 有各式各样的开发板,其中最通用的是Arduino UNO。另外,还有很多小型的、微型的、基于蓝牙和Wi-Fi的变种开发板。还有一款新增的开发板叫做Arduino Mega 2560,它提供了更多的I/O引脚和更大的存储空间,并且启动更加迅速。以Arduino UNO为例,Arduino UNO的处理器核心是ATmega 328,同时具有14路数字输
10、入/输出口(其中6路可作为PWM输出),6路模拟输入,一个16MHz的晶体振荡器,一个USB口,一个电源插座,一个ICSP header和一个复位按钮。因为Arduino UNO开发板的基础构成在一个表里显示不下,所以这里特意设计了两个表来展示,如表1-1和表1-2所示。 表1-1 Arduino UNO开发板基本概要构成(ATmega328)1 处理器 工作电压 输入电压 数字I/O脚 模拟输入脚 串口 ATmega328 5V 6-20V 14 6 1 表1-2 Arduino UNO开发板基本概要构成(ATmega328)2 IO脚直流电流 3.3V脚直流电流 程序存储器 SRAM EE
11、PROM 工作时钟 40 mA 50 mA 32 KB 2 KB 1 KB 16 MHz 图1-4对一块Arduino UNO开发板功能进行了详细标注。 图1-4 Arduino UNO R3功能标注 Arduino UNO可以通过以下三种方式供电,能自动选择供电方式: 外部直流电源通过电源插座供电; 电池连接电源连接器的GND和VIN引脚; USB接口直接供电,图1-4所示的稳压器可以把输入的7V12V电压稳定到5V。 进入Arduino的世界 第1章 5 在电源接口上方,一个右侧引出 3 个引脚,左侧一个比较大的引脚细看会发现上面有AMST1117的字样,其实这个芯片是个三端5V稳压器,电
12、源口的电源经过它稳压之后才给板子输入,其实电源适配器内已经有稳压器,但是电池没有。可以理解为它是一个安检员,一切从电源口经过的电源都必须过它这一关,这个“安检员”对不同的电源会进行区别对待。 首先,AMS1117的片上微调把基准电压调整到1.5%的误差以内,而且电流限制也得到了调整,以尽量减少因稳压器和电源电路超载而造成的压力。再者根据输入电压的不同而输出不同的电压,可提供1.8V、2.5V、2.85V、3.3V、5V稳定输出,电流最大可达800mA,内部的工作原理这里不必去探究,读者只需要知道,当输入5V的时候输出为3.3V,输入9V的时候输出才为5V,所以用9V(9V12V均可,但是过高的
13、电源会烧坏板子)电源供电的原因就在这,如使用5V的适配器与Arduino连接,之后连接外设做实验,会发现一些传感器没有反应,这就是某些传感器需要5V的信号源,可是板子最高输出只能达到3.3V,必然有问题。 重置按钮和重置接口都用于重启单片机,就像重启电脑一样。若利用重置接口来重启单片机,应暂时将接口设置为0V即可重启。 GND引脚为接地引脚,也就是0V。A0A5引脚为模拟输入的6个接口,可以用来测量连接到引脚上的电压,测量值可以通过串口显示出来。当然也可以用作数字信号的输入输出。 Arduino同样需要串口进行通信,图1-4所示的串口指示灯在串口工作的时候会闪烁。Arduino通信在编译程序和
14、下载程序时进行,同时还可以与其他设备进行通信。而与其他设备进行通信时则需要连接RX(接收)和TX(发送)引脚。ATmega 328芯片中内置的串口通信硬件是可以通过同步和异步模式工作的。同步模式需要专用的信号来表示时钟信息,而Arduino的串口(USART外围设备,即通用同步/异步接收发送装置)工作在异步模式下,这和大多数PC的串口是一致的。数字引脚0和1分别标注着RX和TX,表明这两个可以当做串口的引脚是异步工作的,即可以只接收、发送,或者同时接收和发送信号。 1.3.2 Arduino 扩展硬件 与Arduino相关的硬件除了核心开发板外,各种扩展板也是重要的组成部分。Arduino开发
15、板设计的可以安装扩展板,即盾板进行扩展。它们是一些电路板,包含其他的元件,如网络模块、GPRS模块、语音模块等。在图1-4所示的开发板两侧可以插其他引脚的地方就是可以用于安装其他扩展板的地方。它被设计为类似积木、通过一层层的叠加而实现各种各样的扩展功能。例如Arduino UNO同W5100网络扩展板可以实现上网的功能,堆插传感器扩展板可以扩展Arduino连接传感器的接口。图1-5和图1-6为Arduino同扩展板连接的例子。 图1-5 Arduino UNO与一块原型扩展板连接 Arduino开发从零开始学 6 图1-6 Arduino UNO与网络扩展板连接 虽然Arduino开发板支持
16、很多扩展板来扩展功能,但其扩展插座中引脚的间距并不严格规整。仔细观察开发板会发现上面两个最远的引脚之间距离为4.064mm,这与标准的2.54mm网格的面包板及其他扩展工具并不兼容,尽管要求改正的呼声很强烈,但是这个误差却很难改正,一旦改正将使得原来的大量扩展板变得不兼容,所以这个误差便没有去改动。 虽然这个误差没有改动,但是很多公司和个人在生产Arduino兼容的产品时兼顾增加了额外两行2.54mm的针孔来解决这个问题,另外美国Gravitech(www.gravitech.us)公司完全舍弃了扩展板兼容来解决这个问题。 1.4 Arduino展望未来 Arduino自诞生以来,简单、廉价的
17、特点使得Arduino如同雨后春笋般迅速风靡全球,在不断发展的同时,Arduino也在发挥着更重要的作用。本节将对Arduino发展的特点和未来发展做一点总结和展望。 1.4.1 创客文化 在介绍Arduino发展前景之前,首先需要了解逐渐兴起的“创客”文化。什么是“创客”?“创客”一词来源于英文单词“Maker”,指的是不以盈利为目标,努力把各种创意转变为现实的人。其实就是热爱生活,愿意亲手创新为生活增加乐趣的一群人。他们精力旺盛,坚信世界会因为自己的创意而改变。 创客文化兴起于国外,经过一段时间红红火火的发展,如今已经成为一种潮流。国内也不示弱,一些硬件发烧友了解到国外的创客文化后被其深深
18、吸引,经过圈子中的口口相传,大量的硬件、软件、创意人才聚集在了一起。各种社区、空间、论坛的建立使得创客文化在中国真正流行起来。北京、上海、深圳已经发展成为中国创客文化的三大中心。 那么,是什么推动创客文化如此迅猛发展呢?众所周知,硬件的学习和开发是有一定的难度的,人人都想通过简单的方式实现自己的创意,于是开源硬件应运而生。而开源硬件平台中知名度较高的应该就是日渐强大的Arduino了。 Arduino作为一款开源硬件平台,一开始被设计的目标人群就是非电子专业尤其是艺术家学习使用的,让他们更容易实现自己的创意。当然,这不是说Arduino性能不强、有些业余,而是表明Arduino 很简单,易上手
19、。Arduino 内部封装了很多函数和大量的传感器函数库,即使不懂软件开发和电子设计的人也可以借助Arduino很快创作出属于自己的作品。可以说Arduino与创客文化是进入Arduino的世界 第1章 7 相辅相成的。 一方面,Arduino简单易上手、成本低廉这两大优势让更多的人都能有条件和能力加入创客大军;另一方面,创客大军的日益扩大也促进了Arduino的发展。各种各样的社区、论坛的完善,不同的人、不同的环境、不同的创意每时每刻都在对Arduino进行扩展和完善。在2011年举行的Google I/O开发者大会上,Google公司发布了基于Arduino的Android Open Ac
20、cessory标准和ADK工具,这使得大家对Arduino的巨大的发展前景十分看好。 Arduino发展潜力巨大,既可以让创客根据创意改造成为一个小玩具,也可以大规模制作成工业产品。国内外Arduino社区良好的运作和维护使得几乎每一个创意都能找到实现的理论和实验基础,相信随着城市的不断发展,人们对生活创新的不断追求,会有越来越多的人听说Arduino、了解Arduino、玩转Arduino。 1.4.2 快速原型设计 纵观计算机语言的发展,从0和1相间的二进制语言到汇编语言,从K Arduino语言也像C语言一样,同样追随C语言的脚步,在硬件的世界里,使用灯光的闪烁代表hello world
21、,下面我们编写第一个Sketch! 打开Arduino IDE后,需要新建一个空的Sketch。之后就可以在编辑器上编写第一个Sketch,如程序2-2所示。 程序2-2:Arduino向世界问好 void setup() pinMode(13,OUTPUT); /将13引脚设置为输出引脚 void loop() 开始Arduino之旅 第2章 19 digitalWrite(13,HIGH); /13引脚输出高电平,即将小灯点亮 delay(1000); digitalWrite(13,LOW); /13引脚输出低电平,即将小灯熄灭 delay(1000); 这个例子是Arduino示例Ba
22、sics中的Blink程序,也可以通过图2-19所示的操作打开该程序。Blink作为Arduino入门的初始程序非常简洁易懂,在每句话的后面作者都给出了注释,官方示例中的程序如图2-20所示。 图2-19 Blink所在位置 图2-20 Blink程序 编写或者打开Blink之后,便可以连接Arduino开发板,将开发板的USB接口连接到电脑上,当系统提示安装成功,并且开发板的绿色“ON”指示灯亮起时,就可以进行 Blink 的上传。单击“上传”按钮,再经过短暂的几秒烧写之后,会发现开发板的串口指示灯闪烁了数次,提示成功之Arduino开发从零开始学 20 后,开发板装载的LED灯便开始不停闪
23、烁。 之后再来看状态区域,状态区域显示“下载成功”和“二进制程序大小1018字节”的字样。我们第一个Arduino程序就下载并成功运行了。 2.3.2 用Arduino IDE开发程序流程 当程序编写好之后,关闭前需要将文件保存到一个目录中。如果是开发一个项目,编写的Sketch可能不止一个,负责不同部分和模块开发的人员都各自编写好Sketch,最后综合Sketeh 时发现程序特别难以阅读,并且很多变量名称不一致,修改起来非常麻烦,这就需要一个规范的开发流程。 在软件工程中,软件项目开发有很多不同的模型适用于不同的开发需求,例如瀑布模型、螺旋模型等。由于嵌入式项目bug排查起来比较费力,为了开
24、发一个稳定的嵌入式系统,往往采用“增量”式模型,即在功能最简单、最基本的系统基础上逐渐扩展其功能。 因此,在编写程序之前,必须对程序所实现的功能有一个详细的规划,对整个系统的基本功能需求有一个清晰的定义。在编写程序时应当约定好各种变量、函数名称,并做好注释和文档记录。不同的模块在开发过程中需要不断的测试,也要做好详细的开发和测试记录。 编写程序时也是同样道理,增量式模型要求迅速将系统整体的基本功能实现出来,对于不同的功能可以利用不同的函数进行实现和测试,而不必在主程序中直接定义和实现,这样既快捷又清晰易读。 2.3.3 函数库和程序架构介绍 Arduino程序的架构大体可分为3个部分。 (1)
25、声明变量及接口的名称。 (2)setup()。在Arduino程序运行时首先要调用setup()函数,用于初始化变量、设置针脚的输出/输入类型、配置串口、引入类库文件等等。每次 Arduino 上电或重启后,setup()函数只运行一次。 (3)loop()。在setup()函数中初始化和定义变量,然后执行loop()函数。顾名思义,该函数在程序运行过程中不断地循环,根据反馈,相应地改变执行情况。通过该函数动态控制Arduino主控板。 程序2-3中包含了完整的Arduino基本程序框架。 程序2-3:闪灯程序 int LEDPin = 3; void setup() pinMode(LEDP
26、in, OUTPUT); /将3引脚设置为输出引脚 void loop() digitalWrite(LEDPin, HIGH); /3引脚输出高电平,即将小灯点亮 delay(1000); digitalWrite(LEDPin, LOW); /3引脚输出低电平,即将小灯熄灭 开始Arduino之旅 第2章 21 delay(1000); 这是一个简单的实现LED灯闪烁的程序,在这个程序里,int LEDPin = 3;就是上面架构的第一部分,用来声明变量及接口。void setup()函数则将LEDPin引脚的模式设为输出模式。在void loop()中则循环执行点亮熄灭LED灯,实现LE
27、D灯的闪烁。 Arduino官方团队提供了一套标准的Arduino函数库,如表2-1所示。 表2-1 Arduino标准库文件 库文件名 说明 EEPROM 读写程序库 Ethernet 以太网控制器程序库 LiquidCrystal LCD控制程序库 Servo 舵机控制程序库 SoftwareSerial 任何数字IO口模拟串口程序库 Stepper 步进电机控制程序库 Matrix LED矩阵控制程序库 Sprite LED矩阵图象处理控制程序库 Wire TWI/I2C总线程序库 在标准函数库中,有些函数会经常用到。如小灯闪烁的数字 I/O 口输入输出模式定义函数pinMode(pin
28、,mode),时间函数中的延时函数 delay(ms)、串口定义波特率函数 Serial.begin(speed)和串口输出数据函数Serial.print(data)。了解和掌握这些常用函数可以帮助开发人员使用Arduino实现各种各样的功能。 2.3.4 Hello World做了什么 在2.3.1小节中实现了第一个Arduino闪灯程序,这个程序不只是让开发板上的LED灯进行闪烁。在程序的背后,再思考一下,IDE是如何用编写好的程序来驱动单片机工作的呢,是不是开发板在Arduino的语言驱动下直接工作? 在解决这个问题之前,先来了解一下计算机语言的工作原理。对于计算机来说,进行开发的语言
29、并不是计算机直接可以读懂的。那么计算机能够看懂什么语言呢?有经验的读者肯定会说,二进制语言。是的,计算机的脑子只能看懂两个字符,即0和1。以一个最简单的说明为例,假如计算机会说话,那么它的启动方式可看做是两种可能:一种是通电,一种是断电。可以把通电看成是1,断电看作是0。那么计算机中的很多零部件也是一样,工作起来的状态为1,不工作的状态为0。计算机中的数据通过存储器储存起来,处理器通过一串0和1组成的地址,找到存储器中数据的位置,对数据进行一系列操作,从而有条不紊的完成了各个程序的执行任务。 因此,在Arduino IDE编程并下载程序到开发板的过程,实际上是编译器将程序翻译为机器语言(即二进
30、制语言)的过程。计算机将二进制的指令传送到单片机程序闪存中,单片机识别指令后进行工作。图2-21是从编写好的程序到Arduino开发板运行程序的流程。 Arduino开发从零开始学 22 图2-21 从代码到开发板 Arduino编译器的作用除了是一位必不可少的翻译官外,还是一位一丝不苟的检察官。写好的程序在编译器翻译成机器语言之前,需要检查程序是否存在语法错误,如果不符合程序框架,或者有些函数没有定义或者使用错误,还有变量类型不正确,编译器都会尽职尽责地检查出来,并明确错误位置。没有编译器,程序编写好后将无法进行解释和分析,也就无法转化成相应的机器语言。 2.4 Arduino语法变量和常量
31、 加载第一个程序后,要想写出一个完整的程序,需要了解和掌握 Arduino 语言,本节将对Arduino语言做一个初步讲解,首先介绍变量和常量。 2.4.1 变量 变量来源于数学,是计算机语言中能储存计算结果或者能表示某些值的一种抽象概念。通俗来说可以认为是给一个值命名。当定义一个变量时,必须指定变量的类型。如果要变量全是整数,这种变量称为整型(int),那么如果要定义一个名为LED的变量值为11,变量应该这样声明: int led 11; 一般变量的声明方法为类型名+变量名+变量初始化值。变量名的写法约定为首字母小写,如果是单词组合则中间每个单词的首字母都应该大写,例如ledPin、ledC
32、ount等,一般把这种拼写方式称为小鹿拼写法(pumpy case)或者骆驼拼写法(camel case)。 变量的作用范围又称为作用域,变量的作用范围与该变量在哪儿声明有关,大致分为如下两种。 (1)全局变量:若在程序开头的声明区或是在没有大括号限制的声明区,所声明的变量作用域为整个程序。即整个程序都可以使用这个变量代表的值或范围,不局限于某个括号范围内。 (2)局部变量:若在大括号内的声明区所声明的变量,其作用域将局限于大括号内。若在主程序与各函数中都声明了相同名称的变量,当离开主程序或函数时,该局部变量将自动消失。 使用变量还有一个好处,就是可以避免使用魔数。在一些程序代码中,代码中出现
33、但没有解释的数字常量或字符串称为魔数(magic number)或魔字符串(magic string)。魔数的出现使得程开始Arduino之旅 第2章 23 序的可阅读性降低了很多,而且难以进行维护。如果在某个程序中使用了魔数,那么在几个月(或几年)后将很可能不知道它的含义是什么。 为了避免魔数的出现,通常会使用多个单词组成的变量来解释该变量代表的值,而不是随意给变量取名。同时,理论上一个常数的出现应该对其做必要地注释,以方便阅读和维护。在修改程序时,只需修改变量的值,而不是在程序中反复查找令人头痛的“魔数”。 【示例1】 带变量的闪灯程序 在接下来的程序2-4里会用到ledPin这个变量,通
34、过它来做一个带变量的闪灯程序。 程序2-4:带变量的闪灯程序 int ledPin = 13; int delayTime = 1000; void setup() pinMode(ledPin,OUTPUT); void loop() digitalWrite(ledPin,HIGH); delay(delayTime); /延时1s digitalWrite(ledPin,LOW); delay(delayTime); /延时1s 这里还使用了一个名为延时的delayTime变量,在延时(delay)函数中使用的参数单位为毫秒,用到delay函数中,即延时1000毫秒。 【示例2】 改变闪
35、烁频率的闪灯程序 如果希望小灯闪烁快些,将延时函数值改小就可以了,读者可以尝试将delayTime改成500,可以看到小灯闪烁的频率变大了。如果在程序的后面再加上1行代码“delayTime=delayTime+100;”可以发现小灯闪烁的频率越来越小,即小灯闪烁的越来越慢了。当按下“重置”按钮后,小灯闪烁又重新变快了,如下面程序2-5所示。 程序2-5:改变闪烁频率的闪灯程序 int ledPin = 13; int delayTime = 1000; void setup() pinMode(ledPin,OUTPUT); void loop() Arduino开发从零开始学 24 dig
36、italWrite(ledPin,HIGH); delay(delayTime); /延时 digitalWrite(ledPin,LOW); delay(delayTime); delayTime=delayTime+100; /每次增加延时时间0.1s 2.4.2 常量 常量是指值不可以改变的量,例如定义常量const float pi = 3.14,当pi = 5时就会报错,因为常量是不可以被赋值的。编程时,常量可以是自定义的,也可以是Arduino核心代码中自带的。下面就介绍一下Arduino核心代码中自带的一些常用的常量,以及自定义常量时应该注意的问题。 1逻辑常量(布尔常量):fa
37、lse和true false的值为零,true通常情况下被定义为1,但true具有更广泛的定义。在布尔含义(Boolean Sense)里任何非零整数为true。所以在布尔含义中-1、2和-200都定义为true。 2数字引脚常量:INPUT和OUTPUT 首先要记住这两个常量必须是大写的。当引脚被配置成INPUT时,此引脚就从引脚读取数据;当引脚被配置成 OUTPUT 时,此引脚向外部电路输出数据。在前面程序中经常出现的pinMode(ledPin,OUTPUT),表示从 ledPin 代表的引脚向外部电路输出数据,使得小灯能够变亮或者熄灭。 3引脚电压常量:HIGH和LOW 这两个常量也是
38、必须大写的。HIGH表示的是高电位,LOW表示的是低电位。例如:digitalWrite(pin,HIGH);就是将pin这个引脚设置成高电位的。还要注意,当一个引脚通过pinMode被设置为INPUT,并通过digitalRead读取(read)时。如果当前引脚的电压大于等于3V,微控制器将会返回为HIGH,引脚的电压小于等于2V,微控制器将返回为LOW。 当一个引脚通过pinMode配置为OUTPUT,并通过digitalWrite设置为LOW时,引脚为0V,当digitalWrite设置为HIGH时,引脚的电压应在5V。 4自定义常量 在Arduino中自定义常量包括宏定义#define
39、和使用关键字const来定义,它们之间有细微的区别。在定义数组时只能使用const。一般const相对的define是首选的定义常量语法。 2.5 Arduino语法数据类型 Arduino与C语言类似,有多种数据类型。数据类型在数据结构中的定义是一个值的集合,以及定义在这个值集上的一组操作,各种数据类型需要在特定的地方使用。一般来说,变量的数据类型决定了如何将代表这些值的位存储到计算机的内存中。在声明变量时需要指定它的数据类型,所开始Arduino之旅 第2章 25 有变量都具有数据类型,以便决定存储不同类型的数据。 2.5.1 常用的数据类型 常用的数据类型有布尔类型、字符型、字节型、整型
40、、无符号整型、长整型、无符号长整型、浮点型、双精度浮点型等,本小节会依次介绍这些数据类型。 1布尔类型 布尔值(bollean)是一种逻辑值,其结果只能为真(true)或者假(false)。布尔值可以用来进行计算,最常用的布尔运算符是与运算( 3字节型 字节(byte)只能用一个字节(8位)的存储空间,它可以用来存储0255之间的数字。例如: byte B=8; 4整型 整型(int)用两个字节表示一个存储空间,它可以用来存储-32768+32767 之间的数字。在Arduino中,整型是最常用的变量类型。例如: Arduino开发从零开始学 26 int C=13; 5无符号整型 同整型一样
41、,无符号整型(unsigned int)也用两个字节表示一个存储空间,它可以用来存储065536之间的数字,通过范围可以看出,无符号整型不能存储负数。例如: unsigned int D=65535; 6长整型 长整型(long)可以用4个字节表示一个存储空间,其大小是int型的2倍。它可以用来存储-21474836482147483648 之间的数字。例如: long E=2147483647; 7无符号长整型 无符号长整型(unsigned long)同长整型一样,用4个字节表示一个存储空间,它可以用来存储04294967296之间的数字。例如: unsigned long F=42949
42、67295; 8浮点型 浮点数(float)可以用来表示含有小数点的数,例如:1.24。当需要用变量表示小数时,浮点数便是所需要的数据类型。浮点数占有4个字节的内存,其存储空间很大,能够存储带小数的数字。例如: a = b / 3; 当b = 9时,显然a = 3,为整型。 当b = 10时,正确结果应为3.3333,可是由于a是整型,计算出来的结果将会变为3,这与实际结果不符。 但是,如果方程为:float a = b / 3.0。 当b = 9时,a = 3.0。 当b = 10时,a = 3.3333,结果正确。 如果在常数后面加上“.0”,编译器会把该常数当做浮点数而不是整数来处理。
43、9双精度浮点型 双精度浮点型(double)同float类似,它通常占有8个字节的内存,但是,双精度浮点型数据比浮点型数据的精度高,而且范围广。但是,双精度浮点型数据和浮点型数据在Arduino中是一样的。 2.5.2 数据类型转换 在编写程序过程中需要用到一些有关数据类型转换的函数,这里介绍几个常见的数据类型转换函数。 开始Arduino之旅 第2章 27 (1)char() 功能:将一个变量的类型变为char。 语法:char(x) 参数:x:任何类型的值 返回值:char型值 (2)byte() 功能:将一个值转换为字节型数值。 语法:byte(x) 参数:x:任何类型的值 返回值:字节
44、 (3)int() 功能:将一个值转换为整型数值。 语法:int(x) 参数:x:任何类型的值 返回值:整型的值 (4)long() 功能:将一个值转换为长整型数值。 语法:long(x) 参数:x:任何类型的值 返回值:长整型的值 (5)float() 功能:将一个值转换换浮点型数值。 语法:float(x) 参数:x:任何类型的值 返回值:浮点型的值 (6)word() 功能:把一个值转换为word数据类型的值,或由两个字节创建一个字符。 语法:word(x)或word(H,L) 参数:x:任何类型的值,H:高阶字节(左边),L:低阶字节(右边) 返回值:字符 2.5.3 自定义数据类型
45、在Arduino中可以根据自己的需要定义结构类型的数据,其方法和C语言是一致的。 struct 名称 Arduino开发从零开始学 28 成员列表; ; 例如: struct Student char20 name; int number; char2 sex; int score; ; 2.6 Arduino语法数组 数组是一种可访问的变量的集合。Arduino的数组是基于C语言的,实现起来虽然有些复杂,但使用却很简单。 2.6.1 创建或声明一个数组 数组的声明和创建与变量一致,下面是一些创建数组的例子。 arrayInts 6; arrayNums = 2,4,6,8,11; array
46、Vals 6 = 2,4,-8,3,5; char arrayString7 = “Arduino“; 由例子中可以看出,Arduino数组的创建可以指定初始值,如果没有指定,那么编译器默认为0,同时,数组的大小可以不指定,编译器在监察时会计算元素的个数来指定数组的大小。在arrayString中,字符个数正好等于数组大小。 在声明时元素的个数不能够超过数组的大小,即小于或等于数组的大小。 2.6.2 指定或访问数组 在创建完数组之后,可以指定数组的某个元素的值。 int intArray3; intArray2=2; 数组是从零开始索引的,也就说,数组初始化之后,数组第一个元素的索引为0,如
47、上例所示,arrayString0为“A”即数组的第一个元素是0号索引,并以此类推。这也意味着,在包含10个元素的数组中,索引9是最后一个元素。因此,在下个例子中: int intArray10 = 1,2,3,4,5,6,7,8,9,10; 开始Arduino之旅 第2章 29 /intArray9的数值为10 / intArray10,该索引是无效的,它将会是任意的随机信息(内存地址) 出于这个原因,在访问数组时应该注意。如果访问的数据超出数组的末尾如访问intArray10,则将从其他内存中读取数据。从这些地方读取的数据,除了产生无效的数据外,没有任何作用。向随机存储器中写入数据绝对是一
48、个坏主意,通常会导致一些意外的结果,如导致系统崩溃或程序故障。顺便说一句,不同于Basic或Java,C语言编译器不会检查访问的数组是否大于声明的数组。 【示例3】 串口打印数组 数组创建之后在使用时,往往在for循环中进行操作,循环计数器可用于访问数组中的每个元素。例如,将数组中的元素通过串口打印,程序可以这样写。 程序2-6:串口打印数组 void setup() / put your setup code here, to run once: int intArray10 = 1,2,3,4,5,6,7,8,9,10; /定义长度为10的数组 int i; for (i = 0; i =
49、(右移等于)将某个变量的值按位进行右移,例如:K=n,将K变量的值右移n位,与K=Kn相同。 2.7.2 算数运算符 +(加)对两个值进行求和,例如:A=x+y,将x与y变量的值相加,其和放入A变量。 -(减)对两个值进行做差,例如:B=x-y,将x变量的值减去y变量的值,其差放入B变量。 *(乘)对两个值进行乘法运算,例如:C=x*y,将x与y变量的值相乘,其积放入C变量。 /(除)对两个值进行除法运算,例如:D=x/y,将 x变量的值除以 y变量的值,其商放入 D变量。 %(取余)对两个值进行取余运算,例如:E=x%y,将x变量的值除以y变量的值,其余数放入E变量。 2.7.3 关系运算符 =(相等)判断两个值是否相等,例如:x=y,比较x与y变量的值是否相等,相等则其结果为1,不相等则为0。 !=(不等)判断两个值是否不等,例如:x!=y,比较x与y变量的值是