آموزش راه‌اندازی ماژول RM3100

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

آموزش راه‌اندازی ماژول RM3100

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

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

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

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

 

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

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

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

کدنویسی:

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

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


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


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

 

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


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

 

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

 


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

 

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


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


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

 

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

 

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

آموزش راه‌اندازی ماژول RM3100

پیوست

 

/*******************************************************

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    : ۰۵/۱۲/۲۰۱۹

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       : ۰

Data Stack size         : ۵۱۲

*******************************************************/

#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};

                  //۶۰۰Hz,300Hz,150Hz,75Hz,37Hz,18Hz,9Hz,4.5Hz,2.3Hz,1.2Hz,.6Hz,.3Hz,.015Hz,.075Hz//

//۰             ۱          ۲         ۳        ۴       ۵       ۶     ۷         ۸         ۹        ۱۰     ۱۱     ۱۲        ۱۳

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++);

}

 

 

 

برای مشاهده سنسورهای مغناطیس اینجا لیک کنید.

برای مشاهده دیتاشیت اینجا کلیک کنید.