這篇文章來(lái)源于DevicePlus.com英語(yǔ)網(wǎng)站的翻譯稿。
點(diǎn)擊此處閱讀本文第1部分 >
在智能寵物喂食機(jī)的第1部分“使用Arduino Uno制作智能自動(dòng)寵物喂食機(jī)”中,我們建立了一個(gè)自動(dòng)化平臺(tái),可以判斷您的寵物是否被喂食以及計(jì)算下一次喂食的時(shí)間。在第2部分中,我們將嘗試通過(guò)MIT App Inventor開(kāi)發(fā)一個(gè)應(yīng)用程序并添加語(yǔ)音識(shí)別功能,使系統(tǒng)更加“智能”。在之前的教程中,我們已經(jīng)使用過(guò)MIT App Inventor來(lái)創(chuàng)建應(yīng)用程序。App Inventor是一種易于使用的基于塊的語(yǔ)言,用于設(shè)計(jì)Android應(yīng)用程序。
硬件
? Arduino UNO
? RFID RC522
? HC-05 藍(lán)牙模塊
沿用第1部分的硬件:
? Arduino Uno
? 距離傳感器 Sharp GP2Y0A21YK
? RFID RC522
? 蜂鳴器
? 電機(jī) SG90
? RTC DS1307
軟件
Arduino IDE
GitHub上的PetFeeder
MIT App Inventor
我們?cè)?b>第1部分中設(shè)置的用于EEPROM的標(biāo)簽—在該存儲(chǔ)器中,標(biāo)簽將被保存到我們將其清除為止。此功能有助于我們將自己的寵物與其他寵物分開(kāi)來(lái),只為帶有指定標(biāo)簽的寵物提供食物。
我們?cè)?b>第1部分中設(shè)置了兩個(gè)標(biāo)簽,并使用EEPROM來(lái)存儲(chǔ)數(shù)據(jù)。RFID標(biāo)簽有助于識(shí)別您的寵物并將其與其他人的寵物區(qū)分開(kāi),從而僅向帶有指定標(biāo)簽的寵物提供食物。使用EEPROM可以確保數(shù)據(jù)在系統(tǒng)重新啟動(dòng)后也可以安全地存儲(chǔ)在內(nèi)存中。您可以使用以下代碼從EEPROM更改標(biāo)簽信息:
#include #include #include boolean match = false; boolean programMode = false; int isOurPet; byte storedCard[4]; byte readCard[4]; byte masterCard[4]; #define SS_PIN 10 #define RST_PIN 9 MFRC522 mfrc522(SS_PIN, RST_PIN); void setup() { Serial.begin(9600); SPI.begin(); mfrc522.PCD_Init(); if (EEPROM.read(1) != 143) { do { isOurPet = findOurPet(); } while (!isOurPet); 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); } } void loop () { do { isOurPet = findOurPet(); } while (!isOurPet); if ( master(readCard)) { programMode = true; Serial.println(F("Our Pet - Green Tag")); int count = EEPROM.read(0); } else { Serial.println(F("Not our pet - Purple Tag")); } } int findOurPet() { if ( ! mfrc522.PICC_IsNewCardPresent()) { return 0; } if ( ! mfrc522.PICC_ReadCardSerial()) { return 0; } for (int i = 0; i < 4; i++) { readCard[i] = mfrc522.uid.uidByte[i]; } mfrc522.PICC_HaltA(); // Stop reading return 1; } void readCollar( int number ) { int start = (number * 4 ) + 2; for ( int i = 0; i < 4; i++ ) { storedCard[i] = EEPROM.read(start + i); } } boolean EEpromCheck ( 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; } } boolean master( byte test[] ) { if ( EEpromCheck( test, masterCard ) ) return true; else return false; }
圖1:我們?cè)贓EPROM中的寵物標(biāo)簽
上次,我們將寵物指定為紅色標(biāo)簽。這次,我們將標(biāo)簽更改為綠色。
步驟2:怎樣控制伺服
伺服電機(jī)通過(guò)來(lái)自微控制器的PWM(脈沖寬度調(diào)節(jié))來(lái)更改其位置。伺服需要進(jìn)行校準(zhǔn),并將其閥門開(kāi)度角度設(shè)置為90度。
為了控制伺服,我們將使用ArduinoSweep 代碼。該代碼中伺服電機(jī)軸可以旋轉(zhuǎn)180度。我們將把旋轉(zhuǎn)角度從0-180度更改為10-170度。
#include Servo myservo; // create servo object to control a servo int pos = 0; // variable to store the servo position void setup() { myservo.attach(9); // attaches the servo on pin 9 to the servo object } void loop() { for(pos = 10; pos <= 170; pos += 1) // goes from 10 degrees to 170 degrees // in steps of 1 degree { myservo.write(pos); // tell servo to go to position in variable ‘pos’ delay(15); // waits 15ms for the servo to reach the position } for(pos = 170; pos>=10; pos -= 1) // goes from 170 degrees to 10 degrees { myservo.write(pos); // tell servo to go to position in variable ‘pos’ delay(15); // waits 15ms for the servo to reach the position } }
關(guān)于伺服的注意事項(xiàng):
您的伺服在某些時(shí)候可能會(huì)行為異常。當(dāng)您由于Arduino自行重啟而無(wú)法執(zhí)行指令時(shí),可能是因?yàn)?a target="_blank">USB端口沒(méi)有提供足夠的電源來(lái)驅(qū)動(dòng)伺服。在這種情況下,Arduino會(huì)進(jìn)行重置,應(yīng)用程序也無(wú)法工作。用以下兩種方法可以避免此問(wèn)題的產(chǎn)生:
1. 您可以在面包板上的GND和5V之間添加一個(gè)大容值電容器(470uF或更大)。當(dāng)Arduino沒(méi)有足夠的電源來(lái)維持電流時(shí),該電容器可以用作臨時(shí)電源。較長(zhǎng)的端子必須連接到VDD=5V,而較短的端子必須連接到GND。
2. 您可以通過(guò)USB對(duì)開(kāi)發(fā)板進(jìn)行編程,之后斷開(kāi)連接。然后,您可以使用手機(jī)充電器通過(guò)插頭來(lái)為裝置供電,因?yàn)樗哂懈蟮碾娏魅萘俊?/p>
讓我們簡(jiǎn)要地看一下 庫(kù)的工作方式。
#include
必須含有該指令才能使用Servo.h庫(kù)。Servo庫(kù)中給出的兩個(gè)示例是“Knob”和“Sweep”。這兩個(gè)控件對(duì)伺服的測(cè)試很有用。使用Knob,您就可以通過(guò)電位計(jì)將伺服轉(zhuǎn)動(dòng)到特定角度。使用Sweep,您就可以在180度的范圍內(nèi)來(lái)回掃動(dòng)伺服軸。
Servo servo;
這是一個(gè)類型的聲明。它定義了servo類型的變量Servo。它與其他用于伺服的類型相似,如int(整型)和float(浮點(diǎn)型)。
servo.attach(servoPin);
在設(shè)置代碼塊時(shí),您需要將伺服分配給特定的引腳。該指令用于將伺服變量分配引腳。
servo.write(angle);
此指令將設(shè)置伺服軸角度(在0到180度范圍內(nèi)),然后將伺服轉(zhuǎn)動(dòng)至該角度。
步驟3:添加HC-05藍(lán)牙模塊
———-
關(guān)于藍(lán)牙HC-05 – 用戶使用手冊(cè)
藍(lán)牙串行模塊的運(yùn)行不需要進(jìn)行驅(qū)動(dòng),并且可以與具有串行接口的其他藍(lán)牙設(shè)備進(jìn)行通信。兩個(gè)藍(lán)牙模塊之間實(shí)現(xiàn)通信至少需要兩個(gè)條件:
(1) 必須在主設(shè)備和從設(shè)備之間進(jìn)行。
(2) 密碼必須正確。
該模塊的屬性:
? 可以在主模式和從模式之間切換
? 藍(lán)牙名稱: HC-05
? 密碼: 1234
配對(duì):主設(shè)備不僅可以與指定的藍(lán)牙地址配對(duì)(如手機(jī)、計(jì)算機(jī)適配器、從設(shè)備),還可以自動(dòng)搜索從設(shè)備并與之配對(duì)。
典型方法:在某些特定條件下,主設(shè)備和從設(shè)備可以自動(dòng)配對(duì)(這是默認(rèn)方法)。
———-
在本項(xiàng)目中,我們選擇了藍(lán)牙連接,因?yàn)檫@種方式易于配置。藍(lán)牙模塊用作Arduino的串行端子,將被連接到TX和RX引腳。
想要通過(guò)藍(lán)牙進(jìn)行數(shù)據(jù)傳輸需要遵循一些規(guī)則。我們需要有:
? (通常值為邏輯0)
? 數(shù)據(jù)位
? 校驗(yàn)位(數(shù)據(jù)位的和;我們將會(huì)比較從頭到尾所有位的和)
? 停止位(大多數(shù)情況下值為邏輯1)
引腳連接:
1.將HC-05的TX引腳連接到Arduino的RX引腳。
2.將HC-05的RX引腳連接到Arduino的TX引腳。
3.將GND引腳連接在一起。
在我們之前的教程 制作您自己的Arduino RFID門鎖—第2部分:用智能手機(jī)解鎖中對(duì)HC-05設(shè)置進(jìn)行了詳細(xì)說(shuō)明。如果您在連接藍(lán)牙模塊時(shí)遇到問(wèn)題,請(qǐng)參考上述教程。
圖2:HC-05和Arduino Uno之間的連接
藍(lán)牙傳輸代碼:
#include #include #include #include #include #include #include #include #include String voice; #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() { pinMode(8, OUTPUT); 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); Serial.println(""); } } void loop() { int valueFromLightSensor = analogRead(lightSensor); //Serial.print("Light Value= "); //Serial.println(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()); while (Serial.available()) { delay(10); char c = Serial.read(); voice += c; } if (voice.length() > 0) { Serial.println(voice); if(voice == "feed") { myservo.write(130); delay(1000); myservo.write(50); delay(1000); myservo.write(130); delay(1000); myservo.write(50); delay(1000); digitalClockDisplay(); } if(voice == "feed2") { myservo.write(130); delay(1000); myservo.write(50); delay(1000); digitalClockDisplay(); } if(voice == "feed1") { myservo.write(130); delay(1000); myservo.write(50); delay(1000); myservo.write(130); delay(1000); myservo.write(50); delay(1000); myservo.write(130); delay(1000); myservo.write(50); delay(1000); digitalClockDisplay(); } ; } 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){ // Serial.println(distance); myservo.write(130); delay(100); myservo.write(50); delay(100); myservo.write(130); delay(100); myservo.write(50); delay(100); digitalClockDisplay(); } delay(300); }
if ((hour()>=12) && (hour()<=16 )){ if (distance>=20){ // Serial.println(distance); myservo.write(130); delay(100); myservo.write(50); delay(100); myservo.write(130); delay(100); myservo.write(50); delay(100); digitalClockDisplay(); } delay(300); } if ((hour()>=16) && (hour()<=20 )){ if (distance>=20){ // Serial.println(distance); myservo.write(130); delay(100); myservo.write(50); delay(100); myservo.write(130); delay(100); myservo.write(50); delay(100); digitalClockDisplay(); } delay(300); } if ((hour()>=20) && (hour()<=8 )){ if (distance>=20){ // Serial.println(distance); myservo.write(130); delay(100); myservo.write(50); delay(100); myservo.write(130); delay(100); myservo.write(50); delay(100); digitalClockDisplay(); } delay(300); } } else { // If not, show that the ID was not valid Serial.println(F("You shall not pass")); } } } } 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(); // Stop reading 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; } void digitalClockDisplay() { Serial.print(hour()); printDigits(minute()); //printDigits(second()); Serial.print(" "); Serial.print(day()); Serial.print(" "); Serial.print(month()); Serial.print(" "); Serial.print(year()); Serial.println(); } void printDigits(int digits){ // utility function for digital clock display: prints preceding colon and leading 0 Serial.print(":"); if(digits < 10) Serial.print('0'); Serial.print(digits); }
該代碼中的算法非常簡(jiǎn)單:我們對(duì)串口進(jìn)行初始化,然后等待端口打開(kāi)。我們將通過(guò)該代碼發(fā)送指令。如果代碼不可用,程序?qū)⒉粫?huì)執(zhí)行,“喂食”指令將不會(huì)發(fā)送到微控制器進(jìn)行相應(yīng)處理。
該程序還將比較來(lái)自“voice(聲音)”變量的字符串和串口讀取的字符串。如果兩者相同,則會(huì)向電機(jī)發(fā)送一個(gè)指令來(lái)觸發(fā)SG90伺服電機(jī)。
圖3:連接到第1部分裝置中的HC-05藍(lán)牙模塊
步驟3:設(shè)計(jì)應(yīng)用程序
現(xiàn)在,讓我們來(lái)創(chuàng)建一個(gè)應(yīng)用程序吧!和以前一樣,我們將使用MIT App Inventor。我們的最終目標(biāo)是創(chuàng)建一個(gè)對(duì)所連接的多種設(shè)備進(jìn)行集成的組合型應(yīng)用程序(例如,集成了多個(gè)所連接設(shè)備的智能家居應(yīng)用程序)。
有關(guān)MIT App Inventor的設(shè)置指南,請(qǐng)參考上一教程制作您自己的Arduino RFID門鎖—第2部分:用智能手機(jī)解鎖 (步驟3:應(yīng)用程序)。本教程將分步指導(dǎo)您使用App Inventor創(chuàng)建自己的應(yīng)用程序。
我們所創(chuàng)建的應(yīng)用程序?qū)?huì)具有一個(gè)簡(jiǎn)單的界面,其中包含以下功能:
? 連接到藍(lán)牙
? 使您可以遠(yuǎn)程喂食寵物
? 存儲(chǔ):將數(shù)據(jù)(以文件形式)存儲(chǔ)在手機(jī)中
? 顯示日期:在手機(jī)屏幕上顯示日期信息
圖4:寵物喂食器應(yīng)用程序的簡(jiǎn)單用戶界面
該程序的模塊圖非常簡(jiǎn)單易懂:
?第一個(gè)模塊:第一個(gè)模塊用于藍(lán)牙按鈕
? ListPicker – MIT App Inventor
單擊該按鈕,將顯示文本列表供用戶選擇。可以通過(guò)Designer或Blocks Editor來(lái)指定文本內(nèi)容,方法是將ElementsFromString屬性設(shè)置為文本的拆分字符串級(jí)聯(lián)(例如,選擇1,選擇2,選擇3)或者將Elements屬性設(shè)置為一個(gè)Blocks editor中的列表。
? ListPicker 顯示所有可用的藍(lán)牙;該功能在您選擇某一個(gè)藍(lán)牙前有效。
圖5:第一個(gè)模塊
? 第二個(gè)模塊:通過(guò)調(diào)用BluetoothClient1.Connect address現(xiàn)應(yīng)用程序與客戶端之間的連接。您手機(jī)中的藍(lán)牙將搜索附近的設(shè)備,并將其顯示在ListPicker中。您可以選擇要配對(duì)的設(shè)備。
圖6:第二個(gè)模塊
同時(shí)還有一個(gè)標(biāo)簽,在建立連接后標(biāo)簽上會(huì)顯示相關(guān)消息。如果設(shè)備已經(jīng)成功連接,您將在屏幕上看到“已連接(Connected)”的消息。
? 第三個(gè)模塊:僅用于連接完成時(shí)通過(guò)客戶端發(fā)送一個(gè)消息。該文本以串行通信的方式,通過(guò)藍(lán)牙從一個(gè)設(shè)備發(fā)送到另一個(gè)設(shè)備。這就像在Arduino的串行監(jiān)視器中鍵入文本一樣。
當(dāng)我們從串行讀取數(shù)據(jù)時(shí),就是在對(duì)用戶的輸入與Arduino內(nèi)存中存儲(chǔ)的字符串進(jìn)行比較。這就是算法的工作原理。
圖7:第三個(gè)模塊
我們接下來(lái)看看另一組模塊圖:
? 第一個(gè)模塊:將藍(lán)牙傳輸?shù)娜掌诒4娴酱鎯?chǔ)在手機(jī)內(nèi)存里的.txt文件中。
圖8:第一個(gè)模塊
? 第二個(gè)模塊:當(dāng)按下按鈕時(shí),將會(huì)讀取保存在文本文件中的數(shù)據(jù)。
圖9:第二個(gè)模塊
? 第三個(gè)模塊:將喂食的時(shí)間和標(biāo)簽寫入屏幕。這個(gè)信息很有用,因?yàn)樗梢詭椭覀儗?duì)喂食時(shí)間進(jìn)行記錄,如果我們不想對(duì)寵物喂食過(guò)多,可以查看時(shí)間來(lái)確認(rèn)。
圖10:第三個(gè)模塊
? 第四個(gè)模塊:發(fā)生錯(cuò)誤時(shí),該模塊將刪除.txt文件中的所有數(shù)據(jù)。這一功能很重要,因?yàn)橐坏﹫?zhí)行,將不再顯示以前的信息。
圖11:第四個(gè)模塊
該應(yīng)用程序的第二部分提供了不同的喂食模式:正常喂食模式,用于寵物寶寶的喂食模式和用于成年寵物的喂食模式。這也為您提供了需要為寵物喂食多少食物量的有關(guān)信息。其中最酷的功能之一是語(yǔ)音識(shí)別模式。我們將在下文中討論有關(guān)該功能的更多內(nèi)容。
圖12:應(yīng)用程序上顯示的非正確時(shí)間和日期
如果想要查找喂食的日期和時(shí)間,可以按“顯示日期”按鈕。該應(yīng)用程序是以精簡(jiǎn)模式制作的,因?yàn)椴⒉皇敲總€(gè)人都希望看到所有信息。如圖所示,日期和時(shí)間顯示不正確。為了獲得確切的日期和時(shí)間,我們需要使用Arduino IDE中的Set Time 示例。現(xiàn)在,RTC模塊將指示正確的日期和時(shí)間。
圖13:如何找到Arduino IDE中的SetTime
Set Time code: #include #include #include const char *monthName[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; tmElements_t tm; void setup() { bool parse=false; bool config=false; // get the date and time the compiler was run if (getDate(__DATE__) && getTime(__TIME__)) { parse = true; // and configure the RTC with this info if (RTC.write(tm)) { config = true; } } Serial.begin(9600); while (!Serial) ; // wait for Arduino Serial Monitor delay(200); if (parse && config) { Serial.print("DS1307 configured Time="); Serial.print(__TIME__); Serial.print(", Date="); Serial.println(__DATE__); } else if (parse) { Serial.println("DS1307 Communication Error :-{"); Serial.println("Please check your circuitry"); } else { Serial.print("Could not parse info from the compiler, Time=""); Serial.print(__TIME__); Serial.print("", Date=""); Serial.print(__DATE__); Serial.println("""); } } void loop() { } bool getTime(const char *str) { int Hour, Min, Sec; if (sscanf(str, "%d:%d:%d", &Hour, &Min, &Sec) != 3) return false; tm.Hour = Hour; tm.Minute = Min; tm.Second = Sec; return true; } bool getDate(const char *str) { char Month[12]; int Day, Year; uint8_t monthIndex; if (sscanf(str, "%s %d %d", Month, &Day, &Year) != 3) return false; for (monthIndex = 0; monthIndex < 12; monthIndex++) { if (strcmp(Month, monthName[monthIndex]) == 0) break; } if (monthIndex >= 12) return false; tm.Day = Day; tm.Month = monthIndex + 1; tm.Year = CalendarYrToTm(Year); return true; }
圖14顯示了該應(yīng)用程序的最終版本:
圖14:應(yīng)用程序的最終版本
應(yīng)用程序概述:
? 需要連接到藍(lán)牙。
? 根據(jù)寵物的年齡采用不同的喂食模式。
? 要激活語(yǔ)音識(shí)別模式,只需單擊“語(yǔ)音識(shí)別喂食”按鈕并講話即可。
? 僅當(dāng)正確說(shuō)出指令時(shí),喂食器才能運(yùn)行。如果關(guān)鍵字不正確(無(wú)法正確識(shí)別),則只會(huì)在標(biāo)簽上顯示而不執(zhí)行指令。
? 在語(yǔ)音識(shí)別的模式下,當(dāng)兩次說(shuō)出/重復(fù)“喂食”指令(比如您沒(méi)有等待幾秒鐘的時(shí)間讓系統(tǒng)對(duì)信息進(jìn)行處理)時(shí),指令就會(huì)變成“喂食喂食”,這不是有效的指令。它將保留在標(biāo)簽上而不執(zhí)行。
? 如果語(yǔ)音識(shí)別上的“喂食”指令正常工作,標(biāo)簽上將會(huì)打印出時(shí)間。
? 還包括一個(gè)喂食指南,您可以根據(jù)寵物的體重查找有關(guān)所應(yīng)提供食物量的信息。
圖15:寵物喂食指南/ ?Fish4Dogs
所有指令都可以在Arduino IDE的串行監(jiān)視器上找到。這有助于我們?cè)诒匾獣r(shí)對(duì)應(yīng)用程序進(jìn)行調(diào)試。
圖16:串行監(jiān)視器中顯示的喂食數(shù)據(jù)
對(duì)于語(yǔ)音識(shí)別,我們需要一個(gè)按鈕來(lái)激活該模式。我們可以使用App Inventor中已經(jīng)提供的SpeechRecognizer組件。
圖17:在MIT App Interventor上添加SpeechRecognizer組件
有了這兩個(gè)組件后,將它們連接起來(lái)非常簡(jiǎn)單。您需要處理來(lái)自講話者的文本。這是通過(guò)調(diào)用SpeechRecognizer.GetText來(lái)完成的。之后,您需要有一個(gè)標(biāo)簽來(lái)顯示所說(shuō)的內(nèi)容,也可以沒(méi)有這個(gè)標(biāo)簽,但是如果沒(méi)有標(biāo)簽?zāi)鷮o(wú)法看到自己是否說(shuō)了正確的指令。在程序循環(huán)中,您還需要通過(guò)藍(lán)牙將語(yǔ)音指令傳輸?shù)紸rduino,需要使用SentText text程序。
圖18:語(yǔ)音識(shí)別模塊
對(duì)于每種模式,您都需要有相對(duì)應(yīng)的按鈕。每個(gè)按鈕對(duì)應(yīng)不同的指令,該指令將會(huì)被發(fā)送到Arduino,然后據(jù)此喂食不同量的食物。
圖19:寵物寶寶模式,正常喂食模式和成年寵物模式模塊
審核編輯黃宇
-
RFID
+關(guān)注
關(guān)注
388文章
6161瀏覽量
238034 -
語(yǔ)音識(shí)別
+關(guān)注
關(guān)注
38文章
1742瀏覽量
112692 -
程序
+關(guān)注
關(guān)注
117文章
3788瀏覽量
81103 -
Arduino
+關(guān)注
關(guān)注
188文章
6471瀏覽量
187231
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論