本文介绍如何为arduino编写函数库。本文从一个简单的摩斯电码例子开始,描述如何将它的功能改写成函数库。这将使代码变得更为易用,也更易维护和升级功能。 先从一个简单的摩斯电码程序开始:
int pin
= 13; void setup
(){ pinMode
(pin, OUTPUT
);} void loop
(){ dot
(); dot
(); dot
(); dash
(); dash
(); dash
(); dot
(); dot
(); dot
(); delay
(3000);} void dot
(){ digitalWrite
(pin, HIGH
); delay
(250); digitalWrite
(pin, LOW
); delay
(250);} void dash
(){ digitalWrite
(pin, HIGH
); delay
(1000); digitalWrite
(pin, LOW
); delay
(250);}运行以上程序,Arduino的13脚LED将按SOS方式(一种求救信号格式)闪烁。
这段代码中的一部分可以写成库函数: 首先,用于闪烁的blink()和dash()两个功能函数; 其次,用于指定使用哪个管脚的ledPin变量 最后,初始化管脚的pinMode()函数调用
让我们把这段代码改写成函数库吧!
一个函数库应至少包含两个文件:头文件(扩展名为*.h*)和源代码文件(扩展名为*.cpp*)。头文件包含函数库的**,即函数库的功能说明列表;源代码文件包含函数库的实际实现。让我们来为这个函数库起个名字吧—-“Morse”,那么头文件就命名为Morse.h。看看这个文件里都有些什么内容—-开始的时候可能会显得有些奇怪,但当你看到代码实现之后就能完全理解是怎么回事了。
头文件的核心内容,是一个封装了成员函数与相关变量的类**:
class Morse
{ public: Morse
(int pin
); void dot
(); void dash
(); private: int _pin
;};简单点说,类就是一个把函数和变量放在一起的集合。类里的函数与变量,其访问权限可以是public(公有,即提供给函数库的使用者使用),也可以是private(私有,即只能由类自己使用)。类有个特殊的函数–构造函数,它用于创建类的一个实例。构造函数的类型与类相同,且没有返回值。
头文件里还有些其它杂项。如为了使用标准类型和Arduino语言的常量,需要#include语句(Arduino的IDE会自动为普通代码加上这些#include语句,但不会自动为函数库加)。这些#include语句类似:
#include "Arduino.h"最后,为了防止多次引用头文件造成各种问题,我们常用一种看起来有点奇怪的方式来封装整个头文件的内容:
#ifndef Morse_h#define Morse_h // the #include statment and code go here... #endif该封装的主要作用是防止头文件被引用多次。
通常也会在函数库的头文件里,加上一些关于作者、用途、日期、协议等注释。
最终完成的头文件如下:
/* Morse.h - Library for flashing Morse code. Created by David A. Mellis, November 2, 2007. Released into the public domain.*/#ifndef Morse_h#define Morse_h #include "Arduino.h" class Morse
{ public: Morse
(int pin
); void dot
(); void dash
(); private: int _pin
;}; #endif接下来,让我们继续完成源代码文件,Morse.cpp。
首先仍然是一些#include语句。这些语句让下面的程序能够使用Arduino的标准函数和刚才在Morse.h里**的类。
#include "Arduino.h"#include "Morse.h"接下来是构造函数。再次说下,构造函数是当创建类的一个实例时调用的。在本例中,用于指定使用哪个管脚。我们把该管脚设置成输出模式并且用一个私有成员变量保存起来,以备其它函数使用。
Morse
::Morse(int pin
){ pinMode
(pin, OUTPUT
); _pin
= pin
;}这段代码看起来有好几个怪地方。一是函数名之前的Morse::。这其实是用来指定该函数是Morse类的成员函数。下面定义类的其它成员函数时,将会一再出现。另一个不常见的是私有成员变量名_pin中的下划线。其实你可以按C++的命名规则,给它任意命名。加下划线是一种约定俗成的不成文规范,让我们既能区分传进来的pin参数,也能清晰地知道它的private私有性质。