這篇文章來源于DevicePlus.com英語網站的翻譯稿。
第 1 部分 續 >
第4步:添加 RFID
RFID是該系統的核心。當你的寵物靠近喂食器時,RFID將讀取標簽上的值,并決定是否提供更多的食物。RFID系統采用SPI通信,將標簽的值存儲在EEPROM存儲器中。在這種情況下,如果發生系統故障(例如斷電等引發的問題),信息將被保存到存儲器中。
有關Arduino SPI通信的更多信息,請參閱 Arduino 通信協議教程。
就RFID而言,必須添加以下庫:
SPI
MFRC522
EEPROM
圖13:添加了RDIF的接線圖
圖14:RFID與其他組件連接的示意圖
我們有兩個RFID標簽。紅的會裝在寵物身上。作為測試組,藍的會裝在外人身上(不是你寵物的其他東西)。該系統有兩個功能:
白天:上午8時至晚上8時,喂食器每4小時投放3次食物。當食物被投放出來以后,蜂鳴器會發出聲音作為信號,它會叫你的寵物過來進食。當有聲音時,寵物就會知道該吃飯了,它會靠近自己的碗(食物容器)。當標簽靠近RFID閱讀器時,食物就會被投放出來
晚上:不會發出聲音,但如果寵物在早上0點以后接近RFID,則將被喂食一次。
圖15:在串口監視器上所顯示的分配標簽
第5步:安裝電機
我們將使用伺服電機SG90。伺服角度的大小是(0-180度)。我們的鎖具系統將類似于一個角度控制的鎖具(當“鎖具”打開/解鎖時,可控制投喂多少食物)。
以下是一些要點:
0 度:“鎖具”完全關閉,沒有食物投放;
180 度:“鎖具”完全打開,食物全部投放;
在 0-180: 之間:你可以選擇投放多少食物。
圖16:完整的項目接線圖
第6步:制作機械部分
在我們討論電機的編程之前,我們需要制作喂食器的支架。現在就需要研究一下喂食器的機械部分。我們需要以下材料:
金屬板(或木板)- 35×25 厘米
瓶子(或塑料容器)
打開/關閉食物分配器所需要用到的2塊硬質材料
把瓶子固定在金屬板上
用鉆在金屬板上鉆4個洞,為碗留出空間(這個距離取決于你的碗/食物容器有多高。之后,你需要把瓶子倒過來,用兩根線固定到金屬板上。
圖17:用兩根線把瓶子(食物分配器)連到金屬板上
“鎖具”系統不能懸在半空中,所以我們要用一塊堅硬的材料來固定它。這為食物分配器提供了一個很好的開口。我們需要用鉆頭或膠帶將其固定在金屬板上,這樣它就不會塌下來,以防你把太多食物放在分配器里。如下圖所示,為了防止鎖具的錯位,需要彎曲金屬部分的外緣。
圖18:支架安放位置
放置伺服電機
我們需要把電機接到金屬板上。我在金屬板上鉆了個洞,以便牢牢地固定伺服電機。接下來,我們需要將伺服電機連接到機械系統上,通過滑動鎖蓋來打開和關閉鎖具。這是通過線纜將蓋板的中間(靠近外緣)連接到電機上的(圖17)。只要確保蓋板順利地打開和關閉,你可以用任何材料來制作這個裝置。
圖19:在合適的地方鉆一個用來連接電機的孔
到這里,你差不多就要完工了。接下來,你只需要把喂食器固定到你想要的地方。請確保這個地方足夠安全,你的寵物無法輕易地拆除喂食器即可。
圖20:在支架附近接好電機
為了保證精度,請不要弄彎連接食物分配器蓋板和電機的線纜,否則電機的馬力會因此削弱。
圖21:完工后的寵物自動喂食器
圖22:最終成品
#include #include #include #include #include #include #include #include #define SS_PIN 10 #define RST_PIN 9 Servo myservo; boolean match = false; boolean programMode = false; boolean replaceMaster = false; int lightSensor = 0; int distanceSensor=1; int pos = 0; int successRead; byte storedCard[4]; byte readCard[4]; byte masterCard[4]; MFRC522 mfrc522(SS_PIN, RST_PIN); void setup() { Serial.begin(9600); setSyncProvider(RTC.get); myservo.attach(9); Serial.begin(9600); SPI.begin(); mfrc522.PCD_Init(); if (EEPROM.read(1) != 143) { do { successRead = getID(); } while (!successRead); for ( int j = 0; j < 4; j++ ) { EEPROM.write( 2 + j, readCard[j] ); } EEPROM.write(1, 143); } for ( int i = 0; i < 4; i++ ) { masterCard[i] = EEPROM.read(2 + i); Serial.print(masterCard[i], HEX); } } void loop() { int valueFromLightSensor = analogRead(lightSensor); int valueFromDistanceSensor = analogRead(distanceSensor); int distance= 4800/(valueFromDistanceSensor - 20); Serial.println(distance); do { successRead = getID(); } while (!successRead); if (programMode) { if ( isMaster(readCard) ) { programMode = false; return; } else { if ( findID(readCard) ) { } } } else { if ( isMaster(readCard)) { programMode = true; int count = EEPROM.read(0); } else { if ( findID(readCard) ) { if ((hour()>=8) && (hour()<=12 )){ if (distance>=20){ for(pos = 130; pos>=1; pos-=1) { myservo.write(pos); delay (20); } for(pos = 50; pos < 180; pos += 1) { myservo.write(pos); delay(20); } } delay(10000); } if ((hour()>=12) && (hour()<=16 )){ if (distance>=20){ for(pos = 130; pos>=1; pos-=1) { myservo.write(pos); delay (20); } for(pos = 50; pos < 180; pos += 1) { myservo.write(pos); delay(20); } } delay(10000); } if ((hour()>=0) && (hour()<=8 )){ if (distance>=20){ for(pos = 130; pos>=1; pos-=1) { myservo.write(pos); delay (20); } for(pos = 50; pos < 180; pos += 1) { myservo.write(pos); delay(20); } } delay(20000); } if ((hour()>=16) && (hour()<=20 )){ if (distance>=20){ Serial.println(distance); for(pos = 130; pos>=1; pos-=1) { myservo.write(pos); delay (20); } for(pos = 50; pos < 180; pos += 1) { myservo.write(pos); delay(20); } } delay(10000); } } } } } int getID() { if ( ! mfrc522.PICC_IsNewCardPresent()) { return 0; } if ( ! mfrc522.PICC_ReadCardSerial()) { return 0; } Serial.println(F("Scanned PICC's UID:")); for (int i = 0; i < 4; i++) { // readCard[i] = mfrc522.uid.uidByte[i]; Serial.print(readCard[i], HEX); } Serial.println(""); mfrc522.PICC_HaltA(); return 1; } void readID( int number ) { int start = (number * 4 ) + 2; for ( int i = 0; i < 4; i++ ) { storedCard[i] = EEPROM.read(start + i); } } boolean checkTwo ( byte a[], byte b[] ) { if ( a[0] != NULL ) match = true; for ( int k = 0; k < 4; k++ ) { if ( a[k] != b[k] ) match = false; } if ( match ) { return true; } else { return false; } } int findIDSLOT( byte find[] ) { int count = EEPROM.read(0); for ( int i = 1; i <= count; i++ ) { readID(i); if ( checkTwo( find, storedCard ) ) { return i; break; } } } boolean findID( byte find[] ) { int count = EEPROM.read(0); for ( int i = 1; i <= count; i++ ) { readID(i); if ( checkTwo( find, storedCard ) ) { return true; break; } else { } } return false; } boolean isMaster( byte test[] ) { if ( checkTwo( test, masterCard ) ) return true; else return false; }
這就是本項目的第一部分。這個設備凝聚了我對電子設備以及軟件編程的熱情,也讓我免于在一天之內喂好幾次寵物。它完美地在一個簡易項目和一個實用的家庭發明之間作出了平衡。在接下來的部分,我們將探究更先進的用戶界面,那時你就可以遠程控制喂食器了。
Tiberia Todeila
Tiberia目前是布加勒斯特理工大學電氣工程學院的大四學生。她非常熱衷于智能家居設備的設計和開發,旨在讓我們的日常生活更加輕松。
審核編輯黃宇
-
RFID
+關注
關注
387文章
6108瀏覽量
237405 -
Arduino
+關注
關注
187文章
6464瀏覽量
186665 -
喂食器
+關注
關注
1文章
23瀏覽量
3054
發布評論請先 登錄
相關推薦
評論