你曾懶得餵你家寵物嗎?我們愛我們的寵物,但有時我們也希望能讓餵寵物這件事變得自動化一點。今天我們將使用Arduino Uno做一個智慧自動寵物餵食器!該專案的主要元件包括一個用來追蹤時間、管理餵養計畫的RTC模組,一個用來監控食物水平的距離感測器,一個用來區分白天黑夜的光敏感測器,一個用來識別寵物的RFID。好了!讓我們開始吧!
我們使用SparkFun光敏感測器TEMT6000來檢測白天和黑夜。之所以需要區分這兩者,主要原因是因為我們要確定何時需要投放食物,兩次食物投放之間需要間隔多久。TEMT6000光敏感測器有3個引腳:SIG;GND;VCC。將這個感測器接到Arduino板上的步驟非常簡單:VCC連接到5V引腳;GND到板上的GND引腳,然後SIG需要接到類比輸入上。我選擇了A0引腳。輸出引腳SIG的作用就好像一個電晶體,因此在感測器附近的光越亮,引腳輸出的電壓就越高。
下圖顯示了TEMT6000感知到的電流和照度之間的關係。照度是總光通量(即光源發出的可見光,以lm為單位)除以面積(m²)的量度。一般來說,1照度(Ix) = 1 / m²。TEMT6000可以識別典型的人類可見光光譜,波長在390-700納米之間。
TEMT6000 技術規格書:https://www.sparkfun.com/datasheets/Sensors/Imaging/TEMT6000.pdf?_ga=1.236184897.1967866376.1482950454
由於該感測器連接在類比引腳上,而模數轉換器的解析度是10位的,所以其最大值為1023。例如,當感測器接收到來本身的行動電話閃光燈的最亮照射時,從感測器讀出的值大約是1023。
光敏感測器的代碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
int lightSensor = 0; void setup() { Serial.begin(9600); } void loop() { int valueFromLightSensor = analogRead(lightSensor); Serial.println(valueFromLightSensor); delay(1000); } |
為了測量距離,我選擇了一個類比感測器(Sharp GP2Y0A21YK),因為與其他距離感測器相比,它的效果最好。其工作原理如下:首先發出一個訊號,當它發現路上有障礙物時,它也會發回一個訊號(一個電壓值,該電壓值隨障礙物的遠近而變化),這個電壓會轉換成距離。
GP2Y0A21YK將被安置在食物容器上方,在開啟自動餵食功能前,需要先測量瓶子裡的剩餘空間(即食物的多少)。有了這個距離感測器,系統將檢測食物容器(或瓶子)是滿的還是空的。具體工作方式如下:
這裡的距離表示從安裝距離感測器的位置到食品容器底部的距離。由於感測器的量程為10-80 cm,所以感測器需要在食品容器頂部以上10cm處才能讀取正確的距離值。
如何確定感測器的最佳擬合線:
摘自Pololu.com
感測器的輸出電壓與測量距離的倒數之間的關係在感測器的可用範圍內近似線性。您可以使用此圖將感測器輸出電壓轉換為一個近似的距離,方法是創建一條最佳擬合線,將輸出電壓(V)的倒數與距離(cm)聯繫起來。線性化方程的最簡形式可以表述為到反射物體的距離約等於一個常數尺度因數(~ 27v *cm)除以感測器的輸出電壓之後的數值。因此增加一個恒定的距離偏移量並修改縮放因數可以改善這條線的擬合。
摘自Phidgets.com
基於夏普的“典型值”,將感測器值轉換為距離的公式(公式僅適用於感測器值在80 – 500之間)為:
距離 (cm) = 4800/(感測器值 – 20)
這種感測器可以找到離物體的距離,這些物體呈現出非常窄的邊緣,比如角度非常尖銳的牆壁。
注: 該感測器的輸出因單元而異,並取決於目標的特性(反射率、尺寸、運動方向、目標對準)。
代碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
int lightSensor = 0; int distanceSensor=1; void setup() { Serial.begin(9600); } void loop() { int valueFromLightSensor = analogRead(lightSensor); Serial.print("Light Value= "); Serial.print(valueFromLightSensor); Serial.println(""); Serial.print("Distance Value= "); int valueFromDistanceSensor = analogRead(distanceSensor); int distance= 4800/(valueFromDistanceSensor - 20); Serial.print(distance); delay(1000); } |
RTC DS1307模型將被用來確定時間。一個即時的時脈系統承擔了確定時間的功能。該電路基於一個頻率為32.768 kHz的晶體振盪器展開工作。其原理與手錶類似。一個基於晶體振動的機械共振的電子振盪器能產生精確的頻率。此頻率用來追蹤源自電腦的日期和時間。
這是一個實用模組,即使在系統斷路時,上面所配備的電池也能保證系統工作的連續性。
為了獲得最佳的使用效果,需要為模組添加兩個程式館。
這兩個程式館可以在我的網址 https://github.com/todeilatiberia/AutomaticFeeder上找到:
我們將運行一個測試代碼來檢測模組。當我們將程式上傳到Arduino board時,串口監視器會顯示當前的日期和時間。這兩個程式館有一個用於查找日期和時間的示例代碼,稱為“SetTime”。
找出設定時間:
點擊 Arduino IDE → 檔 → 示例 → DS1307RTC → 設定時間
在圖11中,您將看到模組在顯示當前日期和時間當下正常工作。
在這裡,我們將只測量小時的運行情況。為此,我們需要從RTC模組中提取確切的時間。這將透過名為“setSyncProvider(RTC.get)”的RTC簡單函數來完成。在實現此功能後,您將能夠同時看到串口監視器上的小時數以及距離感測器和光敏感測器上的數值。
代碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
#include <Time.h> #include <Wire.h> #include <DS1307RTC.h> int lightSensor = 0; int distanceSensor=1; void setup() { Serial.begin(9600); setSyncProvider(RTC.get); } void loop() { int valueFromLightSensor = analogRead(lightSensor); Serial.print("Light Value= "); Serial.print(valueFromLightSensor); Serial.println(""); Serial.print("Distance Value= "); int valueFromDistanceSensor = analogRead(distanceSensor); int distance= 4800/(valueFromDistanceSensor - 20); Serial.println(distance); Serial.print("Hour= "); Serial.println(hour()); delay(1000); } |