|
Combined MEMS sensor for robots and inertial navigation systems. Three axis gyroscope and three axis accelerometer. The high precision and low cost sensor based on ADXL203 accelerometers, ADXRS300 gyroscopes, AD7718 DAC IC and ATmega8 microcontroller.

Schematic diagram part 1. Click to enlarge.

Schematic diagram part 2. Click to enlarge.
MEMS Sensor PCAD2006 Schematic file. Click to download.
Source code (IAR Embedded Workbench):
#include <iom8.h> // Declares the internal register addresses for ATmega8
#include <inavr.h> // Intrinsics for iccAVR
void initPorts (void);void clearReadings (void);void resetADC (void);void initUSART (unsigned char baud);void initMasterSPI (void);void transmitMasterSPI (unsigned char SPIData);void configADC (void);void setChannel (unsigned char channel);long ReadADC (void);long SetAndReadADC (unsigned char channel);void transmitUSART(unsigned char tdata);void clearADCreadings(void);#define ST1 PB0 // Selftest pin for accelerometers and angular rate sensor
#define ST2 PB1 // Selftest pin for angular rate sensor only
#define DRDY (PIND & 4) // ADC Data Ready (active low, ADC master)
#define RSTADC PD3 // ADC Reset (active low, ADC slave)
#define MOSI PB3
#define SCK PB5
#define TXDPIN PD1
#define CommWR 0
#define CommRD 64
#define CommMode 1
#define CommControl 2
#define CommFilter 3
#define CommData 4
#define CommOffset 5
#define CommGain 6
#define CommIO 7
#define CommTest1 12
#define CommTest2 13
#define CommID 15
#define updateRateNoCHOP1365Hz 3 // ADC update rate = 1365.33 Hz
#define updateRateNoCHOP315Hz 13 // ADC update rate = 315 Hz
#define updateRateNoCHOP59Hz 69 // ADC update rate = 59.36 Hz
#define updateRateNoCHOP16Hz 255 // ADC update rate = 16.06 Hz
#define updateRateCHOP105Hz 13 // ADC update rate = 105.3 Hz
#define updateRateCHOP59Hz 23 // ADC update rate = 59.36 Hz
#define updateRateCHOP51Hz 27 // ADC update rate = 50.56 Hz
#define updateRateCHOP30Hz 45 // ADC update rate = 30.3 Hz
#define BaseModeNoCHOP 147 // Chopping is disabled
#define BaseModeCHOP 19 // Chopping is enabled
#define BaseControl 15 // Select input AIN1, enable unipolar coding, select the ADC input range as 0...+5 V
#define accelerXnoFch 1
#define RNUM 200
unsigned long ulAccXZeroCode;
unsigned long ulAccXCurCode;unsigned long ulAccXCurCode2;
long ADCreadings[RNUM];
long num = 0;
void main (void)
{
__disable_interrupt();
initPorts();
initUSART(12); initMasterSPI();
resetADC();
configADC();
setChannel(accelerXnoFch);
clearADCreadings();
for (num = 0; num < RNUM ; num++)
ADCreadings[num] = ReadADC();
for (num = 0; num < RNUM ; num++)
ulAccXZeroCode += ADCreadings[num];
ulAccXZeroCode /= RNUM;
while (1) {
ulAccXCurCode = ReadADC();
if (ulAccXCurCode > ulAccXZeroCode) ulAccXCurCode = (ulAccXCurCode - ulAccXZeroCode) + 0x80000000;
else ulAccXCurCode = 0x80000000 - (ulAccXZeroCode - ulAccXCurCode);
transmitUSART((unsigned char)(ulAccXCurCode>>24));
transmitUSART((unsigned char)(ulAccXCurCode>>16));
transmitUSART((unsigned char)(ulAccXCurCode>>8));
transmitUSART((unsigned char)(ulAccXCurCode));
}
}
void clearADCreadings(void)
{
long numr = 0;
for (numr = 0; numr < RNUM ; numr++) ADCreadings[num] = 0;
}
void initPorts(void){
DDRB = 0; DDRC = 0;
DDRD = 0;
DDRB |= ( 1 << ST1 ); DDRB |= ( 1 << ST2 );
DDRD |= ( 1 << RSTADC ); DDRD |= ( 1 << TXDPIN );
PORTB &= ~( 1 << ST1 ); PORTB &= ~( 1 << ST2 );
PORTD &= ~( 1 << RSTADC );}
void initUSART(unsigned char baud){
UBRRH = (unsigned char)(baud>>8);
UBRRL = (unsigned char) baud;
UCSRB = (( 1 << RXEN ) | ( 1 << TXEN )); UCSRC = ( 1 << URSEL ) | ( 1 << USBS ) | ( 3 << UCSZ0 );}
void transmitUSART(unsigned char tdata){
while ( !( UCSRA & (1<<UDRE)) );
UDR = tdata;
}
void resetADC(void){
PORTD &= ~( 1 << RSTADC ); __delay_cycles( 3200000 );
PORTD |= ( 1 << RSTADC ); __delay_cycles( 3200000 );}
void initMasterSPI(void){
DDRB |= (( 1 << MOSI ) | ( 1 << SCK )); SPCR = ( 1 << SPE ) | ( 1 << MSTR ) | ( 1 << SPR0 );}
void transmitMasterSPI(unsigned char SPIData ){
SPDR = SPIData; while( !( SPSR & ( 1 << SPIF )));}
void configADC (void){
transmitMasterSPI( CommWR | CommFilter );
transmitMasterSPI( updateRateNoCHOP315Hz );
transmitMasterSPI( CommWR | CommMode );
transmitMasterSPI( BaseModeNoCHOP );
transmitMasterSPI( CommWR | CommControl );
transmitMasterSPI( BaseControl );
while ( DRDY ) ;
}
void setChannel (unsigned char channel){
channel <<= 4;
transmitMasterSPI( CommWR | CommControl );
transmitMasterSPI( channel | BaseControl );
while ( DRDY ) ;
}
long ReadADC (void){
long ADCword = 0;
while ( DRDY ) ;
transmitMasterSPI( CommRD | CommData );
transmitMasterSPI( 0xFF );
ADCword = SPDR;
ADCword <<= 8;
transmitMasterSPI( 0xFF );
ADCword |= SPDR;
ADCword <<= 8;
transmitMasterSPI( 0xFF );
ADCword |= SPDR;
return ADCword;
}
long SetAndReadADC (unsigned char channel){
setChannel ( channel );
return ReadADC ();
}
|