در دنیای پهپادها، رباتهای خودران، سیستمهای امنیتی و اتوماسیون صنعتی، سنجش دقیق فاصله یکی از حیاتیترین نیازهاست. میان فناوریهای مختلف اندازهگیری فاصله، فناوری LiDAR (Light Detection and Ranging) به عنوان یک راهحل دقیق، سریع و قابل اعتماد، تحول شگرفی ایجاد کرده است. برخلاف سنسورهای اولتراسونیک که دقت محدودی دارند یا سنسورهای مادون قرمز که تحت تأثیر نور محیط قرار میگیرند، LiDAR با استفاده از پالسهای لیزر، قادر به اندازهگیری فاصله با دقت میلیمتری است. ماژول TOF20 نمونهای پیشرفته و مقرونبهصرفه از فناوری LiDAR است که در دسته سنسورهای ToF (Time-of-Flight) قرار میگیرد. این ماژول با ارسال پالسهای لیزر مادون قرمز و اندازهگیری زمان بازگشت آنها، قادر به محاسبه فاصله تا اجسام در محدوده ۰.۱ تا ۲۰ متر با دقت ±۱ سانتیمتر با سرعت نمونهبرداری ۲۰۰ هرتز است. ماژول از ارتباط سریال (UART) و I2C پشتیبانی میکند که دست شما را برای طراحی باز میگذارد.
ویژگیهای کلیدی TOF20 شامل مصرف انرژی پایین (تنها ۰.۳۳ وات در حالت کاری)، مقاومت در برابر نور محیط (تا ۱۰۰ کیلو لوکس)، قابلیت عملکرد در شرایط آبوهوایی مختلف و اندازه جمعوجور آن است که امکان نصب بر روی پلتفرمهای متحرک مانند رباتها و پهپادها را فراهم میکند. در این مقاله، به بررسی ماژول TOF20 میپردازیم. از اصول عملکرد فناوری ToF و مشخصات فنی ماژول آغاز کرده، سپس راهاندازی عملی، پروتکل ارتباطی و نحوه برنامهنویسی آن برای میکروکنترل را آموزش میدهیم. همچنین کاربردهای متنوع این ماژول در پروژههای واقعی، از نقشهبرداری سهبعدی و اجتناب از مانع در رباتیک تا سیستمهای نظارتی و صنعتی را بررسی خواهیم کرد. با ما همراه شوید تا دنیای شگفتانگیز سنجش فاصله با لیزر را کشف کنیم.
LiDAR (Light Detection and Ranging) یک فناوری سنجش از دور است که با ارسال پالسهای نور لیزر و اندازهگیری زمان بازگشت آنها، فاصله تا اجسام را محاسبه میکند. اساس کار LiDAR بر پایه ToF یا Time-of-Flight استوار است – همان مفهومی که در مسابقات دو میدانی شاهد آن هستیم: جسمی مسیری را طی میکند و زمان رفتوبرگشت آن اندازهگیری میشود. در فناوری ToF، یک پالس لیزر با سرعت نور (≈۳۰۰,۰۰۰ کیلومتر بر ثانیه) به سمت هدف ارسال میشود. پس از برخورد به جسم، این پالس منعکس شده و به سنسور بازمیگردد. با اندازهگیری دقیق زمان رفتوبرگشت (t) و با استفاده از فرمت ساده فاصله = (سرعت نور × زمان) / ۲، فاصله تا جسم محاسبه میشود. دقت این روش آنقدر بالا است که حتی تغییرات میلیمتری را نیز میتواند تشخیص دهد. در ادامه مقایسهای از فناوریهای مختلف خواهیم داشت.
| فناوری | اصول کار | محدوده اندازهگیری | دقت | سرعت | تأثیرپذیری از محیط | هزینه | مصارف رایج |
| LiDAR (ToF) – مدل سبک | پالس لیزر + زمان پرواز | از چند سانتی متر تا چند متر | بسیار بالا (±۱cm) | بسیار بالا (تا ۲۰۰Hz) | نور مستقیم، مه | متوسط | رباتیک، پهپاد، نقشهبرداری |
| LiDAR صنعتی/نظامی | پالس لیزر + زمان پرواز | تا ۱۰+ کیلومتر | میلیمتری | بالا | آبوهوای نامساعد | بسیار زیاد | توپوگرافی، سیستمهای دفاعی |
| اولتراسونیک | امواج صوتی + پژواک | چند سانتی متر (عمومی) | متوسط | پایین (۱۰-۲۰Hz) | دما، باد | بسیار پایین | پارک خودرو، سطحسنجی |
| مادون قرمز (IR) | مثلثسازی زاویهای | ۱۰cm-۵m | پایین | متوسط | نور محیط، رنگ | پایین | خطیاب ربات |
| رادار RF – موج میلیمتری | امواج رادیویی | ۰.۱-۲۵۰ متر | بالا | بالا | کم | متوسط-بالا | خودروهای خودران، صنعت |
| رادار نظامی/هوایی | امواج رادیویی + داپلر | تا ۴۰۰+ کیلومتر | متغیر | بسیار بالا | تقریباً بیتأثیر | بسیار بالا | پدافند هوایی، هواشناسی |
| بینایی کامپیوتر | پردازش تصویر استریو | وابسته به میدان دید | متغیر | پایین | نور، بافت | بالا | چهرهشناسی، AR |
همانطور که در این جدول مشاهده میکنید فناوریهای مختلف با کاربردهای گوناگونی وجود دارد که هرکدام برای هدفی مناسب هستند. ماژولی که در اینجا باهم بررسی میکنیم با ترکیب دقت بالا، برد مناسب و قیمت مقرونبهصرفه، بین فناوریهای ارزانقیمت اما کمدقت (مانند اولتراسونیک) و سیستمهای صنعتی بسیار گرانقیمت یک تعادل مناسب ایجاد کرده است. این ماژول برای پروژههایی که به دقت بیشتری نسبت به اولتراسونیک نیاز دارند اما بودجه محدودی برای خرید سیستمهای LiDAR صنعتی دارند، گزینهای ایدهآل محسوب میشود.

در جدول زیر مشخصات این ماژول را به طور خلاصه مشاهده میکنید.
| آیتم | حداقل | معمول | حداکثر | واحد | توضیحات |
| فرکانس اندازهگیری فاصله | 50 | 100 | 250 | هرتز | تعداد اندازهگیریهای فاصله در ثانیه (50/100/250 هرتز) |
| محدوده فاصلهیابی | 0٫1 | – | 20 | متر | با انعکاسپذیری ۸۰٪ |
| خطای نسبی | – | – | – | – | – |
| • 0.2 متر ≤ فاصله < 1 متر | – | 30 | – | میلیمتر | – |
| • 1 متر ≤ فاصله ≤ 6 متر | – | 60 | – | میلیمتر | – |
| • فاصله > 6 متر | – | ۱٪ | – | درصد | از فاصله اندازهگیریشده |
| شرایط نوری محیط | – | ۱۰۰هزار | – | لوکس | – |
| ولتاژ کاری | – | 3٫3 | – | ولت | – |
| جریان کاری | 20 | 105 | 150 | میلیآمپر | – |
| مصرف توان | 66 | 346 | 495 | میلیوات | (بر اساس جریان 150mA در 3.3V) |
| دمای کاری | 20- | 25 | 50 | درجه سانتیگراد | – |
| دمای نگهداری | 20- | 25 | 80 | درجه سانتیگراد | – |
| ابعاد (طول×عرض×ارتفاع) | – | ۲۱×۱۵×۷.۸۷ | – | میلیمتر | – |
| وزن | – | 1٫35 | – | گرم | وزن خالص |
همانطور که در جدول مشخصات ماژول مشاهده میکنید، این ماژول دارای قابلیتهای برجستهای از جمله دقت بالا، برد قابل توجه، سرعت نمونه برداری مناسب، حساسیت کم به نور زیاد، مصرف بهینه و وزن و ابعاد کم است که آن را به انتخابی ایدهآل برای پروژههای دقیق و سریع تبدیل میکند.
همانطور که قبلا اشاره شد این ماژول از پروتکل I2C و UART پشتیبانی میکند که شما میتوانید با استفاده از یک صفر یا یک کردن پینی که در تصویر مشاهده میکنید (INT) مشخص کنید که قرار است از کدام قابلیت این ماژول استفاده کنید.

ترتیب پینها در ماژول به این صورت است:

برای ارتباط برقرار کردن به ماژول در حالت UART نیاز است که تنظیمات به صورت زیر اعمال کنید:
Baud Rate:115200, Parity: None, Bits: 8, Stop Bits:1, Flow Control: None
حداکثر و حداقل سرعت انتقال داده در UART به ترتیب ۹۲۱۶۰۰ و ۹۶۰۰ است و لازم به ذکر است که ارتباط با ماژول فقط ازطریق پروتکلی که بعدا شرح داده میشود انجام میشود. همچنین بهتر است ابتدا ولتاژ ماژول را با لاین (3V3) متصل کرده و دستورات لازم را برای ماژول ارسال کنید و سپس اقدام به روشن کردن لیزر با اتصال ولتاژ به لاین (3v3_LASER) کنید. دستوراتی که با استفاده از UART برای ماژول میفرستید لازم است به صورت زیر باشد.
| بایت | نام | توضیحات |
| Byte0 | هدر (Head) | هدر فریم دستور (مقدار ثابت: 0x5A) |
| Byte1 | طول (Len) | طول کل فریم دستور (شامل Head و Checksum،به بایت) |
| Byte2 | شناسه (ID) | نمایانگر روشهای تجزیه دستورات مختلف |
| Byte3 تا ByteN-2 | پیام (Payload) | بخش دادهها، بر اساس ID تفسیر میشود؛ دادهها با فرمت little-endian هستند |
| ByteN-1 | Checksum | جمع هشت بایت کم ارزش از هدر تا پیام (جمع & 0xFF) |
به عنوان مثال میتوانید از پیامهای زیر برای استفاده از قابلیتهای مختلف ماژول استفاده کنید:
| پارامتر | دستور | پاسخ | توضیحات | پیشفرض |
| دریافت نسخه فرمور | 5A 04 01 5F | 5A 07 01 V1 V2 V3 SU | نسخه V3.2.1 | – |
| ریست سیستم | 5A 04 02 60 | 5A 05 02 00 61 (موفق) 5A 05 02 01 62 (ناموفق) |
– | – |
| نرخ فریم | 5A 06 03 LL HH SU | 5A 06 03 LL HH SU | ۱-۱۰۰۰ هرتز | ۱۰۰ هرتز |
| تحریک تشخیص | 5A 04 04 62 | فریم داده | بعد از تنظیم نرخ فریم روی ۰، با این دستور میتوان تشخیص را فعال کرد | – |
| فرمت خروجی | 5A 05 05 01 65 5A 05 05 02 66 5A 05 05 06 6A |
5A 05 05 01 65 5A 05 05 02 66 5A 05 05 06 6A |
استاندارد ۹ بایت (سانتیمتر) √ Pixhawk / استاندارد ۹ بایت (میلیمتر) / |
استاندارد ۹ بایت (سانتیمتر) |
| نرخ baudrate | 5A 08 06 H1 H2 H3 H4 SU | 5A 08 06 H1 H2 H3 H4 SU | تنظیم نرخ baudrate مثال: 256000(دسیمال)=3E800(هگزادسیمال)، H1=00,H2=E8,H3=03,H4=00 |
115200 |
| فعال/غیرفعال کردن خروجی | 5A 05 07 00 66 5A 05 07 01 67 |
5A 05 07 00 66 5A 05 07 01 67 |
غیرفعال کردن خروجی داده / فعال کردن خروجی داده √ |
فعال |
| تنظیم رابط ارتباطی | 5A 05 0A MODE SU | 5A 05 0A 00 69 5A 05 0A 01 6A |
۰ (UART) ۱ (I2C) |
UART |
| تغییر آدرس I2C | 5A 05 0B ADDR SU | 5A 05 0B ADDR SU | تغییر آدرس I2C | 0x10 |
| دریافت فریم داده | 5A 05 00 01 60 5A 05 00 06 65 |
فریم داده (۹ بایت-سانتیمتر) فریم داده (۹ بایت-میلیمتر) |
فقط در حالت IIC کار میکند | – |
| فعال کردن حالت I/O | 5A 09 3B MODE DL DH ZoneL ZoneH SU | – | باز یا بستن حالت خروجی I/O MODE: 0–حالت داده استاندارد 1–I/O، نزدیک بالا و دور پایین 2–I/O، نزدیک پایین و دور بالا Zone: منطقه هیسترزیس |
0 (حالت داده استاندارد) |
| آستانه قدرت و فاصله زیر آستانه | 5A 07 22 XX LL HH 00 | 5A 07 22 XX LL HH SU | مثال: وقتی قدرت زیر ۱۰۰ باشد، خروجی فاصله ۱۲۰۰ سانتیمتر تنظیم شود. XX=100/10=10(DEC)=0A(HEX) 1200(DEC)=4B0(HEX) LL=B0، HH=04 |
آستانه قدرت = ۱۰۰ فاصله زیر آستانه = ۰ |
| حالت مصرف کم انرژی | 5A 06 35 0X 00 SU | 5A 06 35 0X 00 SU | محدوده X(HEX) ۰~A، نرخ فریم در حالت کممصرف نمیتواند بیش از ۱۰ هرتز باشد؛ X>0: حالت کممصرف فعال؛ X=0: حالت کممصرف غیرفعال |
– |
| بازنشانی تنظیمات کارخانه | 5A 04 10 6E | 5A 05 10 00 6F (موفق) 5A 05 10 01 70 (ناموفق) |
– | – |
| ذخیره تنظیمات | 5A 04 11 6F④ | 5A 05 11 00 70 (موفق) 5A 05 11 01 71 (ناموفق) |
– | – |
برای اینکار ابتدا لازم است GPIO که قبل از این در قسمت UART درمورد آن صحبت کردیم را به صورت Pull-Up متصل کنید تا ماژول درحالت تبادل داده با I2C قراربگیرد. سپس لازم است I2C را به صورت زیر تنظیم کنید.
| پارامتر | مقدار | توضیحات |
| رابط (Interface) | I²C | رابط ارتباطی |
| حداکثر نرخ انتقال (Max transmission rate) | 400 کیلوبیت بر ثانیه | سرعت انتقال دادهها |
| حالت Master/Slave | حالت Slave | ماژول به عنوان دستگاه فرعی (Slave) عمل میکند |
| آدرس پیشفرض (Default address) | 0x10 | آدرس I²C پیشفرض ماژول |
| محدوده آدرس (Address range) | 0x01 تا 0x7F | محدوده آدرسهای قابل تنظیم |
در این ارتباط میکروکنترلر در نقش Master است و ماژول نقش Slave را دارد. ابتدا لازم است پبام پیکربندی را ارسال کنید و سپس ۱۰۰ میلی ثانیه منتظر بمانید تا دستور پردازش شده اما برای دریافت نتیجه اندازهگیری نیاز به هیچ وقفهای نیست. رجیسترهای I2C مطابق جدول زیر هستند.
| Address | R/W | Name | Initial Value | Description |
| 0x00 | R | DIST_LOW | — | Distance low byte (cm) |
| 0x01 | R | DIST_HIGH | — | Distance high byte |
| 0x02 | R | AMP_LOW | — | Amplitude low byte |
| 0x03 | R | AMP_HIGH | — | Amplitude high byte |
| 0x04 | R | TEMP_LOW | — | Unit: 0.01 °C |
| 0x05 | R | TEMP_HIGH | — | Temperature high byte |
| 0x06 | R | TICK_LOW | — | Timestamp low byte |
| 0x07 | R | TICK_HIGH | — | Timestamp high byte |
| 0x08 | – | Reserved | Hold | |
| 0x09 | R | ERROR_LOW | — | Hold |
| 0x0A | R | VERSION_REVISION | — | Revised version |
| 0x0B | R | VERSION_MINOR | — | Minor version |
| 0x0C | R | VERSION_MAJOR | — | Major version |
| 0x0D–0x0F | – | Reserved | Hold | |
| 0x10–0x1D | R | SN | — | Production code (14 bytes ASCII, 0x10 first byte) |
| 0x1E–0x1F | – | Reserved | Hold | |
| 0x20 | W | SAVE | — | Write 0x01 to save current setting |
| 0x21 | W | SHUTDOWN / REBOOT | — | Write 0x02 to reboot |
| 0x22 | W/R | SLAVE_ADDR | 0x10 | I²C address range: 0x08–0x77 |
| 0x23 | W/R | MODE | 0x00 | 0x00: Continuous mode / 0x01: Trigger mode |
| 0x24 | W | TRIG_ONE_SHOT | — | 0x01: Trigger once (trigger mode only) |
| 0x25 | W/R | ENABLE | 0x01 | 0x00: Turn off LiDAR / 0x01: Turn on LiDAR |
| 0x26 | W/R | FPS_LOW | 0x64 | Frames per second low byte |
| 0x27 | W/R | FPS_HIGH | 0x00 | Frames per second high byte |
| 0x28 | W/R | HOLD | — | Reserved |
| 0x29 | W | RESTORE_FACTORY_DEFAULTS | — | Write 0x01 to restore factory defaults |
| 0x2A | W/R | AMP_THR_LOW | 0x2C | Amplitude threshold low byte |
| 0x2B | W/R | AMP_THR_HIGH | 0x01 | Amplitude threshold high byte |
| 0x2C | W/R | DUMMY_DIST_LOW | 0xFF | Dummy distance low byte |
| 0x2D | W/R | DUMMY_DIST_HIGH | 0xFF | Dummy distance high byte |
| 0x2E | W/R | MIN_DIST_LOW | 0x00 | Minimum distance low byte (mm) |
| 0x2F | W/R | MIN_DIST_HIGH | 0x00 | Minimum distance high byte |
| 0x30 | W/R | MAX_DIST_LOW | 0xFF | Maximum distance low byte (mm) |
| 0x31 | W/R | MAX_DIST_HIGH | 0xFF | Maximum distance high byte |
| 0x32–0x3B | – | Reserved | Hold | |
| 0x3A–0x3F | R | SIGNATURE | — | ASCII string (e.g. “TOF20-L”) |
ماژول TFmini Plus میتواند دادهها را از طریق پورت سریال در دو فرمت مختلف ارسال کند که امکان تغییر بین این دو فرمت با استفاده از دستور (Command) وجود دارد.
در این حالت، داده خروجی به صورت رشته متنی و با واحد متر (m) ارسال میشود.
برای مثال اگر فاصله اندازهگیریشده 1.21 متر باشد، خروجی به صورت زیر خواهد بود:
|
1 |
1.21\r\n |
(یعنی بعد از عدد، کاراکترهای پایان خط CR و LF ارسال میشوند.)
در این حالت، هر فریم داده شامل ۹ بایت است. این فریم اطلاعات زیر را در بر دارد:
تمام دادهها به صورت هگزادسیمال (HEX) ارسال میشوند و هر فریم دقیقاً ۹ بایت دارد که به صورت زیر است:
| بایت | نام | توضیح |
| Byte0 | 0x59 | هدر فریم (ثابت) |
| Byte1 | 0x59 | هدر فریم (ثابت) |
| Byte2 | Dist_L | 8 بیت کمارزش فاصله |
| Byte3 | Dist_H | 8 بیت پرارزش فاصله |
| Byte4 | Strength_L | 8 بیت کمارزش قدرت سیگنال |
| Byte5 | Strength_H | 8 بیت پرارزش قدرت سیگنال |
| Byte6 | Temp_L | 8 بیت کمارزش دما |
| Byte7 | Temp_H | 8 بیت پرارزش دما |
| Byte8 | Checksum | 8 بیت کمارزش مجموع بایتهای 0 تا 7 |
نکات مهم:
Distance (فاصله) نشاندهنده فاصله اندازهگیریشده توسط ماژول است که بهصورت پیشفرض با واحد سانتیمتر ارسال میشود و مقدار آن بهصورت عدد دهدهی است. Strength (قدرت سیگنال) نشاندهنده قدرت سیگنال بازگشتی است و مقدار آن بهصورت پیشفرض در بازه 0 تا 65535 قرار دارد. اگر قدرت سیگنال کمتر از 100 باشد یا مقدار قدرت سیگنال برابر 65535 باشد (حالت اشباع یا overexposed) رخ میدهد. در این شرایط اندازهگیری معتبر نیست و ماژول مقدار فاصله را 0 قرار میدهد.
مثالی از پکت دریافتی:
|
1 2 3 4 5 |
59 59 DB 00 29 52 48 09 59 59 DB 00 26 52 48 09 59 59 DB 00 15 52 48 09 59 59 DB 00 FE 51 48 09 59 59 DB 00 EC 51 48 09 |
برای اینکار به برنامه (WINCC_TF) نیاز دارید که میتوانید از این لینک دریافت کنید. پس از آن به ترتیبی که قبلا گفته شد ماژول را راه اندازی کنید و با استفاده از یک مبدل (USB-Serial) و برنامهای که دانلود کردید مشابه آنچه در تصویر مشاهده میکنید با ماژول ارتباط بگیرید.

کد نویسی برای این ماژول کار دشواری نیست زیرا تمام اطلاعات لازم را دارید اما برای سرعت بخشیدن به فرایند توسعه محصول اینجا به بررسی کدی که برای شما عزیزان آماده کردیم میپردازیم. در این کد ابتدا برقراری ارتباط صحیح بررسی میشود و سپس درخواست دریافت اطلاعات از طریق UART برای ماژول ارسال شده و داده ها بررسی شده و نمایش داده میشود. sketch آردوینو به صورت زیر است:
|
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 |
#include "TFS20.h" #define BAUDRATE 115200 // Use Serial1 for module (Pin 0 RX, Pin 1 TX) TFS20 lidar(Serial1); void setup() { Serial.begin(BAUDRATE); lidar.begin(BAUDRATE); Serial.println("TFS20 test start..."); if (!lidar.checkModule(500)) { Serial.println("ERROR: Module not responding"); while (1); } Serial.println("Module OK"); lidar.startContinuous(); Serial.println("Continuous mode started"); } void loop() { uint16_t distance, strength, tempRaw; if (lidar.readData(distance, strength, tempRaw)) { Serial.print("Distance: "); Serial.print(distance); Serial.print(" | Strength: "); Serial.print(strength); Serial.print(" | Temp raw: "); Serial.println(tempRaw); } } |
ابتدا با درخواست دریافت نسخه فریمور بررسی میکنیم که اتصالات سخت افزاری به درستی برقرار است و سپس از تابع readData استفاده میکنیم. این تابع فاصله، زمان و دما را از پکت ارسالی ماژول استخراج کرده و نمایش میدهد. همچنین Checksum و Strength را بررسی میکند که اگر مقدار اشتباهی داشتند به کاربر اعلام کند. این تابع به صورت زیر است:
|
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 |
bool TFS20::readData(uint16_t &distance, uint16_t &strength, uint16_t &tempRaw) { uint8_t buf[9]; if (serial.available() >= 9) { if (serial.read() == 0x59 && serial.read() == 0x59) { buf[0] = 0x59; buf[1] = 0x59; for (int i = 2; i < 9; i++) { buf[i] = serial.read(); } // Check checksum if (calcChecksum(buf, 8) != buf[8]) { return false; } distance = buf[2] | (buf[3] << 8); strength = buf[4] | (buf[5] << 8); tempRaw = buf[6] | (buf[7] << 8); // Strength validation if (strength >= 65535 || strength < 100) { return false; } return true; } } return false; } |
چنانچه برنامه به درستی کار کند خروجی مانند زیر خواهید داشت:

برای دانلود و استفاده از این کد میتوانید به این آدرس گیت مراجعه فرمایید.
وبسایت: http://www.arvidtek.com
www.arvidtek.com | گروه مهندسی آرویدتک | فعال حوزه الکترونیک و مخابرات | فروشگاه تخصصی قطعات الکترونیک
سیسوگ با افتخار فضایی برای اشتراک گذاری دانش شماست. برای ما مقاله بنویسید.