پروژه راه اندازی ماژول سنسور مغناطیسی سه محوره RM3100 با استفاده از میکروکنترلر ATMEGA

 پروژه راه اندازی ماژول سنسور مغناطیسی سه محوره  RM3100 با استفاده از میکروکنترلر  ATMEGA

راهنمای راه اندازی ماژول RM3100 با استفاده از برد آموزشی  پلاریس Polaris

هدف از انجام این پروژه آموزش و فراگیری کار با پورت های SPI   میکروکنترلر ATMEGA  میباشد

3-axis-Electronic-compass-Magnetic-field-sensor

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

طبق تکنولوژی انحصاری  magneto-inductive شرکت PNI، این سنسورها رزولوشن و عملکرد بالایی داشته و نسبت به سنسورهای اثرهال، تکرارپذیری با بیش از ده برابر رزولوشن بهتر و 20 مرتبه نویز کمتر را دارا می‌باشند. این ویژگی‌ها سبب شده تا بتوان جهت‌یابی دقیقی توسط این سنسورها داشت. این سنسورها گین و نرخ نمونه برداری بالایی داشته و هیسترزیس ندارند. همچنین مغناطیس‌سنج‌های PNI نیازی به کالیبراسیون دمایی یا پالس‌های set & reset قبل از هر اندازه‌گیری ندارند.

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

از کاربردهای آن به ردیابی حرکت (Motion tracking)، قطب نما، کنترل بازی، کنترل تلویزیون و ست-آپ باکس و اندازه‌گیری میدان مغناطیسی، می‌توان اشاره کرد.

راه اندازی RM3100 توسط برد AVR WIZZARD

راه اندازی RM3100 توسط برد AVR WIZZARD
راه اندازی RM3100 توسط برد AVR WIZZARD

هدف: در این پروژه سنسور زئو مغناطیسی RM3100 توسط برد AVR WIZZARD راه‌اندازی شده و داد‌های مربوط به هر محور ضمن نمایش بر روی LCD، از طریق درگاه سریال نیز ارسال می‌شود.

نیازمندی‌ها:

  • برد AVR WIZZARD
  • ماژول FTDI232 (USB to Serial)
  • ماژول RM3100
  • آداپتور تغذیه
  • سیم جامپر

کدنویسی:

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

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

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

rm3100 ایجاد پروژه

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

پیغام مربوط به code wizard

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

پیغام مربوط به code wizardانتخاب خانواده avr

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

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

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

PORTB.4 تعریف به عنوان خروجی

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

نظیمات مربوط به LCD

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

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

SPI فعال سازی

حال تنظیمات مربوط به UART را انجام می‌دهیم.

پورت های uart
پورت های uart

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

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


This program was created by the CodeWizardAVR V3.33 
Automatic Program Generator
© Copyright 1998-2018 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project : RM3100_AVR WIZZARD
Version : V1.0
Date    : 05/12/2019
Author  : Hossein GS
Company : Kei_Can
Comments: 
Chip type               : ATmega32A
Program type            : Application
AVR Core Clock frequency: 8.000000 MHz
Memory model            : Small
External RAM size       : 0
Data Stack size         : 512

#include <mega32a.h>
// SPI functions
#include <spi.h>
// Alphanumeric LCD functions
#include <alcd.h>
#include <stdint.h>
#include <delay.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

// Declare your global variables here
Const int Data_rate[] = {0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F};
                  //600Hz,300Hz,150Hz,75Hz,37Hz,18Hz,9Hz,4.5Hz,2.3Hz,1.2Hz,.6Hz,.3Hz,.015Hz,.075Hz//
//0             1          2         3        4       5       6     7         8         9        10     11     12        13
uint8_t Status=0x00,i,mag[9],page=0;
uint8_t Status_add=0xB4;
int32_t x,y,z;
char x_ch[8],y_ch[8],z_ch[8],sta[8];
float norm;
void uart_putchar(char );
void cycleCount(uint8_t,uint8_t) ;
void reg_write(uint8_t,uint8_t ) ;
uint8_t reg_read(uint8_t );
void uart_print(char *st);
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=Out Bit2=In Bit1=In Bit0=In 
DDRB=(1<<DDB7) | (0<<DDB6) | (1<<DDB5) | (1<<DDB4) | (1<<DDB3) | (0<<DDB2) | (0<<DDB1) | (0<<DDB0);
// State: Bit7=0 Bit6=T Bit5=0 Bit4=0 Bit3=0 Bit2=T Bit1=T Bit0=T 
PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (1<<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) | (1<<PORTD1) | (0<<PORTD0);
// USART initialization
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=(0<<URSEL) | (0<<UMSEL) | (0<<UPM1) | (0<<UPM0) | (0<<USBS) | (1<<UCSZ1) | (1<<UCSZ0) | (0<<UCPOL);
UBRRH=0x00;
UBRRL=0x67;
// SPI initialization
// SPI Type: Master
// SPI Clock Rate: 125.000 kHz
// SPI Clock Phase: Cycle Start
// SPI Clock Polarity: Low
// SPI Data Order: MSB First
SPCR=(1<<SPIE) | (1<<SPE) | (0<<DORD) | (1<<MSTR) | (0<<CPOL) | (0<<CPHA) | (1<<SPR1) | (0<<SPR0);
SPSR=(0<<SPI2X);
// 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_clear();
lcd_gotoxy(6,0); //row 0 column 6
lcd_printf("KEI");
lcd_gotoxy(6,1); //row 1 column 6
lcd_printf("CAN");
delay_ms(3000);
lcd_clear();
cycleCount(0x04,100);      //cycle count register
reg_write(0x0B,0x96);     //dataRate
reg_write(0x01,0x79);    //measurment mode (CMM register)


while (1)
      {
      // Place your code here 
        Status=reg_read(0xB4);                       //reading status register to check DRDY bit
        Status=(Status & 0x80);                     //DRDY is bit 8th
        if (Status == 0x80)                        //if DRDY=1
           {  
            PORTB.4=0;                           //CS Low
            for (i=0;i<20;i++);                 //delay
            SPDR=0xA4;                         //sending register address   
            while(!(SPSR & (1<<SPIF)));       //Wait for transmission complete
            for(i=0;i<9;i++)                 //getting 9 byte data,each axis has 3 byte data
            {
            SPDR=0xFF;                     //sending any data to sensor's buffer to recieve it's data
            while(!(SPSR & (1<<SPIF)));   //Wait for transmission complete
            mag[i]=SPDR;                 //recieved data
            }
            PORTB.4=1;                 //cs pin go to high 
            x=((int32_t)((int8_t) mag[0])<<16)|(int32_t)(mag[1])<<8|(mag[2]);//24 bit data X-axis
            y=((int32_t)((int8_t) mag[3])<<16)|(int32_t)(mag[4])<<8|(mag[5]);//24 bit data Y-axis
            z=((int32_t)((int8_t) mag[6])<<16)|(int32_t)(mag[7])<<8|(mag[8]);//24 bit data Z-axis      
            
            if (page==0)                     // selecting which axis data display on LCD
               {    
                    itoa(x,x_ch);          // converting int data to string for displaying on LCD 
                    lcd_clear();          //clearing LCD display 
                    lcd_gotoxy(0,0);     //row 0 column 0 
                    lcd_printf("X = ");
                    lcd_puts(x_ch);    //X axis data
                    uart_print("X= ");                 
                    uart_print(x_ch); // sending data by UART
                    uart_print(", "); 
               }
            else if (page==1)
               { 
                    lcd_clear();
                    itoa(y,y_ch);   
                    lcd_gotoxy(0,0); 
                    lcd_printf("Y = ");
                    lcd_puts(y_ch);    //Y axis data  
                    uart_print("Y= ");                 
                    uart_print(y_ch); // sending data by UART
                    uart_print(", ");
               }
           
            else if (page==2)
               {     
                    itoa(z,z_ch);
                    lcd_clear(); 
                    lcd_gotoxy(0,0); 
                    lcd_printf("Z = ");
                    lcd_puts(z_ch);    //Z axis data  
                    uart_print("Z= ");                 
                    uart_print(z_ch); // sending data by UART
                    uart_print(", ");

               } 
            else if (page==3)
            {       
                    itoa(x,x_ch);
                    itoa(y,y_ch);
                    itoa(z,z_ch);
                    uart_print(x_ch);
                    uart_print(", ");
                    uart_print(y_ch);
                    uart_print(", ");
                    uart_print(z_ch);
                    uart_print(", ");
                    lcd_clear(); 
                    lcd_gotoxy(0,0); 
                    lcd_printf("axises data are on serial port!"); 
            } 
               if(PINC.3==0)  // SW2 KEY
               {
                   delay_ms(500);
                   page++; 
               }
               if(page==4)
               page=0;
            
            }  
            delay_ms(1);
            
      }   
  }

void cycleCount(uint8_t address,uint8_t data)   //function for config cyclecount register
{
    if(data==50)data=0x32; else if(data==100)data=0x64; else data=0xC8;
    PORTB.4=0;                       //cs pin go to low   
    for (i=0;i<20;i++);             //delay   
    SPDR=address;                  //send config register address to spi buffer 
     while(!(SPSR & (1<<SPIF)));  //Wait for transmission complete
    for(i=0;i<3;i++)             //config 3-axis cyclecount registers
    {
   
    SPDR=0x00;                    //MSB data
    while(!(SPSR & (1<<SPIF)));  //Wait for transmission complete
    SPDR=data;                  //LSB data
    while(!(SPSR & (1<<SPIF)));//Wait for transmission complete
    }
    PORTB.4=1;               //cs pin go to high  
    delay_ms(10);
}

void reg_write(uint8_t address,uint8_t data)
{
    PORTB.4=0;                      //cs pin go to low 
    for (i=0;i<20;i++);            //delay     
    SPDR=address;                 //send config register address to spi buffer
    while(!(SPSR & (1<<SPIF)));  //Wait for transmission complete  
    SPDR=data;                  //config data
    while(!(SPSR & (1<<SPIF)));//Wait for transmission complete
    PORTB.4=1;                //cs pin go to high  
    delay_ms(10); 
}

uint8_t reg_read(uint8_t address)
{
    PORTB.4=0;                      //cs pin go to low     
    for (i=0;i<20;i++);            //delay 
    SPDR=address;                 //send reading register address to spi buffer
    while(!(SPSR & (1<<SPIF)));  //Wait for transmission complete
    SPDR=0xFF;                  //sending any data to sensor's buffer to recieve it's data   
    while(!(SPSR & (1<<SPIF)));//Wait for transmission complete
    PORTB.4=1;                //cs pin go to high  
    delay_ms(10);
    return SPDR ;
}  
  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++);
}

3axis-geo-rm3100-polaris-atmega

3axis-geo-rm3100-polaris-atmega ca output
خروجی سنسور قطب نما با استفاده از برد اموزشی پلاریس

output data of rm3100

zahra_ahmadi

پاسخ دهید

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

19 + 11 =