جستجو
منو بسته
نظر ها  (0) سلولهای خورشیدی چگونه کار میکنند

چگونه سلول های خورشیدی کار می کند

شما احتمالاً ماشین حساب هایی که سلول های خورشیدی solar cells دارند را دیده اید. دستگاه هایی که اصلاً به باتری نیاز ندارند و برخی موارد از این دستگاه ها حتی دکمه خاموشی ندارند. تا زمانی که نور کافی وجود داشته باشد، به نظر می رسد که برای همیشه کار کنند. شما همچنین ممکن است پنل های خورشیدی بزرگتری را در علائم جاده های اضطراری، جعبه های تماس، کوچه و حتی در پارکینگ ها برای روشن کردن چراغ ها دیده باشید.

اگر چه این پنل های بزرگتر به عنوان ماشین حساب های خورشیدی کاربردی ندارند، اما این پنل ها در بیرون وجود دارند و پیدا کردن آنها سخت نیست اگر شما بدانید که در کجا آنها را جستجو کنید. در واقع، فتوولتائیک photovoltaics که تقریباً به تنهایی در فضا استفاده شده بود و جهت برق دار کردن سیستم های الکتریکی ماهواره ها تا سال 1958 به کار گرفته میشد، امروزه بیشتر و بیشتر در موارد کمتر عجیب و غریب استفاده می‌شوند. این تکنولوژی در تمام دستگاه ها در تمام زمان ها از عینک آفتابی تا ایستگاه های شارژ خودرو ها به سرعت عملی می‌شود.

امید به "انقلاب خورشیدی" برای دهه ها شناور بوده است. این ایده که روزی همه ما از برق رایگان تولید شده از انرژی خورشید استفاده کنیم، یک وعده اغوا کننده است. چراکه در روز روشن و آفتابی، اشعه های خورشید حدود 1000 وات انرژی به هر متر مربع از سطح زمین می‌دهند. اگر ما بتوانیم تمام این انرژی را جمع آوری کنیم، می توانیم به راحتی خانه و دفاتر خود را به صورت رایگان اداره کنیم.

در این مقاله، ما سلولهای خورشیدی را بررسی خواهیم کرد تا یاد بگیرید که چگونه سلولهای خورشیدی انرژی خورشید را به طور مستقیم به برق تبدیل می‌کنند. در این فرآیند شما یاد می گیرید که چرا ما به استفاده از انرژی خورشید هر روز نزدیک‌تر می‌شویم و چرا هنوز تحقیقات بیشتری برای انجام این کار انجام می‌شود قبل از اینکه این فرایند مقرون به صرفه شود.

نظر ها  (0) طول عمر و مرگ باتریهای لیتیوم یونی

طول عمر و مرگ باتریهای لیتیوم یونی

معمولا پک های باتری لیتیوم یونی گران قیمت هستند بنابراین برای استفاده درست و طول عمر باتریهای لیتیوم یونی به موارد زیر توجه بفرمایید.
با توجه به ساختار شیمیایی باتریهای لیتیوم یونی بهتر است که باتری کامل تخلیه نشود و به صورت جزیی شارژ شود این باور اشتباه گاها بین مردم دیده میشود که گفته میشود باتریهای لیتیومی بهتر است کاملا تخلیه شوند.از آنجا که در باتریهای لیتیومی اثر حافظه ای وجود ندارد، لزومی ندارد که باتری کاملا تخلیه شود . و از طرف دیگر پایین رفتن سلولهای لیتیوم یونی از یک مقدار خاص باعث مرگ باتری میشود.

تاریخ تولید باتریهای لیتیوم یونی مهم است و طول عمر باتریهای لیتیوم یون از روز تولید شروع میشود مثلا این تصور اشتباه است که باتری لپ تاپ را از آن جدا کنیم و انتظار داشته باشیم که عمر آن مقدار قابل توجهی افزایش پیدا کند معمولا طول عمر باتریهای لیتیوم یونی بین 2 تا 4 سال است چه استفاده کنیم یا نه !

همانطور که قبلا هم اشاره شد حرارت و گرمای زیاد دشمن باتریهای لیتیوم یونی است و طول عمر آنها را به شدت کم میکند.

دیگر موردی که در طول عمر باتریهای لیتیومی تاثیر گذار است ولتاژ و جریان شارژ است به این معنی که تجاورز از ولتاژ و جریان توصیه شده برای شارژ سلول باعث کاهش طول عمر و خرابی باتری میشود.

 

انفجار و آتش گرفتن باتریهای لیتیومی

انفجار و آتش گرفتن باتریهای لیتیومی

معمولا اگر باتری به اندازه ای گرم شود که بتواند الکترولیت را بسوزاند باعث آتشسوزی و انفجار میشود، این آتشسوزی نتیجه اتصال درون باتری است. همانطور که از بخش قبل به یاد دارید بین الکترودهای مثبت و منفی باتری یک جدا کننده عایق وجود دارد ، حال اگر به دلیل ضربه، سوراخ شدن و یا حرارت این لایه جدا کننده پاره شود و بین الکترود مثبت و منفی اتصال به وجود آید ،
به دلیل انرژی بسیار زیادی که در باتری ذخیره شده و حرکت سریع یونهای لیتیوم حرارت بسیار بالارفته و الکترولیت و صفحه های مثبت و منفی آتش گرفته و فوران میکند.
باید یاد آوری کنیم که در حالت عادی این اتفاق بسیار به ندرت اتفاق می افتد ولی همین تعداد کم هم اکثرا به فراخوان همه باتری ها به کارخانه سازنده می انجامد.

 

نظر ها  (0) نگاهی به درون یک باتری لیتیومی و پک های لیتیوم یون

نگاهی به درون یک باتری لیتیومی و پک ها


پکهای باتری لیتیومی به اشکال گوناگون دیده میشوند، اما درون همه سلولهای آنها یکسان است.اگر شما یک پک باتری لیتیومی لپ تاپ را باز کنید (البته ما توصیه میکنیم به دلیل احتمال اتصال کوتاه و آتشسوزی این کار را انجام ندهید) موارد زیر را خواهید دید :

پک باتری لپ تاپ


سلول های باتری لیتیوم یون که معمولا استوانه ای و از نوع لیتیوم یون 18650 هستند و یا از انواع باتری مستطیل شکل تخت.
یک برد الکترونیکی کنترلر شارژ و دشارژ باتری شامل :
یک سنسور دما جهت مانیتورینگ دمای باتری هنگام شارژ و دشارژ
یک مدار مبدل ولتاژ و رگولاتور جهت حفظ سطح ایمن ولتاژ و جریان هنگام شارژ و دشارژ
یک فیش کانکتور که امکان اتصال و جدا کردن باتری از لپ تاپ را دارد
A voltage tap, which monitors the energy capacity of individual cells in the battery pack
یک سیم نمونه برداری از ولتاژ سلولها که وظیفه اش مانیتور کردن ظرفیت ذخیره سازی انرژی در تک تک سلول های پک باتری است
مدار مانیتورینگ شارژ باتری که یک برد الکترونیکی کوچک است و وظیفه آن کنترل تمام فرایند شارژ است به گونه ای که اطمینان حاصل شود تمام سلولهای لیتیوم یون به صورت کامل و با سرعت شارژ میشوند.
اگر پک باتری در حین شارژ بیش از حد تعیین شده گرم شود سنسور دمای نصب شده روی باتری دما را به برد کنترل شارژ فرستاده و برد کنترل شارژ جریان را به منظور خنک شدن باتری قطع میکند.
وظیفه دیگر این برد کنترل شارژ جلوگیری از خالی شدن کامل سلولهای لیتیومی است زیرا تخلیه کامل این سلولها موجب خراب شدن باتی میشود.
همچنین این برد امکان ارتباط با خارج از باتری را دارد و معمولا تعداد دفعات شارژ و دشارژ را ذخیره میکند و مقدار باقیمانده از ظرفیت باتری را به لپ تاپ اعلام میکند.
همه این کارها را این برد کوچک روی باتری انجام میدهد و البته این برد حدود 5 درصد ظرفیت باتری را مصرف میکند حتی در حالی که لپ تاپ خاموش است.

سلول های لیتیوم یون

همانند اکثر باتریها پوسته بیرونی سلولهای لیتیوم یونی از فلز ساخته شده است.استفاده از فلز برای پوسته باتریهای لیتیوم یونی بسیار مهم است زیرا معمولا فشار در باتری بالاست.
معمولا این پوسته فلزی از نوعی دریچه تخلیه گاز تحت فشار بهره میبرد که وظیفه آن جلوگیری از فشار زیاد و انفجار باتری است.معمولا در صورت تخلیه گاز در اثر بالا رفتن حرارت و فشار باتری خراب میشود و استفاده از آن توصیه نمیشود
داخل این پوشش فلزی یک رول مارپیچ طولانی شامل سه لایه ورق است که به صورت بسیار فشرده قرار دارد :
الکترود مثبت
الکترود منفی
جدا کننده یا separator
این رول متشکل از این سه لایه در مایعی به نام الکترولیت قرار میگیرند . اتر هم به عنوان الکترولیت استفاده میشود.
سپراتور یا جداکننده یک لایه بسیار نازک پلاستیک است و وظیفه آن جدا نگه داشتن صفحات مثبت و منفی از یکدیگر است.
در باتریهای لیتیوم یونی الکترود مثبت از ماده شیمیایی Lithium cobalt oxide, or LiCoO2 و الکترود منفی از کربن درست میشود.
هنگام شارژ یونهای لیتیوم از الکترود مثبت به سمت الکترود منفی میروند و در هنگام دشارژ یونهای لیتیوم از کربن یا اکترود منفی به سمت لایه مثبت یا اکسید کبالت لیتیوم حرکت میکنند.
حرکت این یونها در یک ولتاژ نسبتا بالا اتفاق می افتد، بنابراین هر سلول 3.7 ولت تولید میکند.این ولتاژ به مراتب بالاتر از ولتاژ سلولهای آلکالاین با ولتاژ 1.5 ولت است و این باعث میشود باتریهای لیتیوم یونی کوچکتر و سبکتر باشند و در اکثر دستگاههایی که نیاز به باتری کوچک دارند مانند تلفنهای هوشمند و لپ تاپها کاربرد دارند.

در مقاله بعدی در مورد طول عمر باتریهای لیتیوم یونی و علت انفجار آنها صحبت میکنیم.

نظر ها  (0) باتریهای لیتیوم یونی چگونه کار میکنند

باتریهای لیتیوم یونی چگونه کار میکنند How Lithium-ion Batteries Work

این روزها باتریهای لیتیوم یون بسیار محبوب هستند. شما میتوانید باتریهای لیتیوم یون را در لپ تاپها، تبلتها، تلفنهای همراه، پاور بانکها و بسیاری از محصولات دیگر پیدا کنید.
این نوع از باتریها خیلی رایج هستند. زیرا، چگالی انرژی ذخیره شده در آنها از اکثر باتریها بالاتر است. به این معنی که باتریهای لیتیوم یونی در همان ابعاد و اندازه و وزن میتواند مقدار بیشتر از انرژی را در خود ذخیره کنند.
این روزها در اخبار گاهی اوقات خبر انفجار و آتش گرفتن باتریهای لیتیوم یونی شنیده میشود، البته این اتفاق رایج نیست و بر اساس آمار از هر یک میلیون باتری فقط دو باتری دچار صانحه میشوند که جای نگرانی زیادی ندارد و شرکتهای معتبر معمولا برای همین درصد کم هم تمام باتریها را فراخوانی کرده و تعویض میکنند همانند اتفاقی که برای باتری موبایل سامسونگ گلکسی نوت 7 رخ داد.
حال با این اوصاف سوال اینجاست که
چرا باتریهای لیتیوم یونی LI-Ion Batteries تا این حد محبوب شده اند؟
در چه شرایطی آنها آتش میگیرند؟
و راههای ایمن نگاهداشتن و جلوگیری از چنین اتفاقاتی چیست؟
روشها نگهدارای و بالا بردن طول عمر باتریهای لیتیوم یونی چیست؟
در این مقاله سعی خواهیم کرد پاسخ این سوالات و هر آنچه در مورد باتریهای لیتیوم یونی ضروری است را بدهیم.

ابتدا سوال اول و دلیل محبوبیت و استفاده گسترده از باتریهای لیتیوم یونی را پاسخ میدهیم. باتریهای لیتیومی به خصوص لیتیوم یونی داری مزایای مهمی نسبت به سایر تکنولوژیهای رقیب هستند، آنها عموما بسیار سبکتر از سایر انواع باتریهای قابل شارژ در همان ظرفیت هستند.
الکترودهای لیتیوم از لایه های سبک و نازک لیتیوم و کربن ساخته شده اند. لیتیوم یه عنصر بسیار واکنشی است به این معنی که میتواند انرژی زیادی را در اتمهای خود ذخیره کند به بیان ساده تر تراکم و چگالی انرژی الکتریکی ذخیره شده در باتریهای لیتیوم یونی بسیار بالا و قابل توجه است.

برای روشن شدن این موضوع مثالی ساده اما مستند میزنیم، یک باتری لیتیوم یونی Li-Ion با وزن یک کیلو گرم توانایی ذخیره سازی 150 وات ساعت انرژی الکتریکی را دارد.
این حجم ذخیره سازی انرژی در یک کیلو گرم باتریهای نیکل متال Ni-Mh 100 وات ساعت
و برای یک کیلو گرم باتری سیلد اسید SLA Batteries فقط 25 وات ساعت است
در واقع برای ذخیره سازی انرژی 150 وات ساعت یک پک باتری یک کیلوگرمی لیتیوم یونی و یا یک باتری 6 کیلوگرمی سیلد اسید نیاز دارید که این خود به تنهایی یک مزیت بسیار بزرگ و تمام کننده برای باتریهای لیتیوم یونی است.
مزیت بعدی باتریهای لیتیوم یونی این است که این نوع باتریها در هرماه فقط 5 درصد از شارژ خود را از دست میدهند در صورتی که باتریهای نیکل متال 20 درصد از شارژ خود را هر ماه از دست میدهند.
مزیت بعدی باتریهای لیتیوم یون نداشتن هیچ اثر حافظه ای memory effect است به این معنی که برای شارژ کامل باتریهای لیتیوم یونی نیازی نیست آنها را کاملا تخلیه و مجددا شارژ نماییم این مورد در برخی از تکنولوژیهای شیمیایی مانند نیکل متال و نیکل کادمیوم دیده میشود.
مزیت دیگر باتریهای لیتیوم یونی نسبت به برخی باتریها چرخه شارژ و دشارژ بیشتر charge/discharge cycles است به این معنی که صدها بار بدون مشکل میتوانند شارژ و دشارژ شوند.
اینها همه مزاییای باتریهای لیتیوم یون بودند اما این بدین معنا نیست که آنها هیچگونه عیبی ندارند در زیر کمی به معایب باتریهای لیتیوم یونی میپردازیم
اولین عیب باتریهای لیتیوم یونی طول عمر آنهاست این باتریها به محض تولید دو تا سه سال عمر مفید خواهند داشت چه استفاده کنیم یا نه !
عیب دوم و مهم آنها حساسیت زیادشان به دماهای بالا است. دماهای بالا معمولا باعث کوتاه شدن عمر باتری نسبت به حالت عادی میشود.
عیب دیگر باتری لیتیوم یونی این است که در صورت تخلیه کامل باتری خراب خواهد شد و برای جلوگیری از این حالت بایستی یک برد کنترل شارژ یا PCM برای مراقبت از باتری در نظر گرفته شود که این مورد باعث گرانتر شدن پک باتری میشود.
عیب بسیار کوچک دیگر احتمال انفجار و آتش گرفتن باتریهای لیتیوم یون است. همانطور که گفته شد این احتمال حدود دو باتری در یک میلیون است.

بسیاری از موارد و خصوصیات گفته شده را میتوان با نگاهی به عناصر شیمیایی داخل این نوع باتریها درک کرد در مقالات بعدی به این موارد خواهیم پرداخت.

نظر ها  (0) پنل خورشیدی چیست و طرز کار آن چگونه است

پنل خورشیدی یا سولار پنل به بیان ساده نور خورشید را به انرژی الکتریکی جریان مستقیم تبدیل می کنند.

سلول خورشیدی

این پنل ها با عنوان photovoltaic cell یا سلولهای فوتو ولتاییک نیز شناخته میشوند.

در واقع پنلهای خورشیدی یا سولار پنل از کنار هم قرار گرفتن تعدادی سلول خورشیدی تشکیل میشوند. این پنلهای خورشیدی در اندازه و قدرتهای مختلف تولید میشوند مثلا از کسری از یک وات تا صدها وات.

صفحات سولار یا خورشیدی از لحاظ تکنولوژی ساخت به سه سته زیر تقسیم میشوند :

 

صفحات فتوولتائیک پلی کریستال (Photovoltaic Polycrystalline)

صفحات پلی کریستال از ویفر های سیلیکون ساخته میشوند و دارای ساختار غیر یکنواخت هستند این نوع از سلولها که اکثر بازار پنلهای خورشیدی را در اختیار دارند دارای راندمان پایینتری نسبت به صفحات مونو کریستال هستند و بنابر این قیمت پایینتری نیز دارند راندمان پنل های خورشیدی پلی کریستال در حدود  12 تا 16 درصد است . از مزایای سلولهای پلی کریستال به مونو کریستال میتوان به قیمت پایین تر و سرعت تولید بالاتر آن اشاره کرد و عیب آن نیز راندمان پایینتر آن میباشد.

صفحات فتوولتائیک مونوکریستال (Photovoltaic Monocrystalline Panels)

صفحات خورشیدی مونوکریستال نیز از برش ویفرهای سیلیکون ساخته میشوند. این صفحات به صورت سری و موازی به صورت یک ماتریس در کنار همدیگر قرار میگیرند و تشکیل یک پنل خورشیدی مونو کریستال را میدهند معمولا پنلها را داخل قاب آلمینیومی قرار میدهند و برای استحکام ویفرها روی آنها از رزینهای شفاف استفاده میکنند.

پنلهای فوتو ولتاییک مونو کریستا از راندمان 16 تا 20 درصد بهره میبرند که نسبت به تکنولوژی مونو کریستال به مراتب بهتر میباشند اما فرایند تولید آنها طولانی تر و قیمتشان نیط نسبت به نمونه های پلی کریستال بالاتر میباشد.

تفاوت پنلهای مونو وپلی کریستال mono vs poly

تفاوت سولار پلی کریستال و مونو کریستال


صفحات فتوولتائیک نواری (Thin Film).

 صفحات فوتو ولتاییک نواری یا Thin Film  از نوارهای بسیار نازک نیمه هادی تشکیل میشوند و دارای انعطافپزیری خوبی هستند. استفاده ازاین سلولهای خورشیدی به دلیل راندمان پایینتر نسبت به سایر تکنولوژیها زیاد رایج نیست و بیشتر در پروژه های کوچک که نیاز به سلولهای انعطاف پذیر وجود دارد استفاده میشوند.

 

برای تهیه پنل خورشیدی و سایر ملزومات به  این لینک مراجعه نمایید.

نظر ها  (0) دماسنج دیجیتالی

نکاتی در مورد انتخاب دماسنج دیجیتالی :

برای انتخاب یک دماسنج دیجیتالی مناسب ابتدا بایستی ببینیم که کاربرد این دماسنج کجاست و یا اینکه ما چه چیزی را از این دماسنج دیجیتالی انتظار داریم. دماسنجها انواع بسیار زیادی دارند که با توجه به کاربردشان دارای حساسیت ، دقت و رنج دمایی متفاوتی هستند.

برخی از انواع ماسنج دیجیتالی  :

دماسنج و رطوبت سنج دیجیتالی محیطی

این نوع از دماسنج دیجیتالی که عمدتا همراه با رطوبت سنج دیجیتالی و ساعت در یک دستگاه به صورت ترکیبی ساخته میشوند و معمولا فقط نمایشگر دما و رطوبت هستند. این دماسنج رطوبت سنجهای دیجیتالی معمولا دارای دقت قابل قبول و قیمت پایینی هستند و به دلیل استفاده در محیط خانه از طراحی زیبا و صفحه نمایش بزرگی بهره میبرند. دماسنج دیجیتالی محیطی معمولا در خانه ، دفتر کار ، گلخانه های کوچک ، ادارات ، اتاق کودک و ... قابل استفاده است.

دماسنج دیجیتال محیطی

 خرید دماسنج دیجیتالی 

برخی از این نوع نمایشگرهای دما و رطوبت دارای یک سنسور اضافی نیز هستند که معمولا با یک سیم کوتاه حدودا یک متری از نمایشگر فاصله میگیرند و به اصطلاح دمای داخل و خارج را که با IN و OUT مشخص شده را نمایش میدهند. مثلا در یک گلخانه کوچک خانگی دمای داخل بایستی از دمای خانه متفاوت باشد به راحتی این امکان وجود دارد که سنسور دوم را از یک سوراخ داخل گلخانه قرار داد و دمای آن را کنترل کرد و همچنین از این دماسنج دیجیتالی میتوان به عنوان دماسنج اتاق نوزاد و کودک استفاده کرد.

دماسنج رطوبت سنج دیجیتال محیطی

 خرید دماسنج دیجیتالی دو سنسور

به این نوع از دماسنجها اصطلاحا نمایشگر محیطی دما نیز می گویند. مدلهایی که در تصاویر فوق ملاحظه میکنید امکان ذخیره حداکثر و حد اقل دمای ثبت شده را نیز دارند.

 

دماسنج دیجیتالی پزشکی

دماسنج پزشکی همانطور که از نام این محصول مشخص است جزء ابزارآلات پزشکی محسوب میشود ، بنابر این بایستی از دقت  عملکرد بسیار بالایی بهره مند باشد و همچنین مجوزها و استانداردهای لازم را دریافت کرده باشد.

دماسنجهای پزشکی نیز انواع مختلفی دارند ازجمله دماسنج های دیجیتالی غیر تماسی یا لیزری، دماسنجهای دیجیتال تماسی که معمولا زیر بغل یا داخل دهان قرار میگیرند و .. .

دماسنج دیجیتال پزشکی

 

دماسنج دیجیتالی میله ای

از دماسنج دیجیتال میله ای در محیطهای مختلفی از جمله خانه ، محیطهای صنعتی و ... برای اندازه گیری عمق مواد از جمله غذا ، مایعات ، مواد شیمیایی ، غلات و .. استفاده میشود. دماسنج دیجیتال میله ای از یک میله که سنسور دما داخل آن قرار دارد و یک نمایشگر در انتهای آن تشکیل شده است و معمولا از  جنس استیل ضد زنگ و خوردگی درست میشود.

دماسنج میله ای

 

شرایط دسترسی در Rfid Mifare Access conditions

 Access conditions
شرایط دسترسی

The access conditions for every data block and sector trailer are defined by 3 bits,

which are stored non-inverted and inverted in the sector trailer of the specified

sector.

شرایط دسترسی برای هر دیتا بلوک و تریلر سکتور به صورت سه بیت تعریف میشود که به صورت non-inverted و inverted در مکان

مشخصی از بلوک  تریلر هر سکتور ذخیره می شود .

The access bits control the rights of memory access using the secret keys A and B.
اکسس بیت ها کنترل درست دسترسی به حافظه به وسیله کلیدهای آ و بی را  بر عهده دارند .

 The access conditions may be altered, provided one knows the relevant key and the

current access condition allows this operation.

 شرایط دسترسی ممکنه تغییر داده بشه برای کلید مربوطه و شرایط دسترسی جاری اجازه این عملیات را بده .

Remark:
نکته :

With each memory access the internal logic verifies the format of the access
conditions.

هر دسترسی به حافظه توسط منطق درونی و فرمت شرایط دسترسی  بررسی میشود

If it detects a format violation the whole sector is irreversible blocked.

اگر مکانیزم درونی مایفر نقض فرمت شرایط دسترسی را تشخیص دهد  تمام سکتور مذکور به صورت برگشت ناپذیر قفل می شود .


Remark:
نکته :

In the following description the access bits are mentioned in the non-inverted
mode only.

در توضیحات زیر اکسس بیتها به صورت "non-inverted mode" هستند

The internal logic of the MF1ICS50 ensures that the commands are executed only after an
authentication procedure or never

مکانیزم داخلی مایفر مطمعن میشود که دستورات بعد از احراز هویت اجرا شوند و در غیر اینصورت هرگز

AccessBits Valid Command Block Description
C1,3-C2,3-C3,3 
read, write
 3
sector trailer
 
C1,2-C2,2-C3,2 
read, write, increment, decrement,
transfer, restore
 2 Data Block
C1,1-C2,1-C3,1 
read, write, increment, decrement,
transfer, restore
 1  Data Block
C1,0-C2,0-C3,0 
read, write, increment, decrement,
transfer, restore
 0  Data Block

 

Access conditions for the sector trailer Depending on the access bits for the sector trailer (block 3) the read/write access to the
keys and the access bits is specified as ‘never’, ‘key A’, ‘key B’ or key A|B’ (key A or key B).

شرایط دسترسی برای بلوک آخر هرسکتور یا تریلر بلوک وابسته به اکسس بیتهای تریلر بلوک است.

خواندن / نوشتن برای کلیدها و لکسس بیتها مشخص شده است با  ‘never’, ‘key A’, ‘key B’ or key A|B’ (key A or key B).


On chip delivery the access conditions for the sector trailers and key A are predefined as transport configuration.

در کارتهای تحویلی از کارخانه شرایط دسترسی برای تریلر بلوکها و کلید آ از قبل تعریف شده به تنظیمات transport .

Since key B may be read in transport configuration, new cards must be authenticated with key A.

از آنجایی که کلید بی ممکنه در تنظیمات ترانسپورت خونده بشه کارتهای جدید باید با کلید آ  احراز هویت شوند .

Since the access bits themselves can also be blocked, special care should be taken during personalization of cards.

از آنجایی که خو اکسس بیتها نیز میتوانند قفل شوند  ، باید در طمان شخصی سازی کارتها دقت زیادی بکنید .

 

جدول : Access conditions for the sector trailer

Access conditions for the sector trailer

 

نکته : خطوط خاکستری رنگ اکسس کاندیشنهایی هستند که کلید بی قابل خواندن هستند و ممکن است به عنوان حافظه ذخیره سازی دیتا استفاده شود .

 

Access conditions for data blocks

اکسس کاندیشنها برای دیتا بلوک
Depending on the access bits for data blocks (blocks 0...2) the read/write access is specified as ‘never’, ‘key A’, ‘key B’ or ‘key A|B’ (key A or key B).

بسته به اکسس بیتها دسترسی به بلوکهای 0-1-2 از هر سکتور مشخص شده اند که میتوانند هرکز - کلید آ - کلید بی - کلید آ یا کلید بی باشند

The setting of the relevant access bits defines the application and the corresponding applicable commands.


Read/write block: The operations read and write are allowed.


Value block: Allows the additional value operations increment, decrement, transfer and restore.

Value Block معمولا برای سیستمهای تیکتینگ استفاده میشود و امکان افزایش ، کاهش ، انتقال و بازیابی را به برنامه می دهد

 

In one case (‘001’) only read and decrement are possible for a non-rechargeable card.

001 فقط امکان کاهش و خواندن را برای کارتهای غیر قابل شارژ ممکن میکند

In the other case (‘110’) recharging is possible by using key B.
110 امکان شارژ را به وسیله کلید بی به وجود می آورد

 

Manufacturer block: The read-only condition is not affected by the access bits setting!
بلوک صفر فقط خواندنی است و با تنظیمات اکسس بیت قابل تغییر نیست

 

Key management: In transport configuration key A must be used for authentication

 

[1]
if Key B may be read in the corresponding Sector Trailer it cannot serve for authentication (all grey marked lines in previous table). Consequences: If the reader tries to authenticate any block of a sector with key B using grey marked access conditions, the card will refuse any subsequent memory access after authentication.

اگر کارتخوان سعی کند برای احراز هویت هر بلوک از سکتور با کلید بی با اکسس کاندیشنهایی که در جدول فوق خاکستری رنگ نمایش داده شده اند ، کارت ریفیوز (رد) خواهد کرد هر دسترسی را بعد از احراز هویت .

Rfid MIFARE card memory layout

اصطلاحات

UID = Unique ID   کد یونیک
PICC = short for Proximity Integrated Circuit Card (RFID Tag itself) actually your code header explains this. تگ آر اف آی دی

PCD = (Proximity Coupling Device): NXP MFRC522 Contactless Reader IC کارت خوان

 Block 0 = is read only manufacturer data  شماره کارت و اطلاعات کارخانه

یادگیری ساختار حافظه کارتهای RFID

کارتهای Mifare Classic Card در واقع یک حافظه قابل خواندن و نوشتن هستند .

این کارتها از تعدادی سکتور تشکیل شده اند که هر سکتور خود به چهار بلوک تقسیم می شود و  هر بلوک 16 بایت ظرفیت دارد .

مثلا هر کارت یک کیلو بایتی از 16 سکتور * چهار بلوک * 16 بایت تشکیل شده که جمعا 1024 بایت را تشکیل میدهد  . تصویر اول

 

هر سکتور توسط یک کلید محافظت میشود و بلوک چهارم از هر سکتور شامل کلید دسترسی به آن سکتور است . تصویر دوم

Understanding the memory structure of MIFARE Classic cards

The MIFARE Classic card is a memory storage device. The memory is divided into sectors, which are also divided into blocks of 16 bytes.

The MIFARE Classic 1K card has 16 sectors, each of which are divided into four blocks. If we do the math, we can figure out how the memory structure would be like: 16 bytes (1 block) * 4 blocks * 16 sectors = 1024 bytes.

Mifare Card Memory Layout

 

 

کارت های 4 کیلوبایتی دارای 40 سکتور هستند که 32 سکتور آن به بلوکهای  چهارتایی تقسیم شده اند و هشت سکتور آخر نیز به بلوکهای هشت تایی تقسیم شده اند .

32 سکتور * 4 بلوک * 16 بایت

+

8 سکتور * 16 بلوک * 16 بایت

=4096 بایت

The MIFARE Classic 4K card has 40 sectors, 32 of which are divided into four blocks and the remaining 8 are divided into 16 blocks. 16 bytes (1 block) * 4 blocks * 32 sectors + 16 bytes (1 block) * 16 blocks * 8 sectors = 4096 bytes. The memory structure is as follows:

 

Answer to Request

 

With the Answer to Request sequence the MIFARE® RWD (Read Write Device) requests allMIFARE® cards in the antenna field. When a card is in the operating range of a RWD, theRWD continues communication with the appropriate protocol.

Anticollision loop

In the Anticollision loop the serial number of the card is read. If there are several cards in theoperating range of a RWD they can be distinguished by their different serial numbers and onecan be selected (Select card) for further transactions. The unselected cards return to thestandby mode and wait for a new Answer to Request and Anticollision loop.

 

 

Select Card

With the Select Card command the RWD selects one individual card for further authenticationand memory related operations. The card returns the Answer to Select (ATS) code, whichdetermines the individual type of the selected card.

 

 

Access Specification

After identification and selection of one card the RWD specifies the memory location of the following access.

Three Pass Authentication

The appropriate access key for the previously specified access is used for 3 Pass Authentication. Any communication after authentication is automatically encrypted at the sender and decrypted by the receiver.

Read/Write

After authentication any of the following operations may be performed:

READ          reads one block

WRITE        writes one block

DECREMENT    decrements the contents of one block and stores the result

              in the data-register

INCREMENT    increments the contents of one block and stores the result

              in the data-register

TRANSFER     writes the contents of the data-register to one block

RESTORE      stores the contents of one block in the data-register

 

 

The MF1ICS50 IC of a Mifare Classic has integrated a 8192 Bit EEPROM which is split into 16 sectors with 4 blocks.One block consists of 16 bytes (1 Byte = 8 Bit).

 

 

Manufacturer Code (Block 0 of Sector 0)

The first block of the memory is reserved for manufacturer data like 32 bit serial number. This is a read only block. In many documents it is named "Block 0".

Data Block (Block 0 to 3 except "Block 0")

 

Access conditions for the Data Blocks are defined in the Sector Trailers. According to these conditions data can be read, written, incremented, decremented, transferred or restored either with Key A, Key B or never.

 

 

 

 

 بلوک چهارم از هر سکتور به نام سکتور تریلر شناخته میشود که مانند شکلهای بالا شامل کلید

A کلید B

و چهار بایت قواعد دسترسی می باشد .

 

 

 

 

وضعیت بایتهای 6-7-8 در کارتهای تحویل شده از کارخانه

 

 

If Key B may be read in the corresponding Sector Trailer it cannot serve for authentication (all grey marked lines inprevious table). Consequences: If the RWD tries to authenticate any block of a sector with key B using grey marked

access conditions, the card will refuse any subsequent memory access after authentication

 

 

The described memory organization makes it possible to appoint different sectors to different applications and to prevent data corruption by using application specific secret keys. Keys can only be altered by a RWD which has stored the actual Key A or Key B if this is allowed according to access conditions. Otherwise the actual key cannot be changed any more.

Before the execution of a command the correct format of the Access Conditions is checked by the Card-IC. Thus , when programming the Sector Trailer the card needs to be fixed within the operating range of a RWD's antenna to prevent interruption of the write operation because any unsuccessful write operation may lead to blocking the whole sector.

 

 

 

Example of a New Mifare Classic 1K Card

The follow memory dump illustrates the structure of a 1K Mifare Classic Card, where the data and Sector Trailer blocks can be clearly seen:

برای مشاهده بلوکهای حافظه از نرم افزارهای اندروید زیر استفاده نمایید

MifareClassicTool-2.0.7.apk

MifareClassicTool-2.0.7.apk

دانلود از گوگل پلی استور

------------------------------------------------------------------------------------------------

 

nfctaginfo.apk

دانلود از گوگل پلی استور

نمونه ای از حافظه یک کارت خالی تریلر بلوک شامل کلیدهای آ و بی و قواعد دسترسی به بلوکها کاملا مشخص هستند

 

[--------------------------Start of Memory Dump--------------------------]
------------------------Sector 0-------------------------
Block 0  8E 02 6F 66 85 08 04 00 62 63 64 65 66 67 68 69  ?.of?...bcdefghi
Block 1  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 2  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 3  00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF  ......ÿ.?iÿÿÿÿÿÿ
------------------------Sector 1-------------------------
Block 4  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 5  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 6  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 7  00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF  ......ÿ.?iÿÿÿÿÿÿ
------------------------Sector 2-------------------------
Block 8  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 9  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 11 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF  ......ÿ.?iÿÿÿÿÿÿ
------------------------Sector 3-------------------------
Block 12 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 13 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 15 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF  ......ÿ.?iÿÿÿÿÿÿ
------------------------Sector 4-------------------------
Block 16 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 17 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 19 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF  ......ÿ.?iÿÿÿÿÿÿ
------------------------Sector 5-------------------------
Block 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 21 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 22 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 23 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF  ......ÿ.?iÿÿÿÿÿÿ
------------------------Sector 6-------------------------
Block 24 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 25 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 26 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 27 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF  ......ÿ.?iÿÿÿÿÿÿ
------------------------Sector 7-------------------------
Block 28 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 29 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 31 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF  ......ÿ.?iÿÿÿÿÿÿ
------------------------Sector 8-------------------------
Block 32 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 33 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 34 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 35 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF  ......ÿ.?iÿÿÿÿÿÿ
------------------------Sector 9-------------------------
Block 36 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 37 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 38 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 39 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF  ......ÿ.?iÿÿÿÿÿÿ
------------------------Sector 10-------------------------
Block 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 41 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 42 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 43 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF  ......ÿ.?iÿÿÿÿÿÿ
------------------------Sector 11-------------------------
Block 44 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 45 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 46 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 47 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF  ......ÿ.?iÿÿÿÿÿÿ
------------------------Sector 12-------------------------
Block 48 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 49 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 51 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF  ......ÿ.?iÿÿÿÿÿÿ
------------------------Sector 13-------------------------
Block 52 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 53 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 54 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 55 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF  ......ÿ.?iÿÿÿÿÿÿ
------------------------Sector 14-------------------------
Block 56 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 57 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 58 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 59 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF  ......ÿ.?iÿÿÿÿÿÿ
------------------------Sector 15-------------------------
Block 60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 61 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 62 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
Block 63 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF  ......ÿ.?iÿÿÿÿÿÿ
[---------------------------End of Memory Dump---------------------------]

 

 

 

 

MFRC522.h – A Library to use ARDUINO RFID MODULE KIT 13.56 MHZ BY COOQROBOT.

 

There are three hardware components involved:

 

1) The micro controller: An Arduino

2) The PCD (Proximity Coupling Device): NXP MFRC522 Contactless Reader IC

3) The PICC (short for Proximity Integrated Circuit Card): A card or tag using the ISO 14443A interface, eg Mifare or NTAG203.

 

 

MIFARE Classic 1K (MF1S503x):

 

Has 16 sectors * 4 blocks/sector * 16 bytes/block = 1024 bytes. The blocks are numbered 0-63.

 

Block 3 in each sector is the Sector Trailer.

*                         Bytes 0-5:   Key A

*                         Bytes 6-8:   Access Bits

*                         Bytes 9:     User data

*                         Bytes 10-15: Key B (or user data)

 

Block 0 is read only manufacturer data.

 

To access a block, an authentication using a key from the block's sector must be performed first.

 

Example: To read from block 10, first authenticate using a key from sector 3 (blocks 8-11).

 

All keys are set to FFFFFFFFFFFFh at chip delivery.

 

Warning: Please read section 8.7 "Memory Access". It includes this text: if the PICC detects a format violation the whole sector is irreversibly blocked.

  "value block" برای کاربردها تیکتینگ استفاده می شود

To use a block in "value block" mode (for Increment/Decrement operations) you need to change the sector trailer. Use PICC_SetAccessBits() to calculate the bit patterns.

 

Commands sent to the PICC.

 

The commands used by the PCD to manage communication with several PICCs (ISO 14443-3, Type A, section 6.4)

 

 

PICC_CMD_REQA = 0x26,    

REQuest command, Type A. Invites PICCs in state IDLE to go to READY and prepare for anticollision or selection. 7 bit frame.

PICC_CMD_WUPA = 0x52,           

Wake-UP command, Type A. Invites PICCs in state IDLE and HALT to go to READY(*) and prepare for anticollision or selection. 7 bit frame.

PICC_CMD_CT  = 0x88,            

Cascade Tag. Not really a command, but used during anti collision.

PICC_CMD_SEL_CL1    = 0x93,            

Anti collision/Select, Cascade Level 1

PICC_CMD_SEL_CL2    = 0x95,            

Anti collision/Select, Cascade Level 2

PICC_CMD_SEL_CL3    = 0x97,            

Anti collision/Select, Cascade Level 3

PICC_CMD_HLTA = 0x50,           

HaLT command, Type A. Instructs an ACTIVE PICC to go to state HALT.

 

 

The commands used for MIFARE Classic

Use PCD_MFAuthent to authenticate access to a sector, then use these commands to read/write/modify the blocks on the sector.

The read/write commands can also be used for MIFARE Ultralight.

 

 

PICC_CMD_MF_AUTH_KEY_A    = 0x60,            

Perform authentication with Key A

PICC_CMD_MF_AUTH_KEY_B    = 0x61,            

Perform authentication with Key B

PICC_CMD_MF_READ           = 0x30,            

Reads one 16 byte block from the authenticated sector of the PICC. Also used for MIFARE Ultralight.

PICC_CMD_MF_WRITE          = 0xA0,            

Writes one 16 byte block to the authenticated sector of the PICC. Called "COMPATIBILITY WRITE" for MIFARE Ultralight.

PICC_CMD_MF_DECREMENT     = 0xC0,            

Decrements the contents of a block and stores the result in the internal data register.

PICC_CMD_MF_INCREMENT     = 0xC1,            

Increments the contents of a block and stores the result in the internal data register.

PICC_CMD_MF_RESTORE        = 0xC2,            

Reads the contents of a block into the internal data register.

PICC_CMD_MF_TRANSFER      = 0xB0,            

Writes the contents of the internal data register to a block.

 

 

 

List of the functions in the library

 

Functions for setting up the Arduino

 

MFRC522(byte chipSelectPin, byte resetPowerDownPin);

void setSPIConfig();

 

Basic interface functions for communicating with the MFRC522

 

void PCD_WriteRegister(byte reg, byte value);

void PCD_WriteRegister(byte reg, byte count, byte *values);

byte PCD_ReadRegister(byte reg);

void PCD_ReadRegister(byte reg, byte count, byte *values, byte rxAlign = 0);

void setBitMask(unsigned char reg, unsigned char mask);

void PCD_SetRegisterBitMask(byte reg, byte mask);

void PCD_ClearRegisterBitMask(byte reg, byte mask);

byte PCD_CalculateCRC(byte *data, byte length, byte *result);

 

Functions for manipulating the MFRC522

 

void PCD_Init();

void PCD_Reset();

void PCD_AntennaOn();

 

Functions for communicating with PICCs

 

byte PCD_TransceiveData(byte *sendData, byte sendLen, byte *backData, byte *backLen, byte *validBits = NULL, byte rxAlign = 0, bool checkCRC = false);

 

 

byte PCD_CommunicateWithPICC(byte command, byte waitIRq, byte *sendData, byte sendLen, byte *backData = NULL, byte *backLen = NULL, byte *validBits = NULL, byte rxAlign = 0, bool checkCRC = false);

 

byte PICC_RequestA(byte *bufferATQA, byte *bufferSize);

byte PICC_WakeupA(byte *bufferATQA, byte *bufferSize);

byte PICC_REQA_or_WUPA(   byte command, byte *bufferATQA, byte *bufferSize); 

byte PICC_Select(Uid *uid, byte validBits = 0);

byte PICC_HaltA(); 

 

Functions for communicating with MIFARE PICCs

 

byte PCD_Authenticate(byte command, byte blockAddr, MIFARE_Key *key, Uid *uid);

void PCD_StopCrypto1();

byte MIFARE_Read(byte blockAddr, byte *buffer, byte *bufferSize);

byte MIFARE_Write(byte blockAddr, byte *buffer, byte bufferSize);

byte MIFARE_Decrement(byte blockAddr, long delta);

byte MIFARE_Increment(byte blockAddr, long delta);

byte MIFARE_Restore(byte blockAddr);

byte MIFARE_Transfer(byte blockAddr);

byte MIFARE_Ultralight_Write(byte page, byte *buffer, byte bufferSize);

      

Support functions

 

byte PCD_MIFARE_Transceive(      byte *sendData, byte sendLen, bool acceptTimeout = false);

const char *GetStatusCodeName(byte code);

byte PICC_GetType(byte sak);

const char *PICC_GetTypeName(byte type);

void PICC_DumpToSerial(Uid *uid);

void PICC_DumpMifareClassicToSerial(Uid *uid, byte piccType, MIFARE_Key *key);

void PICC_DumpMifareClassicSectorToSerial(Uid *uid, MIFARE_Key *key, byte sector);

void PICC_DumpMifareUltralightToSerial();

void MIFARE_SetAccessBits(byte *accessBitBuffer, byte g0, byte g1, byte g2, byte g3);

 

 

Convenience functions - does not add extra functionality

 

bool PICC_IsNewCardPresent();

bool PICC_ReadCardSerial();     

 

Detailed documentation – enum and structures

 

PICC types we can detect. Remember to update PICC_GetTypeName() if you add more.

 

enum PICC_Type

 

Return codes from the functions in this class. Remember to update GetStatusCodeName() if you add more.

 

enum StatusCode

 

A struct used for passing the UID of a PICC.

 

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

 

A struct used for passing a MIFARE Crypto1 key

 

typedef struct {

       byte          keyByte[MF_KEY_SIZE];

       } MIFARE_Key;

 

Example:

// Prepare key - all keys are set to FFFFFFFFFFFFh at chip delivery from the factory.

MFRC522::MIFARE_Key key;

for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF;

 

Member variables

 

       Uid uid;            Used by PICC_ReadCardSerial().

 

Detailed documentation – functions

 

+Create object instance

MFRC522(

byte chipSelectPin,       Arduino pin used for SPI chip select

byte resetPowerDownPin    Arduino pin used for SPI reset

);

Example:

#include <SPI.h>

#include <MFRC522.h>

#define SS_PIN 10   //Arduino Uno

#define RST_PIN 9

MFRC522 mfrc522(SS_PIN, RST_PIN);       // Create MFRC522 instance.

 

+Initializes the MFRC522 chip.

void MFRC522::PCD_Init()

Example:

void setup() {

       Serial.begin(9600);       // Init serial communications with PC

       SPI.begin();               // Init SPI bus

       mfrc522.PCD_Init();       // Init MFRC522 card

}

 

+Set SPI bus to work with MFRC522 chip.

 

Please call this function if you have changed the SPI config since the MFRC522 constructor was run.

 

void MFRC522::setSPIConfig()

 

+Performs a soft reset on the MFRC522 chip and waits for it to be ready again.

void MFRC522::PCD_Reset()

 

+Turns the antenna on by enabling pins TX1 and TX2.

After a reset these pins are disabled.

void MFRC522::PCD_AntennaOn()

 

+Transmits a REQuest command, Type A. Invites PICCs in state IDLE to go to READY and prepare for anticollision or selection. 7 bit frame.

Beware: When two PICCs are in the field at the same time I often get STATUS_TIMEOUT - probably due do bad antenna design.

return STATUS_OK on success, STATUS_??? otherwise.

byte MFRC522::PICC_RequestA(

byte *bufferATQA,   The buffer to store the ATQA (Answer to request) in

byte *bufferSize    Buffer size, at least two bytes. Also number of bytes returned if STATUS_OK.

 

 

+Transmits a Wake-UP command, Type A. Invites PICCs in state IDLE and HALT to go to READY(*) and prepare for anticollision or selection. 7 bit frame.

Beware: When two PICCs are in the field at the same time I often get STATUS_TIMEOUT - probably due do bad antenna design.

return STATUS_OK on success, STATUS_??? otherwise.

byte MFRC522::PICC_WakeupA(     

byte *bufferATQA,   The buffer to store the ATQA (Answer to request) in

byte *bufferSize    Buffer size, at least two bytes. Also number of bytes returned if STATUS_OK.

 

 

+Transmits SELECT/ANTICOLLISION commands to select a single PICC.

Before calling this function the PICCs must be placed in the READY(*) state by calling PICC_RequestA() or PICC_WakeupA().

On success:

 

-The chosen PICC is in state ACTIVE(*) and all other PICCs have returned to state IDLE/HALT. (Figure 7 of the ISO/IEC 14443-3 draft.)

-The UID size and value of the chosen PICC is returned in *uid along with the SAK.

 

 

A PICC UID consists of 4, 7 or 10 bytes.

Only 4 bytes can be specified in a SELECT command, so for the longer UIDs two or three iterations are used:

 

UID size     Number of UID bytes        Cascade levels      Example of PICC

========     ===================        ==============      ===============

single              4                    1                    MIFARE Classic

double              7                    2                    MIFARE Ultralight

triple              10                  3                    Not currently in use?

 

return STATUS_OK on success, STATUS_??? otherwise.

byte MFRC522::PICC_Select(

Uid *uid,                  Pointer to Uid struct. Normally output, but can also

                           be used to supply a known UID.

 

byte validBits             The number of known UID bits supplied in *uid.

 

                           Normally 0. If set you must also supply uid->size.

 

Description of buffer structure:

 

Byte 0: SEL         Indicates the Cascade Level: PICC_CMD_SEL_CL1, PICC_CMD_SEL_CL2 or PICC_CMD_SEL_CL3

Byte 1: NVB                Number of Valid Bits (in complete command, not just the UID): High nibble: complete bytes, Low nibble: Extra bits.

Byte 2: UID-data or CT    See explanation below. CT means Cascade Tag.

Byte 3: UID-data

Byte 4: UID-data

Byte 5: UID-data

Byte 6: BCC                Block Check Character - XOR of bytes 2-5

Byte 7: CRC_A

Byte 8: CRC_A

 

The BCC and CRC_A is only transmitted if we know all the UID bits of the current Cascade Level.

Description of bytes 2-5: (Section 6.5.4 of the ISO/IEC 14443-3 draft: UID contents and cascade levels)

 

UID size     Cascade levelByte2  Byte3  Byte4  Byte5

========     ==================  =====  =====  =====

4 bytes             1             uid0   uid1   uid2   uid3

7 bytes             1             CT     uid0   uid1   uid2

                     2             uid3   uid4   uid5   uid6

10 bytes            1             CT     uid0   uid1   uid2

                     2             CT     uid3   uid4   uid5

 

 

 

+Instructs a PICC in state ACTIVE(*) to go to state HALT.

return STATUS_OK on success, STATUS_??? otherwise.

byte PICC_HaltA();

Example:

// Halt PICC

mfrc522.PICC_HaltA();

 

 

+Executes the MFRC522 MFAuthent command.

This command manages MIFARE authentication to enable a secure communication to any MIFARE Mini, MIFARE 1K and MIFARE 4K card.

The authentication is described in the MFRC522 datasheet section 10.3.1.9 and http://www.nxp.com/documents/data_sheet/MF1S503x.pdf section 10.1. for use with MIFARE Classic PICCs.

The PICC must be selected - ie in state ACTIVE(*) - before calling this function.

Remember to call PCD_StopCrypto1() at the end of communication with the authenticated PICC - otherwise no new communications can start.

All keys are set to FFFFFFFFFFFFh at chip delivery.

return STATUS_OK on success, STATUS_??? otherwise. Probably STATUS_TIMEOUT if you supply the wrong key.

byte MFRC522::PCD_AuthenticateI(

byte command,       PICC_CMD_MF_AUTH_KEY_A or PICC_CMD_MF_AUTH_KEY_B

byte blockAddr,            The block number. See numbering in the comments in

                          the .h file.

MIFARE_Key *key,           Pointer to the Crypto1 key to use (6 bytes)

Uid *uid                   Pointer to Uid struct. The first 4 bytes of the UID

                           is used.

)

Example:

MFRC522::MIFARE_Key key;

for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF;

byte trailerBlock   = 7;

byte status;

if ( ! mfrc522.PICC_ReadCardSerial()) return;

status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(mfrc522.uid));

if (status != MFRC522::STATUS_OK) {

   Serial.print("PCD_Authenticate() failed: ");

   Serial.println(mfrc522.GetStatusCodeName(status));

   return;

}

 

+Used to exit the PCD from its authenticated state.

Remember to call PCD_StopCrypto1() at the end of communication with the authenticated PICC - otherwise no new communications can start.

void MFRC522::PCD_StopCrypto1()

Example:

// Stop encryption on PCD

mfrc522.PCD_StopCrypto1();                           

 

+Reads 16 bytes (+ 2 bytes CRC_A) from the active PICC.

For MIFARE Classic the sector containing the block must be authenticated before calling this function.

For MIFARE Ultralight only addresses 00h to 0Fh are decoded.

* The MF0ICU1 returns a NAK for higher addresses.

* The MF0ICU1 responds to the READ command by sending 16 bytes starting from

      the page address defined by the command argument.

* For example; if blockAddr is 03h then pages 03h, 04h, 05h, 06h are returned.

* A roll-back is implemented: If blockAddr is 0Eh, then the contents of pages 0Eh, 0Fh, 00h and 01h are returned.

The buffer must be at least 18 bytes because a CRC_A is also returned.

Checks the CRC_A before returning STATUS_OK.

return STATUS_OK on success, STATUS_??? otherwise.

byte MFRC522::MIFARE_Read(

byte blockAddr,     MIFARE Classic: The block (0-0xff) number.

                     MIFARE Ultralight: The first page to return data from.

byte *buffer,The buffer to store the data in

 

byte *bufferSize    Buffer size, at least 18 bytes. Also number of bytes returned

                    if STATUS_OK.

Example:

byte valueBlockA   = 4; byte buffer[18]; byte size = sizeof(buffer);

byte status = mfrc522.MIFARE_Read(valueBlockA, buffer, &size);

 

+Writes 16 bytes to the active PICC.

For MIFARE Classic the sector containing the block must be authenticated before calling this function.

For MIFARE Ultralight the operation is called "COMPATIBILITY WRITE".

Even though 16 bytes are transferred to the Ultralight PICC, only the least significant 4 bytes (bytes 0 to 3)are written to the specified address. It is recommended to set the remaining bytes 04h to 0Fh to all logic 0.

return STATUS_OK on success, STATUS_??? otherwise.

byte MFRC522::MIFARE_Write(     

byte blockAddr,

                     MIFARE Classic: The block (0-0xff) number.

                     MIFARE Ultralight: The page (2-15) to write to.

byte *buffer,The 16 bytes to write to the PICC

byte bufferSize     Buffer size, must be at least 16 bytes. Exactly 16 bytes are

                     written.

Example:

byte valueBlockA   = 4;

byte value1Block[] = { 1,2,3,4, 5,6,7,8, 9,10,255,12, 13,14,15,16};

status = mfrc522.MIFARE_Write(valueBlockA, value1Block, 16);

if (status != MFRC522::STATUS_OK) {

   Serial.print("MIFARE_Write() failed: ");

   Serial.println(mfrc522.GetStatusCodeName(status));

}

                                        

 

+MIFARE Decrement subtracts the delta from the value of the addressed block, and stores the result in a volatile memory.

For MIFARE Classic only. The sector containing the block must be authenticated before calling this function.

Only for blocks in "value block" mode, ie with access bits [C1 C2 C3] = [110] or [001].

Use MIFARE_Transfer() to store the result in a block.

return STATUS_OK on success, STATUS_??? otherwise.

byte MFRC522::MIFARE_Decrement(

byte blockAddr,     The block (0-0xff) number.

long delta          This number is subtracted from the value of block blockAddr.

 

             

+MIFARE Increment adds the delta to the value of the addressed block, and stores the result in a volatile memory.

For MIFARE Classic only. The sector containing the block must be authenticated before calling this function.

Only for blocks in "value block" mode, ie with access bits [C1 C2 C3] = [110] or [001].

Use MIFARE_Transfer() to store the result in a block.

return STATUS_OK on success, STATUS_??? otherwise.

byte MFRC522::MIFARE_Increment( 

byte blockAddr,     The block (0-0xff) number.

long delta          This number is added to the value of block blockAddr.            

Example:

// Add 1 to the value of valueBlockA and store the result in valueBlockA.

byte valueBlockA    = 5;

Serial.print("Adding 1 to value of block "); Serial.println(valueBlockA);

byte status = mfrc522.MIFARE_Increment(valueBlockA, 1);

if (status != MFRC522::STATUS_OK) {

       Serial.print("MIFARE_Increment() failed: ");

       Serial.println(mfrc522.GetStatusCodeName(status));

       return;

}

status = mfrc522.MIFARE_Transfer(valueBlockA);

if (status != MFRC522::STATUS_OK) {

       Serial.print("MIFARE_Transfer() failed: ");

       Serial.println(mfrc522.GetStatusCodeName(status));

       return;

}

                          

 

+MIFARE Restore copies the value of the addressed block into a volatile memory.

For MIFARE Classic only. The sector containing the block must be authenticated before calling this function.

Only for blocks in "value block" mode, ie with access bits [C1 C2 C3] = [110] or [001].

Use MIFARE_Transfer() to store the result in a block.

return STATUS_OK on success, STATUS_??? otherwise.

byte MFRC522::MIFARE_Restore(   

byte blockAddr      The block (0-0xff) number.

The datasheet describes Restore as a two step operation, but does not explain what data to transfer in step 2.Doing only a single step does not work, so I chose to transfer 0L in step two.

 

+Helper function for the two-step MIFARE Classic protocol operations Decrement, Increment and Restore.

return STATUS_OK on success, STATUS_??? otherwise.

byte MFRC522::MIFARE_TwoStepHelper(   

byte command,The command to use

byte blockAddr,     The block (0-0xff) number.

long data           The data to transfer in step 2

                                                              )

 

+MIFARE Transfer writes the value stored in the volatile memory into one MIFARE Classic block.

For MIFARE Classic only. The sector containing the block must be authenticated before calling this function.

Only for blocks in "value block" mode, ie with access bits [C1 C2 C3] = [110] or [001].

return STATUS_OK on success, STATUS_??? otherwise.

byte MFRC522::MIFARE_Transfer(  

byte blockAddr      The block (0-0xff) number.

                                               

 

+Returns a string pointer to a status code name.

const char *MFRC522::GetStatusCodeName(

byte code    One of the StatusCode enums.

                                                      

       code values         return values

       STATUS_OK:                "Success."

       STATUS_ERROR:             "Error in communication."

       STATUS_COLLISION:  "Collision 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:      "A MIFARE PICC responded with NAK."

       default:                  "Unknown error"

      

Example:

Serial.println(mfrc522.GetStatusCodeName(status));

 

+Translates the SAK (Select Acknowledge) to a PICC type.

return PICC_Type

byte MFRC522::PICC_GetType(

byte sak            The SAK byte returned from PICC_Select().

 

                    

sak                 return value

sak & 0x04          PICC_TYPE_NOT_COMPLETE

0x09                PICC_TYPE_MIFARE_MINI

0x08                PICC_TYPE_MIFARE_1K

0x18                PICC_TYPE_MIFARE_4K

0x00                PICC_TYPE_MIFARE_UL

0x10 or 0x11PICC_TYPE_MIFARE_PLUS

0x01                PICC_TYPE_TNP3XXX

sak & 0x20          PICC_TYPE_ISO_14443_4

sak & 0x40          PICC_TYPE_ISO_18092

else                PICC_TYPE_UNKNOWN

 

+Returns a string pointer to the PICC type name.

const char *MFRC522::PICC_GetTypeName(

byte piccTypeOne of the PICC_Type enums.

 

 

piccType                   return value

PICC_TYPE_ISO_14443_4     "PICC compliant with ISO/IEC 14443-4"

PICC_TYPE_ISO_18092:      "PICC compliant with ISO/IEC 18092 (NFC)"

PICC_TYPE_MIFARE_MINI     "MIFARE Mini, 320 bytes"

PICC_TYPE_MIFARE_1K"MIFARE 1KB"

PICC_TYPE_MIFARE_4K"MIFARE 4KB"

PICC_TYPE_MIFARE_UL"MIFARE Ultralight or Ultralight C"

PICC_TYPE_MIFARE_PLUS     "MIFARE Plus"

 

PICC_TYPE_TNP3XXX          "MIFARE TNP3XXX"

PICC_TYPE_NOT_COMPLETE    "SAK indicates UID is not complete."

PICC_TYPE_UNKNOWN          "Unknown type”

Example:

Serial.println(mfrc522.PICC_GetTypeName(piccType));

 

+Dumps debug info about the selected PICC to Serial.

On success the PICC is halted after dumping the data.

For MIFARE Classic the factory default key of 0xFFFFFFFFFFFF is tried.

void MFRC522::PICC_DumpToSerial(

Uid *uid     Pointer to Uid struct returned from a successful PICC_Select().

Example:

mfrc522.PICC_DumpToSerial(&(mfrc522.uid));

 

+Dumps memory contents of a sector of a MIFARE Classic PICC.

Uses PCD_Authenticate(), MIFARE_Read() and PCD_StopCrypto1.

Always uses PICC_CMD_MF_AUTH_KEY_A because only Key A can always read the sector trailer access bits.

void MFRC522::PICC_DumpMifareClassicSectorToSerial(

Uid *uid,           Pointer to Uid struct returned from a successful PICC_Select()

MIFARE_Key *key,    Key A for the sector.

byte sector         The sector to dump, 0..39.

 

+Calculates the bit pattern needed for the specified access bits. In the [C1 C2 C3] tuples C1 is MSB (=4) and C3 is LSB (=1).

void MFRC522::MIFARE_SetAccessBits(   

byte *accessBitBuffer,    Pointer to byte 6, 7 and 8 in the sector trailer.

                          Bytes [0..2] will be set.

 

byte g0,                   Access bits [C1 C2 C3] for block 0

                           (for sectors 0-31) or blocks 0-4 (for sectors 32-39)

 

byte g1,                   Access bits C1 C2 C3] for block 1 (for sectors 0-31)

                           or blocks 5-9 (for sectors 32-39)

 

byte g2,                   Access bits C1 C2 C3] for block 2 (for sectors 0-31)

                           or blocks 10-14 (for sectors 32-39)

 

byte g3                    Access bits C1 C2 C3] for the sector trailer, block 3

                           (for sectors 0-31) or block 15 (for sectors 32-39)

 

The access bits are stored in a peculiar fashion.

There are four groups:

 

g[3]   Access bits for the sector trailer, block 3 (for sectors 0-31) or block 15 (for sectors 32-39)

 

g[2]   Access bits for block 2 (for sectors 0-31) or blocks 10-14 (for sectors 32-39)

g[1]   Access bits for block 1 (for sectors 0-31) or blocks 5-9 (for sectors 32-39)

g[0]   Access bits for block 0 (for sectors 0-31) or blocks 0-4 (for sectors 32-39)

 

Each group has access bits [C1 C2 C3]. In this code C1 is MSB and C3 is LSB.

The four CX bits are stored together in a nibble cx and an inverted nibble cx_.

Example:

// Sector trailer that defines blocks 5 and 6 as Value Blocks and enables key B.

byte trailerBuffer[] = {255,255,255,255,255,255,0,0,0,0, 255,255,255,255,255,255};

// Keep default keys.

// g1=6(i.e.110) => block 5 value block. Key B write&increment, A or B decrement.

// g2=6 => Same thing for block 6.

// g3=3 => Key B must be used to modify the Sector Trailer. Key B becomes valid.

mfrc522.MIFARE_SetAccessBits(&trailerBuffer[6], 0, 6, 6, 3);

 

+Check if a card is present

bool MFRC522::PICC_IsNewCardPresent()

Returns true if a PICC responds to PICC_CMD_REQA.

Only "new" cards in state IDLE are invited. Sleeping cards in state HALT are ignored.

Example:

// Look for new cards

if ( ! mfrc522.PICC_IsNewCardPresent()) return;

 

 

+Read Card Serial

bool MFRC522::PICC_ReadCardSerial()

Simple wrapper around PICC_Select.

Returns true if a UID could be read.The read UID is available in the class variable uid.

Remember to call PICC_IsNewCardPresent(), PICC_RequestA() or PICC_WakeupA() first.

return true if one selected

Now a card is selected. The UID and SAK is in mfrc522.uid.

Example:

Serial.print("Card UID:");

for (byte i = 0; i < mfrc522.uid.size; i++) {

   Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");

   Serial.print(mfrc522.uid.uidByte[i], HEX);

}

// Dump PICC type

byte piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);

Serial.print("PICC type: ");

Serial.println(mfrc522.PICC_GetTypeName(piccType));

if ( piccType != MFRC522::PICC_TYPE_MIFARE_MINI

     && piccType != MFRC522::PICC_TYPE_MIFARE_1K

     &&       piccType != MFRC522::PICC_TYPE_MIFARE_4K) {

     Serial.println("This sample only works with MIFARE Classic cards.");

     return;

}

 

How to convert a normal block into a value block

Usually a normal block has 000 access bits, while a value block has 110 access bits

Example:

byte valueBlockA    = 5;

byte valueBlockB    = 6;

byte trailerBlock   = 7;

// We need a sector trailer with blocks 5 and 6 as Value Blocks and enables key B.

byte trailerBuffer[] = { 255,255,255,255,255,255,

                          0,0,0,0,255,255,255,255,255,255}; // Keep default keys.

// g1=6 => block 5 as value block. Key B to write&increment, A or B for decrement.

// g2=6 => Same thing for block 6.

// g3=3 => Key B must be used to modify the Sector Trailer. Key B becomes valid.

mfrc522.MIFARE_SetAccessBits(&trailerBuffer[6], 0, 6, 6, 3);

byte status = mfrc522.MIFARE_Write(trailerBlock, trailerBuffer, 16);

if (status != MFRC522::STATUS_OK) {

       Serial.print("MIFARE_Write() failed: ");

       Serial.println(mfrc522.GetStatusCodeName(status));

       return;

}     

 

How to setup a Value Block with a value set to zero

Example:

byte blockAddr=5;

byte valueBlock[] = {0,0,0,0, 255,255,255,255, 0,0,0,0,                                                           blockAddr,~blockAddr,blockAddr,~blockAddr };

byte status = mfrc522.MIFARE_Write(blockAddr, valueBlock, 16);

if (status != MFRC522::STATUS_OK) {

       Serial.print("MIFARE_Write() failed: ");

       Serial.println(mfrc522.GetStatusCodeName(status));

}

 

 

 

 

تغییر کلیدهای A و B مایفر
برای تغییر کلیدهای A و B کارتهای مایفر باید در تریلر بلوک هر سکتور اطلاعات را بنویسیم .
همانطور که قبلا گفته شد تریلر بلوک Trailer Block شامل 16 بایت است که 6 بایت کلید A و 4 بایت قواعد دسترسی و 6 بایت کلید B میباشد .
 
// In this sample we use the second sector,
    // that is: sector #1, covering block #4 up to and including block #7
    byte sector         = 1;
    byte valueBlockA    = 5;
    byte valueBlockB    = 6;
    byte trailerBlock   = 7;      //شماره تریلر بلوک در واقع بلوک 4 از سکتور 2
    MFRC522::StatusCode status;
    byte buffer[18];
    byte size = sizeof(buffer);
    long value;

    // Authenticate using key A تایید اعتبار با کلید آ
    Serial.println(F("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.print(F("PCD_Authenticate() failed: "));
        Serial.println(mfrc522.GetStatusCodeName(status));
        return;
    }

    // Show the whole sector as it currently is
    Serial.println(F("Current data in sector:"));
    mfrc522.PICC_DumpMifareClassicSectorToSerial(&(mfrc522.uid), &key, sector);
    Serial.println();
    
    // We need a sector trailer that defines blocks 5 and 6 as Value Blocks and enables key B
    // The last block in a sector (block #3 for Mifare Classic 1K) is the Sector Trailer.
    // See http://www.nxp.com/documents/data_sheet/MF1S503x.pdf sections 8.6 and 8.7:
    //      Bytes 0-5:   Key A
    //      Bytes 6-8:   Access Bits
    //      Bytes 9:     User data
    //      Bytes 10-15: Key B (or user data)
   // ابتدا تریلر بلاک را به صورت یک آرایه از نوع بایت تعریف کرده و 6 بایت کلید آ و 6 بایت کلید ب را مینویسیم و 4 بایت قواعد دسترسی را صفر قرار میدهیم
   // البته میتوان از همان اول قواعد دسترسی را نوشت ولی راه درست استفاده از تابع اکسس بیت است
    byte trailerBuffer[] = {
        32, 33, 34, 35, 36, 37,       // Keep default key A
        0, 0, 0,
        0,
        42, 43, 44, 45, 46, 47};      // Keep default key B

    // The access bits are stored in a peculiar fashion.
    // There are four groups:
    //      g[0]    Access bits for block 0 (for sectors 0-31)  این پارامتر دسترسی به بلاک 0 در سکتورهای 0 تا31 است-نکته کارتهای 1 کیلوبایتی 16 و کارتهای 2 کیلوبایتی 32 سکتور دارند و کارتهای 4 کیلوبایتی 39 سکتور دارند .
    //              or blocks 0-4 (for sectors 32-39)
    //      g[1]    Access bits for block 1 (for sectors 0-31)  این پارامتر دسترسی به بلاک ۱ در سکتورهای 0 تا31 است
    //              or blocks 5-9 (for sectors 32-39)
    //      g[2]    Access bits for block 2 (for sectors 0-31) این پارامتر دسترسی به بلاک 2 در سکتورهای 0 تا31 است
    //              or blocks 10-14 (for sectors 32-39)
    //      g[3]    Access bits for the Sector Trailer: block 3 (for sectors 0-31) این پارامتر دسترسی به بلاک 3 یا تریلر بلوک در سکتورهای 0 تا31 است
    //              or block 15 (for sectors 32-39)
    // Each group has access bits [C1 C2 C3], in this code C1 is MSB and C3 is LSB.
    // Determine the bit pattern needed using MIFARE_SetAccessBits:
    //      g0=0    access bits for block 0 (of this sector) using [0 0 0] = 000b = 0
    //              which means key A|B have r/w for block 0 of this sector
    //              which (in this example) translates to block #4 within sector #1;
    //              this is the transport configuration (at factory delivery).
    //      g1=6    access bits for block 1 (of this sector) using [1 1 0] = 110b = 6
    //              which means block 1 (of this sector) is used as a value block,
    //              which (in this example) translates to block #5 within sector #1;
    //              where key A|B have r, key B has w, key B can increment,
    //              and key A|B can decrement, transfer, and restore.
    //      g2=6    same thing for block 2 (of this sector): set it to a value block;
    //              which (in this example) translates to block #6 within sector #1;
    //      g3=3    access bits for block 3 (of this sector): the Sector Trailer here;
    //              using [0 1 1] = 011b = 3 which means only key B has r/w access
    //              to the Sector Trailer (block 3 of this sector) from now on
    //              which (in this example) translates to block #7 within sector #1;
    Serial.println("=========================================");
    Serial.println(trailerBuffer[6]);
    Serial.println(trailerBuffer[7]);
    Serial.println(trailerBuffer[8]);
    Serial.println(trailerBuffer[9]);
    Serial.println("==========================================");
    mfrc522.MIFARE_SetAccessBits(&trailerBuffer[6], 0, 6, 6, 3);
    Serial.println(trailerBuffer[6]);
    Serial.println(trailerBuffer[7]);
    Serial.println(trailerBuffer[8]);
    Serial.println(trailerBuffer[9]);
    Serial.println("===========================================");

    // Read the sector trailer as it is currently stored on the PICC
    Serial.println(F("Reading sector trailer..."));
    status = mfrc522.MIFARE_Read(trailerBlock, buffer, &size);
    if (status != MFRC522::STATUS_OK) {
        Serial.print(F("MIFARE_Read() failed: "));
        Serial.println(mfrc522.GetStatusCodeName(status));
        return;
    }
    Serial.println(mfrc522.GetStatusCodeName(status));
    // Check if it matches the desired access pattern already;
    // because if it does, we don't need to write it again...
    Serial.println("===========>>>>>>KEY_A>>>>>>===========");
    Serial.println(buffer[0]);
    Serial.println(buffer[1]);
    Serial.println(buffer[2]);
    Serial.println(buffer[3]);
    Serial.println(buffer[4]);
    Serial.println(buffer[5]);
    Serial.println("===========>>>>>>ACCESS_CONDITIONS>>>>>>===========");
    Serial.println(buffer[6]);
    Serial.println(buffer[7]);
    Serial.println(buffer[8]);
    Serial.println(buffer[9]);
    Serial.println("=========>>>>>>KEY_B>>>>>>===========");
    Serial.println(buffer[10]);
    Serial.println(buffer[11]);
    Serial.println(buffer[12]);
    Serial.println(buffer[13]);
    Serial.println(buffer[14]);
    Serial.println(buffer[15]);
    Serial.println("============>>>>>>>>>>>>>>>>===========");
    if (    buffer[6] != trailerBuffer[6]
        &&  buffer[7] != trailerBuffer[7]
        &&  buffer[8] != trailerBuffer[8]) {
        // They don't match (yet), so write it to the PICC
        Serial.println(F("Writing new sector trailer..."));
        status = mfrc522.MIFARE_Write(trailerBlock, trailerBuffer, 16);
        if (status != MFRC522::STATUS_OK) {
            Serial.print(F("MIFARE_Write() failed: "));
            Serial.println(mfrc522.GetStatusCodeName(status));
            return;
        }
    }