在上一篇文章自製 Arduino RFID門鎖中,我們製作了Arduino RFID門鎖,並且能夠使用RFID標籤或鍵盤來解鎖。那麼,如果您想要進一步簡化流程該怎麼辦呢?在第二部分中,我們將添加一個附加功能:使用智慧手機來解鎖。這是一種更簡單的控制門的辦法,尤其是當所有人都希望能夠透過一個裝置就能控制所有物品的時候。那麼我們該怎麼做呢?我們將會把藍牙模組連接到先前的設定中,並連接電子門。
在這一步中,我們將深入研究HC-05藍牙模組。
Arduino-info Wiki
有以下兩種操作模式:
針對我們的應用程式,我們將使用資料模式,因為我們僅需要使用序列通信來從手機接收資訊。
有關序列通信的更多資訊,請參考Arduino序列通信課程。
在此應用程式中,我們需要使用以下引腳—Arduino-info Wiki:
藍牙使用序列通信;“Serial.write(Serial.read());”連接了RX和TX引腳後,該指令將會正常運行。如果這對藍牙模組不適用,則下面的代碼返回的內容與您在Arduino IDE中編寫的文本相同。
1 2 3 4 5 6 7 8 9 10 |
void setup(){ Serial.begin(9600); Serial.println("What did you say?:"); } void loop(){ if (Serial.available()) Serial.write(Serial.read()); } |
您需要在裝置管理員中找到Arduino的程式設計埠;連接藍牙後,將出現“藍牙連結上的標準序列”,您必須選擇“USB-SERIAL”才能對Arduino進行程式設計。您需要使用序列電纜上傳程式,不能使用無線藍牙將程式上傳到研發板。
連接RX和TX後,您將收到許多錯誤資訊,如下所示:
為了避免這些錯誤,您需要在藍牙的TX引腳沒有連接到Arduino研發板的情況下上傳程式。藍牙的TX引腳具有低電阻,而Arduino的RX輸入具有高電阻。最終的電阻將為較低的一個,而RX輸入將會被繞過(從USB埠產生的電流直接透過藍牙輸出,而不是Arduino研發板)。這就是資料無法傳輸到期望位置點的原因。另外,電流直接流入裝置的輸出端將會在模組之間產生錯誤的連接,會導致電氣故障。我們想要做的是對Arduino進行程式設計,而不是將資料發送到藍牙模組。
斷開藍牙的TX引腳後,一切都會正常工作,您就可以上傳代碼了。
上傳代碼後,下一步是連接到電腦上的藍牙。您需要重新連接藍牙的TX引腳,因為現在我們將使用無線通訊,序列電纜只用於供電。
請按照以下步驟將藍牙連接到PC(在Windows 10系統上):
如果您已經按照上述步驟進行了操作,那麼您的藍牙連接應該就成功了,您可以對模組進行測試。有一種簡單的檢查連接是否成功建立的方法:在Arduino IDE中鍵入一個單詞,然後查看是否返回相同的單詞,如果是的話,就說明一切正常,您可以繼續往下進行了!如果不是,請返回之前的步驟並再次對藍牙配對。
因為我們不再使用透過電纜的序列通信,所以需要找到藍牙的COM。我們需要回到埠(PORTS)部分的裝置管理員(Device Manager),並搜索藍牙裝置。在我的應用中是PORT 17:
在裝置管理員中找到COM後,您需要在Arduino IDE中執行相同的操作(即將COM埠設定為COM 17)。您需要點擊TOOLS → PORT → COM 17。
選擇正確的COM後,您可以對模組進行測試,查看是否工作正常。
請確保您在序列監視器中選擇了以下兩個選項:
在我們的演示中,我們將輸入資訊“Hello!”
輸出內容應與輸入內容相同:
讓我們參考一下上一篇文章自製Arduino RFID門鎖!我們將使用與之前相同的元件,然後增加一個藍牙模組(HC-05)。為了將資料從智慧手機傳輸到Arduino,我們需要藍牙模組。
斷開藍牙的TX引腳很重要,否則我們將會遇到跟步驟1中相同的錯誤。
有三種方式可以打開門鎖:
該鎖具有很高的電流量(800mA)。我們添加一個綠色LED燈來查看代碼是否運行正常。鍵入“*123456#” 代碼且系統解鎖後,LED指示燈將為高電平。
在下一步中,我們將添加電池和繼電器。我們使用兩節9V電池給門鎖供電。如果您打算將裝置電壓設定為固定值,則需要購買一種可以從切換電源的220V電壓中獲得5V電壓的裝置。
因為鎖的電流消耗很高,所以電池並聯連接。在這種情況下,Arduino由電池供電。我們需要使用將9V轉換為5V的DC-DC降壓模組。輸入電壓由Arduino研發板的Vin引腳進入。我們將不再使用電腦USB的供電。
降壓模組的輸出電壓要固定在5V。您需要使用萬用表進行校準;輸入電壓為9V,我們將旋扭電位器,直到輸出電壓為5V。
完整代碼
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 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 |
#include <EEPROM.h> #include <SPI.h> #include <MFRC522.h> #include <Wire.h> #include <LiquidCrystal_I2C.h> #include <Keypad.h> int state_bt=1; int relPin; int stare=0; byte COD[10]; byte AUX[10]; int k=0; String codacces="*123456#"; String codpairing="*654321#"; //nfc #define RST_PIN 9 // Configurable, see typical pin layout above #define SS_PIN 10 // Configurable, see typical pin layout above MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance #define NEW_UID {0xDE, 0xAD, 0xBE, 0xEF} MFRC522::MIFARE_Key key; //lcd LiquidCrystal_I2C lcd(0x27,16,2); //TASTATURA const byte numRows= 4; //number of rows on the keypad const byte numCols= 4; //number of columns on the keypad //keymap defines the key pressed according to the row and columns just as appears on the keypad char keymap[numRows][numCols]= { {'1', '2', '3', 'A'}, {'4', '5', '6', 'B'}, {'7', '8', '9', 'C'}, {'*', '0', '#', 'D'} }; //Code that shows the the keypad connections to the arduino terminals byte rowPins[numRows] = {2,3,4,5}; //Rows 0 to 3 byte colPins[numCols]= {A0,7,8,9}; //Columns 0 to 3 //initializes an instance of the Keypad class Keypad myKeypad= Keypad(makeKeymap(keymap), rowPins, colPins, numRows, numCols); void setup() { pinMode(A0,OUTPUT); digitalWrite(A0,HIGH); pinMode(A3,OUTPUT); digitalWrite(A3,HIGH); pinMode(A1,OUTPUT); digitalWrite(A1,HIGH); pinMode(A2,OUTPUT); digitalWrite(A2,LOW); pinMode(6,OUTPUT); digitalWrite(6,HIGH); //nfc Serial.begin(9600); // Initialize serial communications with the PC Serial.println("What did you say?:"); while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4) SPI.begin(); // Init SPI bus mfrc522.PCD_Init(); // Init MFRC522 card for (byte i = 0; i < 6; i++) { key.keyByte[i] = 0xFF; } lcd.init(); lcd.backlight(); lcd.setCursor(0,0); lcd.clear(); lcd.print("BLOCKED"); } void citireNFC(){ for (byte i =0; i<(mfrc522.uid.size); i++) { COD[i]=mfrc522.uid.uidByte[i]; } Serial.print("COD"); Serial.print(COD[0]); Serial.print(COD[1]); Serial.print(COD[2]); Serial.print(COD[3]); } void pairNFC(){ Serial.println("COD in pair"); Serial.print(COD[0]); Serial.print(COD[1]); Serial.print(COD[2]); Serial.print(COD[3]); long r=0; int c=0; for(int i=1;i<=EEPROM.read(0);i++){ switch(i%4){ case 1 :{AUX[0]=EEPROM.read(i); break;} case 2 :{AUX[1]=EEPROM.read(i); break;} case 3 :{AUX[2]=EEPROM.read(i); break;} case 0 :{AUX[3]=EEPROM.read(i); break;} } if((i)%4==0) {Serial.println(r); if( AUX[0]==COD[0] && AUX[1]==COD[1] && AUX[2]==COD[2] && AUX[3]==COD[3] ){ lcd.clear(); lcd.setCursor(0,0); lcd.print("CODE ALREADY IN"); lcd.setCursor(0,1); lcd.print("SYSTEM"); delay(2000); c=1; break;} } } if(c==0){int ttt=EEPROM.read(0); Serial.println("CODE PAIRED"); Serial.print(COD[0]); Serial.print(COD[1]); Serial.print(COD[2]); Serial.print(COD[3]); EEPROM.write(ttt+1,COD[0]); EEPROM.write(ttt+2,COD[1]); EEPROM.write(ttt+3,COD[2]); EEPROM.write(ttt+4,COD[3]); ttt=ttt+4; Serial.println("ttt"); Serial.println(ttt); EEPROM.write(0,0); EEPROM.write(0,ttt); lcd.clear(); lcd.setCursor(0,0); lcd.print("CODE PAIRED"); delay(2000);} } boolean validareNFC(){ boolean c=false; for(int i=1;i<=EEPROM.read(0);i++){ switch(i%4){ case 1 :{AUX[0]=EEPROM.read(i); break;} case 2 :{AUX[1]=EEPROM.read(i); break;} case 3 :{AUX[2]=EEPROM.read(i); break;} case 0 :{AUX[3]=EEPROM.read(i); break;} } if((i)%4==0) { if( AUX[0]==COD[0] && AUX[1]==COD[1] && AUX[2]==COD[2] && AUX[3]==COD[3]) c=true; }} return c; } int comparareCOD(String a) { if(a.equals(codacces)) return 1; else if(a.equals(codpairing)) return 2; else return 0; } String iaCOD(char x) { char vec[10]; vec[0]=x; lcd.setCursor(0,0); lcd.clear(); lcd.print('X'); for(int i=1;i<8;i++) {vec[i]=myKeypad.waitForKey(); lcd.print('X');} vec[8]=NULL; String str(vec); return str; } void loop() { //Start BT autentification if(Serial.available()) { char c=Serial.read(); switch (state_bt) { case 1: if(c=='*') state_bt=2; else state_bt=1; break; case 2: if(c=='1') state_bt=3; else state_bt=1; break; case 3: if(c=='2') state_bt=4; else state_bt=1; break; case 4: if(c=='3') state_bt=5; else state_bt=1; break; case 5: if(c=='4') state_bt=6; else state_bt=1; break; case 6: if(c=='5') state_bt=7; else state_bt=1; break; case 7: if(c=='6') state_bt=8; else state_bt=1; break; case 8: if(c=='#') state_bt=9; else state_bt=1; break; case 9: lcd.init(); lcd.backlight(); lcd.print("OPEN"); digitalWrite(6,LOW); delay(5000); digitalWrite(6,HIGH); lcd.init(); lcd.backlight(); lcd.print("BLOCKED"); state_bt=1; break; default: break; } } switch(stare){ case 0: { mfrc522.PCD_Init(); if ( mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial() ){ citireNFC(); if(validareNFC()) {stare=1; lcd.clear(); lcd.setCursor(0,0); lcd.print("VALID NFC CODE"); delay(1000); return; } else{ lcd.clear(); lcd.setCursor(0,0); lcd.print("INVALID NFC CODE"); delay(1000); lcd.setCursor(0,0); lcd.clear(); lcd.print("BLOCKED"); return; } } char c=myKeypad.getKey(); if(c != NO_KEY){ String codcurent=iaCOD(c); int A=comparareCOD(codcurent); if(A==0) {lcd.clear(); lcd.print("INVALID CODE"); delay(2000); lcd.setCursor(0,0); lcd.clear(); lcd.print("BLOCKED"); return;} if(A==1) {lcd.setCursor(0,0); lcd.clear(); lcd.print("VALID CODE"); delay(2000); stare = 1; return;} if(A==2); {stare=2; lcd.clear(); lcd.setCursor(0,0); lcd.print("Pairing..."); delay(2000); return;} } break; } case 1:{ lcd.clear(); lcd.setCursor(0,0); lcd.print("UNLOCKED"); digitalWrite(A3,LOW); digitalWrite(A1,LOW); digitalWrite(A2,HIGH); //tone(6,3000,5010); digitalWrite(6,LOW); delay(5000); digitalWrite(6,HIGH); digitalWrite(A3,HIGH); digitalWrite(A1,HIGH); digitalWrite(A2,LOW); stare=0; lcd.setCursor(0,0); lcd.clear(); lcd.print("BLOCKED"); return; } case 2:{ mfrc522.PCD_Init(); if ( mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial() ){ citireNFC(); pairNFC(); stare=0; delay(2000); lcd.clear(); lcd.setCursor(0,0); lcd.print("BLOCKED"); } break; } } } |
在此步驟中,我們將為系統創建應用程式。我使用的是MIT App Inventor 2程式。這個程式很簡單,不需要很高的程式設計技能,可以在此處下載:MIT AppInventor。為了打開該應用程式,您需要:
在安裝了程式之後,您會找到如下的一個佈局介面:
為了對您的程式進行測試,您需要在手機上從Google Play下載“MIT AI2”應用程式。這是一個免費的應用程式,專門用於將網路應用程式同步到智慧手機上。
如果您想要在手機上查看應用程式的螢幕,需要點擊Connect → AI Companion。
點擊之後,該應用程式將為您提供兩種操作方式:
我將使用第二種方法,將電腦產生的6個字母的代碼輸入到手機應用程式中。
我選擇這個應用程式是因為它易於使用;您無需具備程式設計技能即可實現如上所述的簡單代碼。您只需要構思一下應用程式的外觀,在該應用程式中進行外觀設定也非常簡單。
我們先從使用者介面開始:
您可以在螢幕上添加應用程式的任何元素(按鈕,圖像,文字方塊,標籤)。在右側功能表中,您可以選擇想要從螢幕上獲取的特長(水準對齊,應用名稱,標題)。如果您想要背景圖像,可以從背景圖像(Background Image)功能表中進行選擇。在該應用程式中,我選擇在藍牙和手機之間的連接打開時顯示綠色背景,在連接斷路時顯示紅色背景。
該應用程式中螢幕上的三個要素:
感測器組件 & 使用者介面元件 – MIT App Inventor
如果未連接藍牙,您會收到一個錯誤資訊,該錯誤資訊會顯示在連接狀態(Link Status)部分中。我在沒有連接裝置的情況下輸入了打開門的密碼,應用程式提醒我裝置沒有打開。這是一個很好的通知器,因為您有可能會忘記進行裝置的配對,這樣就無法把門打開。
該應用程式有三個按鈕:
應用程式是如何工作的 – Pevest App Inventor 2: 學習編碼
“當輸入Clock1.Timer指令時,該應用程式會檢查藍牙是否打開。變數 ByteAvailable 和 CommandByte將被初始化設定為0,以用於傳輸。如果獲取到了有關資料,則使用ReceiveSigned1ByteNumber讀取傳入資料的第一個位元組。這是指令位元組。根據指令的值,將採用合適的藍牙模組中的方法(method)來讀取下一個位元組。”
該專案由於需要使用大量的週邊裝置之間的通信而具有一定的挑戰性,因此我花了一些時間來尋找連接所有元件的理想方式。它説明我瞭解了製造複雜裝置的過程中可能發生的一些錯誤,以及避免這些錯誤的方法。