RFID čítačka II: Rozdiel medzi revíziami
Zo stránky SensorWiki
(21 medziľahlých úprav od rovnakého používateľa nie je zobrazených.) | |||
Riadok 35: | Riadok 35: | ||
* priebehy dôležitých signálov | * priebehy dôležitých signálov | ||
[[Súbor:RFID.jpg|300px|center]] | |||
[[Súbor: | |||
<table frame="border" rules = "all"> | |||
'''Popis pinov PCF 8583''' | |||
<tr><th>PIN</th><th>Skratka-označenie</th><th>Krátky popis</th><th>I/O</th></tr> | |||
<tr><td>1</td><td>VCC</td><td>Napájanie +5V </td><td>P</td></tr> | |||
<tr><td>2</td><td>/ENABLE</td><td>Tento pin nastavený do LOW nastaví RFID čítačku a aktivuje anténu</td><td>I</td></tr> | |||
<tr><td>3</td><td>SOUT</td><td>Seriový výstup</td><td>O</td></tr> | |||
<tr><td>4</td><td>GND</td><td>Napájacia zem</td><td>G</td></tr> | |||
</table> | |||
'''Rozhranie UART''' | |||
Pri asynchrónnom prenose je dátový rámec definovaný nasledovne: | Pri asynchrónnom prenose je dátový rámec definovaný nasledovne: | ||
Riadok 59: | Riadok 55: | ||
*Stop bity (1 alebo 2) – ukončenie prenosu, stav linky je v log. 1 | *Stop bity (1 alebo 2) – ukončenie prenosu, stav linky je v log. 1 | ||
*Stav nečinnosti – ak sa žiadne dáta po linke neodosielajú ostáva v log. 1. | *Stav nečinnosti – ak sa žiadne dáta po linke neodosielajú ostáva v log. 1. | ||
[[Súbor:Byt.jpg|500px|center]] | |||
Popis registrov | Popis registrov: | ||
Modul USART mikropočítača Atmega8 obsahuje štyri 8-bitové registre: | Modul USART mikropočítača Atmega8 obsahuje štyri 8-bitové registre: | ||
* údajový register UDR, | * údajový register UDR, | ||
Riadok 66: | Riadok 62: | ||
* riadiaci a stavový register B, UCSRB | * riadiaci a stavový register B, UCSRB | ||
* riadiaci a stavový register C, UCSRC | * riadiaci a stavový register C, UCSRC | ||
[[Médiá:28140-28340-RFID-Reader-Documentation-v2.2.pdf]] | |||
== Princíp RFID (Radio Frequency Identification): == | |||
Základný princíp komunikácie medzi RFID čítačkou (reader) a kartou (tag) je cez elektromagnetické pole generované cievkou, | |||
ktorá sa nachádza sa v čítačke. Cievka, ktorá sa nachádza na karte, prijíma elektromagnetické pole od čítačky a vytvára prúd v obvode karty, | |||
ktorý sa použiva na napájanie katry a odosielanie dát z karty na čítačku. | |||
[[Súbor:Bez_názvu.jpg|500px|center]] | |||
V zadaní sme pracovali s Paralax RFID čítačkou, ktorá je napájaná 5V, podporuje sériovú komunikáciu UART pracujúcu na rýchlosti 2400 Baud . Čítačka je schopná načítavať 125 kHz karty, ktoré majú 10 digitové ID. | |||
Komunikačný protokol: využíva štart bit, jeden stop bit a osem dátových bitov po asynchrónnej zbernici. Keď je čítačka aktívna tak po priložení naprogramovanej karty sa ID karty odosiela ako 12 bytoví ASCII string vo formáte uvedenom nižšie: | |||
[[Súbor:data.jpg|500px|center]] | |||
Štart a Stop bit sú použité pre ošetrenie správneho prijatia dát, dokým stredných desať bytov predstavuje ID karty. Ako príklad sa uvádza naprogramovaná karta s ID: 0F0184F07A a byty, ktoré sú odoslané sú nasledovné: 0x0A, 0x30, 0x46, 0x30, 0x31, 0x38, 0x34, 0x46, 0x30, 0x37, 0x41, 0x0D. | |||
== Princíp funkcie: == | |||
[[Súbor:Bez názvu.png|500px|center]] | |||
Ako prvé čítačka načíta kartu(Tag). Na základe kódu karty sa zistí či je daná karta Master Tag(Master karta) alebo User Tag(Užívateľská karta). Master karta realizuje naprogramovanie alebo vymazanie ďalších užívateľských kárt do systému. Pokiaľ po Master karte sa načíta karta, ktorá je systému známa tak sa daná karta vymaže z databázy nahratých užívateľských kariet. Ak je karta po načítaní master karty neznáma tak sa uloží do databázy a je ňou možné otvárať daný zámok. Ak je užívateľská karta v systéme nahratá, tak po priložení na čítačku, systém porovnáva kód s uloženými kódmi kariet v databáze. Ak je kód uložený prístup sa povolí. Ak nieje uložený kód karty v databáze tak sa prístup zamietne. | |||
== Popis riešenia == | == Popis riešenia == | ||
Za úlohu sme mali naprogramovať RFID čítačku na otvorenie zámku dverí. Zapojenie čítačky k procesoru vyzerá nasledovne: | |||
[[Súbor: | [[Súbor:zapojenie1.jpg|500px|center]] | ||
'''Popis činnosti:''' | |||
Po zapojení na napätie sa RFID čítačka inicializuje. Pri načítaní prvej karty zasiela ID karty procesoru na spracovanie. Procesor na základe naprogramovaného kódu rozhodne či ID karty patrí Master karte ktorá je už nahratá v EEPROM pamäti alebo užívateľskej karte. Pokiaľ načíta master kartu, "rozbliká sa" biela dióda na 5 sekúnd( čo značí, že je v programovacom móde po 5-tich sekundách sa programovací mód vypne). V programovacom móde ak vložíme užívateľskú kartu, ktorej ID nieje uložené v EEPROM pamäti tak ID karty do nej uloží. Ak tam ID karty uložené je, tak ho vymaže. Takýmto spôsobov sa pridávajú alebo odoberajú užívatelia zámku. Rozsvietenie zelenej diódy značí, že prístup je povolený teda ID karty je uložené v EEPROM pamäti. Ak sa rozsvieti červená dióda tak ID karty uložené nieje v pamäti EEPROM. | |||
[[Súbor:Ulozena master karta.jpg|600px|center]] | |||
Na obrázku je možné vidieť výpis z pamäti EEPROM pomocou Terminal.exe. Vyznačené ID je ID master karty, ktorá spúšťa programovací mód. Každé ďalšie ID karty je ukladané alebo vymazávané do/z znázornených "chlievikov" oddelených symbolom "|" za sebou. | |||
Riadok 91: | Riadok 104: | ||
<source lang="c"> | <source lang="c"> | ||
int main( | |||
#include "common.h" | |||
printf(" | #include <avr/interrupt.h> | ||
return(0); | #include <stdlib.h> | ||
#include "serial.h" | |||
#include<stdio.h> | |||
#include <avr\io.h> | |||
#include <util/delay.h> | |||
#include <avr/eeprom.h> | |||
FILE uart_output = FDEV_SETUP_STREAM(sendchar, NULL, _FDEV_SETUP_WRITE); | |||
FILE uart_input = FDEV_SETUP_STREAM(NULL, recchar, _FDEV_SETUP_READ); | |||
static void RFID_init(void); | |||
static void RFID_ena(uint8_t ena); | |||
static void TunedDelay(uint16_t); | |||
void blinkRed(); | |||
void blinkGreen(); | |||
void blinkWhite(); | |||
void longWhiteBlink(); | |||
void blinkAll(); | |||
void printAllEeprom(); //vypise vsetko z eepromu | |||
void printAll(); //vypise vsetky z pola | |||
void clearEeprom(); //vymaz vsetko z eepromu | |||
void saveCardToEeprom(int card[12]); //uloz jednu do eepromu | |||
int findPosition(int card[12]); //najdi poziciu karty v poli | |||
void deleteCard(int card[12]); //vymaz kartu z pola a eepromu | |||
void saveCard(int card[12]); //uloz kartu do pola a eepromu | |||
void loadCard(int position); // nacitaj kartu do pola z eepromu na pozicii i | |||
void loadCardsFromEeprom(); // nacitaj vsetky karty z eepromu -> pri startovani | |||
int containsCard(int card[12]); //nachadza sa karta v poli? -> ma povoleny pristup? | |||
#define RFID_IN PIND2 | |||
#define RFID_ENA PIND3 | |||
#define CENTER_DELAY 471 | |||
#define INTRABIT_DELAY 950 | |||
#define MAX_CARDS 102 | |||
#define PROGRAM_MODE_MAX_SECONDS 5 | |||
#define EEPROM_MAX 512 | |||
#define PROGRAM_MODE 2 | |||
static volatile uint8_t bDataReady; | |||
static volatile uint8_t rxIdx; | |||
int RFID_tag[12]; | |||
int cards[102][5]; | |||
int cardArraySize = 0; | |||
int mode = 0; | |||
int saveModePassedSeconds=0; | |||
int main() | |||
{ | |||
inituart(); | |||
stdout = &uart_output; | |||
stdin = &uart_input; | |||
DDRD = (1<<DDD6) | (1<<DDD5); //Zapni D5(zelena LED), zapni D6(cervena LED) | |||
PORTD = (0<<PD6) | (0<<PD5); //Vypni D5, vypni D6 | |||
RFID_init(); | |||
RFID_ena(1); | |||
TunedDelay(947); | |||
//clearEeprom(); | |||
printAllEeprom(); | |||
loadCardsFromEeprom(); //inicializacia pola kariet | |||
printAll(); //vypis nacitane karty z pola | |||
printf("RFID Initialized"); | |||
blinkAll(); | |||
printf(" %d cards saved", cardArraySize); | |||
while(1) | |||
{ | |||
if(mode == PROGRAM_MODE){ | |||
blinkWhite(); | |||
saveModePassedSeconds++; | |||
} | |||
if(saveModePassedSeconds >= PROGRAM_MODE_MAX_SECONDS){ //ak ubehlo PROGRAM_MODE_MAX_SECONDS (5s) | |||
saveModePassedSeconds=0; | |||
mode=0; | |||
} | |||
if (bDataReady){ | |||
printf(" %d cards saved", cardArraySize); | |||
//saveCard(RFID_tag); | |||
printf("RFID tag: "); | |||
for(uint8_t x = 1; x <= 10; x++) | |||
{ | |||
x++; | |||
printf("%i",RFID_tag[x]); | |||
if (x%2==0 && x<9) | |||
printf("-"); | |||
} | |||
printf("\n"); | |||
if(mode == PROGRAM_MODE){ // ak sme v programovacom mode, uloz/vymaz kartu | |||
saveCard(RFID_tag); | |||
//blinkRed(); | |||
longWhiteBlink(); | |||
rxIdx = 0; | |||
bDataReady = 0; | |||
continue; | |||
} | |||
int ret = containsCard(RFID_tag); //zapis do premennej ret ci sa karta nachadza v poli | |||
if(ret == 2){ // master card pouzita -> zapisovaci mod | |||
mode = PROGRAM_MODE; | |||
_delay_ms(500); | |||
}else if(ret == 1){ | |||
printf("Správny kód"); | |||
printf("Prístup povolený \n"); | |||
blinkGreen(); | |||
} | |||
else { | |||
printf("Nesprávny kód!! \n"); | |||
printf("Priloz inu kartu!\n\n"); | |||
blinkRed(); | |||
} | |||
rxIdx = 0; | |||
bDataReady = 0; | |||
} | |||
} | |||
} | |||
void RFID_init() | |||
{ | |||
bDataReady = 0; | |||
rxIdx = 0; | |||
// RFID_IN input from RFID Reader SOUT, RFID_ENA output to RFID Reader /ENA | |||
BSET(DDRD, RFID_ENA); | |||
BSET(PORTD,RFID_IN); // pullup | |||
BSET(PCICR,PCIE2); // pin change interrupt control register pcie2 -> PCICR = 0b00000100 | |||
BSET(PCMSK2,PCINT18); // enable pin change interrupt for PCINT18 (PD2) -> PCMSK2 = 0b00000100 | |||
BSET(SREG,7); // Set SREG I-bit -> SREG = 0b10000000 | |||
} | |||
ISR(PCINT2_vect) | |||
{ | |||
if (BCHK(PIND,RFID_IN)) // Start bit goes low | |||
return; | |||
uint8_t bit = 0; | |||
TunedDelay(CENTER_DELAY); // Center on start bit | |||
for (uint8_t x = 0; x < 8; x++) | |||
{ | |||
TunedDelay(INTRABIT_DELAY); | |||
if (BCHK(PIND,RFID_IN)) | |||
BSET(bit,x); | |||
else | |||
BCLR(bit,x); | |||
} | |||
TunedDelay(INTRABIT_DELAY); | |||
RFID_tag[rxIdx] = bit; | |||
++rxIdx; | |||
if (rxIdx == 12) | |||
bDataReady = 1; | |||
//else{ | |||
// printf("bdata not ready "); | |||
// } | |||
} | |||
void RFID_ena(uint8_t ena) | |||
{ | |||
if (ena) | |||
BCLR(PORTD,RFID_ENA); | |||
else | |||
BSET(PORTD,RFID_ENA); | |||
} | |||
void TunedDelay(uint16_t delay) // delay function | |||
{ | |||
uint8_t tmp=0; | |||
asm volatile("sbiw %0, 0x01 \n\t" | |||
"ldi %1, 0xFF \n\t" | |||
"cpi %A0, 0xFF \n\t" | |||
"cpc %B0, %1 \n\t" | |||
"brne .-10 \n\t" | |||
: "+r" (delay), "+a" (tmp) | |||
: "0" (delay) | |||
); | |||
} | |||
void CriticalSegment(uint8_t ena) | |||
{ | |||
static uint8_t sreg; | |||
if (ena) | |||
{ | |||
sreg = SREG; // save off our global status register | |||
cli(); // zastav globalne prerusenia | |||
} else | |||
{ | |||
SREG = sreg; // restore global interrupt flag (and any other prev settings) | |||
} | |||
} | |||
void blinkRed(){ | |||
PORTD = (1<<PD6); | |||
_delay_ms(2000); | |||
PORTD = (0<<PD6); | |||
} | |||
void blinkGreen(){ | |||
PORTD = (1<<PD5); | |||
_delay_ms(2000); | |||
PORTD = (0<<PD5); | |||
} | |||
void blinkWhite(){ | |||
PORTD = (1<<PD7); | |||
_delay_ms(500); | |||
PORTD = (0<<PD7); | |||
_delay_ms(500); | |||
} | |||
void longWhiteBlink(){ | |||
PORTD = (1<<PD7); | |||
_delay_ms(2000); | |||
PORTD = (0<<PD7); | |||
} | |||
void blinkAll(){ | |||
PORTD = (1<<PD6); | |||
_delay_ms(500); | |||
PORTD = (1<<PD5); | |||
_delay_ms(500); | |||
PORTD = (1<<PD7); | |||
_delay_ms(500); | |||
PORTD = (0<<PD6); | |||
PORTD = (0<<PD5); | |||
PORTD = (0<<PD7); | |||
} | |||
void printAllEeprom(){ | |||
for(int i=0; i< EEPROM_MAX; i++){ | |||
printf("%d ", eeprom_read_byte(i)); | |||
if((i+1) % 5 == 0 && i != 1 && i != 0){ | |||
printf(" | "); | |||
} | |||
} | |||
} | } | ||
void printAll(){ | |||
for(int i=0; i< cardArraySize; i++){ | |||
printf("%d ", cards[i]); | |||
} | |||
} | |||
void clearEeprom(){ | |||
for(int i=0; i< EEPROM_MAX; i++){ | |||
eeprom_write_byte(i, 255); | |||
} | |||
} | |||
void saveCardToEeprom(int card[12]){ | |||
int i=0; | |||
while(eeprom_read_byte(i) != 255){ | |||
i++; | |||
} | |||
for(int j=2; j<12; j+=2){ | |||
eeprom_write_byte(i, card[j]); | |||
i++; | |||
} | |||
} | |||
int findPosition(int card[12]){ | |||
for(int i = 0; i < cardArraySize; i++){ | |||
int k=2; | |||
int j; | |||
for(j=0; j < 5; j++){ | |||
if(cards[i][j] != card[k]){ | |||
break; | |||
} | |||
k+=2; | |||
} | |||
if(j==5){ // vrat poziciu | |||
return i; | |||
} | |||
} | |||
} | |||
void deleteCard(int card[12]){ | |||
if(containsCard(card) != 1){ //ak karta nie je zapisana, vyskoc z funkcie (nemame co mazat) | |||
return; | |||
} | |||
int position = findPosition(card); | |||
if(position == 0) //nedovolime vymazat master (prvu) | |||
return; | |||
for(int i=0; i < 5; i++){ | |||
cards[position][i] = 255; | |||
eeprom_write_byte((position * 5) + i, 255); | |||
} | |||
} | |||
void saveCard(int card[12]){ | |||
if(containsCard(card)){ // ak je karta uz zapisana, pokus sa ju vymazat | |||
deleteCard(card); | |||
saveModePassedSeconds=0; | |||
mode=0; | |||
// blinkAll(); | |||
return; | |||
} | |||
int i=0; | |||
cardArraySize+=1; | |||
for(int j=2; j<12; j+=2){ //zapis kartu do pola | |||
cards[cardArraySize][i] = card[j]; | |||
// printf("savujem na %d miesto %d ", i, card[j]); | |||
i++; | |||
} | |||
saveCardToEeprom(card); //zapis kartu do eepromu | |||
// blinkAll(); | |||
// _delay_ms(1000); | |||
// blinkAll(); | |||
cardArraySize+=1; | |||
saveModePassedSeconds=0; | |||
mode=0; | |||
} | |||
void loadCard(int position){ | |||
int j=0; | |||
for(int i = position; i < position + 5; i++){ | |||
int temp = eeprom_read_byte(i); | |||
if(temp == 255){ | |||
cardArraySize--; | |||
break; | |||
} | |||
cards[cardArraySize][j] = temp; | |||
//printf("%d ", cards[cardArraySize][j]); | |||
j++; | |||
} | |||
cardArraySize++; | |||
} | |||
void loadCardsFromEeprom(){ | |||
int i=0; | |||
while(i <= 255){ | |||
loadCard(i); | |||
i+=5; | |||
} | |||
} | |||
int containsCard(int card[12]){ | |||
//printf("card size: %d ", cardArraySize); | |||
for(int i = 0; i < cardArraySize; i++){ | |||
int k=2; | |||
int j; | |||
for(j=0; j < 5; j++){ | |||
//printf(" porovnanie: %d %d ",cards[i][j],card[k] ); | |||
if(cards[i][j] != card[k]){ | |||
//printf("vyskakujem z loopu"); | |||
break; | |||
} | |||
k+=2; | |||
} | |||
//printf("J: %d ", j); | |||
if(i == 0 && j==5){ //ak sme na prvej karte a vsetkych 5 sa zhodovalo, vrat 2 | |||
return 2; | |||
} | |||
if(j == 5){ | |||
return 1; | |||
} | |||
} | |||
return 0; | |||
} | |||
</source> | </source> | ||
Nezabudnite však nahrať aj kompletné zdrojové kódy vášho programu! | Nezabudnite však nahrať aj kompletné zdrojové kódy vášho programu! | ||
Zdrojový kód: [[Médiá: | Zdrojový kód: [[Médiá:Zadanie.c]] | ||
[[serial.h]] | |||
[[ | [[serial.c]] | ||
[[ubre.c]] | |||
[[ubre.h]] | |||
=== Overenie === | === Overenie === | ||
[https://www.youtube.com/watch?v=4dp8c_tVRnw&feature=youtu.be Video funkčnosti RFID čítačky] | |||
[[Category:AVR]] [[Category:DVPS]] | [[Category:AVR]] [[Category:DVPS]] |
Aktuálna revízia z 15:24, 18. január 2015
Autori: | Martinkovič a Valach | |
Študijný odbor: | Aplikovaná mechatronika | 2. Ing. (2014) |
Zadanie
Pomocou RFID čítačky navrhnite elektronický zámok na kód. Popíšte princíp RFID vyhodnocovanie, zistite akú triedu RFID prvkov je schopná čítačka rozpoznať a zmerajte ukážkové data a vyhodnoťte meranie.
http://www.parallax.com/product/28140
Literatúra:
- Zoznam použitej literatúry, vrátane katalógových údajov (datasheet), internetových odkazov a pod.
Analýza
V tejto časti popíšete ako idete daný problém riešiť. Uvediete sem aj všetky potrebné technické údaje, ktoré sú potrebné na úspešné vyriešenie projektu. Napríklad:
- popis komunikačnej zbernice (i2c, 1-wire, RS-232 a pod.)
- obrázok zapojenia vývodov použitej súčiastky
- odkaz na katalógový list
- priebehy dôležitých signálov
PIN | Skratka-označenie | Krátky popis | I/O |
---|---|---|---|
1 | VCC | Napájanie +5V | P |
2 | /ENABLE | Tento pin nastavený do LOW nastaví RFID čítačku a aktivuje anténu | I |
3 | SOUT | Seriový výstup | O |
4 | GND | Napájacia zem | G |
Rozhranie UART
Pri asynchrónnom prenose je dátový rámec definovaný nasledovne:
- Štart bit – začiatok prenosu, slúži na zosynchronizovanie vysielača a prijímača, stav linky je v log. 0
- Dátové bity – môže ich byť 5 až 9, začína sa bitom najnižšej váhy (LSB)
- Parity bit – slúži ako kontrolná suma pri prenose dát
- Stop bity (1 alebo 2) – ukončenie prenosu, stav linky je v log. 1
- Stav nečinnosti – ak sa žiadne dáta po linke neodosielajú ostáva v log. 1.
Popis registrov: Modul USART mikropočítača Atmega8 obsahuje štyri 8-bitové registre:
- údajový register UDR,
- riadiaci a stavový register A, UCSRA
- riadiaci a stavový register B, UCSRB
- riadiaci a stavový register C, UCSRC
Médiá:28140-28340-RFID-Reader-Documentation-v2.2.pdf
Princíp RFID (Radio Frequency Identification):
Základný princíp komunikácie medzi RFID čítačkou (reader) a kartou (tag) je cez elektromagnetické pole generované cievkou, ktorá sa nachádza sa v čítačke. Cievka, ktorá sa nachádza na karte, prijíma elektromagnetické pole od čítačky a vytvára prúd v obvode karty, ktorý sa použiva na napájanie katry a odosielanie dát z karty na čítačku.
V zadaní sme pracovali s Paralax RFID čítačkou, ktorá je napájaná 5V, podporuje sériovú komunikáciu UART pracujúcu na rýchlosti 2400 Baud . Čítačka je schopná načítavať 125 kHz karty, ktoré majú 10 digitové ID. Komunikačný protokol: využíva štart bit, jeden stop bit a osem dátových bitov po asynchrónnej zbernici. Keď je čítačka aktívna tak po priložení naprogramovanej karty sa ID karty odosiela ako 12 bytoví ASCII string vo formáte uvedenom nižšie:
Štart a Stop bit sú použité pre ošetrenie správneho prijatia dát, dokým stredných desať bytov predstavuje ID karty. Ako príklad sa uvádza naprogramovaná karta s ID: 0F0184F07A a byty, ktoré sú odoslané sú nasledovné: 0x0A, 0x30, 0x46, 0x30, 0x31, 0x38, 0x34, 0x46, 0x30, 0x37, 0x41, 0x0D.
Princíp funkcie:
Ako prvé čítačka načíta kartu(Tag). Na základe kódu karty sa zistí či je daná karta Master Tag(Master karta) alebo User Tag(Užívateľská karta). Master karta realizuje naprogramovanie alebo vymazanie ďalších užívateľských kárt do systému. Pokiaľ po Master karte sa načíta karta, ktorá je systému známa tak sa daná karta vymaže z databázy nahratých užívateľských kariet. Ak je karta po načítaní master karty neznáma tak sa uloží do databázy a je ňou možné otvárať daný zámok. Ak je užívateľská karta v systéme nahratá, tak po priložení na čítačku, systém porovnáva kód s uloženými kódmi kariet v databáze. Ak je kód uložený prístup sa povolí. Ak nieje uložený kód karty v databáze tak sa prístup zamietne.
Popis riešenia
Za úlohu sme mali naprogramovať RFID čítačku na otvorenie zámku dverí. Zapojenie čítačky k procesoru vyzerá nasledovne:
Popis činnosti: Po zapojení na napätie sa RFID čítačka inicializuje. Pri načítaní prvej karty zasiela ID karty procesoru na spracovanie. Procesor na základe naprogramovaného kódu rozhodne či ID karty patrí Master karte ktorá je už nahratá v EEPROM pamäti alebo užívateľskej karte. Pokiaľ načíta master kartu, "rozbliká sa" biela dióda na 5 sekúnd( čo značí, že je v programovacom móde po 5-tich sekundách sa programovací mód vypne). V programovacom móde ak vložíme užívateľskú kartu, ktorej ID nieje uložené v EEPROM pamäti tak ID karty do nej uloží. Ak tam ID karty uložené je, tak ho vymaže. Takýmto spôsobov sa pridávajú alebo odoberajú užívatelia zámku. Rozsvietenie zelenej diódy značí, že prístup je povolený teda ID karty je uložené v EEPROM pamäti. Ak sa rozsvieti červená dióda tak ID karty uložené nieje v pamäti EEPROM.
Na obrázku je možné vidieť výpis z pamäti EEPROM pomocou Terminal.exe. Vyznačené ID je ID master karty, ktorá spúšťa programovací mód. Každé ďalšie ID karty je ukladané alebo vymazávané do/z znázornených "chlievikov" oddelených symbolom "|" za sebou.
Algoritmus a program
Uveďte stručný popis algoritmu, v akom jazyku a verzii vývojového prostredia ste ho vytvorili. Je vhodné nakresliť aspoň hrubú štruktúru programu napríklad vo forme vývojového diagramu. Rozsiahly program pre lepšiu prehľadnosť rozdeľte do viacerých súborov.
Vyberte podstatné časti zdrojového kódu, použite na to prostredie source:
#include "common.h"
#include <avr/interrupt.h>
#include <stdlib.h>
#include "serial.h"
#include<stdio.h>
#include <avr\io.h>
#include <util/delay.h>
#include <avr/eeprom.h>
FILE uart_output = FDEV_SETUP_STREAM(sendchar, NULL, _FDEV_SETUP_WRITE);
FILE uart_input = FDEV_SETUP_STREAM(NULL, recchar, _FDEV_SETUP_READ);
static void RFID_init(void);
static void RFID_ena(uint8_t ena);
static void TunedDelay(uint16_t);
void blinkRed();
void blinkGreen();
void blinkWhite();
void longWhiteBlink();
void blinkAll();
void printAllEeprom(); //vypise vsetko z eepromu
void printAll(); //vypise vsetky z pola
void clearEeprom(); //vymaz vsetko z eepromu
void saveCardToEeprom(int card[12]); //uloz jednu do eepromu
int findPosition(int card[12]); //najdi poziciu karty v poli
void deleteCard(int card[12]); //vymaz kartu z pola a eepromu
void saveCard(int card[12]); //uloz kartu do pola a eepromu
void loadCard(int position); // nacitaj kartu do pola z eepromu na pozicii i
void loadCardsFromEeprom(); // nacitaj vsetky karty z eepromu -> pri startovani
int containsCard(int card[12]); //nachadza sa karta v poli? -> ma povoleny pristup?
#define RFID_IN PIND2
#define RFID_ENA PIND3
#define CENTER_DELAY 471
#define INTRABIT_DELAY 950
#define MAX_CARDS 102
#define PROGRAM_MODE_MAX_SECONDS 5
#define EEPROM_MAX 512
#define PROGRAM_MODE 2
static volatile uint8_t bDataReady;
static volatile uint8_t rxIdx;
int RFID_tag[12];
int cards[102][5];
int cardArraySize = 0;
int mode = 0;
int saveModePassedSeconds=0;
int main()
{
inituart();
stdout = &uart_output;
stdin = &uart_input;
DDRD = (1<<DDD6) | (1<<DDD5); //Zapni D5(zelena LED), zapni D6(cervena LED)
PORTD = (0<<PD6) | (0<<PD5); //Vypni D5, vypni D6
RFID_init();
RFID_ena(1);
TunedDelay(947);
//clearEeprom();
printAllEeprom();
loadCardsFromEeprom(); //inicializacia pola kariet
printAll(); //vypis nacitane karty z pola
printf("RFID Initialized");
blinkAll();
printf(" %d cards saved", cardArraySize);
while(1)
{
if(mode == PROGRAM_MODE){
blinkWhite();
saveModePassedSeconds++;
}
if(saveModePassedSeconds >= PROGRAM_MODE_MAX_SECONDS){ //ak ubehlo PROGRAM_MODE_MAX_SECONDS (5s)
saveModePassedSeconds=0;
mode=0;
}
if (bDataReady){
printf(" %d cards saved", cardArraySize);
//saveCard(RFID_tag);
printf("RFID tag: ");
for(uint8_t x = 1; x <= 10; x++)
{
x++;
printf("%i",RFID_tag[x]);
if (x%2==0 && x<9)
printf("-");
}
printf("\n");
if(mode == PROGRAM_MODE){ // ak sme v programovacom mode, uloz/vymaz kartu
saveCard(RFID_tag);
//blinkRed();
longWhiteBlink();
rxIdx = 0;
bDataReady = 0;
continue;
}
int ret = containsCard(RFID_tag); //zapis do premennej ret ci sa karta nachadza v poli
if(ret == 2){ // master card pouzita -> zapisovaci mod
mode = PROGRAM_MODE;
_delay_ms(500);
}else if(ret == 1){
printf("Správny kód");
printf("Prístup povolený \n");
blinkGreen();
}
else {
printf("Nesprávny kód!! \n");
printf("Priloz inu kartu!\n\n");
blinkRed();
}
rxIdx = 0;
bDataReady = 0;
}
}
}
void RFID_init()
{
bDataReady = 0;
rxIdx = 0;
// RFID_IN input from RFID Reader SOUT, RFID_ENA output to RFID Reader /ENA
BSET(DDRD, RFID_ENA);
BSET(PORTD,RFID_IN); // pullup
BSET(PCICR,PCIE2); // pin change interrupt control register pcie2 -> PCICR = 0b00000100
BSET(PCMSK2,PCINT18); // enable pin change interrupt for PCINT18 (PD2) -> PCMSK2 = 0b00000100
BSET(SREG,7); // Set SREG I-bit -> SREG = 0b10000000
}
ISR(PCINT2_vect)
{
if (BCHK(PIND,RFID_IN)) // Start bit goes low
return;
uint8_t bit = 0;
TunedDelay(CENTER_DELAY); // Center on start bit
for (uint8_t x = 0; x < 8; x++)
{
TunedDelay(INTRABIT_DELAY);
if (BCHK(PIND,RFID_IN))
BSET(bit,x);
else
BCLR(bit,x);
}
TunedDelay(INTRABIT_DELAY);
RFID_tag[rxIdx] = bit;
++rxIdx;
if (rxIdx == 12)
bDataReady = 1;
//else{
// printf("bdata not ready ");
// }
}
void RFID_ena(uint8_t ena)
{
if (ena)
BCLR(PORTD,RFID_ENA);
else
BSET(PORTD,RFID_ENA);
}
void TunedDelay(uint16_t delay) // delay function
{
uint8_t tmp=0;
asm volatile("sbiw %0, 0x01 \n\t"
"ldi %1, 0xFF \n\t"
"cpi %A0, 0xFF \n\t"
"cpc %B0, %1 \n\t"
"brne .-10 \n\t"
: "+r" (delay), "+a" (tmp)
: "0" (delay)
);
}
void CriticalSegment(uint8_t ena)
{
static uint8_t sreg;
if (ena)
{
sreg = SREG; // save off our global status register
cli(); // zastav globalne prerusenia
} else
{
SREG = sreg; // restore global interrupt flag (and any other prev settings)
}
}
void blinkRed(){
PORTD = (1<<PD6);
_delay_ms(2000);
PORTD = (0<<PD6);
}
void blinkGreen(){
PORTD = (1<<PD5);
_delay_ms(2000);
PORTD = (0<<PD5);
}
void blinkWhite(){
PORTD = (1<<PD7);
_delay_ms(500);
PORTD = (0<<PD7);
_delay_ms(500);
}
void longWhiteBlink(){
PORTD = (1<<PD7);
_delay_ms(2000);
PORTD = (0<<PD7);
}
void blinkAll(){
PORTD = (1<<PD6);
_delay_ms(500);
PORTD = (1<<PD5);
_delay_ms(500);
PORTD = (1<<PD7);
_delay_ms(500);
PORTD = (0<<PD6);
PORTD = (0<<PD5);
PORTD = (0<<PD7);
}
void printAllEeprom(){
for(int i=0; i< EEPROM_MAX; i++){
printf("%d ", eeprom_read_byte(i));
if((i+1) % 5 == 0 && i != 1 && i != 0){
printf(" | ");
}
}
}
void printAll(){
for(int i=0; i< cardArraySize; i++){
printf("%d ", cards[i]);
}
}
void clearEeprom(){
for(int i=0; i< EEPROM_MAX; i++){
eeprom_write_byte(i, 255);
}
}
void saveCardToEeprom(int card[12]){
int i=0;
while(eeprom_read_byte(i) != 255){
i++;
}
for(int j=2; j<12; j+=2){
eeprom_write_byte(i, card[j]);
i++;
}
}
int findPosition(int card[12]){
for(int i = 0; i < cardArraySize; i++){
int k=2;
int j;
for(j=0; j < 5; j++){
if(cards[i][j] != card[k]){
break;
}
k+=2;
}
if(j==5){ // vrat poziciu
return i;
}
}
}
void deleteCard(int card[12]){
if(containsCard(card) != 1){ //ak karta nie je zapisana, vyskoc z funkcie (nemame co mazat)
return;
}
int position = findPosition(card);
if(position == 0) //nedovolime vymazat master (prvu)
return;
for(int i=0; i < 5; i++){
cards[position][i] = 255;
eeprom_write_byte((position * 5) + i, 255);
}
}
void saveCard(int card[12]){
if(containsCard(card)){ // ak je karta uz zapisana, pokus sa ju vymazat
deleteCard(card);
saveModePassedSeconds=0;
mode=0;
// blinkAll();
return;
}
int i=0;
cardArraySize+=1;
for(int j=2; j<12; j+=2){ //zapis kartu do pola
cards[cardArraySize][i] = card[j];
// printf("savujem na %d miesto %d ", i, card[j]);
i++;
}
saveCardToEeprom(card); //zapis kartu do eepromu
// blinkAll();
// _delay_ms(1000);
// blinkAll();
cardArraySize+=1;
saveModePassedSeconds=0;
mode=0;
}
void loadCard(int position){
int j=0;
for(int i = position; i < position + 5; i++){
int temp = eeprom_read_byte(i);
if(temp == 255){
cardArraySize--;
break;
}
cards[cardArraySize][j] = temp;
//printf("%d ", cards[cardArraySize][j]);
j++;
}
cardArraySize++;
}
void loadCardsFromEeprom(){
int i=0;
while(i <= 255){
loadCard(i);
i+=5;
}
}
int containsCard(int card[12]){
//printf("card size: %d ", cardArraySize);
for(int i = 0; i < cardArraySize; i++){
int k=2;
int j;
for(j=0; j < 5; j++){
//printf(" porovnanie: %d %d ",cards[i][j],card[k] );
if(cards[i][j] != card[k]){
//printf("vyskakujem z loopu");
break;
}
k+=2;
}
//printf("J: %d ", j);
if(i == 0 && j==5){ //ak sme na prvej karte a vsetkych 5 sa zhodovalo, vrat 2
return 2;
}
if(j == 5){
return 1;
}
}
return 0;
}
Nezabudnite však nahrať aj kompletné zdrojové kódy vášho programu!
Zdrojový kód: Médiá:Zadanie.c serial.h serial.c ubre.c ubre.h