پروژه های AVR, پروژه‌ها

پروژه راه اندازی سنسور ژیروسکوپ و شتاب سنج ICM20689 با استفاده از مجموعه آموزشی AVR WIZARD به زبان C

فهرست مطالب

راهنمای راه‌اندازی سنسور ژیروسکوپ و شتاب‌سنج ICM20689 با استفاده از مجموعه آموزشی AVR WIZARD به زبان C

هدف از این آموزش راه‌اندازی واحد I2C با سنسور ژیروسکوپ و شتاب‌سنج ICM20689 ، به زبان برنامه‌نویسی C توسط مجموعه آموزشی AVR WIZARD می‌باشد .

قطعات مورد نیاز

  1. برد اصلی AVR WIZARD

  2.  LCD کاراکتری 2×16 

  3. ماژول سنسور ژیروسکوپ و شتاب‌سنج ICM20689

  4.  تغذیه 9 ولت

شتاب‌سنج سنسور‌هایی هستند که شتاب را اندازه‌گیری می‌کنند ، یعنی سرعت تغییر یک جسم بر حسب متر در مجذور ثانیه (m / s2) ). شتاب‌سنج برای سنجش لرزش در سیستم‌ها یا برنامه‌های جهت‌گیری مفید هستند.

شتاب‌سنج‌ها دستگاه‌های الکترومکانیکی هستند که نیروی استاتیک یا دینامیکی شتاب را حس می‌کنند. نیروهای استاتیک شامل جاذبه هستند ، در حالی که نیروهای پویا می توانند شامل ارتعاشات و حرکت شوند.

شتاب‌سنج می‌تواند شتاب را در یک ، دو یا سه محور اندازه‌گیری کند. واحدهای 3 محوره با کاهش هزینه‌های توسعه برای استفاده متداول‌تر می‌شوند.

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

سایر شتاب‌سنجها می‌توانند در اطراف مواد پیزو‌الکتریک محور باشند. این سازه‌های کریستالی ریز هنگامی که تحت فشار مکانیکی قرار می‌گیرند ، بار‌الکتریکی تولید می‌کنند (مثلاً شتاب).

بیشتر شتاب‌‍سنجها دامنه انتخابی از نیروهایی را دارند که می‌توانند اندازه بگیرند. این محدوده می‌تواند از1G تا 250G متغیر باشد. به طور معمول هر چه دامنه کوچکتر باشد ، خوانش‌ها از شتاب‌سنج حساس‌تر خواهد بود.

به عنوان مثال برای اندازه‌گیری ارتعاشات کوچک روی میز ، استفاده از شتاب‌سنج با برد کوچک ، داده‌های دقیق‌تری را نسبت به استفاده از برد 250g  که برای موشک‌ها مناسب‌تر است  ارائه می‌دهد.

نحوه اتصال و برقراری ارتباط با شتاب سنج

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

آنالوگ: شتاب‌سنج با یک رابط آنالوگ شتاب را از طریق متغیر ولتاژ نشان می‌دهد. این مقادیر معمولاً بین سطح زمین و ولتاژ منبع تغذیه متغیر هستند. سپس می‌توان از ADC در میکروکنترلر برای خواندن این مقدار استفاده کرد. این شتاب‌سنج ها معمولاً ارزان‌تر از شتاب‌سنج‌‎های دیجیتال هستند.

دیجیتال: شتاب سنج با رابط دیجیتال می‌توانند با پروتکل‌های ارتباطی SPI یا I2C ارتباط برقرار کنند. این شتاب‌سنج‌ها عملکرد بیشتری دارند و نسبت به شتاب‌سنج‌های آنالوگ کمتر مستعد ابتلا به نویز  هستند.

Pulse-Width Modulation(PWM): شتاب‌سنج‌هایی که داده‌ها را از طریق مدولاسیون پالس (PWM) استخراج می‌کنند ، امواج مربعی را با یک دوره مشخص تولید می‌کنند.

سنسور ژیروسکوپ

ژیروسکوپ یا GYRO سنسور‌هایی هستند که حرکت چرخشی را اندازه‌گیری می‌کنند. gyrosMEMS ( سیستم میکرو‌الکترومکانیکی ) سنسورهای کوچک و ارزان قیمتی هستند که سرعت زاویه‌ای را اندازه می‌گیرند. واحدهای سرعت زاویه‌ای در درجه در ثانیه (درجه در ثانیه) یا چرخش در ثانیه (RPS) اندازه‌گیری می‌شوند. سرعت زاویه‌ای اندازه‌گیری سرعت چرخش است.

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

هنگامی که همه‌چیز در یک محور می‌چرخد ،  دارای سرعت زاویه‌ای است. چرخ ریسندگی را می‌توان با چرخش در ثانیه ( RPS ) یا درجه در ثانیه ( درجه در ثانیه ) اندازه‌گیری کرد. اگر سنسور را به چرخ نشان داده‌شده در بالا وصل کنید ، می‌توانید سرعت زاویه‌ای محور z gyro را اندازه‌گیری کنید. دو محور دیگر هیچ چرخشی را اندازه‌گیری نمی‌کنند.

شکل 1. چرخ ریسندگی

چرخش در ژیروسکوپ

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

یک ژیروسکوپ MEMS با محور سه‌گانه ، مشابه آنچه در تصویر بالا نشان داده‌ شده‌است ( ITG-3200 ) ، می‌تواند چرخش را در حدود سه محور: x ، y و z اندازه‌گیری کند. بعضی از ژیروها در محورهای یک و دو محوره قرار می‌گیرند ، اما ژیرو محور سه‌گانه در یک تراشه منفرد کوچک‌تر ، ارزان‌تر و محبوب‌تر می‌شود.

شکل 2. ژیروسکوپ با محور سه‌گانه (ITG-3200)

سنسور ژیروسکوپ

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

سنسور ژیروسکوپ در MEMS بسیار کوچک است (بین 1 تا 100 میکرومتر ، اندازه موهای انسان). هنگامی که ژیرو چرخانده می‌شود ، با تغییر سرعت زاویه‌ای ، یک توده تشدید کننده کوچک جابجا می‌شود. این حرکت به سیگنال‌های الکتریکی بسیار کم جریان تبدیل می‌شود که توسط میکروکنترلر میزبان تقویت و خوانده می‌شود.

شکل 3. سنسورهای MEMS

خصوصیات ژیروسکوپ

دامنه:

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

حساسیت:

حساسیت در mV در هر درجه در ثانیه (mV / ° / s) اندازه‌‎گیری می‌شود. تعیین می‌کند که چقدر ولتاژ برای یک سرعت زاویه‌ای مشخص تغییر می‌کند. به عنوان مثال ، اگر یک ژیرو با حساسیت 30mV / ° / s مشخص شده است و تغییر 300 میلی‌ولت در خروجی را مشاهده می‌کنید ، شما ژیرو را با 10 درجه در ثانیه چرخانده‌اید.

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

 

BIAS:

مانند هر سنسور ، مقادیر اندازه‌گیری شده حاوی مقداری خطا است. هنگامی که هنوز ژیروسکوپ است ، می‌توانید با اندازه‌گیری میزان خروجی ، خطای ژیرو را مشاهده کنید. این خطاها گاهی اوقات بی‌ثبات یا بی‌ثباتی نامیده می‌‎شوند. دمای سنسور روی BIAS تأثیر زیادی دارد. برای كمك به حداقل رساندن منبع این خطا ، بیشتر آنها همراه سنسور دما داخلی ساخته شده‌اند. بنابراین ، شما قادر به خواندن دمای سنسور و اصلاح یا هرگونه تغییر وابسته به دما هستید. برای تصحیح این خطاها ، باید ژیرو کالیبره شود. این کار معمولاً با ثابت نگه داشتن gyro و صفر کردن تمام خوانش‌های موجود در کد شما انجام می‌شود.

 

پین های ماژول ICM20689

شکل 4. ماژول ICM20689

برنامه نویسی

کد برنامه نویسی به زبان c هدر فایل TWI

				
					
#ifndef TwoWire_h
#define TwoWire_h
#include <mega16a.h>
#define uint8_t     unsigned char
#define ACK     0
#define NACK     1
void Twi_Start(void);
void Twi_Send(uint8_t data)  ;
uint8_t Twi_ReadStatus(void)   ;
void Twi_Stop()  ;
void Twi_Init(void)  ;
uint8_t Twi_Read(uint8_t ack_n)  ;
void Twi_AsSlave(uint8_t slave_a)    ;
void Twi_listen(void)  ;

 void Twi_Start(void)
{
    TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
    while ((TWCR & (1<<TWINT))==0);    
    
}

void Twi_Send(uint8_t data)
{
    TWDR=data;
    TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWEA);
    while ((TWCR & (1<<TWINT))==0); 
}

uint8_t Twi_ReadStatus(void)
{
    uint8_t i=0;
    i=TWSR & 0XF8;
    return i;
}

void Twi_Stop()
{
    TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
}

void Twi_Init(void)
{
    TWSR=0;
    TWBR=0x48;
    TWCR=0x44;
}
uint8_t Twi_Read(uint8_t ack_n)
{
    if(ack_n==0)
    TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWEA);
    else
    TWCR=(1<<TWINT)|(1<<TWEN);
    while ((TWCR & (1<<TWINT))==0);
    return TWDR;
}

void Twi_AsSlave(uint8_t slave_a)
{
    TWAR=slave_a;
    TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWEA);
}

void Twi_listen(void)
{
  while ((TWCR & (1<<TWINT))==0);
}  

#endif

				
			

در ادامه برنامه به زبان C در تابع MAIN را مشاهده می کنید:

				
					
#include <mega16a.h>
#include <alcd.h>
#include <delay.h>
#include <stdlib.h>
#include "TCS34725.h"
#include "Twi.h"
#define  WHO_AM_I   0x75
#define ICM20689_ADDRESS     0x68
#define ICM20689_ADDRESS_WRITE    0|(ICM20689_ADDRESS<< 1)
#define ICM20689_ADDRESS_READ     1|(ICM20689_ADDRESS<< 1)    
#define ICM20689_CONFIG     0X1A
#define ICM20689_GYRO_CONFIG        0X1B
#define ICM20689_ACCEL_CONFIG      0X1C
#define ICM20689_ACCEL_CONFIG2     0X1D
#define ICM20689_LPMODE_CFG        0X1E
#define ICM20689_FIFO_ENA               0X23
#define ICM20689_USER_CONTROL     0X6A
#define ICM20689_PWR_MGMT1           0X6B
#define ICM20689_PWR_MGMT2           0X6C
#define ACCEL_XOUT_H           0X3B
#define ACCEL_XOUT_L           0X3C
#define ACCEL_YOUT_H           0X3D
#define ACCEL_YOUT_L           0X3E
#define ACCEL_ZOUT_H           0X3F
#define ACCEL_ZOUT_L           0X40

void ICM20689_WriteData(uint8_t RegisterName,uint8_t value)
{
  Twi_Start();   
  Twi_Send(ICM20689_ADDRESS_WRITE);   
  Twi_Send(RegisterName);    
  Twi_Send(value);
}

uint8_t ICM20689_ReadData(uint8_t RegisterName)
{
  Twi_Start();   
  Twi_Send(ICM20689_ADDRESS_WRITE);   
  Twi_Send(RegisterName);    
  Twi_Start();
  Twi_Send(ICM20689_ADDRESS_READ);  
  return Twi_Read(NACK); 
}

void ICM20689_Init(void)
{
  ICM20689_WriteData(ICM20689_PWR_MGMT1,0x20) ;
  ICM20689_WriteData(ICM20689_PWR_MGMT2,0x80) ;
  ICM20689_WriteData(ICM20689_CONFIG,0x7) ;
  ICM20689_WriteData(ICM20689_GYRO_CONFIG,0x18) ;
  ICM20689_WriteData(ICM20689_ACCEL_CONFIG,0x18) ;
  ICM20689_WriteData(ICM20689_ACCEL_CONFIG2,0x37) ;
  ICM20689_WriteData(ICM20689_LPMODE_CFG,0x80) ;
  ICM20689_WriteData(ICM20689_FIFO_ENA,0xF8) ;
  ICM20689_WriteData(ICM20689_USER_CONTROL,0xC0) ;
}

uint16_t ICM20689_GetRawData(uint8_t hvalue,uint8_t lvalue)
{
  uint16_t x;
  uint16_t t;
  t=Tcs34725_ReadData(lvalue);  
 delay_ms(1); 
  x=Tcs34725_ReadData(hvalue);
  x <<= 8;
  x |= t;    
  return x;
}

// Declare your global variables here

// Standard Input/Output functions
#include <stdio.h>

void main(void)
{
  uint8_t data_rx    ;    
  uint16_t xa, ya, za;                         
  char xabuffer[6],yabuffer[6],zabuffer[6];
// Declare your local variables here

// Input/Output Ports initialization
// Port A initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In 
DDRA=(0<<DDA7) | (0<<DDA6) | (0<<DDA5) | (0<<DDA4) | (0<<DDA3) | (0<<DDA2) | (0<<DDA1) | (0<<DDA0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T 
PORTA=(0<<PORTA7) | (0<<PORTA6) | (0<<PORTA5) | (0<<PORTA4) | (0<<PORTA3) | (0<<PORTA2) | (0<<PORTA1) | (0<<PORTA0);

// Port B initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In 
DDRB=(0<<DDB7) | (0<<DDB6) | (0<<DDB5) | (0<<DDB4) | (0<<DDB3) | (0<<DDB2) | (0<<DDB1) | (0<<DDB0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T 
PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0);

// Port C initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In 
DDRC=(0<<DDC7) | (0<<DDC6) | (0<<DDC5) | (0<<DDC4) | (0<<DDC3) | (0<<DDC2) | (0<<DDC1) | (0<<DDC0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T 
PORTC=(0<<PORTC7) | (0<<PORTC6) | (0<<PORTC5) | (0<<PORTC4) | (0<<PORTC3) | (0<<PORTC2) | (0<<PORTC1) | (0<<PORTC0);

// Port D initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In 
DDRD=(0<<DDD7) | (0<<DDD6) | (0<<DDD5) | (0<<DDD4) | (0<<DDD3) | (0<<DDD2) | (0<<DDD1) | (0<<DDD0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T 
PORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);

// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: Off
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud Rate: 9600
UCSRA=(0<<RXC) | (0<<TXC) | (0<<UDRE) | (0<<FE) | (0<<DOR) | (0<<UPE) | (0<<U2X) | (0<<MPCM);
UCSRB=(0<<RXCIE) | (0<<TXCIE) | (0<<UDRIE) | (0<<RXEN) | (1<<TXEN) | (0<<UCSZ2) | (0<<RXB8) | (0<<TXB8);
UCSRC=(1<<URSEL) | (0<<UMSEL) | (0<<UPM1) | (0<<UPM0) | (0<<USBS) | (1<<UCSZ1) | (1<<UCSZ0) | (0<<UCPOL);
UBRRH=0x00;
UBRRL=0x67;

// Alphanumeric LCD initialization
// Connections are specified in the
// Project|Configure|C Compiler|Libraries|Alphanumeric LCD menu:
// RS - PORTB Bit 0
// RD - PORTB Bit 1
// EN - PORTB Bit 2
// D4 - PORTA Bit 4
// D5 - PORTA Bit 5
// D6 - PORTA Bit 6
// D7 - PORTA Bit 7
// Characters/line: 16
//printf("hi "); 
lcd_init(16);
lcd_putsf( "   HI Wellcom   " ) ;
lcd_gotoxy( 0 , 1 );
lcd_putsf( "TO REDRONIC.COM" ) ;                     
delay_ms(2000);
lcd_clear();
Twi_Init() ;
ICM20689_Init();
while (1)
      {      
             lcd_clear();
             xa=ICM20689_GetRawData(ACCEL_XOUT_H,ACCEL_XOUT_L);           
             ya=ICM20689_GetRawData(ACCEL_YOUT_H,ACCEL_YOUT_L); 
             za=ICM20689_GetRawData(ACCEL_ZOUT_H,ACCEL_ZOUT_L);    
             itoa (xa,xabuffer);
             itoa (ya,yabuffer);
             itoa (za,zabuffer);
             lcd_gotoxy(0,0);
               lcd_putsf("XA:");
               lcd_gotoxy(3,0); 
               lcd_puts(xabuffer); 
               lcd_gotoxy(9,0);
               lcd_putsf("YA:");   
               lcd_gotoxy(12,0);  
               lcd_puts(yabuffer);
               lcd_gotoxy(0,1);
               lcd_putsf("ZA:");
               lcd_gotoxy(3,1); 
               lcd_puts(zabuffer);    
               delay_ms(200); 
//               lcd_gotoxy(9,1);  
//               lcd_putsf("C");       
//               lcd_gotoxy(11,1); 
//               lcd_puts(clearbuffer);        
//           data_rx=Tcs34725_ReadData(WHO_AM_I); 
//           printf("   id=%x  ",data_rx);      
//           delay_ms(2000); 
      }
}

				
			

خروجی برنامه

شکل 5. خروجی برنامه

نظرتان را درباره این مقاله بگویید 2 نظر

پروژه راه اندازی سنسور ژیروسکوپ و شتاب سنج ICM20689 با استفاده از مجموعه آموزشی AVR WIZARD به زبان C

نوشته های مشابه

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

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دو × یک =