راه اندازی ADXL345 با آردوینو – بخش دوم

مقدمه

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

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

بخش نرم افزاری

استفاده از کتابخانه ADXL345 شرکت Sparkfun : 

با استفاده از این کتابخانه علاوه بر آسان شدن کدنویسی ، میتوانیم به راحتی انتخاب کنیم که از پروتکل I2C یا SPI استفاده کنیم. 

برای دانلود کتابخانه از این لینک استفاده کنید و سپس بر روی گزینه Clone or download کلیک کنید و گزینه Download ZIP رو انتخاب کنید. 

فایل دانلود شده چند بخش مهم دارد : 

  • فایل های کتابخانه ای h. و cpp. 
  • مثالی از راه اندازی ماژول
  • مثالی از کالیبراسیون ماژول

قبل از هر کاری باید این کتابخانه رو به نرم افزار Arduino  ، اضافه کنیم. ما قبلا در این جلسه نحوه اضافه کردن کتابخانه ها رو به دو شیوه جدید و قدیم توضیح داده بودیم که اگه با نحوه اضافه کردن کتابخانه ها آشنا نیستید ، پیشنهاد میکنم این جلسه رو بخونید.[post_shop]

کد راه اندازی ماژول

پس از نصب کتابخانه، مثالی که با نام SparkFun_ADXL345_Example.ino هست رو باز کنید. 

ابتدا یک سری تنظیمات را بر روی کد اعمال میکنیم. 

تعیین نوع پروتکل I2C یا SPI : 

[ihc-hide-content ihc_mb_type=”show” ihc_mb_who=”2,3,4,5″ ihc_mb_template=”4″ ]

اولین کار مهمی که باید انجام بدیم این هست که انتخاب کنیم از طریق چه پروتکلی قصد برقراری ارتباط با ماژول ADXL345 رو داریم. آیا میخوایم از SPI استفاده کنیم و یا از I2C . این بخش رو میشه. برای این کار از بخش Communication Section استفاده خواهیم کرد. کد زیر رو ببینید:

 

/*********** COMMUNICATION SELECTION ***********/
/*    Comment Out The One You Are Not Using    */
ADXL345 adxl = ADXL345(10);           // USE FOR SPI COMMUNICATION, ADXL345(CS_PIN);
//ADXL345 adxl = ADXL345();             // USE FOR I2C COMMUNICATION

همونطور که می بینید اگه خط دوم رو کامنت کنیم و از خط اول استفاده کنیم، از پروتکل SPI استفاده کردیم و پایه CS رو هم به پایه شماره 10 دیجیتال اختصاص دادیم. در صورتی هم که خط اول کامنت بشه و از خط دوم استفاده کنیم، از پروتکل I2C استفاده کردیم. 

به صورت پیش فرض، حالت SPI فعال شده است. 

تابع setup : 

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

پارامترهای مهم در یک شتاب سنج - راه اندازی ADXL345 با آردوینو

در این شکل ما با دو ضربه روبرو هستیم. اولین ضربه (First tap) و دومین ضربه (Second Tap) . همانطور که در شکل مشاهده میکنید، در هنگام این دو ضربه، مقدار شتاب بالا رفته است. این مقدار شتاب باید از حد مشخصی بالاتر باشد تا شتاب سنج آن ضربه را به عنوان یک Single Tap حساب کند. این مقدار آستانه را ما تعیین میکنیم. یکی از پارامترهایی که در کد آن را تعیین میکنیم، همین پارامتر است که با دستور adxl.setTapThreshold میتوان آن را تعیین کرد. 

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

پارامتر مهم بعدی زمان تاخیر یا Time Latency است. این زمان، مدت زمان پایان یک ضربه تا شروع زمان Window ( یا Time Window ) است که در ادامه آن را بررسی میکنیم. 

آخرین پارامتر، مدت زمان Window یا Time Window است. این مدت زمان، مدت زمانی است که باید در آن ضربه دوم اتفاق بیفتد تا شتاب سنج ضربه اول و دوم را به عنوان یک double Tap در نظر بگیرد. 

حال به سراغ توضیح تابع setup میرویم:

/******************** SETUP ********************/
/*          Configure ADXL345 Settings         */
void setup(){

Serial.begin(9600);                 // Start the serial terminal
Serial.println("SparkFun ADXL345 Accelerometer Hook Up Guide Example");
Serial.println();

adxl.powerOn();                     // Power on the ADXL345

adxl.setRangeSetting(16);           // Give the range settings
                                    // Accepted values are 2g, 4g, 8g or 16g
                                    // Higher Values = Wider Measurement Range
                                    // Lower Values = Greater Sensitivity

adxl.setSpiBit(0);                  // Configure the device to be in 4 wire SPI mode when set to '0' or 3 wire SPI mode when set to 1
                                    // Default: Set to 1
                                    // SPI pins on the ATMega328: 11, 12 and 13 as reference in SPI Library 

adxl.setActivityXYZ(1, 0, 0);       // Set to activate movement detection in the axes "adxl.setActivityXYZ(X, Y, Z);" (1 == ON, 0 == OFF)
adxl.setActivityThreshold(75);      // 62.5mg per increment   // Set activity   // Inactivity thresholds (0-255)

adxl.setInactivityXYZ(1, 0, 0);     // Set to detect inactivity in all the axes "adxl.setInactivityXYZ(X, Y, Z);" (1 == ON, 0 == OFF)
adxl.setInactivityThreshold(75);    // 62.5mg per increment   // Set inactivity // Inactivity thresholds (0-255)
adxl.setTimeInactivity(10);         // How many seconds of no activity is inactive?

adxl.setTapDetectionOnXYZ(0, 0, 1); // Detect taps in the directions turned ON "adxl.setTapDetectionOnX(X, Y, Z);" (1 == ON, 0 == OFF)

// Set values for what is considered a TAP and what is a DOUBLE TAP (0-255)
adxl.setTapThreshold(50);           // 62.5 mg per increment
adxl.setTapDuration(15);            // 625 μs per increment
adxl.setDoubleTapLatency(80);       // 1.25 ms per increment
adxl.setDoubleTapWindow(200);       // 1.25 ms per increment

// Set values for what is considered FREE FALL (0-255)
adxl.setFreeFallThreshold(7);       // (5 - 9) recommended - 62.5mg per increment
adxl.setFreeFallDuration(30);       // (20 - 70) recommended - 5ms per increment

// Setting all interupts to take place on INT1 pin
//adxl.setImportantInterruptMapping(1, 1, 1, 1, 1);     // Sets "adxl.setEveryInterruptMapping(single tap, double tap, free fall, activity, inactivity);" 
                                                        // Accepts only 1 or 2 values for pins INT1 and INT2. This chooses the pin on the ADXL345 to use for Interrupts.
                                                        // This library may have a problem using INT2 pin. Default to INT1 pin.

// Turn on Interrupts for each mode (1 == ON, 0 == OFF)
adxl.InactivityINT(1);
adxl.ActivityINT(1);
adxl.FreeFallINT(1);
adxl.doubleTapINT(1);
adxl.singleTapINT(1);

//attachInterrupt(digitalPinToInterrupt(interruptPin), ADXL_ISR, RISING);   // Attach Interrupt

}

 

  • خطوط 4-7 : در ابتدا که تنظیمات اولیه مربوط به پورت سریال انجام شده و یک عبارت رو بر روی پورت سریال مینویسیم که نکته خاصی نداره. 
  • خط 9: در خط بعد ماژول رو روشن میکنیم و در واقع بهش میگیم که قصد برقراری ارتباط رو باهات داریم. 
  • خط 11: در خط بعد رنج اندازه گیری ماژول رو مشخص میکنیم. در اینجا 16 مشخص شده است. همونطور که میدونیم هر چه این عدد بالاتر باشه ما میتونیم شتاب های بیشتری رو اندازه گیری کنیم ولی دقت اندازه گیری و حساسیت اون پایین هست. در حالی که در رنج های پایین، دقت اندازه گیری بالاتری رو خواهیم داشت. 
  • خط 16: با استفاده از این خط تعیین میکنیم که میخوایم از پروتکل SPI سه پایه استفاده کنیم و یا SPI چهار پایه. اگر آرگومان این خط 0 باشه، از پروتکل SPI چهار سیمه و اگه آرگومانش 1 باشه از پروتکل SPI سه سیمه استفاده میکنیم. 
  • خط 20: در خط بعد تعیین میکنیم که مد Activity در کدوم یک از محورهای مختصات فعال باشه. با توجه به این خط ما خواستیم که این مد رو فقط در محور X ها فعال کنیم. اگه بخوایم در یک محور این مد رو فعال کنیم باید متناظر با محور مربوطه عدد 1 و برای غیر فعال کردن ، عدد صفر رو قرار بدیم. 
  • خط 21: در خط بعد تعیین میکنیم که مقدار افزایش شتاب حداقل چقدر باشه تا ما اون رو به عنوان حالت Activity در نظر بگیریم. 
  • خط 23: این خط برای تشخیص حالت Inactivity است که همانطور که معلوم است، قصد داشتیم این حالت را فقط در محور X ها تشخیص دهیم. 
  • خط 24: در این خط میگیم که میزان تغییرات شتاب کمتر از چه مقداری باشه، ماژول در حالت Inactivity قرار میگیره. 
  • خط 25: در خط بعد تعیین میکنیم که اگه چند ثانیه ماژول حرکتی نکنه، ما حالت inactivity رو برای اون ماژول در نظر بگیریم. 
  • خط 27: خط بعد مربوط به فعال کردن خاصیت Tap ( تک ضربه ) هست که ما در اینجا گفتیم، این خاصیت فقط در محور Z ها فعال باشه. 
  • خط 30: خط بعد مربوط به تنظیم حداقل مقدار شتابی است که یک ضربه به شتاب سنج وارد می شود تا شتاب سنج آن را به عنوان یک Single Tap تشخیص دهد. 
  • خط 31: خط بعد مربوط به حداکثر مدت زمان یک ضربه است. اگر مدت زمان یک ضربه از این عدد پایین تر بود، آن ضربه به عنوان یک Single Tap تشخیص داده می شود ولی اگر این زمان بالاتر بود، معلوم می شود که آن ضربه وارد شده در واقع یک Single Tap نبوده است. 
  • خط 32: خط بعد مربوط به تنظیم زمان Tap Latency هست که ما در بالا اون رو توضیح دادیم. 
  • خط 33: خط بعد هم مربوط به تنظیم زمان Tap Window هست. 
  • خط 36: در خط بعد مقدار آستانه برای شتاب تعیین می شود تا این شتاب با شتاب ها در سه محور x و y و z مقایسه شود و اگر این مقدار کمتر از مقادیر شتاب بود، حالت سقوط آزاد تشخیص داده می شود.
  • خط 37: در خط بعد ما یک حداقل زمان مشخص می کنیم که این زمان ، حداقل مدت زمانی است که باید  مقدار شتاب مشخص شده در خط قبل باید کمتر از شتاب های محورها باشد تا حالت سقوط آزاد تشخیص داده شود. اگر مدت زمانی که در عمل سقوط آزاد اتفاق می افتد، از این زمان کمتر باشد، شتاب سنج سقوط آزاد را تشخیص نمی دهد. 
  • خط 45 تا 49: در پنج خط بعد هم تنظیم کرده ایم که وقفه برای کدام یک از مدها فعال باشد. همانطور که از کد هم مشخص است وقفه را برای تمام حالت های Activity ، Inactivity ، Tap ، double Tap ، FreeFall فعال شده است. 

تابع Loop : 

تابع Loop بسیار ساده در نظر گرفته است. ابتدا کد زیر راببینید تا در مورد خطوط آن توضیح دهیم:

/****************** MAIN CODE ******************/
/*     Accelerometer Readings and Interrupt    */
void loop(){

// Accelerometer Readings
int x,y,z;  
adxl.readAccel(&x, &y, &z);         // Read the accelerometer values and store them in variables declared above x,y,z

// Output Results to Serial
/* UNCOMMENT TO VIEW X Y Z ACCELEROMETER VALUES */  
//Serial.print(x);
//Serial.print(", ");
//Serial.print(y);
//Serial.print(", ");
//Serial.println(z); 

ADXL_ISR();
// You may also choose to avoid using interrupts and simply run the functions within ADXL_ISR(); 
//  and place it within the loop instead.  
// This may come in handy when it doesn't matter when the action occurs. 

}

 

  • در تابع بالا ابتدا سه متغیر با نام های x و y و z در نظر گرفته شده است و سپس مقادیر شتاب در هر سه محور خوانده شده و در این متغیرها ذخیره می شود. 
  • در خط بعد تابع مربوط به روتین وقفه فعال شده است تا تنظیماتی که مربوط به وقفه انجام دادیم برای ما فعال شود. این تابع در زیر آورده شده است که به سادگی قابل فهم می باشد و نیازی به توضیحات بیشتر ندارد: 
void ADXL_ISR() {
  
  // getInterruptSource clears all triggered actions after returning value
  // Do not call again until you need to recheck for triggered actions
  byte interrupts = adxl.getInterruptSource();
  
  // Free Fall Detection
  if(adxl.triggered(interrupts, ADXL345_FREE_FALL)){
    Serial.println("*** FREE FALL ***");
    //add code here to do when free fall is sensed
  } 
  
  // Inactivity
  if(adxl.triggered(interrupts, ADXL345_INACTIVITY)){
    Serial.println("*** INACTIVITY ***");
     //add code here to do when inactivity is sensed
  }
  
  // Activity
  if(adxl.triggered(interrupts, ADXL345_ACTIVITY)){
    Serial.println("*** ACTIVITY ***"); 
     //add code here to do when activity is sensed
  }
  
  // Double Tap Detection
  if(adxl.triggered(interrupts, ADXL345_DOUBLE_TAP)){
    Serial.println("*** DOUBLE TAP ***");
     //add code here to do when a 2X tap is sensed
  }
  
  // Tap Detection
  if(adxl.triggered(interrupts, ADXL345_SINGLE_TAP)){
    Serial.println("*** TAP ***");
     //add code here to do when a tap is sensed
  } 
}

 

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

نمایش مدهای کاری شتاب سنج در پنجره سریال: 

در ابتدا ماژول رو به برد وصل کنید و تنظیمات مربوط به نوع برد و پورت COM رو مشخص کنید و کد مربوطه رو روی برد بریزید. 

همونطور که گفتیم ابتدا بخش مربوط به داده ها را غیر فعال میکنیم تا فقط مدهای کاری را مشاهده کنیم. 

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

[/post_shop]

پنجره خروجی مدهای شتاب سنج - راه اندازی ADXL345 با آردوینو

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

نمایش داده ها: 

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

داده های خام یک شتاب سنج

خوب دوستان. برای این جلسه هم کافی است. مثل همیشه میتوانید ما را در تلگرام و یا اینستاگرام دنبال کنید: 

 

اشتراک گذاری:
مطالب زیر را حتما بخوانید

4 دیدگاه

به گفتگوی ما بپیوندید و دیدگاه خود را با ما در میان بگذارید.

    • با سلام. به دلیل استفاده بیش تر از سنسورهای MPU تصمیم بر آن شد که بخش IMU و ترکیب داده های مربوط به سنسورها (sensor fusion) با سنسورهای MPU پیش رویم و تاکنون راه اندازی سنسورهای MPU6050 و MPU9150 انجام شده است. البته بخش اصلی GY-80 نیز از سنسور MPU6050 تشکیل شده است و که آموزش آن قبلا منتشر شده و میتوانید از این آموزش ها برای راه اندازی GY-80 استفاده کنید. لینک آموزش های مربوط به این سنسور در زیر آوزده شده است:
      آموزش راه اندازی MPU6050
      موف باشید.

    • سلام جناب قاسمی چه طور می تونم با شما تماس بگیرم

      • سلام و درود بر شما.
        پاسخگویی فقط از طریق سایت و بخش نظرات می باشد.
        با تشکر.

دیدگاهتان را بنویسید