به نام خدا : تو این مطلب پروژه و آموزش آردوینو کار با ماژول rc522 رو میخوام قرار بدم، فقط چون مطلب یکم طولانی هستش زیاد حرف نمیزنم، بریم سراغ مطلبمون :
پروژه و آموزش آردوینو کار با ماژول rc522
شماتیک پروژه : از اینجا تا آخر مطلب هر پروژه ای که دیدید شماتیکش به صورت زیر هستش :
کد زیر رو هم ببینید که ترتیب پایه ها برا میکروهای مختلف توش ذکر شده ( روی دکمه زیر کیک کنید تا اتصالات نمایش داده شود ) :
اولا طبق دیتاشیت ماژول RC522 به کارتهای زیر اصطلاح MIFARE اطلاق میشه.
MIFARE Mini
MIFARE 1K
MIFARE 4K
MIFARE Ultralight
MIFARE DESFire EV1
MIFARE Plus RF
کارتهای مایفر هم کارت هایی حافظه دار هستن.
که مثلا مورد 2 و 3 بالا رو ببینید، میبینید! که کارت اولی حافظش 1کیلو هستش و بعدی 4کیلو!، که من تو پروژه های این مطلب از کارت 1کیلو استفاده کردم(MIFARE Classic 1k)، در زیر جدول تقسیم بندی حافظه این کارت(مایفر 1 کیلو) رو مشاهده میکنید(برای مشاهده شکل مربوط به کارت 4 کیلو که شبیه عکس زیر هستش به دیتاشیتی که ته همین عنوان قرار دادم مراجعه کنید) :
چند تا نکته کوچولو :
- همون طور که میبینید(عکس بالا رو) 16 تا Sector داریم و تو هر Sector هم 4 تا Block داریم و هر Block هم 16 بایت هستش. (16تا سکتور * 4 تا بلوک * 16بایت = 1024 بایت = اندازه حافظه کارت های مایفر 1k)
- در مکان Sector0 و Block0 از حافظه(عکس بالا!) کد کارخانه کارتمون ( UID = کد اختصاصی هر کارت ) قرار داره و این مکان از حافظه رزرو شده هتسش.
- هر Sector هم به وسیله دو کد با نام های keyA و keyB(که هر کدومشون 6 رقمی هستن!) محافظت میشه و این کد در 4 امین Block از هر Sector قرار داره ( و به این بلوک میگن sector trailer )
- هر کدوم از این کلید های امنیتی داخل هر سکتور میتونن کنترل کنن عملیات خوندن و نوشتن داخل اون سکتور رو.
- قبل انجام هر کاری بر روی کارت ابتدا باید کارت انتخاب بشه و بعد اعتبار سازی بشه!
- همون طور که میبیند(عکس بالا رو میگم ^_^) هر بلوک کد دسترسی داره!(اول کد رو وارد میکنی و بعد اطلاعات رو بخونی/مینویسی)
- پسورد پیشفرض تمام Sectorهای کارتها به صورت پیشفرض برابر 0xff هستش.
- تو مطلب نیازتون میشه که آدرس یه بلوک رو به یه تابعی بدید!، حالا داستان آدرس بلوک چیه؟ از سکتور 0 بگیرید تا سکتور 15، حدود 16*4 تا بلوک دارم یعنی 64 تا بلوک، شمارش بوک ها از 0 شروع میشه تا 63، به بلوک 0 سکتور0 آدرس 0 میدن و همین طوری میریم بالا و در آخر به بلوک 3 سکتور 15 آدرسش میشه 63 (تو شکل بالا میبینید که تو هر سکتور شماره بلوک ها از 0 هستش تا 3 !!! )
خب یه سری توضیحات هم هستش برا بحث Access Bits که دیگه دیدم اگه بخوام ادامه بدم توضیحاتش رو اوضاع قاراشمیش میشه لذا گفتم فیلم ضبط کنم، در ضمن در یادگیری موضوع فیلم زیر لینک زیر کمک کرد بهم که طبق حرفم تو فیلم لینکش رو میزارم براتون : تغییر رمز کارت های مایفر
خب اگه دیتاشیت کارتهای MIFARE رو بخونید میبینید که یه کلمه هستش با نام UID که در مکان BLOCK0 و Sector0 حافظه کارت قرار داره و یه شماره اختصاصی هستش.(حالا این که کارتی وجود داره که بشه این شمارش رو تغییر داد من اطلاع ندارم که هستش یا نه و شاید هم همه این کارت های MIFARE رو میشه این شماره اختصاصیش رو تغییر داد و من اطلاع ندارم)
یه ساختاری(struct) داخل کتابخونه تعریف شده که اسم این نوع متغییر Uid هستش و داخل خود کتابخونه این ماژول هم یه متغییر از این نوع با نام uid ساخته که ما تو پروژه هامون از این متغییر استفاده میکنیم.
تعریف این ساختار و متغییر ساخته شده ازش به صورت زیر هستش و بعدش متغییر هایی که داخل ساختار Uid قرار داره و ما به کمک متغییر uid بهشون دسترسی پیدا میکنیم رو توضیح میدم :
1 2 3 4 5 6 7 |
typedef struct { byte size; // Number of bytes in the UID. 4, 7 or 10. byte uidByte[10]; byte sak; // The SAK (Select acknowledge) byte returned from the PICC after successful selection. } Uid; // Member variables Uid uid; |
uidByte : کد اختصاصی کارتمون ( UID ) در این آرایه ذخیره میشه.
sak : چیزی که من فهمیدم و تست کردم و جواب گرفتم اینه که به کمک این متغییر میتونیم مدل کارت رو بفهمیم.(که انواع مدل کارت رو در عنوانی قبلی قرار دادم)، در عناوین بعدی میبینید که از این متغییر برای پیدا کردن مدل کارت استفاده میکنیم.
تو توابع بعدی زیاد با این ساختار و متغییر uid کار داریم.
1 2 3 4 5 |
#include <SPI.h> #include <MFRC522.h> MFRC522 mfrc522(10/*SS_PIN*/, 9/*RST_PIN*/); MFRC522::MIFARE_Key key; MFRC522::StatusCode status; |
خب فراخونی کتابخونه و ساخت اشیای جدید و... که باید در اول پروژه تون قرار بدید.
خط 1و2 : فراخونی کتابخونه های مورد نیاز!
خط 3 : ساخت یه شی با نام mfrc522 از کلاس MFRC522 (این کلاس در داخل فایلی که در خط 2 فراخونی کردیم قرار داره)، پارامتر اول شی برا تعیین پایه SS (یا SCK) ماژول هستش که برای انتخاب ماژول برای ارسال و دریافت به کار میره، مربوط میشه به بحث SPI، که برای این که میکرو بتونه از طریق SPI با چندین قطعه ارتباط برقرار کنه یه پایه گزاشت با این نام برای این که میکرو اون قطعه رو به کمک این پایه انتخاب کنه و باهاش تبادل دیتا داشته باشه، خواستین میتونید مطلب زیر رو بخونید :
آموزش جامع آردوینو جلسه ۱۴ SPI AND Virtual SPI
پارامتر دوم این شی هم برا تعیین پایه Reset (یا RST) ماژول هستش.
خط 4و5 : بعد از خوندن مطلب زیر متوجه میشید این دو خط چی هستن، در مورد کارشون هم اینو فقط میگم که خط 4 یه نوع متغییر برای ذخیره کردن کد امنیتی 6 رقمی و خط 5 یه نوع متغییر برای ذخیره کردن خروجی توابع(که به کمکش میفهمیم تابع کارش رو درست انجام داده یا غلط و اگه انجام نداده علتش چی بوده): آموزش کامل typedef و struct
1 2 |
SPI.begin(); mfrc522.PCD_Init(); |
خب برای هر کتابخونه ای یه همچین توابعی هستش که با فراخونیشون اون کتابخونه راه اندازی میشه، کلا کار این تابع ها مقدار دهی اولیه یه سری مقادیر ظرروی اون کتابخونه هستش.(خط 1 برای کتابخونهه SPI و خط 2 برای کتابخونه MFRC522 هستش.)
1 |
bool PICC_IsNewCardPresent(); |
اگه کارتی( tag ) به ماژول ( RFID -RC522 ) نزدیک بشه این تابع مقدار 1 رو بر میگردونه در غیر این صورت مقدار 0 رو برمیگردونه.
1 |
bool PICC_ReadCardSerial(); |
این تابع کارش خوندن دیتای داخل کارت هستش - اگه نتونه بخونه مقدار 0 و در صورت موفق بودن کار عدد 1 رو برمیگردونه.
توجه 0 (مهم) : همون طور که تو نکته 5 از عنوان "توضیحات کوچولویی درباره کارت های MIFARE" خدمتتون عرض کردم، اول باید کارت انتخاب بشه، حالا اگه کدهای داخل این تابع رو نگاه کرده باشید میبینید که درش از تابع PICC_Select استفاده شده، یعنی این تابع کارش هم خوندن اطلاعات کارت هستش و هم انتخاب کارت، ما با تابع PICC_Select کاری نداریم اصلا، و از همین تابعی که این جا میبینید استفاده میکنیم، اینم گفتم تا یه وقت نگید داش شما گفتی کارت باس انتخاب بشه و از این جور حرفا، پس کجاس تابعش و ما باید چطور کارت رو انتخاب کنیم و ...، پس این تابع هم اطلاعات کارت رو میخونه و هم کارت رو انتخاب میکنه(البته این تابع هم چیز خاصی نداره و همش 2-3 خط هستش.)
توجه 1 : بعد از این که به کمک تابع PICC_IsNewCardPresent فهمیدیم کارتی به ماژول نزدیک شده، از این تابع برای خودندن اطلاعات کارت استفاده میکنیم.
توجه 2 : این تابعی اطلاعی نشون نمیده و چیزی به ما نمیده، در ادامه میبینید که چطور به اطلاعات دریافت شده توسط این تابع دسترسی پیدا میکنیم.(در قسمت مربوط به عنوان uid توضیح میدم)
1 |
void PCD_DumpVersionToSerial(); |
نمایش نسخه Firmware ماژول (همون نمایش نسخه ماژول ^_^) در پنجره سریال
توجه : اینو همینجا میگم دیگه برای توابع مثل این دیگه نمیگم، این توابعی که اطلاعاتشون رو تو پنجره سریال(پورت سریال یا هر چی اسمش رو میزارید) باید برای استفاده از این توابع، قبلش تابع Serial.begin رو در تابع Setup قرار داده باشین تا پورت سریال فعال بشه، اگه در این باره چیزی نمیدونید مطالب زیر رو بخونید :
آموزش جامع آردوینو جلسه 4
آموزش جامع آردوینو جلسه 5
آموزش جامع آردوینو جلسه 6
این تابع جوابی به فرم زیر تو پنجره سریال نمایش میده ( که بسته به نسخه ماژولتون داره ) :
Firmware Version: 0x92 = v2.0
1 2 |
PICC_Type PICC_GetType(byte sak); const __FlashStringHelper *PICC_GetTypeName(PICC_Type type); |
1 2 |
MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak); Serial.println(mfrc522.PICC_GetTypeName(piccType)); |
PICC type: MIFARE 1KB
1 |
void PICC_DumpToSerial(Uid *uid); |
جواب1 : سوال خوبی بود ولی چرا میزنی حالا
خب ببیند تو این تابع فرض بر این هستش که رمز تمام سکتور ها برابر مقدار پیشفرض یعنی 0xff هستش ولی اگه رمز رو تغییر بدید دیگه این تابع به کارتون نمیخوره(البته اون موقع بازم میشه ازش استفاده کرد اونم تو نقش جرز لای در
سوال2 : خب حالا ما اومدیم و رمز رو تغییر دادم، حالا تابعی وجود داره که بشه رمز جدید رو بهش داد و به کمکش کل اطلاع کارت رو تو پنجره سریال نمایش داد؟
جواب2 : آراه داش هستش، تو عنوان بعدی قرارش میدم.
1 |
mfrc522.PICC_DumpToSerial(&mfrc522.uid); |
جواب1 : خب اگه شما عنوان "فراخونی کتابخونه و ساخت اشیای جدید و..." که در اوایل این مطلب من گزاشتم رو بری ببینی و خط 3 کدهای اون قسمت رو ببینی، میبینی! که من یه شی با نام mfrc522 از کلاس MFRC522 ساختم و برای دسترسی به توابع و متغییر های public یه کلاس، و برا این کار نام شی یی که ساختم رو مینویسم و بعدی نقطه میزارم و بعدش تابع یا متغییر مد نظرم رو فرا می خونم.
سوال2 : حالا mfrc522.uid& از کجا اومد؟؟؟
جواب2 : خب گفتم دیگه، mfrc522 یه شی از کلاس MFRC522 هستش و uid یه متغییر هستش که داخل کلاس فوق قرار داره و ما به کمک شی ساخته شده بهش دسترسی پیدا میکنیم(توابع جلوی اسمشون پرانتز دارن ولی متغییر ها نه ^_^) و کاراکتر & هم که میدونید برا بحث آدرس به کار میره، الان تو کد بالا من اومدم و آدرس متغییر mfrc522.uid رو به تابع PICC_DumpToSerial دادم.
سوال3 : حالا متغییر uid چیه اصلا؟
جواب3 : برو عناوین بالا رو بخون، اول مطلب کامل توضیح دادم این متغییر رو *_*
1 |
void PICC_DumpMifareClassicToSerial(Uid *uid, PICC_Type piccType, MIFARE_Key *key); |
جواب : تو هم گیر دادی هاااا
1 |
void PICC_DumpMifareClassicSectorToSerial(Uid *uid, MIFARE_Key *key, byte sector); |
uid : اطلاعات کارت سنس شده.
key : کد دسترسی به این سکتور.
sector : سکتور مد نظرتون.
این تابع رو میتونید به صورت زیر استفاده کنید(کد زیر قسمتی از پروژه ای هستش که تو عنوان بعدی یا بعدیش یا بعدیهاش ^_^ قرار میدم)
1 2 3 4 5 6 |
// نمایش سکستور به سکتور اطلاعات کارت سنس شده for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF; Serial.println(F("Sector Block 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 AccessBits")); for (int8_t i = 16 - 1; i >= 0; i--) mfrc522.PICC_DumpMifareClassicSectorToSerial(&mfrc522.uid, &key, i); mfrc522.PICC_HaltA(); // Halt the PICC before stopping the encrypted session. mfrc522.PCD_StopCrypto1(); |
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 |
#include <SPI.h> #include <MFRC522.h> MFRC522 mfrc522(10/*SS_PIN*/, 9/*RST_PIN*/); MFRC522::MIFARE_Key key; MFRC522::StatusCode status; void setup() { Serial.begin(115200); SPI.begin(); mfrc522.PCD_Init(); } void loop() { up: if ( mfrc522.PICC_IsNewCardPresent()) { if ( ! mfrc522.PICC_ReadCardSerial()) { Serial.print("Data Read Fail"); goto up; } // نمایش ورژن ماژول mfrc522.PCD_DumpVersionToSerial(); // نمایش مدل کارت Serial.print("PICC type: "); MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak); Serial.println(mfrc522.PICC_GetTypeName(piccType)); // نمایش کد اختصاصی کارت Serial.print("Card UID:"); dump_byte_array(mfrc522.uid.uidByte ,mfrc522.uid.size); Serial.print("\n\n\n"); // نمایش تمام اطلاعات کارت به کمک پسورد پیشفرض Serial.println("PICC_DumpToSerial"); mfrc522.PICC_DumpToSerial(&mfrc522.uid); Serial.print("\n\n\n"); // نمایش سکستور به سکتور اطلاعات کارت سنس شده for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF; Serial.println(F("Sector Block 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 AccessBits")); for (int8_t i = 16 - 1; i >= 0; i--) mfrc522.PICC_DumpMifareClassicSectorToSerial(&mfrc522.uid, &key, i); mfrc522.PICC_HaltA(); // Halt the PICC before stopping the encrypted session. mfrc522.PCD_StopCrypto1(); } } void dump_byte_array(byte *buffer, byte bufferSize) { for (byte i = 0; i < bufferSize; i++) { Serial.print(buffer[i] < 0x10 ? " 0" : " "); Serial.print(buffer[i], HEX); } } |
پروژه ماژول RC522 با آردوینو
تو این پروژه شماره اختصاصی هر کارت(UID) رو میخونم و اگه در میکرو وجود داشت تو پنجره سریال مینویسم کارت وجود داره در غیر این صورت مینویسم وجود نداره، یه پروژه ساده.
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 |
#include <SPI.h> #include <MFRC522.h> MFRC522 rfid(10/*SS_PIN*/, 9/*RST_PIN*/); MFRC522::MIFARE_Key key; byte ListMyTag[10][4] = { {}, { 107, 104, 15, 43 }, { 70, 27, 235, 72 }, { 109, 131, 58, 213 }, { 87, 84, 58, 213 }, { 23, 222, 58, 213 }, { 183, 161, 58, 213 } }; unsigned char NumberCard; void setup() { Serial.begin(9600); SPI.begin(); rfid.PCD_Init(); } void loop() { if ( ! rfid.PICC_IsNewCardPresent()) return; if ( ! rfid.PICC_ReadCardSerial()) return; Serial.print("The NUID tag = "); dump_byte_array(rfid.uid.uidByte, rfid.uid.size); Serial.print(" ---> "); NumberCard = BarresiVejodeKart(rfid.uid.uidByte) ; if(NumberCard) Serial.println((String)"Card " + NumberCard); else Serial.println(F("Card Vejod Nadarad Dar Hafeze.")); rfid.PICC_HaltA(); // Halt PICC rfid.PCD_StopCrypto1(); // Stop encryption on PCD } void dump_byte_array(byte *buffer, byte bufferSize) { for (byte i = 0; i < bufferSize; i++) { Serial.print(buffer[i] < 0x10 ? " 0" : " "); Serial.print(buffer[i], HEX); } } unsigned char BarresiVejodeKart(byte* YourCard) { for(int i=1; ListMyTag[i][0]!='\0'; i++) { if( YourCard[0] == ListMyTag[i][0] && YourCard[1] == ListMyTag[i][1] && YourCard[2] == ListMyTag[i][2] && YourCard[3] == ListMyTag[i][3] ) return i; } return 0; } |
اینم از جواب پروژه که من با 10 تا کارت تست کردم، 6 تا از کارت ها رو تو میکرو کدشون رو ذخیره کردم و 4 تا رو نه و نتیجه رو در زیر میبینید که پروژه درست کار کرده.
The NUID tag = 6B 68 0F 2B ---> Card 1
The NUID tag = 46 1B EB 48 ---> Card 2
The NUID tag = B7 A1 3A D5 ---> Card 6
The NUID tag = 17 DE 3A D5 ---> Card 5
The NUID tag = 57 54 3A D5 ---> Card 4
The NUID tag = 6D 83 3A D5 ---> Card 3
The NUID tag = D6 88 DA 5D ---> Card Vejod Nadarad Dar Hafeze.
The NUID tag = 46 50 4F 5E ---> Card Vejod Nadarad Dar Hafeze.
The NUID tag = 16 66 2F 5E ---> Card Vejod Nadarad Dar Hafeze.
The NUID tag = 76 89 48 5E ---> Card Vejod Nadarad Dar Hafeze.
فعلا همین دو تا پروژه کافیه تا اینجای مطلب، بقیه پروژه ها بمونه برا بعد، فعلا چند تا دیگه تابع توضیح بدم و بعد برا اون توابع هم مثال قرار میدم.
1 2 |
void PCD_AntennaOn(); void PCD_AntennaOff(); |
1 |
void PCD_Reset(); |
از اسمش معلومه کارش چیه ولی فک نکنم بکارتون بیاد
1 |
bool PCD_PerformSelfTest(); |
بررسی این که ماژول سالمه یا نه - اگه سالم بود عدد 1 وگرنه 0 رو برمیگردونه.
اگه دیتاشیت ماژول قسمت 16.1.1 رو بخونید، میبینید که ماژول یه ویژگی داره به نام Self test که یه سری مراحل داره ولی چون ما از کتابخونه آماده استفاده میکینم دیگه لازم نیست اون مراجل رو انجام بدیم ولی اگه دوست داشتین میتونید به کتابخونه این ماژول مراجعه کنید و ببنید کدهاش رو و ساختار این تابع رو ببینید.
1 |
const __FlashStringHelper *GetStatusCodeName(StatusCode code); |
خب تو این مطلب بعضی توابع خروجیشون به صورت StatusCode هستش، که شما اون متغییر (از نوع ساختار) status که تو قسمت "فراخونی کتابخونه و ساخت اشیای جدید و..." دیدید که من بعد از فراخونی کتابخونه ها این کد رو تو پروژه اضافه کردم، خب میگفتم اون توابعی که خروجیشون به صورت StatusCode هستش رو مقدار اون تابع رو میدیم به متغییر status و حالا برای این که status رو ببینم پیغامش چیه، از این تابعی که میبینید استفاده میکنیم، و این تابع معنای مقدار ذخیره شده داخل status رو به صورت یه رشته به ما میده.(چقدر پیچوندم، لپ کلوم : status به این تابع میدی و معنای اون مقدار ذخیره شده تو status رو به صورت رشته دریافت میکنی، وسلام!)
حالا تعداد حالاتی که بایت تست کنیم تا پسورد یه سکتور رو به دست بیاریم میشه :
6 ^ 256 = 281474976710656
حالا فرض کنیم تست هر 10 تا پسورد 1 ثانیه طول میکشه، برای به دست ابردن پسورد یه سکتور باید زمان زیر رو صرف کرد :
281474976710656 / 10 = 28147497671065.6 Sec
28147497671065.6 / 60 = 469124961184.4 Min
469124961184.4 / 60 = 7818749353.0 Hour
7818749353.0 / 24 = 325781223.0 Day
325781223.0 / 365 = 21421231.1 Year
تازه این برای یک سکتور از 16 سکتور هستش، یعنی عملا هک کردن ماژول فایده ای نداره.
هر چی فک میکنم محاسبات بالا درست هستش، اگه اشتباهی رخ داده بگید.
من الان از تابع هک کردن استفاده کردم برای پیدا کردن پسورد سکتور 2 یکی از کارت هام، حدود 37120 قدر پسورد رو تو مدت 45 دقیقه میکرو تست کرده و هنوز پسورد رو پیدا نکرده
نکته اخلاقی : خب حتما فک کردین میخوام الان بگم که نرین سراغ هک کردن این کارت ها و از این جور حرفا، نه اینو نمیخوام بگم چون میدونم نمیتونید(البته کار نشد نداره ) میخوام بگم که بالام جان حواست باشه پسورد رو عوض میکنی، فراموشش نکنی اون پسورد رو که عین من بدبخت میشی، الان منم زدم پسورد یکی از سکتورها رو تغییر دادم و هر چی تلاش میکنم پیدا نمیکنم پسوردش رو، یعنی عملا دیگه اون کارته بدرد نمیخوره.
1 |
StatusCode PCD_Authenticate(byte command, byte blockAddr, MIFARE_Key *key, Uid *uid); |
خب همون طور که تو نکته 5 عنوان " توضیحات کوچولویی درباره کارت های MIFARE " گفتم(و عمرا یادتون باشه ) : قبل از خوندن باید عملیات اعتار سازی رو انجام بدید و بعد هر بلایی که دوس داشتین سر کارت بیارین(خواستین اطلاعاتش رو بخونید یا روش بنویسید) و در آخر هم باید عملیات رو پایان بدید که این پایان دادن به وسیله دو تا تابع انجام میشه که در عنوان بعدی توضیحشون میدم و بعدش میرم سراغ خوندن و نوشتن و بعدش یه چند تا پروژه مشتی
خب حالا چون که من میدونم شما خیلی ذهتون کنجکاو هستش و اهل سوال پرسیدن هستید(که عمرا نیستید ^_^) میخوام دو تا پارامتر اول تابع بالا رو توضیح بدم، بقیه پارامترهاش رو هم تا الان صد بار دیدم این جور پارامتر ها رو :
command : خب تو این جا میگیم که عملیات اعتبار سازی به وسیله KeyA انجام بشه یا KeyB، برای این کار دو تا متغییر(از نوع enum) داریم به صورت زیر که از اسمشون معلومه که کدوم برا KeyA و کدوم برا KeyB هستش.
PICC_CMD_MF_AUTH_KEY_A
PICC_CMD_MF_AUTH_KEY_B
blockAddr : خب تو هر سکتوری یه 4 تا بوک هستش و یکی از این بلوک ها محل ذخیره سازی پسوردها هستش(آخرین بلوک هر سکتور) و ما آدرس این بلوک رو به تابع میدیم.(نام این بلوک هم trailer Block یا sector trailer هستش!!! کلا مهم اینه که تو اسمش trailer داره )
1 2 |
mfrc522.PICC_HaltA(); mfrc522.PCD_StopCrypto1(); |
بعد از این که اعتار سنجی کردیم و کارتمون رو خوندیم/نوشتیم حالا باید به ارتباط پایان بدیم(بهترین جمله ای که پیدا کردم همین بود!) و برای این کار باید بعد از اتمام کارمون با کارت، این دو تابع رو فراخونی کنیم.
1 |
StatusCode MIFARE_Read(byte blockAddr, byte *buffer, byte *bufferSize); |
به کمک این تابع میتونیم اطلاعات یه بلوک از حافظه کارتمون رو بخونیم.
blockAddr : خب همون طور که تو نکته8 عنوان "توضیحات کوچولویی درباره کارت های MIFARE" گفتم، آدرس بلوک ها از 0 شروع میشه تا 63 (برای کارتهای 1کیلو کلاسیک)، آدرس بلوکی که میخوای بخونیش رو اینجا قرار میدی.
buffer : یه آرایه با حداقل اندازه 18 به این تابع میدی تا اطلاعات خونده شده توسط تابع داخل این تابع ذخیره بشه و بعد ما این تابع رو میخونیم.
bufferSize : خب از اسمش معلومه، اندازه آرایه buffer هستش.
توضیحات بیشتر و مثال بمونه برا پروژه ای که در ادامه میزارم.
1 |
StatusCode MIFARE_Write(byte blockAddr, byte *buffer, byte bufferSize); |
خب اینم که از اسمش معلومه برا نوشتن اطلاعات یه بلوک به کار میره، که به کمک blockAddr میایم و آدرس بلوکی که میخوایم توش دیتا بنویسیم رو به تابع میدیم، به کمک buffer اطلاعاتی که میخوایم تو اون بلوک نوشته بشه رو تعیین میکنیم، bufferSize هم که بیانگر اندازه buffer هستش.
توضیحات بیشتر و مثال در عنوان بعدِ بعدی!
1 2 3 4 5 6 7 8 9 10 11 |
enum StatusCode { STATUS_OK , // Success STATUS_ERROR , // Error in communication STATUS_COLLISION , // Collission detected STATUS_TIMEOUT , // Timeout in communication. STATUS_NO_ROOM , // A buffer is not big enough. STATUS_INTERNAL_ERROR , // Internal error in the code. Should not happen ;-) STATUS_INVALID , // Invalid argument. STATUS_CRC_WRONG , // The CRC_A does not match STATUS_MIFARE_NACK = 255 // A MIFARE PICC responded with NAK. }; |
خب همون طور که تا حالا دیدید خروجی بعضی توابع به صورت StatusCode هستش که اون تابع یه مقداری از مقادیر بالا رو برای ما ارسال میکنه، در ادامه مطلب و پروژه ها ما بیشتر کارمون با STATUS_OK هستش و میخوایم بررسی کنیم که تابع مد نظر کارش رو درست انجام داده یا نه، برا این کار میایم میبینیم که مقداری که اون تابع به ما داده اگه برابر با STATUS_OK بود که یعنی تابع کارش رو درست انجام داده، در غیر این صورت میفهمیم که تابع کارش رو درست انجام نداده و لذا دیگه بقیه عملیات رو متوقف میکنیم، در زیر یه مثال میزنم :
در پروژه ای که در عنوان بعدی میخوام بزارم، اول میام اعتبار سازی میکنم و بعد میام اطلاعات رو میخونم، خب بعد از اعتبار سازی میام بررسی میکنم که آیا این عملیات اعتبار سازی موفقیت آمیز بوده یا نه، اگه بود که میرم سراغ تابع خوندن و اگه نبود که از تابع خوندن هم دیگه خبری نیست و کدهاش اجرا نمیشه.
خب الان شما فقط باس بررسی کنید که که تابع مقدار STATUS_OK رو بر میگردونه یا نه، فقط همین، با بقیه مقادیر ساختار بالا هم کاری نداشته باشید که چی هستن و کارشون چیه و ...
پروژه آردوینو RC522 خواندن و نوشتن اطلاعات کارت
توضیح کلی پروژه : خب تو این پروژه ما اطلاع بلوک به آدرس 2 رو میخونیم و بعد تو اون بلوک اطلاعاتمون رو مینویسیم و بعد دوباره مقدار اون بلوک رو میخونیم تا نشون بدیم به شما که اطلاعات اون بلوک (به درستی) ویرایش شدن؛ این پروژه هم جزو پروژه های نمونه خود این کتابخونه RC522 هستش فقط من یکمکی 😀 تغییرش دادم.
توضیح بیشتر پروژه :
خط 1تا5 : خب این خط ها رو اگه تا اینجای مطلب متوجه نشدید کارشون چیه، دیگه ادامه مطلبو اصلا نخونید.
خط 9تا13 : داخل کدها توضیح خط به خط دادم!
خط 21 : خب تو این جا فرض اینه که شما یه کارت جدید دارین و پسورد و سطح دسترسیش رو تغییر ندادید.(فعلا این پروژه ساده رو ببینید، تو پروژه های بعدی میریم سراغ کارت هایی که پسورد و سطح دسترسیشون رو تغییر دادیم)، الان تو این سطح دسترسی و پسوردی که این کارت های تازه دارن، میتونیم پسورد 0XFFFFFFFFFFFF رو به هر کلید امنیتی(A یا B) بدیم و اطلاعات بلوک ها رو بخونیم یا تغییر بدیم.(الان این پسوردی که تو این خط تعیین کردم برا هر دو کلید A و B هستش ولی همیشه این طور نیست، ممکنه بعضا کلید A با B فرق داشته باشه و کلید هر سکتور هم با سکتور های دیگه برابر نباشه و سطح دسترسی بوک ها هم با هم فرق داشته باشه، لذا همیشه به این سادگی نیست که اول پروژه یه کلید تعریف کنید و دیگه تموم! فعلا چون اول کار هستش پروژه ساده گزاشتیم، تو پروژه های بعدی انشاالله تمام حالت ها رو در حد توان با هم میبینیم و بررسی میکنیم ---> گامس گاماس )
خطوط 32تا57 : تو این خطوط با استفاده از کلید A اول میام عملیات "اعتبار سنجی" رو انجام میدم و در صورت موفق بودن بعدش میرم سراغ خوندن بلوک مد نظرم.
خطوط 65تا101 : تو این خطوط هم با کلید B بعد اعتبار سنجی و موفق بودنش میام تو بلوک مد نظرم اطلاعات مد نظرم رو مینویسم و بعد میام همون بلوک رو میخونم.
دیدید پروژه چقدر آسون بود و چیزی نداشت
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 |
#include <SPI.h> #include <MFRC522.h> MFRC522 mfrc522(10/*SS_PIN*/, 9/*RST_PIN*/); MFRC522::MIFARE_Key key; MFRC522::StatusCode status; byte blockAddr = 2; // آدرس بلوکی که میخوایم اطلاعاتش رو بخونیم و بنویسیم اطلاعاتمون رو داخلش byte trailerBlock = 3; // اینم بلوک تریلر و هم سکتوری! بلوک به آدرس بالا byte dataBlock[] = { 0x13, 0x73, 0x5, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }; // اطلاعاتی که میخوایم بنویسیم در بلوک مد نظرمون byte buffer[18]; // اطلاعات خونده شده از بلوک مد نظرمون داخل این آرایه ذخیره میشه byte size = sizeof(buffer); // اندازه آرایه بالا void setup() { Serial.begin(9600); SPI.begin(); mfrc522.PCD_Init(); for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF; } void loop() { if ( ! mfrc522.PICC_IsNewCardPresent()) return; if ( ! mfrc522.PICC_ReadCardSerial()) return; // Authenticate using key A Serial.println("Authenticating using key A..."); status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(mfrc522.uid)); if (status == MFRC522::STATUS_OK) { Serial.println("Authenticating using key A is Successful"); // Read data from the block Serial.println((String)"Reading data from block " + blockAddr + (String)" ..."); status = mfrc522.MIFARE_Read(blockAddr, buffer, &size); if (status == MFRC522::STATUS_OK) { Serial.println("Reading Successful"); Serial.print((String)"Data in block " + blockAddr + (String)":"); dump_byte_array(buffer, 16); Serial.print("\n\n\n"); } else { Serial.print("Reading Failed : "); Serial.println(mfrc522.GetStatusCodeName(status)); } } else { Serial.print("Authenticating using key A is Failed : "); Serial.println(mfrc522.GetStatusCodeName(status)); } Serial.print("\n\n\n\n\n\n"); // Authenticate using key B Serial.println("Authenticating again using key B..."); status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_B, trailerBlock, &key, &(mfrc522.uid)); if (status == MFRC522::STATUS_OK) { Serial.println("Authenticating using key B is Successful"); // Write data to the block Serial.println((String)"Writing data to block " + blockAddr + (String)" ..."); status = mfrc522.MIFARE_Write(blockAddr, dataBlock, 16); if (status == MFRC522::STATUS_OK) { Serial.println("Writing Successful"); } else { Serial.print("Writing Failed : "); Serial.println(mfrc522.GetStatusCodeName(status)); } // Read data from the block (again, should now be what we have written) Serial.println((String)"Reading data from block " + blockAddr + (String)" ..."); status = mfrc522.MIFARE_Read(blockAddr, buffer, &size); if (status == MFRC522::STATUS_OK) { Serial.println("Reading Successful"); Serial.print((String)"Data in block " + blockAddr + (String)":"); dump_byte_array(buffer, 16); Serial.println(); } else { Serial.print(F("MIFARE_Read() failed: ")); Serial.println(mfrc522.GetStatusCodeName(status)); } } else { Serial.print("Authenticating using key B is Failed : "); Serial.println(mfrc522.GetStatusCodeName(status)); } mfrc522.PICC_HaltA(); mfrc522.PCD_StopCrypto1(); } void dump_byte_array(byte *buffer, byte bufferSize) { for (byte i = 0; i < bufferSize; i++) { Serial.print(buffer[i] < 0x10 ? " 0" : " "); Serial.print(buffer[i], HEX); } } |
1 |
void MIFARE_SetAccessBits(byte *accessBitBuffer, byte g0, byte g1, byte g2, byte g3); |
همون طور که تو فیلم اول مطلب توضیح دادم، با تجوه به 2-3 تا جدول توی دیتاشیت، میتونیم سطح دسترسی رو تعیین کنیم، به این تابع یه سری دیتا میدیم و این تابع 3بایت موردنیاز برای دادن به بیت های Access Bits رو به ما میده!(عمرا کسی فهمیده باشه!)
accessBitBuffer : آرایه ای که به تابع میدیم و تابع 3 بیت مورد نیاز ما رو داخل این تابع ذخیره میکنه و ما هم این 3 بیت رو در بلوک مد نظرمون در قسمت اکسس بیت مینویسیم!
g0,g1,g2,g3 : خب این 4 تا متغییر از نوع byte هر کدوم برا یه بلوک هستن، مثلا g0 برا بلوک 0 و به همین ترتیب g3 برای بلوک3، حالا این متغییر ها چی هستن و ما باید چی چی به جای این متغییر ها قرار بدیم و از این جور حرفا، که در زیر توضیح میدم :
همون طور که در عکس زیر میبینید، برای بلوک های دیتا و Trailer جدول هایی داریم که میتونیم سطح دسترسی مد نظرمون رو به کمکشون انتخاب کنیم، حالا مثلا ما مقادیر C1تاC3 رو برای 4 بلوکمون به صورت زیر برا بر نیازمون انتخاب کردیم :
Block0 : C1=0, C2=0, C3=0 ----> g0=?
Block1 : C1=1, C2=1, C3=0 ----> g1=?
Block2 : C1=1, C2=0, C3=1 ----> g2=?
Block3 : C1=0, C2=0, C3=1 ----> g3=?
حالا شما C3 رو بیت0، C2 رو بیت1 و C1 رو بیت2 در نظر بگیرید لذا مقادیر gها به صورت زیر میشه.
g0=0, g1=6, g2=5, g3=1
حالا این gها رو ما به تابع بالا میدیم و یه آرایه به اندازه 3 خونه به تابع میدیم و کدهای مورد نیاز رو تابع بالا داخل آرایه میریزه و ما ازش استفاده میکنیم.
جواب : خب همون طور که شکل زیر رو میبینید مربوطه به بلوک Trailer که 6تا بایت اول پسA و 4تا وسطی مربوط به Access Bit و 6تای آخر هم مربوط به پسB هستش، بیت 4ام اکسس بیت که سرکاری هستش و مقدارش مهم نیست، الان ما 3بیت اصلی Access Bit که بیت های 6و7و8 هستش رو داریم، میمونه KeyA و KeyB که این دو مورد رو هم باس داشته باشیم!
و بعد یه آرایه 16 تایی ایجاد میکنیم و پسAوB و اکسس بیت ها رو میریزیم داخلش و بعد این آرایه رو داخل این بلوک مینویسیم، این طوری سطح دسرسی بلوک های 0تا3 رو تعیین کردیم و پسورد هم امکان داره تغییر کنه(بستگی به این داره که در چه مدی هستید و آیا میتونید پس رو تغییر بدید یا نه و این که پسورد جدید وارد کردید یا نه، اگه همون پسورد قبلی رو وارد کرده باشید که پسورد هم تغییر نمیکنه و فقط سطح دسترسی ها رو تغییر دادید.)
1 2 |
StatusCode MIFARE_GetValue(byte blockAddr, long *value); StatusCode MIFARE_SetValue(byte blockAddr, long value); |
قبل از این که این تابع رو فراخونی بکنید باید بلوک اعتبار سازی بشه(که تابعش رو دربالا براتون گزاشتم قبلا!)
حالا این دو تابع کارشون چیه؟ البته از اسمشون معلومه ولی خب در زیر بازم توضیح میدم :
MIFARE_GetValue : خوندن مقدار بلوک blockAddr و ذخیره مقدارش در متغییر value
MIFARE_SetValue : نوشتن متغییر value در بلوک blockAddr
جواب : خب سوال خوبی هستش، ببینید تو دو تابعی که گفتی ما مقدار Hex تک تک خونه ها رو مینویسیم و میخونیم، ولی تو این دو تا تابعی که الان معرفی کردم مقادیر رو به صورت یه متغییر عددی میخونید و مینویسید، مثلا فک کنید کارت های مترو، یه قسمت این کارت ها مقدار هزینه کارت رو ذخیره میکنه، خب حالا این آقا رفته تو مترو و کارتش رو زده به دستگاه، حالا باید یه پولی از اون کارت کم بشه دیگه، برای این کم کردن میتونیم مقدار پول اون کارت رو به کمک MIFARE_GetValue بخونیم و بعد یه چیزی ازش کنم کنیم و مقدار جدید رو به کمک MIFARE_SetValue بنوسیم تو اون بلوک از حافظه کارت، حالا شاید بازم براتون سوال بشه که خب این کارا رو هم با اون دو تا تابعی که قبلا باهاش آشنا شدیم هم میشه کرد، جواب اینه که آره میشه ولی خب این دو مورد یکم کار رو ساده کردن، البته برا بحث این کارت های مترو، دو تا تابع بعدی رو هم بخونید و یه توضیح کامل تری دربارشون میدم.
1 2 3 4 |
StatusCode MIFARE_Decrement(byte blockAddr, long delta); StatusCode MIFARE_Increment(byte blockAddr, long delta); StatusCode MIFARE_Restore(byte blockAddr); StatusCode MIFARE_Transfer(byte blockAddr); |
این دو تابع هم شبیه دو تابع بالا هستا تقریبا، باید قبل از استفاده ازشون عملیات اعتبار سازی رو انجام بدید، باید مد دسترسی بلوک های دیتا(که میخواید برا اون بلوک ها از این دو تابع استفاده کنید) رو رو حالت Value Block بزارید.
MIFARE_Decrement : بلوک به آدرس blockAddr ، مقدارش رو به اندازه delta قدر کاهش میده.
MIFARE_Increment : بلوک به آدرس blockAddr ، مقدارش رو به اندازه delta قدر افزایش میده.
مثال : مثلا همون کارت های مترو، طرف کارتش رو میزنه به دستگاه و الان باید یه مقدار پولی از کارتش کم بشه، به کمک تابع MIFARE_Decrement میشه این کارو کرد، یا مثلا طرف میره کارتش رو شارژ کنه، به کمک تابع MIFARE_Increment میشه این کارو کرد و برا خوندن مقدار پول کارت میتونیم از تابع MIFARE_GetValue استفاده کنیم.
MIFARE_Transfer : خب حالا بعد از این که از توابع بالا استفاده کردید باید برای اعمال تغییرات این تابع رو فراخونی بکنید.
MIFARE_Restore : این تابع رو هم من هر چی تست کردم ازش جواب نگرفتم، کسی اگه جواب گرفته بگه.
تو خطوط 20تا30 هم اومدم سطح دسترسی رو تعیین کردم، شما فقط یک بار از این تابع برای هر کارت استفاده کنید و در دفعات بعدی این کد رو از پروژه حذف کنید(به حالت توضیحات در بیارید.)
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 |
#include <SPI.h> #include <MFRC522.h> MFRC522 mfrc522(10/*SS_PIN*/, 9/*RST_PIN*/); MFRC522::MIFARE_Key key; MFRC522::StatusCode status; byte sector = 1; byte valueBlockA = 5; byte trailerBlock = 7; long value; long Number = 0; void setup() { Serial.begin(9600); SPI.begin(); mfrc522.PCD_Init(); for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF; byte trailerBuffer[] = { 255, 255, 255, 255, 255, 255, // Keep default key A 0, 0, 0, 0, 255, 255, 255, 255, 255, 255 // Keep default key B }; mfrc522.MIFARE_SetAccessBits(&trailerBuffer[6], 0, 6, 6, 3); status = mfrc522.MIFARE_Write(trailerBlock, trailerBuffer, 16); if (status != MFRC522::STATUS_OK) { Serial.println(mfrc522.GetStatusCodeName(status)); } } void loop() { if ( ! mfrc522.PICC_IsNewCardPresent()) return; if ( ! mfrc522.PICC_ReadCardSerial()) return; status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_B, trailerBlock, &key, &(mfrc522.uid)); if (status != MFRC522::STATUS_OK) { Serial.println((String)"AuthenticateB Failed: " + mfrc522.GetStatusCodeName(status)); return; } status = mfrc522.MIFARE_SetValue(valueBlockA, Number); if (status != MFRC522::STATUS_OK) { Serial.println((String)"SetValue Failed: " + mfrc522.GetStatusCodeName(status)); return; } status = mfrc522.MIFARE_GetValue(valueBlockA, &value); if (status != MFRC522::STATUS_OK) { Serial.println((String)"GetValue Failed: " + mfrc522.GetStatusCodeName(status)); return; } Serial.println((String)"New value of value block " + valueBlockA + (String)" = " + value); Number += 1000; // Dump the sector data mfrc522.PICC_DumpMifareClassicSectorToSerial(&(mfrc522.uid), &key, sector); Serial.println(); mfrc522.PICC_HaltA(); mfrc522.PCD_StopCrypto1(); } void dump_byte_array(byte *buffer, byte bufferSize) { for (byte i = 0; i < bufferSize; i++) { Serial.print(buffer[i] < 0x10 ? " 0" : " "); Serial.print(buffer[i], HEX); } } |
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 |
#include <SPI.h> #include <MFRC522.h> MFRC522 mfrc522(10/*SS_PIN*/, 9/*RST_PIN*/); MFRC522::MIFARE_Key key; MFRC522::StatusCode status; byte sector = 1; byte valueBlockA = 5; byte trailerBlock = 7; long value; void setup() { Serial.begin(9600); SPI.begin(); mfrc522.PCD_Init(); for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF; byte trailerBuffer[] = { 255, 255, 255, 255, 255, 255, // Keep default key A 0, 0, 0, 0, 255, 255, 255, 255, 255, 255 // Keep default key B }; mfrc522.MIFARE_SetAccessBits(&trailerBuffer[6], 0, 6, 6, 3); status = mfrc522.MIFARE_Write(trailerBlock, trailerBuffer, 16); if (status != MFRC522::STATUS_OK) { Serial.println(mfrc522.GetStatusCodeName(status)); } } void loop() { if ( ! mfrc522.PICC_IsNewCardPresent()) return; if ( ! mfrc522.PICC_ReadCardSerial()) return; status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_B, trailerBlock, &key, &(mfrc522.uid)); if (status != MFRC522::STATUS_OK) { Serial.println((String)"AuthenticateB Failed: " + mfrc522.GetStatusCodeName(status)); return; } status = mfrc522.MIFARE_Increment(valueBlockA, 1000); if (status != MFRC522::STATUS_OK) { Serial.println((String)"Increment Failed: " + mfrc522.GetStatusCodeName(status)); return; } status = mfrc522.MIFARE_Transfer(valueBlockA); if (status != MFRC522::STATUS_OK) { Serial.println((String)"Transfer Failed: " + mfrc522.GetStatusCodeName(status)); return; } status = mfrc522.MIFARE_GetValue(valueBlockA, &value); if (status != MFRC522::STATUS_OK) { Serial.println((String)"GetValue Failed: " + mfrc522.GetStatusCodeName(status)); return; } Serial.println((String)"New value of value block " + valueBlockA + (String)" = " + value); if (value > 10000) { // Check some boundary... Serial.println("Up 10000, so resetting it to 10000 = 0x2710"); status = mfrc522.MIFARE_SetValue(valueBlockA, 10000); if (status != MFRC522::STATUS_OK) { Serial.print((String)"SetValue Failed: " + mfrc522.GetStatusCodeName(status)); Serial.println(); return; } } // Dump the sector data mfrc522.PICC_DumpMifareClassicSectorToSerial(&(mfrc522.uid), &key, sector); Serial.println(); mfrc522.PICC_HaltA(); mfrc522.PCD_StopCrypto1(); } void dump_byte_array(byte *buffer, byte bufferSize) { for (byte i = 0; i < bufferSize; i++) { Serial.print(buffer[i] < 0x10 ? " 0" : " "); Serial.print(buffer[i], HEX); } } |
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 |
#include <SPI.h> #include <MFRC522.h> MFRC522 mfrc522(10/*SS_PIN*/, 9/*RST_PIN*/); MFRC522::MIFARE_Key key; MFRC522::StatusCode status; void setup() { Serial.begin(9600); SPI.begin(); mfrc522.PCD_Init(); for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF; /* byte trailerBuffer[] = { 255, 255, 255, 255, 255, 255, // Keep default key A 0, 0, 0, 0, 255, 255, 255, 255, 255, 255 }; // Keep default key B mfrc522.MIFARE_SetAccessBits(&trailerBuffer[6], 0, 6, 6, 3); status = mfrc522.MIFARE_Write(trailerBlock, trailerBuffer, 16); if (status != MFRC522::STATUS_OK) { Serial.println(mfrc522.GetStatusCodeName(status)); while(1); } */ } void loop() { if ( ! mfrc522.PICC_IsNewCardPresent()) return; if ( ! mfrc522.PICC_ReadCardSerial()) return; byte sector = 1; byte valueBlockA = 5; byte trailerBlock = 7; byte buffer[18]; byte size = sizeof(buffer); long value; status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_B, trailerBlock, &key, &(mfrc522.uid)); if (status != MFRC522::STATUS_OK) { Serial.println((String)"AuthenticateB Failed: " + mfrc522.GetStatusCodeName(status)); return; } status = mfrc522.MIFARE_Decrement(valueBlockA, 1500); if (status != MFRC522::STATUS_OK) { Serial.print((String)"Decrement Failed: " + mfrc522.GetStatusCodeName(status)); return; } status = mfrc522.MIFARE_Transfer(valueBlockA); if (status != MFRC522::STATUS_OK) { Serial.print((String)"Transfer Failed: " + mfrc522.GetStatusCodeName(status)); return; } status = mfrc522.MIFARE_GetValue(valueBlockA, &value); if (status != MFRC522::STATUS_OK) { Serial.print((String)"GetValue Failed: " + mfrc522.GetStatusCodeName(status)); return; } Serial.println((String)"New value of value block " + valueBlockA + (String)" = " + value); if (value <= 0) { // Check some boundary... Serial.println("Below 0, so resetting it to 0 = 0x00"); status = mfrc522.MIFARE_SetValue(valueBlockA, 0); if (status != MFRC522::STATUS_OK) { Serial.print((String)"SetValue Failed: " + mfrc522.GetStatusCodeName(status)); Serial.println(); return; } } // Dump the sector data mfrc522.PICC_DumpMifareClassicSectorToSerial(&(mfrc522.uid), &key, sector); Serial.println(); mfrc522.PICC_HaltA(); mfrc522.PCD_StopCrypto1(); } void dump_byte_array(byte *buffer, byte bufferSize) { for (byte i = 0; i < bufferSize; i++) { Serial.print(buffer[i] < 0x10 ? " 0" : " "); Serial.print(buffer[i], HEX); } } |
- برای این که پروژتون فقط از کارت های 1کیلو پشتیبانی کنه و در قبال کارت های مایفر دیگه کاری نکنه میتونید از کد زیر استفاده کنید، در زیر من یه پیغام گزاشتم داخل if ها ولی شما میتونید، در صورت درست بودن مدل کارت کدهای پروژتون رو اجرا کنید و کدهای پروژتون رو قرار بدید، و اگه کارت پشتیبانی نشد، مثلا یه پیغام بدید که ببم جان، کارتت پشتیبانی نمیشه یا اصلا پیغامی ندید یا هر طور دوس داشتید!
1 2 3 4 5 6 7 |
MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak); if ( piccType != MFRC522::PICC_TYPE_MIFARE_1K ) { Serial.println("This Project only work with MIFARE Classic 1K"); } else { Serial.println("Your Card is MIFARE Classic 1K And Support in This Project"); } |
تا همینجا کافیه، خسته شدم، مطلب هم شدش 7هزار واژه، البته بازم هست بعضی چیزا که میشه گفتم ولی دیگه خداییش خیلی خسته شدمف الان چند روزه پای این مطلبم
خب این مطلب هم تموم شد، دوستان ازم میپرسیدن این مطلبو کی میزاری، چندین نفر منتظر من بودم، همین جا عذرخواهی میکنم بابت دیر شدن، چون نمیخواستم یه چیزی نوشته باشم که نوشته باشم(بر خلاف بعضی ها که همین طوری یه چیزی مینویسن تا سایتشون بیاد بالا)، تا جایی که در توانم و وقتم بود سعی کردم مطلب رو خوب و کامل بنویسم، حالا اگه جایی رو نگفتم و بد گفتم به بزرگی خودتون ببخشید و گوشزد کونید اون موارد رو تا تصحیح کنم.
داستان! : خب برای هر مطلب سایت من چندین روز وقت میزارم و برا بعضی مطالب بعضا شده که 1ماه دنبالش بودم!، از این سایت هم که کسی به ما پولی نمیده و ما هم که از کسی پولی نمیگیریم(چون میدونیم کسی کمک نمیکنه، چرا؟ بله چون وقتی خودم به سایت های مفید کمک نمیکنم چطور توقع باید داشته باشم که دیگران به سایت من کمک کنن)، پروژه دانشجویی هم که مشکل قانونی داره و ما انجام نمیدیم و پروژه های دیگه رو هم به ما نمیدن برا انجام، سالی هم 500 تومن بابت سایت من هزینه میکنم تقریبا، هزینه قطعاتی هم که تا الان خریدم به کنار(که 4-5 کارتون بزرگ الان من دم دستگاه دارم!)، اینا رو نمیگم که منت بزارم در کل اینو میخوام بگم، زورم میاد و ناراحت میشم وقتی کسی رو میبینم که یه چیزی بلد هستش ولی نمیاد یاد بده و به اشتراک بزاره، بارها شده که افرادی رو میشناختم گفتم بیاید مطلب بزار گفتن باشه ولی نیومدن، بعضیها اومدن و چند مطلب گزاشتن و بعد ولش کردن، من خودم پروژه انجام میدم و بعد با ذوق و شوق با پولش میرم قطعه میخرم(جالا بگذریم از وقتایی که این فروشگاه ها به من ظرر زدن، مثلا همین eca به من 130 تومن همین آفتاب رایانه با ارسال یه نمایشگر شکسته_به دست من که رسید شکسته بود_ حدود 45 تومن ظرر زدن و موارد دیگه) و بعد خرید قطعه کار باهاشون رو میرم یاد میگیرم و مطلبش رو میزارم تو سایت تا دیگران مجبور نباشن برا یادگیری کار با اون قطعه دیگه وقت بزارن، و من برنامم اینه که تو این زمینه به دوستان کمک کوچیکی کرده باشم، ولی ناراحت میشم وقتی کسی رو میبینم که فک میکنه اگه چیزی رو که بلده تو اینترنت به اشتراک بزاره …. بگذریم؛ به هر حال یکی از اهداف من تو رایگان گزاشتن مطالب اینه که شاید باشن کسایی که مثل ما جیبشون خالی باشه و پول نداشته باشن بدن آموزش های پولی و این یکی از دلایل و اهداف کار من هستش، و من از این کار بعضیا جدا خیلی ناراحت میشم.(منظورم اونایی نیست که مطلب و آموزش پولی میزارن، یه وقت برداشت اشتباه نکنید از حرفام!)
هزینه مطلب : به بچه های محلتون این چیزایی که بلد هستید رو برید یاد بدید، مثلا همین آردوینو رو برید یاد بدید، یه 10 جلسه 1 ساعته برای رضای خدا برید برای اینا کلاس بزارید، حالا تو مساجد، حسینیه ها میتونید کلاساتون رو برگزار کنید، به فرهنگی یا بسیج مساجد مراجعه کنید و بگید من آمادگیشو رو دارم تا فلان کلاس رو برگزار کنم و آموزش بدم، اونا هم از خداشونه، این طوری اگه تو هر کلاس 10 نفر باشه، هم بچه های محلتون رو یه چیزی یاد دادید و علاقه مندشون کردید به این کارها(من خودم بچگیام یه مدار فلشر دیدم که داشتم ساخته بود و سر همون اومدم رشته الکترونیک و بعد این کارها – اگه همون زمان یکی این چیزا رو یاد میداد بهم به جای این که اون موقع تو جوبا ماهی میگرفتم با آهنگ ربا!، بجاش میرفتم سراغ الکترونیک از همون بچگیم و به این سن که میرسیم یه مخی میشدم برا خودم، خداییش غیر از اینه؟) و میتونن همین بچه ها از طرف مدرسشون برن مسابقات رباتیک و …، هم بچه ها رو از کوچه خیابون ها جمع کردید(خداییش دیگه خودتون باید بدونید که بچه ای که تو کوچه خیابون باشه همش چیزای درستی یاد نمیگیره)….. والا من هرچی فک میکنم ایده خوبی هستش، یه برد آردوینو، یه کامپیوتر یا لبتاب و چند تا قطعه ساده مثل lcd و led و سون سگمنت و موتور dc و از این جور چیزا لازم داره.(خداییش انجام بدید این کار رو، و نتیجه اش رو بهم همینجا بگید)
تا مطلب بعد اگه زنده بودیم یا علی.
مهمان
میگم میشه نمایش کد تگ با ماژول RC522و ال سی دی کاراکتری رو آموزش بدی
مهمان
سلام آرزوی بهترین ها رو برای شما دارم
ولی یه نکته شما درست میگید آدم تو یاد دادن یاد میگیره
بنده در زمینه برق و الکترونیک خودرو فعالیت دارم و در حد توان یه چیزایی رو به اشتراک گزاشتم ولی بعد چند وقت تمامی اطلاعاتی که لو دادم بر ضرر خودم تموم شد باید ببخشید جمله ادبی مناسبی نیست ولی دست یه تعداد افراد نا لایق و سود جو افتاد که رو همون اطلاعات الان دارن کار انجام میدن و 20 تومان اجرت میگیرن فارغ از این که بدونن چه زحماتی برای این اطلاعات کشیده شده
وقتی آدم این رو میبینه خشک و ترو با هم میسوزونه این نظر منه شاید هم اشتباه فکر کنم ؟؟؟؟ …….
مهمان
باسلام
ممنونم از آموزش کاملتان
یک سوالی داشتم :
در رابطه با تابع:
mfrc522.MIFARE_SetAccessBits(&trailerBuffer[6], g0, g1, g2, g3);
من نحوه مقدار دهی g ها رو متوجه نشدم خوب.
مثلا برای بلوک های زیر g ها چه طور مقدار دهی میشوند
block 0 = C10=0 ,C20=1 ,C30=1
block 1 = C11=0 ,C21=1 ,C31=1
block 2 = C12=0 ,C22=1 ,C32=1
block 3 = C13=1 ,C23=1 ,C33=1
ممنون میشوم راهنمایی ام کنید
مهمان
به نظرم یه ” خدا خیرت بده ” خستگی رو از تنت در میکنه . کلا من خیلی چیزا ازت یاد گرفتم و متاسفانه نه شمارو دیدم نه میشناسم فقط میدونم خیلی گلی حتی نمیدونم زنی یا مردی در این حد . خوشحال میشم واتساپ بدی گرفتاریهای الکترونیکیمون رو باهات مطرح کنیم . فدای مهربونیات . اگه مردی بوس بوس ..
مهمان
سلام، من این ماژول رو با atmega8 a و یک کتابخونه آماده راه اندازی کردم و وقتی کارت رو نزدیک می کنم یه سریال 16 رقمی توی مبنای 16 نمایش میده الان نمی دونم این واقعا سریال هست یا چیز دیگه به نظر شما چکار کنم؟
نویسنده این مطلب
سلام/فرمت اطلاعات رو تو دیتاشیت ماژول ببین/کتابخونه رو هم یه بررسی بکن محاسباتشو.
مهمان
آقا مهدی دمت گرم ما که یه تیکه هاشا نفهمیدیم
(البته منظورم بعضی قسمت های تو اون فیلم هست
) اما درکل میخوام اینو بگم درباره “هزینه مطلب” والا ما میخوایم یاد بدیم کسی هم باشه سئوال تو تلگرام جواب میدیم اما خدا شاهده این مسجد و حسینیه و اینا و مدرسه و محله رو نمیشه نمیدونم خودت اینکارو کرد یا نه؟
بعد کلی وقت یه نفر 2 سال بزرگ تر خودم که درگیر کنکوره گفته بیا یادم بده
تو مدرسه هم همینطور شما راضی باش ما منتشر نمیکنیم اما سئوال بود جواب میدیم 
اما هر شب که میرم مسجد یه هم سنما نمیبینم اگه هم میبینم کارشون شده مسخره ما که جن زده شدیم و تو فضا داریم سیر میکنیم و کلا این کارا آت و آشغالن
نویسنده این مطلب
مهمان
سلام مهندس عزیز. خدا قوت.مطالبی که در سایت هست مشخصا زحمتی زیادی میبره. از طرف قشر الکترونیک ازت تشکر میکنم.
مهمان
سلام سایت بسیار خوبی دارید ، من تقریبا 90 درصد آردینو را از سایت شما یاد گرفتم و این باعث افتخاره ، خیلی ممنون که برای کاربرانتون اینقدر وقت میزارید و اهمیت میدید ، یکی از نکات بارز سایت شما تمیز نویسی و دسته بندی توابع همراه با توضیح مفید وکامل به همراه مثال برای هر دستور هست که بسیار حائز اهمیت می باشد
مهمان
سلام
من پنج روز آردینو و ماژول رو روشن گذاشتم هر روز هم با کارت تستش می کردم که ببینم خوب جواب میده یا نه.
الان که نگاه میکنم ماژول هیچ عکس العملی نشون نمیده !!!
پراب اسکوپ رو روی آنتن ماژول گذاشتم سیگنال نداشت!! قبلا تو کار 13.56 مگا رو میزد.
تا زمانی که آردینو ریست نکنم درست نمی شه!!
راهی وجود داره که بشه فهمید ماژول RC255 کار میکنه یا نه؟؟ (تابعی یا چیزی …)
ممنون
مهمان
سلام اقا مهدی این به چه معناست؟
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE
نویسنده این مطلب
سلام – تا زمانی که تابع USART_GetFlagStatus مقدارش 1 هستش، کدهای داخل WHILE اجرا میشوند.
این تابع، چیزی که از اسمش معلومه – وضعیت فلگ TXE از پریفرال ( واحل جانبی ) USART1 رو return میکنه.
مهمان
اموزش این با i2c هست؟
نویسنده این مطلب
SPI
مهمان
ن داداش منظورم اینه با i2c لازم دارم.
نویسنده این مطلب
آها – نه کتابخونشو ندارم – باید سرچ کنی یا خودت آستین بدی بالا
مهمان
داداش راستی من تونستم کارت های _ _ _ _ را رمزشو در بیارم. حالا اطلاعاتش واقعا خستم کرده و نمیدونم چجوری بفهمم مبلغ کجاس و چجوری تغییرش بدم. اگه اطلاعاتی داری ممنون میشم
مهمان
سلام من از خود کد دیفالت write برای این ماژول با اردوینو استفاده می کردم ولی بعد از مدتی دیگه انگار کارت رو تشخیص نمی ده. باید هزار بار خاموش و روشن کنم میکرو رو یا ریستش کنم که کارتو بخونه. جریان چیه؟
مهمان
سلام
چجوری میشه یک تابع بنویسم که با یک شدن پایه مقدار کارت را بخونه و اضافه کنه به کار های مجاز؟
مهمان
ممنون عالی بود
مهمان
سلام
لطفا بنده را در صورت امکان راهنمایی فرمایید
من میخواهم که یک عکس را در کارت های rfid/nfc ذخیره کنم
آیا امکان پذیر است؟
با تشکر
نویسنده این مطلب
سلام – حجم عکستون – و حافظه کارت های فوق رو برسی کنید …
عکس هم یه سری 0 و 1 هستش دیگه.
مهمان
بله اضافه کردم رنگ کداش تغیر می کنه به نظر شما از ورژن نرم افزار اردوینو نیست ورژن من ۸.۵
مهمان
داداش این کدMFR522 mfrc522(10,9(
در کامپیایلر من error میگیره وhas no member named این ارورشه چی کار کنم
نویسنده این مطلب
کتابخونه رو اضافه کردی به آردوینو؟
مهمان
MFRC522::MIFARE_Key key; این :: به چه معناست اصلا این خط یه توضیح بدین خیلی ممنون
نویسنده این مطلب
از کلاس MFRC522، از typedef با نام MIFARE_Key، اومده یه متغییر از این نوع ساخته.
typedef struct {
byte keyByte[MF_KEY_SIZE];
} MIFARE_Key;
مهمان
یه چیز دیگه این توابع کتابخانه را چه گونه شما می فهمید برای چیه دیتا شیت داره یا
نویسنده این مطلب
معمولا هر کتابخونه ای برای هر تابع توضیحاتی مینویسه ( قبل از تعریف تابع ) یا این که به سایت کسی که این کتابخونه رو نوشته میری و آموزش کتابخونه ای که نوشته رو تو سایتش سرچ میکنی – یا تو نت سرچ میکنی ببینی قبلا کسی با این کتابخونه کار کرده که اومده باشه آموزش کار با این کتابخهونه و توابعش رو گزاشته باشه یا نه.
مهمان
سلام این پروژه را میشه بدون استفاده از کتابخانه RC522نوشت یعنی فقط با کتابخانه SPIنوشت
نویسنده این مطلب
سلام – شما با پروتکول spi آشنایی کامل هم داشته باشید باید باید برید دیتاشیت RC522 رو بخونید و از این کتابخونه توی این مطلب، به عنوان نمونه کتابخونه کمک بگیرید.
مهمان
سلام اقا مهدی این library MFRC522 من هرکاری کردم دانلود نشد
لطفا لینک دانلود شا بفرستید تشکر 
نویسنده این مطلب
سلام – رو لینک فوق ( دانلود کتابخانه ماژول MRFC522 برای آردوینو ) که کلیک کردی – در صفحه باز شده به صورت زیر عمل کن :
Clone or download > Download ZIP
مهمان
ولی من خودم ۱۴ سال دارم واین برنامه نویسی والکترونیک رو ۲ ساله شروع کردم و از اول علاقه داشتم
مهمان
سلام مهندس این که گفتید داخل تابع رو ببینید رو چجوری میشه انجام داد
مهمان
با عرض سلام خسته نباشید به شما
ممنون از آموزش های ارزش مندتون و آرزوی موفقیت برای شما
سوالی داشتم از خدمتتون و اون این که من یه برد آردوینو مینی پرو خریدم و توی پروگرم کردن اون مشکلی داشتم و اون این که نمیشه پین ریستش رو مشخص کرد ینی شماره ای نداره و یه مشکل دیگه این که دیتا ای که از برد ارسال میشود رو مدلم نمیتونه تفسیر کنه به طوری که حتی نوشته هایی که توی برنامه مشخص کردم رو نمیتونه نمایش بده ممنون میشم اگر کمکم کنید خیلی این پروژه وقتم رو گرفته خواهشا کمک کنید و لطفا ایمیل کنید پاسختون رو بازم ممنون
مهمان
سلام آقا مهدی مرسی بابت مطلب عالیتون
یه سوال داشتم!من از آردوینو مینی پرو استفاده میکنم پین ریستش رو به ریست ماژول وصل کردم اما این پین شماره ای نداره که توی برنامه مشخص کنم در ضمن پروژه یک رو نمیدونم چرا حروف نامفهوم ارسال میکنه لطف میکنید اگر جواب بدید
نویسنده این مطلب
سلام
پروژه – خط 3
MFRC522 mfrc522(10/*SS_PIN*/, 9/*RST_PIN*/);
پین ریست ماژول رو اینجا تعیین میکنیم که به کدوم پایه میکرو وصل بشه – برای این که ببینی الزامی هستش که این پایه توسط میکرو کنترل بشه یا نه – میتونید دیتاشیت ماژول فوق و یا کتابخونه شو مطالعه/بررسی کنید.
مهمان
دوست عزیز
سلام
سپاس از اموزش کامل تون
من به دنبال راه اندازی این ماژول برای میکروی pic16f877a هستم. آیا می تونید کمک کنید؟
برای پرداخت هزینه هم مشکلی نیست.
سپاس از شما
مهمان
سلام و احترام …
یه کارتی هست که کلید امنیتی a و b هر سکتور متفاوته
چطوری میشه اطلاعاتش رو خوند ؟ا چه کدی؟ (پسوورد ها هم موجود هست )
آقا مهدی اگه نمونه کد بدی واقعا ممنونت میشم
مهمان
ممنون مهدی جان
ما میدونیم شما چقدر زحمت میکشی چون خودمون هم وقتی پروژه انجام میدیم زمان و هزینه و … داره
ولی اگه روی صحبتت “بعضیها اومدن و چند مطلب گزاشتن و بعد ولش کردن” با منه ، که خودتم میدونی علیرغم میل باطنیم واسه چی دیگه باهات همکاری نکردم .
سایتت زیادی سیاسی شده
موفق باشی
مهمان
سلام و عرض ادب .
اقای دمرچیلو عزیز ؛ بنده یه کارتی دارم که تمام سکتورهاش رمز داره و در هر سکتوری هم کلید A و B متفاوت هستش. برای اینکه من بخوام هر سکتور رو اعتبار سنجی کنم از کد پایین استفاده کردم ولی نمیدونم چرا فقط برای کلید A اعتبارسنجی انجام میگیره . اگه راهنماییم کنید ممنون میشم
{
// Authenticate using key A sec 0
{
key.keyByte[0] = 0xa0;
key.keyByte[1] = 0xa1;
key.keyByte[2] = 0xa2;
key.keyByte[3] = 0xa3;
key.keyByte[4] = 0xa4;
key.keyByte[5] = 0xa5;
}
Serial.println(“Authenticating using key A…”);
status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, 3, &key, &(mfrc522.uid));
if (status != MFRC522::STATUS_OK) {
Serial.print(F(“PCD_Authenticate() failed: “));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
Serial.println(“Authenticating using key A Sec 0 is Successful”);
Serial.print(“\n”);
}
{
// Authenticate using key B sec 0
{
key.keyByte[10] = 0xAB;
key.keyByte[11] = 0x76;
key.keyByte[12] = 0xF8;
key.keyByte[13] = 0xBA;
key.keyByte[14] = 0x93;
key.keyByte[15] = 0x54;
}
status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_B, 3, &key, &(mfrc522.uid));
if (status != MFRC522::STATUS_OK) {
Serial.print(F(“PCD_Authenticate() failed: “));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
Serial.println(“Authenticating using key B Sec 0 is Successful”);
Serial.print(“\n”);
}
مهمان
من از آردوینو مگا و UNO استفاده می کنم برنامه ام هم مشکلی نداره اما نمی دونم چرا آپلود نمی شه وقتی می خوام کامبایل شه ارور میده ولی نمیگه مشکل از کجاست و باید چی کار کنم.
به نظر شما من باید چی کار کنم. جالبه که روی دوتا آردوینو هم آپلود نمی شه .خواهش میکنم خواهشا اگه کسی میدونه جواب بده خواهش بازم خواهش
اگه جواب بدین براتون دعا میکنم . خیلی ممنون(اگه پاسخ بدین)
اگه هم جواب ندین
دیگه تو سایتتون نمیام 
نویسنده این مطلب
موقع کامپایل ارور میده – خطاشو هم نشون نمیده؟ عجب
دسترسی بده بیام تو سیستمت ببینم داستان چیه.
یه نرما فزار کنترل PC از راه دور پیدا کن – اسم نرمافزار و یوزر آیدی رو برام بفرست.
مهمان
سلام.چه طور تو پروژه دو تو قسمت شناسایی کارت ها قبلش اطلاعات کارت رو توی حافظه ذخیره کردین؟؟؟
مهمان
چرا جواب ما رو نمی دی داداش؟!؟!؟!؟!
نویسنده این مطلب
شما با چه نامی و در کدوم مطلب سوالی مطرح کردید؟
مهمان
مهدی آقا دمت گرم…
لطفا لینکشو تو مطلب بالا هم بزار تا بقیه هم استفاده کنن.
واقعا دست درد نکنه.
یه سایتی دیدم که Access Bit ها رو خودش محاسبه می کرد. خیلی حال کردم
http://calc.gmss.ru/Mifare1k/
ارادتمندم.
سید علی
مهمان
سلام . با چه کدی میشه پسورد یه کارت که به صورت پیشفرض هست رو تغییر داد ؟
مهمان
سلام
ای کاش می شد به جای اینکه بیایم کلی وقت و هزینه صرف کنیم تا کار با ماژول ها و کتابخونه های آماده رو یاد بگیریم خودمون درستش کنیم با استاندارد های خودمون(مثلا مجبور نیستیم دیگه حتما ارتباط SPI استفاده کنیم!!) سخته اما ارزشش رو داره. از ماژول ها متنفرم!!!
نویسنده این مطلب
سلام
صحیح ولی خب راه بهتر اینه که هر جا ماژولی نیاز داشتیم برا کارمون – از کتابخونه آماده استفاده کنیم و شخصی سازیش کنیم.
مهمان
سلام حاج مهدی
میخواستم برد این ماژول بیشتر کنم ، با آنتن خارجی مخصوص خودشون میشه؟
شهید شی انشاءلله
نویسنده این مطلب
سلام-آگه آنتنش باشه چرا نشه.ولی خب معمولا آنتنو برا بحث افزایش برد استفاده نمیکنن تو rifd ها – اگه اشتباه نکنم – داستانش چیز دیگه ای هستش فک کنم.
مهمان
سلام دست گلت درد نکنه انشالله اجرت با خدا



بسیار مطالب مفید و مناسبی دارید خیلی ممنون
کی گفته نمیشه کارت ها رو رمزشون رو بدست آورد ؟؟؟
mfcuk
Mifare Classic DarkSide Key Recovery Tool
مهمان
سلام مهدی جان

ممنون میشم در این مورد توضیح بدید
خیلی ممنون از توضیحات کاملتون
یه برد با ATMega8 smd طراحی کردم برای کنترل MFRC522 که با کدویژن برنامشو نوشتم و خوب هم کار میکنه
روش کارش اینه که بعد از دریافت اطلاعات از سریال(مثلا دستور خواندن کارت)، کارت رو میخونه وبعد اطلاعات رو پرینت میکنه
همه چیز تا اینجا خوبه فقط بعد از چند بار ارسال دستور و دریافت اطلاعات هنگ میکنه و باید دستی ریستش کنم
گفتم شاید مشکل از کتابخونه rc522 برای کد ویژن باشه
بوت لودر آردوئینو رو روی ATMega8 ریختم و خاستم از کد شما استفاده کنم
در دستورزیر باید کدوم پایه ها رو معرفی کنم؟
MFRC522 mfrc522(10, 9);
10 و 9 یا 10 و 5 یا 10 و 22 تست کردم ولی با دستور زیر خطا میده
mfrc522.PCD_DumpVersionToSerial();
Firmware Version: 0x0 = (unknown)
WARNING: Communication failure, is the MFRC522 properly connected?
خیلی ممنون
مهمان
سلام
ممنون از مطالب عالی
با آردیونو uno تست کردم مشکلی نبود
ولی کد رو که با آردیونو مگا امتحان میکنم جواب نمیده.
اتصال ها هم دقیقا مثل قبلی بستم
نویسنده این مطلب
سلام-پایه های spi تو دو برد فوق فک نکنم یکسان باشه
مهمان
سلام
بله درست میفرمائید.
یه جدول توی دیتاشیت هست که برای بردهای مختلف آردوینو پایه ها متفاوته
از روی اون بستم جواب گرفتم
مهمان
سلام.
میشه آموزش این رو با avr هم بنویسید؟
خیلی ممنون!
نویسنده این مطلب
سلام-امکانش نی فعلا-تو نت کتابخونه ای ازش هستش-تو سایتای چینی فک کنم – دقیقا خاطرم نی
مهمان
حاجی من واقعا لازمش درم. چیکار کنم بنظرت؟
چینی سرچ کنم؟!یه کتابخونه پیدا کردم ولی وقتی میخوام ازش استفاده کنم codevisionavr بهش گیر میده. کتابخونشم ناقصه انگار…
یه راهنمایی بکن خواهشا
نویسنده این مطلب
خو گفتم دیگه – سرچ کن – انگلیسی سرچ کن تو گوگل پیدا میکنی
تو گروه تلگرامی سایت هم یکی قبلا یه کتابخونه ای ازش گزاشته بود – نمیدونم الانم هستش یا نه – تو تاریخچش باید بگردی.
تست شده هم هستش
اون بنده خدا هم سرچ کرده بود و تو این سایتای چینی فک کنم پیداش کرده بود.
مهمان
سلام. خیلی ممنونم از زحماتتون.
این پروژه ای که نوشتید، اگه کارتی که جلوی ماژول میگیریم در لیست باشه تو سریال مانیتور UID شو چاپ میکنه و اگه در لیست نباشه میگه وجود نداره درسته؟؟ حالا اگه بخوام واسه هر کدوم از کارت هایی که در لیست وجود داره شرط جداگانه بذارم چطوری باید این کارو کنم؟ مثلا بگم اگه کارت خوانده شده این { 107, 104, 15, 43 } بود اسم صاحبشو تعیین کنم بگم این اسم رو چاپ کن. یا اگه این { 87, 84, 58, 213 } بود یه اسم دیگه چاپ کن. یعنی چطوری میتونم به تک تک کارت هام اشاره کنم برای شرط گذاشتن؟؟؟ خواهش میکنم جواب بدین خیلی مهمه.
مهمان
سلام
اقا مهدی شرمنده در صورت امکان لینک دانلود فیلم را قرار بدین دانلود کنیم
نویسنده این مطلب
سلام
یه فیلمی داخل منو کشویی “توضیحات کوچولویی درباره کارت های MIFARE” گزاشتم انگار
مهمان
حرررررف نداری برادر

. ینننیییی انقد باحالی 
دمت گرم…
دلم میخواد جای تشکر خفت کنم.
مهمان
سلام میدونم که نیازی نداری ولی خیــــــــــــــــــــــــــلی مرد هستی!
مهمان
چه جوری میشه هر کارت و تو هر بار نزدیک کردن به ماژول فقط یه بار خوند ؟ بدون استفاده از delay ؟
مهمان
کارت درسته
انشالله همیشه موفق باشی
مهمان
سلام داداش
میگم تو اون پروژه ۲ چطوری کارت اضافه کرد ؟ سریال این کارتا تو حروفم هست ولی اینی که تو کدا زدی همش عدده چجوریه قضیه اینا ؟
مهمان
سلام داداش
میگم تو اون پروژه ۲ چطوری کارت اضافه کرد ؟ سریال این کارتا تو حروفم هست ولی اینی که تو کدا زدی همش عدده چجوریه قضیه اینا ؟
مهمان
سلام جناب مهندس
یک سوال داشتم … چطور رمز کارت رو عوض کنیم ممکنه یک مثال ازش بزنید ؟ تابعی داره ؟
ممنون
نویسنده این مطلب
سلام
چیزی خاطرم نی
مهمان
با سلام و تشکر از جناب مهندس دمرچیلو. تا حالا هرچی تو سایت کامنت گذاشتم جوابی نگرفتم
امیدوارم این دیگه جواب بگیره!
مهندس ماژول با ۳٫۳ ولت کار می کنه اما ولتاژ پایه های آردینو مگا و Uno پنج ولت هستش. مشکلی ایجاد نمی کنه؟
ضمنا دوستی در مورد اجرا با Arduino Due سوال پرسیده بود. اجرا نمیشه من برد رو دارم ولی کتابخانه خطا می گیره ونوع پردازنده رو پشتیبانی نمی کنه.
نویسنده این مطلب
سلام
فوقش اگه احساس میکنی در دراز مدت مشکل ایجاد میکنه – یه تقسیم ولتاژ مقاومتی بزن.
با آردوینو due هم کار نکردم – خب باید ببینی خطاش چیه بری تو کتاب خونه اصلاحش کنی دیگه!
مهمان
ممنون بابت پاسخ. فعلا فرصت اصلاح کتابخونه ندارم! میشه این کتابخونه رو برای اتمل استودیو یا AVR-GCC پورت کرد؟
نویسنده این مطلب
برای هر کامپایلری و هر میکرویی میشه – خب باید تغییراتی تو کتابخونه بدی – این که از بدیهیات هستش.
مهمان
دوباره سلام

یه سوال دیگه ای … توی یه بخشی از آموزش نوشته بودین از تابع هک کردن برای پیدا کردن پسوورد استفاده کردین … میشه بگین این تابع چیه ؟ یا اگه ممکنه یه مطلب کوچیک دربارش بزارین
مرسی از زحمتات برادر
مهمان
سلام مجدد جناب دمرچیلو
بنده وقتی کد هارو روی اردوینو آپلود میکنم و وقتی از سریال مانیتور میخوام ازش تست بگیرم نتیجه رو چرت و پرت به من میده
http://s8.picofile.com/file/8303150092/Capture3.JPG
اینم لینک نتیجه اش
اگه ممکنه راهنمایی کنید …با تشکر
نویسنده این مطلب
سلام
والا BAUD RATE برابر نباشه این مشکل رخ میده – نمیدونم – یکم ور برو ببین مشکل از کجاس
مهمان
آقای دمر چیلو فقط بشه پسوورد رو فهمید کافیه ؟ من از جایی شنیدم به غیر از پسوور اینا به یه الگوریتمی هم برای شارژ نیاز دارن . نظر شما چیه ؟
نویسنده این مطلب
اونا رو دیگه من اطلاع ندارم.
مهمان
مرسی از راهنماییتون و وقتی که میزارین … آقای دمرچیلو چطور میشه با شما در ارتباط بود ؟
نویسنده این مطلب