Writing a Library for Arduino
為Arduino編個擴展庫
This document explains how to create a library for Arduino. It starts with a sketch with a sketch for flashing Morse code and explains how to convert its functions into a library. This allows other people to easily use the code that you've written and to easily update it as you improve the library.
本文檔介紹了如何創(chuàng)建一個Arduino擴展庫。它將向你描述如何將一個摩爾斯的代碼功能做成一個擴展庫。這會使別人很容易使用你的代碼,并且你也很方便的編輯和修改你的擴展庫。
We start with a sketch that does simple Morse code:
我們從寫一個簡單的摩爾斯碼開始:
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);
}
If you run this sketch, it will flash out the code for SOS (a distress call) on pin 13.
運行這段代碼,會使Pin 13腳發(fā)出SOS緊急呼救信號。
The sketch has a few different parts that we'll need to bring into our library. First, of course, we have the dot() and dash() functions that do the actual blinking. Second, there's the ledPin variable which the functions use to determine which pin to use. Finally, there's the call to pinMode() that initializes the pin as an output.
代碼有幾個不同的部分,我們將其寫入我們的庫。首先,當然,我們有dot()和dash()功能,它們的功能為閃爍。其次,還要用ledpin變量來確定使用哪個針腳。最后,要用pinmode()函數(shù)來初始化引腳輸出。
Let's start turning the sketch into a library!
讓我們開始把程序?qū)懗蓴U展庫!
You need at least two files for a library: a header file (w/ the extension .h) and the source file (w/ extension .cpp). The header file has definitions for the library: basically a listing of everything that's inside; while the source file has the actual code. We'll call our library "Morse", so our header file will be Morse.h. Let's take a look at what goes in it. It might seem a bit strange at first, but it will make more sense once you see the source file that goes with it.
你至少需要兩個文件:一個頭文件(擴展名為.h)和一個源文件(擴展名為.cpp)。頭文件定義擴展庫:基本上是一個原代碼中所有東西的列表。我們引用我們的擴展庫“Morse”,所以我們把頭文件名寫為“Morse.h”,讓它看上去一目了然。它看上去有點奇怪,但它與源文件一起運行時將有更多的功能。
The core of the header file consists of a line for each function in the library, wrapped up in a class along with any variables you need:
頭文件的核心是一個擴展庫中所有功能的列表,這個列表以及你所需要的所有的變量寫在一個類里面:
class Morse
{
public:
Morse(int pin);
void dot();
void dash();
private:
int _pin;
};
A class is simply a collection of functions and variables that are all kept together in one place. These functions and variables can be public, meaning that they can be accessed by people using your library, or private, meaning they can only be accessed from within the class itself. Each class has a special function known as a constructor, which is used to create an instance of the class. The constructor has the same name as the class, and no return type.
類是一個簡單的函數(shù)和變量的集合。這些函數(shù)和變量可以是公開的,以使別人可以使用你的擴展庫。或者,他們只能從內(nèi)部訪問類本身。每個類有一個特殊的功能,稱為構(gòu)造函數(shù),它是用來創(chuàng)建一個類的實例。構(gòu)造函數(shù)與類具有相同的名字,它沒有返回類型。
You need a couple of other things in the header file. One is an #include statement that gives you access to the standard types and constants of the Arduino language (this is automatically added to normal sketches, but not to libraries). It looks like this (and goes above the class definition given previously):
在頭文件里你還需要一些其他的東西。是一個#include聲明,讓你訪問Arduino語言中的標準變量和常量(它自動添加,但不在擴展庫中)。它看起來像這樣(它將最開始運行):
#include "WProgram.h"
Finally, it's common to wrap the whole header file up in a weird looking construct:
最后,它將把整個頭文件打包進一個特殊的構(gòu)造里:
#ifndef Morse_h
#define Morse_h
// the #include statment and code go here...
// 把聲明和代碼寫在這里
#endif
Basically, this prevents problems if someone accidently #include's your library twice.
基本上,這可以防止別人不小心引用你兩次庫的問題。
Finally, you usually put a comment at the top of the library with its name, a short description of what it does, who wrote it, the date, and the license.
最后,你通常會在頂部加入一些你自己的信息,比如庫的名字、簡短的描述、作者的名字、日期和許可。
Let's take a look at the complete header file:
讓我們看一下完整的頭文件:
/*
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 "WProgram.h"
class Morse
{
public:
Morse(int pin);
void dot();
void dash();
private:
int _pin;
};
#endif
Now let's go through the various parts of the source file, Morse.cpp.
現(xiàn)在讓我們看看源文件morse.cpp的組成。
First comes a couple of #include statements. These give the rest of the code access to the standard Arduino functions, and to the definitions in your header file:
首先是一組#include報表,它提供其余代碼使用標準Arduino功能,并要寫在文件開頭:
#include "WProgram.h"
#include "Morse.h"
Then comes the constructor. Again, this explains what should happen when someone creates an instance of your class. In this case, the user specifies which pin they would like to use. We configure the pin as an output save it into a private variable for use in the other functions:
然后是構(gòu)造函數(shù),再次說明當有人創(chuàng)建你的類的實例時會發(fā)生什么。在這種情況下,用戶會指定要使用的針腳。我們將輸出引腳的配置保存到一個私有變量用于其他功能:
Morse::Morse(int pin)
{
pinMode(pin, OUTPUT);
_pin = pin;
}
There are a couple of strange things in this code. First is the Morse:: before the name of the function. This says that the function is part of the Morse class. You'll see this again in the other functions in the class. The second unusual thing is the underscore in the name of our private variable, _pin. This variable can actually have any name you want, as long as it matches the definition in the header file. Adding an underscore to the start of the name is a common convention to make it clear which variables are private, and also to distinguish the name from that of the argument to the function (pin in this case).
有一些特殊的東西在這個代碼里。首先是在這功能名字前的Morse::。這表示,功能是摩爾斯電碼的類。你會在這個類的其它功能里再次看到。其二是在私有變量名稱前的下劃線,_pin。這個變量可以是任何你想要的名字,只要匹配頭文件中的定義。加下劃線開始的名字是私有變量的約定,同時也從函數(shù)的功能段區(qū)分名字(在這種情況下)。
余下的部分(全文完):
Next comes the actual code from the sketch that you're turning into a library (finally!). It looks pretty much the same, except with Morse:: in front of the names of the functions, and _pin instead of pin:
接下來,源代碼終于變成一個擴展庫。它們看起來非常類似,除了函數(shù)名前有“Morse::”和用“_pin”代替“pin”:
void Morse::dot()
{
digitalWrite(_pin, HIGH);
delay(250);
digitalWrite(_pin, LOW);
delay(250);
}
void Morse::dash()
{
digitalWrite(_pin, HIGH);
delay(1000);
digitalWrite(_pin, LOW);
delay(250);
}
Finally, it's typical to include the comment header at the top of the source file as well.Let's see the whole thing:
最后,在源文件的頂部同樣有注釋部分。讓我們來看看整個源文件:
/*
Morse.cpp - Library for flashing Morse code.
Created by David A. Mellis, November 2, 2007.
Released into the public domain.
*/
#include "WProgram.h"
#include "Morse.h"
Morse::Morse(int pin)
{
pinMode(pin, OUTPUT);
_pin = pin;
}
void Morse::dot()
{
digitalWrite(_pin, HIGH);
delay(250);
digitalWrite(_pin, LOW);
delay(250);
}
void Morse::dash()
{
digitalWrite(_pin, HIGH);
delay(1000);
digitalWrite(_pin, LOW);
delay(250);
}
And that's all you need (there's some other nice optional stuff, but we'll talk about that later). Let's see how you use the library.
這就是所有你需要的(其它一些可選的東西,我們將在以后再談)。讓我們來看看如何使用擴展庫。
First, make a Morse directory inside of the libraries sub-directory of your sketchbook directory.Copy or move the Morse.h and Morse.cpp files into that directory.Now launch the Arduino environment.If you
open the Sketch > Import Library menu, you should see Morse inside.The library will be compiled with sketches that use it.If the library doesn't seem to build, make sure that the files really end in .cpp and
.h (with no extra .pde or .txt extension, for example).
首先,在擴展庫的子目錄建一個莫爾斯擴展庫目錄。把Morse.h和Morse.cpp文件復制或移動到該目錄中,F(xiàn)在打開Arduino編譯器。打開“Sketch”>“Import Library”菜單,你應(yīng)該看到有“Morse”選項。在使用的時候該擴展庫將
同時被編譯。如果沒有看到這個擴展庫,請確保文件名為正常的“.cpp”和“h”(沒有其它多余的如“.pde”或“.txt”這樣的擴展名)。
Let's see how we can replicate our old SOS sketch using the new library:
讓我們看看現(xiàn)在我們怎樣用新的擴展庫來編寫我們的原先的程序:
#include <Morse.h>
Morse morse(13);
void setup()
{
}
void loop()
{
morse.dot(); morse.dot(); morse.dot();
morse.dash(); morse.dash(); morse.dash();
morse.dot(); morse.dot(); morse.dot();
delay(3000);
}
There are a few differences from the old sketch (besides the fact that some of the code has moved to a library).
除了將一些代碼已經(jīng)轉(zhuǎn)移到擴展庫里,代碼有些差別。
First, we've added an #include statement to the top of the sketch.This makes the Morse library available to the sketch and includes it in the code sent to the board.That means if you no longer need a library
in a sketch, you should delete the #include statement to save space.
首先,我們僅需要在代碼頂部添加#include語句,就可以使程序使用這個擴展庫,并且在編譯時會被同時包括進去。這也意味著你在程序中不需要再編寫長長的代碼。而且如果你不再需這個功能,你只要刪除這個“#include”語句
就可以了。
Second, we now create an instance of the Morse class called morse :
現(xiàn)在,我們來創(chuàng)建一個莫爾斯類的實例:
Morse morse(13);
When this line gets executed (which actually happens even before the setup() function), the constructor for the Morse class will be called, and passed the argument you've given here (in this case, just 13 ).
當此行被執(zhí)行時(實際甚至在setup()函數(shù)之前),將引用莫爾斯類(這個例子里中針腳13)。
Notice that our setup() is now empty; that's because the call to pinMode() happens inside the library (when the instance is constructed).
請注意,在這里“void setup()”是空的,這是因為“pinMode()”的調(diào)用發(fā)生在擴展庫中(在調(diào)用函數(shù)的時候)。
Finally, to call the dot() and dash() functions, we need to prefix them with morse. - the name of the instance we want to use.We could have multiple instances of the Morse class, each on their own pin stored
in the _pin private variable of that instance.By calling a function on a particular instance, we specify which instance's variables should be used during that call to a function.That is, if we had both:
最后,調(diào)用“dot()”和“dash()”函數(shù)時,我們需要用“morse”作它們的的前綴。程序中我們可以多次使用這個引用,它們每個的針腳數(shù)據(jù)都儲存在“_pin”私有變量里。我們可以有多個實例莫爾斯類,每一個都有自己的針_pin
該實例的私有變量存儲。在某個程序中調(diào)用函數(shù)時,我們指定的每個針腳變量,都僅是在函數(shù)調(diào)用過程中被使用。也就是說,如果我們有兩次調(diào)用:
Morse morse(13);
Morse morse2(12);
then inside a call to morse2.dot() , _pin would be 12.
后面的私有變量“_pin”將會是針腳12 。
If you tried the new sketch, you probably noticed that nothing from our library was recognized by the environment and highlighted in color.Unfortunately, the Arduino software can't automatically figure out
what you've define in your library (though it would be a nice feature to have), so you have to give it a little help.To do this, create a file called keywords.txt in the Morse directory.It should look like
this:
如果你嘗試使用新的的sketch,你會看到我們的擴展庫沒有被認可,并且用高亮顯示出來。不幸的是,Arduino軟件不能自動找出你在擴展庫中已經(jīng)定義的功能(雖然這將是一個很好的功能),所以你必須給它一個小小的提示。 要
做到這一點,我們要在Morse擴展庫目錄中創(chuàng)建一個名為“keywords.txt”的文件。它的內(nèi)容是這樣的:
Morse KEYWORD1
dash KEYWORD2
dot KEYWORD2
Each line has the name of the keyword, followed by a tab (not spaces), followed by the kind of keyword.Classes should be KEYWORD1 and are colored orange; functions should be KEYWORD2 and will be brown.You'll
have to restart the Arduino environment to get it to recognize the new keywords.
每行有一個關(guān)鍵字,后面有個tab(注意,不是空格),再后面是keyword.Classes類,KEYWORD1是橙色;函數(shù)KEYWORD2是棕色。你必須重新啟動Arduino的環(huán)境,找到到新的關(guān)鍵字。
|