SaGuN's Blog

#Developer #Robotics #Engineer #Hacker

Tilt Sensing With MMA7260Q 3-axis Accelerometer and ATmega32 Microcontroller

I had previously built an accelerometer controlled robot and so here’s the sufficiently commented code for it. This project was done in CodeVisionAVR however, it can easily be done in AVRGCC. In this project, when the ATmega32 starts, it auto-calibrates, the accelerometer center position as the orientation you had at the beginning. On tiling the accelerometer board, you can move the robot front, back, left, right or stop. very simple! the outputs are driven to both L293B h-bridge as well as 16×2 LCD. Actually the total project i’m doing is a far complex one so this is just an accelerometer implementation in Mega32.

CodeVisionAVR C codeView in Github
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
//Freescale MMA7260Q 3-Axis Accelerometer ported to ATmega32 microcontroller
//Started on: Thursday, May 6, 2010
//Update: LCD interface at PortC [Started: Friday, May 7, 2010; 7:00 PM]

#include <mega32.h>
#include <stdio.h>
#include <stdlib.h>

#asm(“.equ __lcd_port=0×15″)
#include < lcd.h>

#define LCDwidth 16
char lcd_buffer[17];
char adc_itoa[7];

unsigned short oldADCpin, ADCpin;
unsigned int ADCtemp;
unsigned int ADCarray[3];
unsigned int xyzOrigin[3];
char xyzSpeed[3];

unsigned char xyzsampledflag;
unsigned char avgOrgflag;
unsigned char xyzResult;

void initialize(void);
void displayOrientation(char val, unsigned char axis);

void main(void) {

    initialize();

    for (;;) { // main loop
        if ((ADCSRA & (1< 2) { //if all x,y,z values are sampled, return to the first x value
            ADCpin = 0;
            xyzsampledflag = 1;
        }

        ADMUX = (1<<5)|(5  ADCpin);
        ADCSRA |= (1<<6); // Start new ADC conversion
        ADCarray[oldADCpin] = ADCtemp;
        oldADCpin = ADCpin;
        if(xyzsampledflag == 1) { //Print only after sampling of all 3 values x,y,z are complete and put in array
            if(avgOrgflag xyzOrigin[0]) {
                xyzSpeed[0] = xyzResult  xyzOrigin[0] ;
            }
            else {
                xyzSpeed[0] = xyzOrigin[0]  xyzResult ;
                xyzSpeed[0] |= 0×80; // set to negative number
            }
            //printf(“\nX=%d”,xyzSpeed[0]);
            //
            xyzResult = ADCarray[1]; // read Y
            if(xyzResult > xyzOrigin[1]) {
                xyzSpeed[1] = xyzResult  xyzOrigin[1];
            }

            else{
                xyzSpeed[1] = xyzOrigin[1]  xyzResult;
                xyzSpeed[1] |= 0×80;
            }
            //printf(“\nY=%d”,xyzSpeed[1]);
            //
            xyzResult = ADCarray[2]; // read Z
            if(xyzResult > xyzOrigin[2]){
                xyzSpeed[2] = xyzResult  xyzOrigin[2];
            }

            else{
                xyzSpeed[2] = xyzOrigin[2]  xyzResult;
                xyzSpeed[2] |= 0×80;
            }
            //printf(“\nZ=%d”,xyzSpeed[2]);
            printf(“\tSpeed [%d,%d,%d],xyzSpeed[0],xyzSpeed[1],xyzSpeed[2]);
        }

        printf(“\r\n[%d,%d,%d],ADCarray[0],ADCarray[1],ADCarray[2]);
        xyzsampledflag = 0;

        displayOrientation(xyzSpeed[0], 0);
        displayOrientation(xyzSpeed[1], 1);

    }
}

void initialize() {
    UCSRB = 0×18 ; // UART to setup TX and Rx
    UBRRL = 103 ; // Baud Rate for mega32.

    ADCpin = 0; // X, Y, Z: 0, 1, 2
    oldADCpin = 0;
    xyzsampledflag = 0;
    avgOrgflag = 0;
    xyzOrigin[0] = 0;
    xyzOrigin[1] = 0;
    xyzOrigin[2] = 0;

    xyzSpeed[0] = 0;
    xyzSpeed[1] = 0;
    xyzSpeed[2] = 0;

    //ADC pin 3-5
    ADMUX = (1< 10 ) { //PORTB = 0×0C;
        if(axis == 1) {
            lcd_gotoxy(0,1);
            lcd_putsf(FRONT);
        }
        if(axis == 0) {
            lcd_gotoxy(0,1);
            lcd_putsf(LEFT );
        }
    }
    /*
    else { //PORTB = 0×08;
    lcd_gotoxy(0,1);
    lcd_putsf(“STOP “);
    }
    */
    }
    else if(val) { // if negative
        val = val & 0×7F;
        // print on le left
        if( val > 10 ) { //PORTB = 0×30;
            if(axis == 1) {
                lcd_gotoxy(0,1);
                lcd_putsf(BACK );
            }
            if(axis == 0) {
                lcd_gotoxy(0,1);
                lcd_putsf(RIGHT);
            }
        }
        else { //PORTB = 0×10;
            lcd_gotoxy(0,1);
            lcd_putsf(STOP );
        }

    }
    //else PORTB = 0; // if zeros
    else {
        lcd_gotoxy(0,1);
        lcd_putsf(STOP );
    }
}

Comments