در این مقاله سعی شده است که در مورد لوکس متر دیجیتال TSL256X توضیحاتی داده شود و همچنین یک پروژه صنعتی شامل کتابخانه های مختلف قرار داده شده است، برای راحتی کار میتوان از ماژولهای موجود در بازار استفاده کرد.
معرفی:
چیپ های TSL2560 و TSL2561 مبدلهای میزان شدت نور به یک سیگنال دیجیتال هستند که در TSL2561 میتوان از طریق رابط I2C و در چیپ TSL2560 از طریق رابط SMBus به محتویات و رجیسترهای داخلی چیپ دسترسی داشت.
در شکل زیر میتوانید معماری داخلی چیپ را مشاهده کنید.
همانطور که در شکل مشخص است قسمت آنالوگ از دو کانال تشکیل شده است که کانال یک، خود از دو فتودیود تشکیل شده است و کانال دوم فقط از یک فتودیود تشکیل شده است. همچنین چیپ از دو کانال ADC برای تبدیل شدت نور تابانده شده به دو کانال سنسور به مقادیر دیجیتالی با رزولوشن 16 بیت،بهره میبرد. البته خروجی این مبدل باید توسط یک سری فرمول که در ادامه توضیح داده میشود، به محدوده پاسخ چشم انسان برده شود.
همانطور که گفتیم چیپ دارای دو کانال ADC هست که سیگنال ورودی از دو کانال فتودیودی را تبدیل میکند که البته این عمل در هر دو کانال با هم یکسان است. بعد از اتمام سیکل تبدیل، این مبدل ها دیتای خروجی را بلافاصله بر روی رجیسترهای مربوط به ADC به صورت جداگانه نوشته میشود (هر کانال برروی یک رجیستر) و بعد از انجام این کار، عملیات تبدیل دوباره آغاز میگردد و این چرخه ادامه دارد.
در شکل زیر میتوانید مدل های مختلف و اینترفیس های مختلف این سنسور را مشاهده کنید.
برای اطلاعات بیشتر از پایه ها و دیگر مولفهها، میتوانید به دیتاشیت قطعه مراجعه کنید. فقط توجه کنید اگر از ماژول استفاده نمیکنید ولتاژ تغذیه چیپ 2.5 تا 3.6 ولت که با ولت متر اندازی گیری شده است، می باشد. ولی اگر از ماژول های موجود استفاده میکنید تقریبا همه با 5 ولت کار میکنند البته باید توجه شود که برخی از مدلها با 3.3 ولت کار میکنند. در شکل زیر میتوانید این مولفه ها را مشاهده کنید.
با توجه به جدول بالا میتوان این نکته را دریافت که اینترفیس ارتباطی سنسور با ولتاژی بین 2.1 تا 3.6 ولت کار میکند و با 5 ولت سازگار نیست.
با توجه به شکل بالا میتوان دریافت که
واحد اندازه گیری شدت نور از دو فتودیود 640 و 940 نانومتری تشکیل شده است.
زمان ادغام(اندازه گیری Tint) وابسته به فرکانس اسیلاتور و همچنین مقدار integration در رجیسترها است. که در ادامه توضیح داده میشوند. اگر فرکانس اسیلاتور 735 کیلوهرتز باشد زمان ادغام برابر با Tint = (number of clock cycles)/fosc خواهد بود.
همچنین با توجه به مقدار رجیستر مربوط به تایمینگ میتوان مدت زمان ادغام را کم و زیاد کرد.
توجه شود که هر چه زمان بیشتری به مبدل بدهیم دقت نیز بالاتر خواهد بود.
Field value 00: Tint = (11 × 918)/fosc = 13.7 ms
Field value 01: Tint = (81 × 918)/fosc = 101 ms
Field value 10: Tint = (322 × 918)/fosc = 402 ms
اگر به فرمول Tint = (number of clock cycles)/fosc توجه شود به راحتی میتوان متوجه شد که با تغییر مقدار Field value که جزئی از رجیسترهای چیپ است، عملا تعداد سیکل هایی که یک تبدیل نیاز دارد کم و زیاد میشود که این مستقیما برروی دقت تبدیل اثر گذار است.
همچنین مقداری که مقیاس ADC به خود میگیرد، وابسته به مقدار تایمی است که به مبدل داده میشود یا به زبان ساده تر به تعداد سیکلی که از کلاک به مبدل تخصیص داده میشود.
که به روش زیر محاسبه میشود.
Full scale ADC count value = ((number of clock cycles)/2 − 2)
Field value 00: Full scale ADC count value = ((11 × 918)/2 − 2) = 5047
Field value 01: Full scale ADC count value = ((81 × 918)/2 − 2) = 37177
Field value 10: Full scale ADC count value = 65535
و چون مقادیر در رجیسترهای 16 بیتی ذخیره میشوند بیشترین مقداری که مبدل میتواند ذخیره کند مقدار 65535 است.
چون برای رسیدن به بیشترین مقدار یعنی 65535 نیاز به 131074 سیکل از کلاک است پس باید زمان اندازه گیری Tint بزرگتر از 178 میلی ثانیه باشد، یعنی باید در رجیستر تایمینگ مقدار 10 که بیشترین زمان اندازه گیری است، مقدار 402 میلی ثانیه است را تنظیم کنیم.
در شکلهای زیر پایهها و انواع پیکیجهای این چیپ را میتوانید مشاهده کنید.
حال نوبت به برقراری ارتباط با چیپ رسیده است.
اینترفیس ارتباطی TSL256X از طریق دو سیم میسر است و میتوان طبق استانداردهای SMBus که مخفف System Management Bus و همچنین رابط I2C یا TWI با چیپ ارتباط برقرار کرد و به رجیسترها و تنظیمات داخلی آن دسترسی داشت. برای آدرسدهی آیسی میتوان از پین ADDR SEL استفاده کرد.
در جدول شکل زیر میتوان حالات پین و مقادیر آدرس را برای هر دو اینترفیس مشاهده کرد.
در این مقاله و سورس کد، از اینترفیس I2C یا همان TWI استفاده شده است. برای اطلاعات بیشتر در مورد SMBus به http://www.smbus.org/specs و برای TWI به http://www.semiconductors.philips.com مراجعه کنید.
در مورد اینترفیس این چیپ در بالا توضیح دادهایم اما پروتکل کاری آن به چه شکل است؟
TSL256X از پروتکل ساده ای استفاده میکند و که به شکل زیر است.
بین بایتهایی که میان پردازنده اصلی و سنسور انتقال داده میشود، اگر بایتی که از طرف پردازنده آمد، پرارزشترین بیت آن یک میباشد. و به این معنی است که بایت دریافتی حاوی دستورات یا COMMAND است و در همین بایت چهار بیت آخر(کم ارزش) حاوی آدرس رجیسترهایی است که پردازنده قصد دسترسی به آن را دارد.
پکت دیتا در TWI و SMBus به صورت زیر میباشد.
در SMBus برای انتقال دیتا میتوان طبق روند زیر عمل کرد.
Send Byte Protocol
Receive Byte Protocol
Write Byte Protocol
Write Word Protocol
Read Word Protocol
Block Write Protocol
Block Read Protocol
اما در TWI فقط دادهها را بصورت پروتکلهای خواندن و نوشتن عادی، به صورت فریمهای هشت بیتی به همراه یک بیت تصدیق، انتقال داد.
رجیسترها
TSL256x دارای 16 رجیستر (سه عدد از آن رزرو) است که توسط آنها میتوان به مانیتورینگ و کنترل چیپ پرداخت. همچنین علاوه براین 16 رجیستر یک رجیستر دیگر به COMMAND دارد. که در شکل زیر این رجیسترها به نمایش در آمده است.
رجیستر COMMAND همیشه اولین فریمی است که ارسال میشود و طبق این فریم، چیپ تشخیص میدهد که دستور چیست. در شکل زیر این رجیستر 8 بیتی را مشاهده میکنید. که
- بیتهای 0 تا 3 مربوط به آدرس رجیسترهای چیپ است (همانطور که آدرس ها را در جدول بالا میبینید).
- بیت چهارم مربوط به اینترفیس SMBus است که تعیین میکند داده ها را به صورت یک بلوک ارسال یا دریافت کند. اگر این بیت یک شود، این عمل انجام میشود.
- بیت 5 مربوط به SMBus است و فقط این بار تعیین میکند که چیپ به صورت WORD داده ها را انتقال دهد یا از پروتکل Write/Read Word استفاده کند.
- بیت 6 به منظور پاک کردن وقفه هاست که با یک شدن این بیت پاک میشوند.
- بیت 7 تقریبا همیشه یک است چون نشان دهنده رجیستر COMMAND است.
به عنوان مثال
میتوان مقادیر ذخیره شده در دو کانال ADC که خود داری چهار رجیستر است را به صورت یک بلوک 32 خواند، اما در TWI باید این رجیسترها را تک به تک خواند و هر بار یک آدرس را بفرستیم تا این که چهار کانال تمام شوند.
رجیستر کنترلی(Control Register 0h)
فقط دو بیت اول این رجیستر قابل دسترسی است که وضعیت پاور را مشخص میکند اگر مقدار 03h نوشته شود چیپ روشن و اگر 00h نوشته شود خاموش میشود.
رجیستر (Timing Register 1h)
این رجیستر برای مقداردهی به گین و همچنین مقدار تایم اندازهگیری که در بالا توضیح داده شد به کار میرود.
بیتهای 0 و 1 مربوط به تعیین زمان اندازهگیر است که طبق جدول زیر میتوان آن را تنظیم نمود.
با نوشتن مقدار یک در بیت 3 چرخه تبدیل آغاز میشود. و همچنین با نوشتن یک در بیت 4 مقدار گین 16 در نظر گرفته میشود و با نوشتن صفر مقدار گین یک حساب میشود. در شکل زیر این رجیستر را مشاهده میکنید.
رجیستر (Interrupt Threshold Register 2h − 5h)
این رجیستر برای تنظیم مقدار نقاط مورد نظر جهت تولید وفقه است که به صورت دو عدد شانزده بیتی برای کمترین و بیشترین مقدار قابل تنظیم است. اگر مقدار خوانده شده از کانال 0 مبدل کمتر یا بیشتر از مقدار مورد نظر باشد روی پین INT یک وقفه فرستاده میشود.
رجیستر کنترل وفقه (Interrupt Control Register 6h)
از این رجیستر برای تنظیم سیکلهای تولید وقفه و همچنین تعیین نوع وفقه تولیدی استفاده میشود.
بیتهای 0 تا 3 ریت( نرخ) تولید وفقه را تعیین میکنند، به طور مثال بعد از هر سیکل، ADC وقفه تولید شود یا بعد از دو دوره از زمان اندازه گیری انجام شود(در بالا توضیح داده شد که به طور مثال برای 101 میلی ثانیه بعد از 202 میلی ثانیه وفقه تولید میشود).
در جدول شکل زیر این مقادیر مشاهده میشود.
در شکل زیر عملکرد بیت های 4 و 5 نشان داده شده است که تعیین میکند چه نوع وفقه ای تولید شود یا کلا غیر فعال باشد.
رجیستر شناسه (ID Register Ah)
همانطور که از اسم آن پیداست مربوط به شناسه چیپ میباشد که از دو قسمت تشکیل شده است. که چهار بیت اول آن مربوط به شناسه سخت افزاری و چهار بیت دوم آن مربوط به شناسه نوع چیپ است که مقدار 0000 مربوط به چیپ TSL2560 و مقدار 0001 مربوط به چیپ TSL2561 میباشد.
رجیستر کانالهای مبدل (ADC Channel Data Registers Ch − Fh)
این چهار رجیستر که دو عدد از آن برای کانال صفر و دو عدد برای کانال یک است، مقادیر خوانده شده از ADC را نگهداری میکند.
حال نوبت به توضیح نمونه کد میرسد که اگر به هدر Tsl2561.h توجه شود تمام آدرسها و مقادیر توضیح داده شده در این مقاله و دیتاشیت را در خود جای داده است.
خب برای روشن کردن سنسور کافیست اتصالات آن را برقرار کنید و تابع کوچک زیر را فرا بخوانید. که مقدار x اگر یک باشد روشن و اگر صفر باشد خاموش میشود.
1 2 | #define TSL_POWER( x ) ((x) ? ( TSL2561_WriteByte( TSL2561_ADDR, TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL, TSL2561_CONTROL_POWERON ) ) : \ ( TSL2561_WriteByte( TSL2561_ADDR, TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL, TSL2561_CONTROL_POWEROFF ) ) ); |
در این هدر ساختارهایی را که میبینید مربوط به تنظیم گین و تایم اندازه گیری است.
1 2 3 4 5 6 | typedef enum { TSL2561_INTEGRATIONTIME_13MS = 0x00, // 13.7m TSL2561_INTEGRATIONTIME_101MS = 0x01, // 101ms TSL2561_INTEGRATIONTIME_402MS = 0x02 // 402ms } |
به سادگی مشخص است که برای مدت زمان اندازه گیری استفاده میشود.
1 2 3 4 5 | typedef enum { TSL2561_GAIN_1X = 0x00, // No gain TSL2561_GAIN_16X = 0x10, // 16x gai } tsl2561Gain |
از ساختار شمارشی هم برای تنظیم گین استفاده میشود حال یک struct به شکل زیر وجود دارد.
1 2 3 4 5 | typedef struct TSL2561 { tsl2561Gain_t gain; tsl2561IntegrationTime_t integ_time; }TSL2561; |
خود این ساختار از دو نوع داده شمارشی تشکیل شده است که میتوان از این ساختار برای تنظیم کلی استفاده کرد به طور مثال میتوان در بدنه اصلی برنامه یک نوع از ساختار را تعریف کنید و مقادیر مورد نظر را تنظیم کنید.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | TSL2561 Light = { TSL2561_GAIN_1X , TSL2561_INTEGRATIONTIME_13MS }; تابع های مورد استفاده void TSL2561_WriteByte ( uint8_t, uint8_t, uint8_t ); uint8_t TSL2561_ReadByte ( uint8_t, uint8_t, uint8_t ); uint16_t TSL2561_ReadWord ( uint8_t, uint8_t ); void TSL2561_Init ( TSL2561 *sens ); void TSL2561_SetGain ( TSL2561 *sens, tsl2561Gain_t gain ); void TSL2561_SetIntegrationTime ( TSL2561 *sens, tsl2561IntegrationTime_t time ); uint16_t TSL2561_CALCULATE_LUX ( TSL2561 *sensor, unsigned int ch0, unsigned int ch1 ); محتویات تابع مربوط نوشتن یک بایت به صورت زیر است void TSL2561_WriteByte ( uint8_t address, uint8_t reg, uint8_t val ) { TWIStartCondition(); TWI_write( address ); TWI_write( reg ); TWI_write( val ); TWIStopCondition(); } |
یکی از ورودیهای این تابع آدرس آیسی است که به صورت زیر تعریف شده است.
1 | #define TSL2561_ADDR ( 0x52 ) |
و ورودی دیگر آن، آدرس رجیستر مورد نظر است که آدرسها در بالا توضیح داده شد و به صورت یک تایپ شمارشی به صورت زیر تعریف شده است.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | enum { TSL2561_REGISTER_CONTROL = 0x00, TSL2561_REGISTER_TIMING = 0x01, TSL2561_REGISTER_THRESHHOLDL_LOW = 0x02, TSL2561_REGISTER_THRESHHOLDL_HIGH = 0x03, TSL2561_REGISTER_THRESHHOLDH_LOW = 0x04, TSL2561_REGISTER_THRESHHOLDH_HIGH = 0x05, TSL2561_REGISTER_INTERRUPT = 0x06, TSL2561_REGISTER_CRC = 0x08, TSL2561_REGISTER_ID = 0x0A, TSL2561_REGISTER_CHAN0_LOW = 0x0C, TSL2561_REGISTER_CHAN0_HIGH = 0x0D, TSL2561_REGISTER_CHAN1_LOW = 0x0E, TSL2561_REGISTER_CHAN1_HIGH = 0x0F }; |
ورودی بعدی این تابع مقداری است که قرار است روی رجیستر مورد نظر نوشته شود.
محتویات تابع خواندن هم به شکل زیر است.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | uint8_t TSL2561_ReadByte ( uint8_t address, uint8_t reg, uint8_t ack ) { uint8_t dat; TWIStartCondition(); TWI_write( address ); TWI_write( reg ); TWIStartCondition(); TWI_write( address + 1 ); dat = TWI_read( ack ); TWIStopCondition(); return dat; } |
وروی آدرس که مانند قبل است.
ورودی رجیستر، رجیستری است که قرار است از آن بخوانیم. اما مقدار ورودی ack یا تصدیق، چون این هدر از رابط TWI استفاده میکند. هنگام خواندن از چیپ نیاز است که دیتاهای گرفته شده از چیپ را تصدیق کنیم و اگر به پایان داده ها رسیدیم به چیپ اشاره کنیم که دادهها به طور کامل دریافت شده است. به همین منظور از این بیت استفاده کردهایم.
برای روشن شدن به کد زیر توجه کنید.
1 | dataWord = (((( uint8_t )TWI_read( ACK )) << 8 ) | TWI_read( NACK )); |
در کد بالا زمانی که اولین بایت را دریافت میکنیم و چون بایت های دیگری مانده است، تصدیق میکنیم ولی دیتای بعدی چون آخرین بایت است آنرا تصدیق نمیکنیم و ایسی متوجه پایان عملیات انتقال دیتا میشود. همچنین مقدار خوانده شده از چیپ در این تابع به صورت هشت بیت برگردانده میشود.
تابع مربوط به تنظیم گین به شکل زیر است.
1 2 3 4 | void TSL2561_SetGain (*sens, tsl2561Gain_t gain ) { TSL2561_WriteByte( TSL2561_ADDR, TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING, sens->integ_time | gain ); } |
ورودیهای کد به صورت یک اشاره گره به ساختار TSL2561 که توضیح داده شد اشاره میکند و ورودی بعدی مربوط به مقدار گین مورد نظر است که در نهایت مقدار گین را تعیین میکند.
برای استفاده از تابع TSL2561_CALCULATE_LUX ابتدا باید مقادیر خام کانال ADC ها خوانده شود و سپس این مقادیر برای محاسبه به تابع TSL2561_CALCULATE_LUX ارسال شود. برای این کار ابتدا این دو کانال را به صورت زیر میخوانیم.
1 2 3 4 5 6 7 8 9 10 | DatL = TSL2561_ReadByte( TSL2561_ADDR, TSL2561_COMMAND_BIT | TSL2561_REGISTER_CHAN0_LOW, NACK ); DatH = TSL2561_ReadByte( TSL2561_ADDR, TSL2561_COMMAND_BIT | TSL2561_REGISTER_CHAN0_HIGH, NACK ); ch0 = DatH ; ch0 <<= 8; ch0 |= DatL; DatL = TSL2561_ReadByte( TSL2561_ADDR, TSL2561_COMMAND_BIT | TSL2561_REGISTER_CHAN1_LOW, NACK ); DatH = TSL2561_ReadByte( TSL2561_ADDR, TSL2561_COMMAND_BIT | TSL2561_REGISTER_CHAN1_HIGH, NACK ); ch1 = DatH; ch1 <<= 8; ch1 |= DatL; |
حال که مقادیر خام را بدست آوردیم مقدار لوکس را طبق کد زیر بدست مینویسیم.
1 | Lux += TSL2561_CALCULATE_LUX( &Light, ch0, ch1 ); |
ورودیهای تابع شامل ساختار مربوط به تنظیمات چیپ میباشد. که در آن مقدار گین و تایم را تنظیم کردهایم. و دو ورودی دیگر مقادیر، جهت خواندن دیتا از مبدلها است.
دانلود سورس پروژه AVR-ARM به همراه دیتاشیت فنی ماژول
پسورد فایل : sisoog.com