這篇文章來(lái)源于DevicePlus.com英語(yǔ)網(wǎng)站的翻譯稿。
第 1 部分 續(xù) >
第4步:添加 RFID
RFID是該系統(tǒng)的核心。當(dāng)你的寵物靠近喂食器時(shí),RFID將讀取標(biāo)簽上的值,并決定是否提供更多的食物。RFID系統(tǒng)采用SPI通信,將標(biāo)簽的值存儲(chǔ)在EEPROM存儲(chǔ)器中。在這種情況下,如果發(fā)生系統(tǒng)故障(例如斷電等引發(fā)的問(wèn)題),信息將被保存到存儲(chǔ)器中。
有關(guān)Arduino SPI通信的更多信息,請(qǐng)參閱 Arduino 通信協(xié)議教程。
就RFID而言,必須添加以下庫(kù):
SPI
MFRC522
EEPROM
圖13:添加了RDIF的接線圖
圖14:RFID與其他組件連接的示意圖
我們有兩個(gè)RFID標(biāo)簽。紅的會(huì)裝在寵物身上。作為測(cè)試組,藍(lán)的會(huì)裝在外人身上(不是你寵物的其他東西)。該系統(tǒng)有兩個(gè)功能:
白天:上午8時(shí)至晚上8時(shí),喂食器每4小時(shí)投放3次食物。當(dāng)食物被投放出來(lái)以后,蜂鳴器會(huì)發(fā)出聲音作為信號(hào),它會(huì)叫你的寵物過(guò)來(lái)進(jìn)食。當(dāng)有聲音時(shí),寵物就會(huì)知道該吃飯了,它會(huì)靠近自己的碗(食物容器)。當(dāng)標(biāo)簽靠近RFID閱讀器時(shí),食物就會(huì)被投放出來(lái)
晚上:不會(huì)發(fā)出聲音,但如果寵物在早上0點(diǎn)以后接近RFID,則將被喂食一次。
圖15:在串口監(jiān)視器上所顯示的分配標(biāo)簽
第5步:安裝電機(jī)
我們將使用伺服電機(jī)SG90。伺服角度的大小是(0-180度)。我們的鎖具系統(tǒng)將類(lèi)似于一個(gè)角度控制的鎖具(當(dāng)“鎖具”打開(kāi)/解鎖時(shí),可控制投喂多少食物)。
以下是一些要點(diǎn):
0 度:“鎖具”完全關(guān)閉,沒(méi)有食物投放;
180 度:“鎖具”完全打開(kāi),食物全部投放;
在 0-180: 之間:你可以選擇投放多少食物。
圖16:完整的項(xiàng)目接線圖
第6步:制作機(jī)械部分
在我們討論電機(jī)的編程之前,我們需要制作喂食器的支架。現(xiàn)在就需要研究一下喂食器的機(jī)械部分。我們需要以下材料:
金屬板(或木板)- 35×25 厘米
瓶子(或塑料容器)
打開(kāi)/關(guān)閉食物分配器所需要用到的2塊硬質(zhì)材料
把瓶子固定在金屬板上
用鉆在金屬板上鉆4個(gè)洞,為碗留出空間(這個(gè)距離取決于你的碗/食物容器有多高。之后,你需要把瓶子倒過(guò)來(lái),用兩根線固定到金屬板上。
圖17:用兩根線把瓶子(食物分配器)連到金屬板上
“鎖具”系統(tǒng)不能懸在半空中,所以我們要用一塊堅(jiān)硬的材料來(lái)固定它。這為食物分配器提供了一個(gè)很好的開(kāi)口。我們需要用鉆頭或膠帶將其固定在金屬板上,這樣它就不會(huì)塌下來(lái),以防你把太多食物放在分配器里。如下圖所示,為了防止鎖具的錯(cuò)位,需要彎曲金屬部分的外緣。
圖18:支架安放位置
放置伺服電機(jī)
我們需要把電機(jī)接到金屬板上。我在金屬板上鉆了個(gè)洞,以便牢牢地固定伺服電機(jī)。接下來(lái),我們需要將伺服電機(jī)連接到機(jī)械系統(tǒng)上,通過(guò)滑動(dòng)鎖蓋來(lái)打開(kāi)和關(guān)閉鎖具。這是通過(guò)線纜將蓋板的中間(靠近外緣)連接到電機(jī)上的(圖17)。只要確保蓋板順利地打開(kāi)和關(guān)閉,你可以用任何材料來(lái)制作這個(gè)裝置。
圖19:在合適的地方鉆一個(gè)用來(lái)連接電機(jī)的孔
到這里,你差不多就要完工了。接下來(lái),你只需要把喂食器固定到你想要的地方。請(qǐng)確保這個(gè)地方足夠安全,你的寵物無(wú)法輕易地拆除喂食器即可。
圖20:在支架附近接好電機(jī)
為了保證精度,請(qǐng)不要弄彎連接食物分配器蓋板和電機(jī)的線纜,否則電機(jī)的馬力會(huì)因此削弱。
圖21:完工后的寵物自動(dòng)喂食器
圖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; }
這就是本項(xiàng)目的第一部分。這個(gè)設(shè)備凝聚了我對(duì)電子設(shè)備以及軟件編程的熱情,也讓我免于在一天之內(nèi)喂好幾次寵物。它完美地在一個(gè)簡(jiǎn)易項(xiàng)目和一個(gè)實(shí)用的家庭發(fā)明之間作出了平衡。在接下來(lái)的部分,我們將探究更先進(jìn)的用戶(hù)界面,那時(shí)你就可以遠(yuǎn)程控制喂食器了。
Tiberia Todeila
Tiberia目前是布加勒斯特理工大學(xué)電氣工程學(xué)院的大四學(xué)生。她非常熱衷于智能家居設(shè)備的設(shè)計(jì)和開(kāi)發(fā),旨在讓我們的日常生活更加輕松。
審核編輯黃宇
-
RFID
+關(guān)注
關(guān)注
388文章
6176瀏覽量
238124 -
Arduino
+關(guān)注
關(guān)注
188文章
6472瀏覽量
187357 -
喂食器
+關(guān)注
關(guān)注
1文章
24瀏覽量
3111
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論