本文是《[Arduino] Develop Library with Arduino eclipse plugin》的中文版本,并增加一點(diǎn)本土內(nèi)容。之所以先寫英文的,是因?yàn)閷懽鬟^(guò)程中,需要和插件作者保持溝通,還請(qǐng)各位見諒。
eclipse.baeyens.it 開發(fā)中的 Arduino Eclipse 插件,能快速將eclipse打造為Arduino的開發(fā)平臺(tái)。從目前的經(jīng)驗(yàn)看來(lái),開發(fā)的部分基本能實(shí)現(xiàn)完全的替代。雖然少了串口助手的部分,但平心而論,ADE(Arduino “官方”標(biāo)準(zhǔn)開發(fā)環(huán)境)的串口助手是很弱的。因?yàn)橹荒軅鬟f可見字符數(shù)據(jù),沒法任意發(fā)送0-255的單字節(jié)數(shù)據(jù)。所以這個(gè)集成的Serial Monitor還是比較雞肋的。所以用自己喜歡而且順手的就是,并不要緊。使用 Arduino Eclipse 插件,在 eclipse 上進(jìn)行開發(fā)的Arduino程序,同樣能方便地移植到 ADE 上,在開源社區(qū)分享,也沒有問(wèn)題。而開發(fā)效率、編譯速度、下載速度,都將大幅提升,爽得一塌糊涂。
在這款插件出現(xiàn)之前,Eclipse 就已經(jīng)可以用來(lái)作 Arduino 的IDE了,但配置過(guò)程相當(dāng)崩潰,有插件就爽了很多,能輕松實(shí)現(xiàn)平臺(tái)搭建。
本文結(jié)合Arduino eclipse Plugin 英文向?qū)?nbsp;and Arduino playground 的 LibraryTutorial 做一個(gè)使用eclipse開發(fā)Arduino類庫(kù)的分步驟教程。建議先查閱一下這2處的內(nèi)容,這樣看下文會(huì)輕松很多。
1. 安裝 Eclipse 及 Arduino 插件
插件官方安裝向?qū)?nbsp;,英文很簡(jiǎn)單,E文不太熟悉的朋友,配合字典就能搞定。我的經(jīng)驗(yàn)就是,安裝帶有CDT(C/C++ Development Kit)的eclipse就是了。如果之前已經(jīng)在用 eclipse 進(jìn)行 Java、Ruby或其它開發(fā)的朋友,并不需要重新下載,直接安裝CDT插件就是了,畢竟Arduino用的是C++。使用 Arduino 插件進(jìn)行開發(fā),并不需要提前安裝 AVR 插件,感覺是已經(jīng)被Arduino插件集成了,所以安裝配置就更簡(jiǎn)單許多。
之前根據(jù)網(wǎng)絡(luò)上的各類資料,重新編輯過(guò)一篇安裝 Eclipse 3.7 Indigo 學(xué)習(xí) Java 的blog,里面提到了漢化如何進(jìn)行,有興趣的朋友不妨去看看,在那個(gè)基礎(chǔ)上,安裝CDT,插件,就能直接用來(lái)開發(fā)Arduino了。那個(gè)時(shí)候剛剛接觸 eclipse,用起來(lái)小心翼翼,現(xiàn)在就放開了許多,都敢碰了,呵呵。
不過(guò)一個(gè)eclipse里面一下運(yùn)行太多插件,對(duì)速度還是有影響的,為Arduino開發(fā),我另外整理了一個(gè)較為“純凈”的eclipse: Eclipse 3.7 Indigo + CDT + Arduino Plugin + Subclipse
Eclipse是綠色軟件,復(fù)制一份原始的安裝包就好了。其中 Subclipse 用于版本控制以及在 Google code 進(jìn)行代碼托管,非常方便。
2. 從一個(gè) Sketch 開始
在安裝及配置好 Arduino Eclipse 插件之后
1) 新建一個(gè)工作空間,例如, “H:\workspace\myArduinoLibs”.

2) 新建一個(gè)sketch, 例如, “MorseTest”


在項(xiàng)目管理器窗口/工作空間目錄下。會(huì)出現(xiàn)2個(gè)文件夾。其中一個(gè)所選用的Arduino平臺(tái)型號(hào)命名,作為 Arduino Core,里面大致的內(nèi)容就是與該板參數(shù)相匹配的Arduino核心庫(kù)。每次使用一個(gè)新的工作空間,這個(gè)Arduino Core文件夾都會(huì)被新建。但如果再次基礎(chǔ)上,添加一個(gè)基于同樣 Arduino 平臺(tái)的 Sketch 時(shí),不會(huì)重復(fù)新建 core 文件夾,它為自動(dòng)在工作空間內(nèi)共享(當(dāng)然,如果不是很有把握,最好也別去改它)。如果后來(lái)在同一工作空間下,使用不同的 Arduino 平臺(tái)開發(fā),將會(huì)新建一個(gè)新平臺(tái)的Core文件夾。

3) 構(gòu)建 Core(不過(guò)并不必要):點(diǎn)擊 Core 文件夾, “Arduino_UNO”,后點(diǎn)擊工具欄的小錘子圖標(biāo)。
4) 構(gòu)建 sketch,點(diǎn)擊 Sketch文件夾, “MorseTest”,后點(diǎn)擊工具欄的小錘子圖標(biāo)。如果跳過(guò)了剛才的第3步,那么此刻編譯器也會(huì)先構(gòu)建 Core,再構(gòu)建 Sketch。注:構(gòu)建,Build,Make,就是編譯、鏈接的意思。如果光點(diǎn)擊程序文件,可能構(gòu)建不出什么東西,還是要選擇工程文件夾,再進(jìn)行構(gòu)建。因?yàn)橐淮螛?gòu)建構(gòu)建的是整個(gè)Project.

如果插件安裝正確的話,此處的構(gòu)建,應(yīng)該沒什么問(wèn)題,也就是說(shuō)編譯、鏈接都應(yīng)該沒問(wèn)題,畢竟現(xiàn)在什么代碼都沒輸入進(jìn)去么。
不過(guò)值得注意的是,在使用目前的 Arduino Core 的過(guò)程中,可能會(huì)出現(xiàn)編譯后帶有警告的情況。這些或許是ADE內(nèi)部自動(dòng)隱藏或是降低了警告級(jí)別造成的。不必?fù)?dān)心,程序一般情況下依然是可以運(yùn)行的。相信隨著 Arduino 底層庫(kù)的不斷完善,這些警告都會(huì)慢慢消失的。在我個(gè)人的實(shí)踐中,基本都要加上 “extern HardwareSerial Serial;” 這句聲明,才能正常使用串口對(duì)象,感覺內(nèi)建的Serial實(shí)例,是以類似全局變量的形式保存, 而在調(diào)用的時(shí)候,是要聲明一下。但是在ADE中插入這句聲明,也不會(huì)影響編譯。所以,就放心地加進(jìn)去咯。至少?gòu)腁NSI的標(biāo)準(zhǔn)來(lái)看,代碼是規(guī)范了不少。
5) 建議此時(shí),可以通過(guò)點(diǎn)擊工具欄的“AVR”按鈕,將這個(gè)空的 Sketch 下載(中文習(xí)慣都是說(shuō)“下載”,就像“XX下載器”,而英文版本里面偏偏都是用上傳“Upload”,比較無(wú)語(yǔ))到Arduino的板子上,測(cè)試連接通訊是否正常。這里,可以理解為和 ADE 一樣,編譯和下載是分開的。但是ADE里面,下載還包含了編譯,而且編譯得很慢。Eclipse里面,這兩個(gè)步驟是完全獨(dú)立的,所以,一次次點(diǎn)擊“下載”,可能下載的都是老文件,如果忘記重新編譯的話。新手要注意這一點(diǎn)。
6) 將 librayTutorial 里的代碼拷貝至 “MorseTest.cpp”. 頭文件 “MorseTest.h”就不用去動(dòng)它了,不需要對(duì)其進(jìn)行任何編輯。
// Do not remove the include below
#include "MorseTest.h"
void dot();
void dash();
int pin = 13;
//The setup function is called once at startup of the sketch
void setup()
{
// Add your initialization code here
pinMode(pin, OUTPUT);
}
// The loop function is called in an endless loop
void loop()
{
//Add your repeated code here
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);
}
此處較例程添加了 dot() 和 dash() 的聲明,相信有C/C++編程經(jīng)驗(yàn)的朋友都知道是為什么。因?yàn)檫@2個(gè)函數(shù),都放置在 loop() 函數(shù)后,而Eclipse里面的GNU/GCC編譯器是對(duì)于規(guī)范要求比較嚴(yán)格的,要么放在loop()之前,要么加聲明,否則就是無(wú)法編譯通過(guò)。ADE則相對(duì)寬松一些,感覺怎么寫都行,ADE優(yōu)化過(guò)的編譯器會(huì)自動(dòng)彌補(bǔ)這些問(wèn)題,讓規(guī)則顯得更加寬松。但作為嚴(yán)謹(jǐn)?shù)?C/C++ 開發(fā)人員來(lái)說(shuō),遵守嚴(yán)謹(jǐn)?shù)囊?guī)則,對(duì)于保證程序正確運(yùn)行、排錯(cuò),是相當(dāng)重要的,而且一般都比較都已經(jīng)是習(xí)慣了。同樣,在ADE中添加聲明,也同樣不會(huì)影響到編譯。
現(xiàn)在就可以開始體驗(yàn)到 Eclipse 的強(qiáng)悍之處了:
- “Tab” 鍵可以正常反應(yīng)了,ADE中竟然直接用2個(gè)空格替代,真是要吐槽一下。而且 Shift+Tab 也能用了,調(diào)整縮進(jìn)爽很多。
- 各種代碼高亮
- Ctrl+Shift+F 進(jìn)行自動(dòng)排版。排版的樣式,可以在 Preferences -> C/C++ -> Formatter 里面自定義,我個(gè)人當(dāng)然是喜歡花括號(hào)獨(dú)占一行而且對(duì)其的樣式~
- Alt+/ 進(jìn)行自動(dòng)補(bǔ)齊,默認(rèn)情況下,按“.”也會(huì)有完整的提示框彈出。有VS使用經(jīng)驗(yàn)的人,一定非常依賴這個(gè)功能,:)
- 實(shí)時(shí)的錯(cuò)誤及警告提示,有的時(shí)候倒也不必驚慌,或許重新Make一下,就消失了
- Ctrl+左鍵單擊,查看引用,這個(gè)是我的最愛,查看Arduino庫(kù)變得非常輕松,終于不用幾個(gè)文檔翻來(lái)倒去了。
這幾條一說(shuō),基本都想把ADE扔一邊了吧~ 那還不趕緊試一下~
7) 構(gòu)建并下載,都沒錯(cuò)的話,應(yīng)該可以看到Arduino上Pin13的LED開始發(fā)出“三短三長(zhǎng)三短”的SOS信號(hào)了。
4. 從 POP 面向過(guò)程 到 OOP 面向?qū)ο?/p>
1) 在 Sketch 項(xiàng)目?jī)?nèi)為 類庫(kù) library 新建一個(gè)文件夾,本例中,命名為“Morse”

2) 在這個(gè) 類庫(kù)文件夾 中新建一個(gè)類,

會(huì)同時(shí)建立2個(gè)文件,.h的頭文件,和.cpp的源文件。什么代碼都還沒寫,eclipse 已經(jīng)把構(gòu)造函數(shù),析構(gòu)函數(shù)的框架都搭起來(lái)了。

3) 在類頭文件“Morse.h”中,包含引用 “Arduino.h”
除非是建一個(gè)純C++的類,或者是應(yīng)用邏輯層的類,否則如果涉及到 Arduino 的底層硬件操作,一般也就是引用“Arduino.h”這個(gè)頭文件就好了,對(duì)于IO設(shè)置,位運(yùn)算都有現(xiàn)成的函數(shù)可用。而且作為一個(gè)Arduino的 sketch,不管怎么樣都會(huì)包含這個(gè)頭文件的,類庫(kù)中就包含一下,也不會(huì)對(duì)最終sketch的文件大小會(huì)有什么影響。而且一個(gè)“Arduino.h”似 乎就包含了所有可能會(huì)用到 Arduino 函數(shù)庫(kù),很方便。寫類,自然還是要學(xué)習(xí)一下C++的編程(學(xué)C++和學(xué)VC是2個(gè)概念)。不過(guò)大體上,可以想象成在寫一個(gè)沒有setup()和 loop()的sketch。
4) 寫類
如 librayTutorial所示, Morse.h:
#ifndef MORSE_H_
#define MORSE_H_
#include "Arduino.h"
class Morse
{
public:
Morse(int pin);
virtual ~Morse();
void dot();
void dash();
private:
int _pin;
};
#endif
Morse.cpp:
|
例程里的代碼,和Eclipse的代碼的主要不同之處,在于在eclipse這邊過(guò)了一個(gè)虛析構(gòu)函數(shù)。這在C++程序里面是非常常見的,讓類可以繼續(xù)得到繼承,是規(guī)范的寫法。相信雖然ADE的這個(gè)例程沒這個(gè)東西,但是也會(huì)欣然接受這種讓類定義更加完整的做法。

這樣,一個(gè)最簡(jiǎn)單的Morse類庫(kù)就寫好了。使用面向?qū)ο缶幊绦陆悾粏螁慰梢杂迷诰帉戭悗?kù),更應(yīng)該用在進(jìn)行應(yīng)用類,或者說(shuō)實(shí)現(xiàn)中間層邏輯類的開發(fā),也 同樣適用。這樣,就能把傳統(tǒng)的面向過(guò)程的編程,轉(zhuǎn)變?yōu)槊嫦驅(qū)ο蟮木幊獭?duì)于玩嵌入式底層開發(fā)的朋友來(lái)說(shuō),可能會(huì)感覺這樣損失了執(zhí)行效率,還增加了程序的大 小。但是對(duì)于大多數(shù)用Arduino玩應(yīng)用的朋友來(lái)講,我相信還是會(huì)舍得這些硬件開銷。仁者見仁智者見智。
5) 調(diào)用類
回到Sketch, “MorseTest.cpp”。因?yàn)榇蟛糠值墓δ艽a已經(jīng)轉(zhuǎn)移(更專業(yè)的叫法,就是“封裝”)到類中。所以主代碼就立馬變得整潔美觀了。記得在頭部,對(duì)類進(jìn)行引用,#include “Morse.h”
// Do not remove the include below
#include "MorseTest.h"
#include "Morse.h" // The header of the class just created
Morse morse(13);
//The setup function is called once at startup of the sketch
void setup()
{
// Add your initialization code here
}
// The loop function is called in an endless loop
void loop()
{
//Add your repeated code here
morse.dot(); morse.dot(); morse.dot();
morse.dash(); morse.dash(); morse.dash();
morse.dot(); morse.dot(); morse.dot();
delay(3000);
}
6) 構(gòu)建OOP工程
點(diǎn)擊小錘子圖標(biāo)進(jìn)行構(gòu)建,此時(shí)會(huì)冒出來(lái)很多錯(cuò)誤……

主要原因是 Sketch 中雖然包含了類庫(kù),但鏈接器并不知道去哪里找它,所以要添加類庫(kù)的路徑。
a) 在項(xiàng)目管理器中,右鍵單擊 Sketch 文件夾,”MorseTest”.
b) 點(diǎn)擊 “Properties”.
c) 進(jìn)入 “C/C++ General -> Path and Symbols”,頁(yè)
d) 在 “Includes” 標(biāo)簽中,在左邊language欄中選擇”GNU C++”, 點(diǎn)擊右側(cè)的”Add…”按鈕。

e) 在”Add directory path”對(duì)話框中選擇 “Workspace…”

f) 找到類庫(kù)的文件夾 “Morse”, 點(diǎn)擊 “OK”.

g) 類庫(kù)路徑被添加進(jìn)來(lái),如下圖所示。點(diǎn)擊“OK”關(guān)閉窗口

h) 如果這個(gè)框框跳出來(lái),就點(diǎn)“Yes”

i) 重新點(diǎn)擊Sketch文件夾,并構(gòu)建,現(xiàn)在應(yīng)該是0錯(cuò)誤,0警告了。
j) 下載到Arduino板子上,實(shí)現(xiàn)的功能,和早先所有程序都堆在一起的而且面向過(guò)程的Sketch是一樣的。
5. 在ADE中,使用類庫(kù)
1) 將類庫(kù)文件夾(“Morse”)復(fù)制至ADE所在文件夾的“libraries”文件夾 (“H:\arduino-1.0\libraries\”)內(nèi)。
2) 打開ADE,就可以在菜單 “Sketch->Import Library…” 中找到Morse類了。(其實(shí)ADE還是實(shí)現(xiàn)了很多不錯(cuò)的功能呢)

3) 點(diǎn)擊它 “#include ” 這句話,就會(huì)被添加到新的這個(gè)Sketch里面。
4) 從eclipse的sketch,MorseTest.cpp, 復(fù)制代碼至ADE 除了
#include “MorseTest.h” ADE會(huì)自己生成一個(gè)類似的文件,或者壓根就不需要吧,反正不用這個(gè)東西了。
#include “Morse.h” 因?yàn)閷?dǎo)入類庫(kù)的時(shí)候,已經(jīng)將這個(gè)頭文件包含進(jìn)來(lái)了。
5) 編譯并下載,應(yīng)該是沒有問(wèn)題。

6) 在ADE的libraries文件夾內(nèi)的類庫(kù)文件夾,“Morse”中,新建一個(gè)“examples”文件夾。把剛才復(fù)制過(guò)來(lái)的sketch保存進(jìn)去,并命名為“SOS”

7) 退出 ADE, 并再次打開。 可以看到 SOS 程序作為 Morse 庫(kù)的一個(gè)實(shí)例,出現(xiàn)在菜單里。也就是說(shuō)現(xiàn)在Morse類,就像ADE已經(jīng)集成的這么多類一樣,可以被導(dǎo)入,并且還提供例程。

6. 在 eclipse 中使用類庫(kù)
1 sketch = 1 main = 1 project. Main() 函數(shù)作為C/C++程序的入口,一個(gè)項(xiàng)目中只允許出現(xiàn)一次,否則編譯器無(wú)法正確進(jìn)行編譯。所以,不能在類的項(xiàng)目(“MorseTest”)中,同時(shí)出現(xiàn)多個(gè)setup()和loop()。
如果要單獨(dú)新建一個(gè)使用自定義類的Arduino工程(Sketch),最穩(wěn)妥的方法,還是使用官方指南里面的方法從ADE目錄中導(dǎo)入類。
如果希望為單個(gè)類庫(kù),編寫多個(gè)示例代碼。我個(gè)人的做法,就是將eclipse中的測(cè)試代碼,復(fù)制到ADE中,以ino格式保存至ADE相應(yīng)類庫(kù)的 examples文件夾內(nèi)。所以,其實(shí)在開發(fā)過(guò)程中,我的測(cè)試文件,”MorseTest.cpp”是不斷變化的,當(dāng)測(cè)試通過(guò)后,就被另存為ino格式。 個(gè)人的習(xí)慣,是不太想為開發(fā)測(cè)試中的類庫(kù),新建一個(gè)又一個(gè)的工程,畢竟大多數(shù)測(cè)試代碼都是比較短小簡(jiǎn)單的,所以做個(gè)備份,或者存?zhèn)INO就好。記得每次升 級(jí)類庫(kù)的時(shí)候,也講ADE的libraries的老類庫(kù)進(jìn)行覆蓋。
總結(jié)一下,ADE確實(shí)做了很多事情,讓編程序看起來(lái)變得更加簡(jiǎn)單。但是作為代碼編輯器來(lái)講,有經(jīng)驗(yàn)的程序員可能用起來(lái)會(huì)比較崩潰,或者說(shuō)習(xí)慣于 VS, eclipse這類高級(jí)IDE的程序員用起來(lái),就會(huì)感覺相當(dāng)奔潰。(對(duì)于那些用記事本直接玩的孩紙,那還是傷不起……)。而借助 Arduino Eclipse 插件,使用eclipse進(jìn)行開發(fā),就會(huì)是Arduino的開發(fā)變得非常輕松、愉快,而且高效。
趕快來(lái)試試吧~
