如何編寫自己的arduino類庫
阿新 • • 發佈:2018-12-22
當我們在arduino中有大量的程式碼需要在不同的工程中重複時,我們可以把這段程式碼進行封裝,那麼由此我們就想到了要編寫自己的arduino類庫。這個工作並不複雜,稍有面對物件程式設計經驗的小夥伴即可比較容易完成。下面我們以例項的方式將步驟一一列出。
我們以,我前面編寫的《Arduino中使用超聲波測距實驗》為例來進行說明。程式碼如下:
int TrgPin = A0; int EcoPin = A1; float dist; void setup() { Serial.begin(9600); //設定TrgPin為輸出狀態 pinMode(TrgPin, OUTPUT); // 設定EcoPin為輸入狀態 pinMode(EcoPin, INPUT); } void loop() { digitalWrite(TrgPin, LOW); delayMicroseconds(8); digitalWrite(TrgPin, HIGH); // 維持10毫秒高電平用來產生一個脈衝 delayMicroseconds(10); digitalWrite(TrgPin, LOW); // 讀取脈衝的寬度並換算成距離 dist = pulseIn(EcoPin, HIGH) / 58.00; Serial.print("Distance:"); Serial.print(dist); Serial.println("cm"); delay(300); }
我在看來,封裝的目的就是讓必要而機械的步驟得到簡化。
從這段程式碼中我們可以看出:
1、對Trig及Echo兩個管腳與Arduino板上的兩個訊號管腳的繫結是必要且機械的工作,所以這個初始化工作我們可以交給我們的初始化函式。
2、讓Trig腳保持高電平已經後續讀取Echo腳的數值,也是機械的,我們可以封裝為一個獲取距離的函式;
3、距離的輸出,是否輸出提示字串是可選的,但距離的數值是必須的,通過串列埠傳送到上位機必須靠它了。
通過上面的分析我們明白了封裝類的設計目的了就好辦了。假定我們定義的類為USensor我們來看看程式碼如何實現:
USensor.h
#ifndef USensor_H #define USensor_H #if defined(ARDUINO) && ARDUINO >= 100 #include "Arduino.h" #else #include "WProgram.h" #endif //#include "pins_arduino.h" #include <inttypes.h> #define PULSE_TIMEOUT 150000L // 100ms #define DEFAULT_DELAY 10 #define DEFAULT_PINGS 5 class USensor { public: /** * Constructor * Ultrasonic sensor SR04, four connections pins * VCC, ECHO, TRIGGER, GND * <br> * \param echoPin digital INPUT-Pin for measuring distance * \param triggerPin if 10us high a trigger signal is generated from * SR04 * * \return void */ USensor(int echoPin, int triggerPin); /** * Do a measurment for this sensor. Return distance as long * in centimenter * \return long distance in centimeter */ long Distance(); /** * Do count measurents and calculate the average. * To avoid defilement from ow/high peaks, min/max values * are substracted from the average * * \param wait delay between measurements, default = DEFAULT_DELAY/ms * \param count number of measurements, default DEFAULT_PINGS * \return long distance in centimeter **/ long DistanceAvg(int wait=DEFAULT_DELAY, int count=DEFAULT_PINGS); /** * Do only a ping. Get result with methode getDistance() * * \param keine */ void Ping() ; /** * return latest distance. Methode Ping() should be called before * \param keine * \return Distanz in Zentimeter */ long getDistance(); private: /** * Do the measurement calculation and return result in centimeter * SR04 measure echo time to obstacle and return way. * <br> * Sound travels with 340m/sec * <br> * Example: Obstace 100cm away from SR04. Measure time is 100cm to * obstacle and 100cm return = 200cm * <br> * 1sec = 1000ms = 1.000.000uS * 1.000.000 / 340 = Distance in microseconds for 100cm * 2941uS fuer 100cm = 5882 uS fuer 200cm * * duration / 5882 * 100 = distance in cm */ long MicrosecondsToCentimeter(long duration); long _currentDistance; int _echoPin, _triggerPin; long _duration, _distance; bool _autoMode; }; #endif
USensor.cpp
//Ultrasonic Sensor Class #include "USensor.h" USensor::USensor(int echoPin, int triggerPin) { _echoPin = echoPin; _triggerPin = triggerPin; pinMode(_echoPin, INPUT); pinMode(_triggerPin, OUTPUT); _autoMode = false; _distance = 999; } long USensor::Distance() { long d = 0; _duration = 0; digitalWrite(_triggerPin, LOW); delayMicroseconds(2); digitalWrite(_triggerPin, HIGH); delayMicroseconds(10); digitalWrite(_triggerPin, LOW); delayMicroseconds(2); _duration = pulseIn(_echoPin, HIGH, PULSE_TIMEOUT); d = MicrosecondsToCentimeter(_duration); delay(25); return d; } long USensor::DistanceAvg(int wait, int count) { long min, max, avg, d; min = 999; max = 0; avg = d = 0; if (wait < 25) { wait = 25; } if (count < 1) { count = 1; } for (int x = 0; x < count + 2; x++) { d = Distance(); if (d < min) { min = d; } if (d > max) { max = d; } avg += d; } // substract highest and lowest value avg -= (max + min); // calculate average avg /= count; return avg; } void USensor::Ping() { _distance = Distance(); } long USensor::getDistance() { return _distance; } long USensor::MicrosecondsToCentimeter(long duration) { long d = (duration * 100) / 5882; //d = (d == 0)?999:d; return d; }
keyword.txt
#######################################
# Syntax Coloring Map For 你的類名
#######################################
#######################################
# Datatypes (KEYWORD1) 資料型別關鍵字
#######################################
TN901 KEYWORD1
#######################################
# Methods and Functions (KEYWORD2) 方法型別關鍵字
#######################################
Init KEYWORD2
Read KEYWORD2
ReadData KEYWORD2
GetData KEYWORD2
#######################################
# Constants (LITERAL1) 常量型別關鍵字
#######################################
ET LITERAL1
OT LITERAL1
最重要的是以下幾點,如果我們不遵照這幾點,我們可能無法真正能使我們封裝的類在arduino的IDE中看到:
1、類名和檔名必須統一(比如你的類名叫做ABC,那麼你的檔名對應為ABC.cpp)
2、必須要有keyword,否則你的在IDE中將無法以顏色卻分於普通的程式碼,普通的變數。
3、編輯好的類檔案必須防止在IDE所在libraries目錄下;
4、編輯好的檔案和keyword必須放在同一個目錄下