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

پروژه شتاب سنج سه محوره ADXL355 با استفاده از میکروکنترلر ATMEGA

راه-اندازی-ADXL335-با-ز-برد-آموزشی-پلاریس-Polaris

فهرست مطالب

راهنمای راه اندازی سنسور شتاب سنج سه محوره ADXL355 

هدف: در این پروژه سنسور شتاب‌سنج سه محوره adxl355 توسط برد AVR WIZARD راه‌اندازی شده و داد‌ه‌های مربوطه بر روی LCDنمایش داده می‌شود.

مقدمه‌ای بر سنسور ADXL355

1. سنسور ADXL355

حسگر ADXL355 ، یک حسگر شتاب سنج سه محوره با خروجی دیجیتال ( SPI یا I2C ) است که دارای چگالی نویز پایین، آفست دریفت کم 0g و مصرف توان پایین می‌باشد. ADXL355 قادر به اندازه‌گیری شتاب، در محدوده‌های 2.048g ، ±4.096g±  و 8.192g±  می‌باشد. از دیگر ویژگی‌های آن به توانایی کار در محیط‌های صنعتی، آفست دریفت پایین متاثر از تغییرات دمایی و Long term stability، می‌توان اشاره کرد که برای کاربردهای دقیق با حداقل کالیبراسیون مناسب است.

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

2. بلوک دیاگرام عملیاتی ADXL355

حسگر ADXL355 دارای یک فیلتر میان‌گذر داخلی قابل تنظیم است. قطب‌های فیلتر بالا گذر و پایین گذر از طریق رجیسترهای مربوط به آن ها قابل تنظیم است. در حالت پیش‌فرض تنظیمات فیلتر به صورت زیر است:

 

فیلتر بالا گذر ( HPF ) :                 off 

فیلتر میان گذر ( LPF ) :            1000 Hz

نرخ داده خروجی ( ODR ):        4000 Hz

راه‌اندازی ADXL355 توسط برد AVR WIZARD

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

کدنویسی

از طریق درگاه SPI ارتباط برقرار می‌کند. برای نوشتن کد مربوطه، ابتدا در CodeVision پروژه جدید تعریف کرده و درگاه‌های SPI آن را راه اندازی می‌کنیم. همچنین تنظیمات مربوط به LCD  را انجام می‌دهیم.

ایجاد پروژه در CodeVision

برای ایجاد پروژه جدید، از شاخه File، گزینه New و سپس Project را انتخاب کنید.

سپس پیغام مربوط به code wizard را مشاهده خواهید کرد؛ دکمه Yes را بزنید.

سپس پنجره دیگری نشان داده خواهد شد؛ گزینه اول را انتخاب کرده و Ok را بزنید.

پس از تایید این گزینه، وارد صفحه جدیدی خواهید شد. در این صفحه تنظیمات مربوط به پورت‌های ورودی و خروجی، LCD و SPI را انجام خواهیم داد. میکرو کنترلر استفاده شده ATMEGA32A می‌باشد.

پایه CS ماژول به PORTB.4 متصل است. در قسمت PORT، این پورت را به عنوان خروجی تعریف می کنیم.

سپس تنظیمات مربوط به LCD را انجام می‌دهیم.

همانطور که روی برد مشخص شده است، خطوط داده LCD به PORTA و خطوط فرمان به PORTB متصل هستند.

در ادامه SPI را فعال سازی می‌کنیم.

در پایان تنظیمات را ذخیره کرده و گزینه تولید فایل‌ها را می‌زنیم.

پس از ذخیره سازی، وارد پنجره کدنویسی خواهیم شد. در این پنجره قسمت‌های مشخص شده اند که کاربر کد خود را در آن جا وارد کند.

				
					
#include <mega32a.h>
// SPI functions
#include <spi.h>
// Alphanumeric LCD functions
#include <alcd.h>
// Declare your global variables here
// Standard Input/Output functions
#include <stdio.h>
#include <stdint.h>
#include <delay.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
//adxl registers
uint8_t status_reg=0x04;
uint8_t temp2=0x06;
uint8_t temp1=0x07;
uint8_t xdata3=0x08;
uint8_t xdata2=0x09;
uint8_t xdata1=0x0A;
uint8_t ydata3=0x0B;
uint8_t ydata2=0x0C;
uint8_t ydata1=0x0D;
uint8_t zdata3=0x0E;
uint8_t zdata2=0x0F;
uint8_t zdata1=0x10;
uint8_t filter=0x28;
uint8_t range=0x2C;
uint8_t mode=0x2D;
uint8_t mode_off=0x01;
uint8_t mode_on=0x00;
long int x,y,z;
float e=0,e1=0,e2=0,k1=.01,k2=.01,k3=0,delta_u=0,out; //PID variables (change k1,k2,k3 (must be<1) to see theire effects)
float acc_x,acc_y,acc_z;
float temperatur;
char x_ch[10],y_ch[10],z_ch[10];
/************** 2G, 4G, 8G *********/
uint8_t range_value[]={0x01,0x02,0x03};
/*******************4000,2000,1000,500,250,125,62.5,31.25,15.625,7.813,3.906 HZ****/
uint8_t ODR_LPF[]= {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A};
void adxl_config(uint8_t,uint8_t);
void adxl_readData(uint8_t);
void uart_print(char*);
void uart_putchar(char);
void main(void)
{
// 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=Out Bit6=In Bit5=Out Bit4=Out Bit3=In Bit2=In Bit1=In Bit0=In
DDRB=(1<<DDB7) | (0<<DDB6) | (1<<DDB5) | (1<<DDB4) | (0<<DDB3) | (0<<DDB2) | (0<<DDB1) | (0<<DDB0);
// State: Bit7=0 Bit6=T Bit5=0 Bit4=0 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: On
// 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) | (1<<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=0x33;
// SPI initialization
// SPI Type: Master
// SPI Clock Rate: 500.000 kHz
// SPI Clock Phase: Cycle Start
// SPI Clock Polarity: Low
// SPI Data Order: MSB First
SPCR=(0<<SPIE) | (1<<SPE) | (0<<DORD) | (1<<MSTR) | (0<<CPOL) | (0<<CPHA) | (0<<SPR1) | (1<<SPR0);
SPSR=(0<<SPI2X);
// TWI initialization
// TWI disabled
TWCR=(0<<TWEA) | (0<<TWSTA) | (0<<TWSTO) | (0<<TWEN) | (0<<TWIE);
// 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
lcd_init(16);
lcd_init(16);
lcd_clear();
lcd_gotoxy(6,0); //row 0 column 6
lcd_printf("KEI");
lcd_gotoxy(6,1); //row 1 column 6
lcd_printf("CAN");
adxl_config(mode,mode_off);
adxl_config(filter, ODR_LPF[8]);
adxl_config(range,range_value[0]);
delay_ms(500);
adxl_config(mode,mode_on);
delay_ms(500);
while (1)
{
// Place your code here
adxl_readData(temp2);
}
}
void adxl_config(uint8_t address,uint8_t value)
{
uint8_t i;
PORTB.4=0;
for (i=0;i<20;i++);
SPDR=(address<<1 | 0x00); //sending register address
while(!(SPSR & (1<<SPIF))); //Wait for transmission complete
SPDR=value; //sending register value
while(!(SPSR & (1<<SPIF))); //Wait for transmission complete
PORTB.4=1;
}
void adxl_readData(uint8_t address)
{
uint8_t status_r,i,read_data[11];
char st[5],temp_ch[5],acc_xch[10],acc_ych[10],acc_zch[10];
/*********check status register************/
PORTB.4=0;//chip select pin
for (i=0;i<20;i++);//delay
SPDR=(status_reg<<1 | 0x01);//status register address
while(!(SPSR & (1<<SPIF)));
SPDR=0xFF;
while(!(SPSR & (1<<SPIF)));
status_r=SPDR;
PORTB.4=1;
for (i=0;i<60;i++);
if(status_r &0x01==1)//if data ready?
{
PORTB.4=0;
for (i=0;i<20;i++);
SPDR=((address)<<1 | 0x01);
while(!(SPSR & (1<<SPIF)));
for(i=0;i<11;++i)
{
SPDR=0xFF;
while(!(SPSR & (1<<SPIF)));
read_data[i]=SPDR;
}
for (i=0;i<20;i++);
PORTB.4=1;
/**************temperature data***********/
temperatur=(long)read_data[0]<<8| read_data[1];
temperatur=((1852-temperatur)/9.05)+25; //from datasheet
/**************PID controller*************/
e2=e1;
e1=e;
e=-temperatur;
delta_u=k1*e + k2*e1 + k3*e2;
temperatur=temperatur+delta_u;
out=temperatur-delta_u;
/**************************************/
x=(long)read_data[2]<<12 | (long)read_data[3]<<4 | read_data[4]>>4; //x-axis data(20 bit)
if(x>=0x00080000) //Data is left justified and formatted as twos complement.
{
x=-1048576 - (~x+1);
}
y=(long)read_data[5]<<12 | (long)read_data[6]<<4 | read_data[7]>>4;
if(y>=0x00080000)
{
y=-1048576 - (~y+1);
}
z=(long)read_data[8]<<12 | (long)read_data[9]<<4 | read_data[10]>>4;
if(z>=0x00080000)
{
z=-1048576 - (~z+1);
}
ltoa(x,x_ch);//ltoa() function in C language converts long data type to string data type
ltoa(y,y_ch);
ltoa(z,z_ch);
acc_x=(float)x/262144; //This formula is for 2G range mode!
acc_y=(float)y/262144;
acc_z=(float)z/262144;
ftoa(acc_x,1,acc_xch); //convert a floating point number to a character array to display on LCD
ftoa(acc_y,1,acc_ych);
ftoa(acc_z,1,acc_zch);
ftoa(out,2,temp_ch);
lcd_clear();
lcd_gotoxy(0,0); //row 0 column 0
lcd_puts(acc_xch);
lcd_puts(", ");
lcd_puts(acc_ych);
lcd_puts(", ");
lcd_puts(acc_zch);
lcd_gotoxy(0,1); //row 1 column 0
lcd_puts("Temp: ");
lcd_puts(temp_ch);
lcd_puts(" 0C");
uart_print("X= ");
uart_print(x_ch); // sending data by UART
uart_print(", ");
uart_print(y_ch); // sending data by UART
uart_print(", ");
uart_print(z_ch); // sending data by UART
uart_print(". \r\n ");
}
}
void uart_putchar(char z)
{
UDR = z;
while ( !( UCSRA & (1<<UDRE)) ) ; //Wait for transmission complete
}
void uart_print(char *st)
{
int stl, i;
stl = strlen(st);
for (i=0; i<stl; i++)
uart_putchar(*st++);
}

				
			

خروجی برنامه

**نکات**

  • داده‌های سطر اول LCD، داده‌های مربوط به محورهای مختلف شتاب سنج هستند که به صورت عددی در بازه‌ی g± نشان داده شده‌اند.
  • سطر دوم داده مربوط به سنسور دما را نشان می‌دهد که برای نمایش بهتر آن، یک کنترل‌کننده PID بر روی آن اعمال شده است. برای تغییر ضرایب کنترل کننده، می‌توان مقادیر مربوط به آن را در کد اصلاح کرد.

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

پروژه شتاب سنج سه محوره ADXL355 با استفاده از میکروکنترلر ATMEGA

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

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

چهار × چهار =