Subversion Repositories Projects

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
964 - 1
#include <avr/io.h>   
2
#include <math.h>
3
#include <stdlib.h>
4
#include "vector.h"
5
#include <util/delay.h>
6
#include <inttypes.h>
7
#include <avr/interrupt.h>
8
#include "headtracker.h"
9
 
10
#if(DEBUG)
11
        #include "UART.h"
12
        #include <string.h>
13
#endif
14
 
15
 
16
volatile        uint16_t ppm_ch[PPM_CHANNELS];
17
 
18
enum calibration_mode {CAL_NONE, CAL_X, CAL_Y, CAL_Z};
19
 
20
void ppm_init(void)
21
{
22
 
23
        for(int i = 0; i<PPM_CHANNELS; i++) ppm_ch[i] = DEFAULT_US;
24
 
25
        //TCNT 1 - PPM out - 
26
        DDRD            |= PPM_PIN;
27
        TIMSK           |= (1<<OCIE1B);
28
 
29
        TCNT1            = 0;
30
        OCR1A            = ppm_ch[0];
31
        OCR1B            = PPM_SYNC_PW;
32
        TCCR1A          |= (1<<COM1B1) | (PPM_INV<<COM1B0)      | (1<<WGM11) | (1<<WGM10);
33
        TCCR1B          |= (1<<WGM13)   | (1<<WGM12);
34
        TCCR1B          |= (0<<CS12)    | (1<<CS11)     | (0<<CS10 );
35
 
36
        sei();
37
 
38
}
39
 
40
 
41
ISR(TIMER1_COMPB_vect)
42
{
43
        static uint8_t i = 0;
44
        static uint16_t frame_pw = PPM_FRAME;
45
 
46
        //output PPM channels
47
        ++i;
48
 
49
        if(i >= PPM_CHANNELS+1)
50
        {
51
                i                       = 0;
52
                frame_pw        = PPM_FRAME;
53
        }
54
 
55
        if(i < PPM_CHANNELS)
56
        {
57
 
58
                OCR1A            = ppm_ch[i];
59
                frame_pw        -= OCR1A;
60
        }
61
        else
62
        {
63
                OCR1A           = frame_pw;
64
        }
65
 
66
}
67
 
68
 
69
 
70
int main()
71
{
72
        _delay_ms(500);  //delay for VCC stabilization
73
 
74
        ppm_init();
75
 
76
        #if(DEBUG)
77
                uart_init();
78
        #endif
79
 
80
        //************************************************************************
81
        //** init LSM303DLH                                                                                                             **
82
        //************************************************************************
83
        DDRC = 0;                              // all inputs
84
        PORTC = (1 << PORTC4) | (1 << PORTC5); // enable pull-ups on SDA and SCL
85
 
86
 
87
        TWSR = 0;  // clear bit-rate prescale bits
88
        TWBR = 17;
89
 
90
        //enable accelerometer
91
        i2c_start();
92
        i2c_write_byte(0x30); // write acc
93
        i2c_write_byte(0x20); // CTRL_REG1_A
94
        i2c_write_byte(0x27); // normal power mode, 50 Hz data rate, all axes enabled
95
        i2c_stop();
96
 
97
        //enable magnetometer
98
        i2c_start();
99
        i2c_write_byte(0x3C); // write mag
100
        i2c_write_byte(0x02); // MR_REG_M
101
        i2c_write_byte(0x00); // continuous conversion mode
102
        i2c_stop();
103
 
104
        //raw acc and mag
105
        vector a, m;
106
        //filtered acc and mag
107
        vector a_avg, m_avg;
108
 
109
        //IIR filter will overshoot at startup, read in a couple of values to get it stable
110
        for(int i = 0; i<20; i++)       read_data(&a_avg, &m_avg);
111
 
112
        //get zero reference
113
        float heading_start, pitch_start, roll_start;
114
        heading_start   = get_heading(&a_avg, &m_avg, &p);
115
        pitch_start     = get_perpendicular(&a_avg, &down, &p);
116
        roll_start              = get_perpendicular(&a_avg, &down, &right);
117
 
118
        enum calibration_mode mode = CAL_NONE;
119
        vector cal_m_max = {0, 0, 0};
120
        vector cal_m_min = {0, 0, 0};
121
 
122
        while(1)
123
        {
124
 
125
                if (mode == CAL_NONE) // run mode
126
                {
127
 
128
                        int thr_in, thr_out;           
129
 
130
                        read_data(&a_avg, &m_avg);
131
 
132
                        //get angle - startoffset
133
                        int heading_us  = thr_filter(get_us(get_heading(&a_avg, &m_avg, &p) - heading_start, HDG_MIN, HDG_MAX, HDG_US_MIN, HDG_US_MAX),&thr_in, &thr_out);
134
                        int pitch_us    = get_us(get_perpendicular(&a_avg, &down, &p) - pitch_start,            PIT_MIN, PIT_MAX, PIT_US_MIN, PIT_US_MAX);
135
                        int roll_us     = get_us(get_perpendicular(&a_avg, &down, &right) - roll_start,         ROL_MIN, ROL_MAX, ROL_US_MIN, ROL_US_MAX);;    
136
 
137
                        #if(DEBUG)
138
                                printf("H %d P %d R %d \n", heading_us, pitch_us, roll_us);
139
                        #endif
140
 
141
 
142
                        ppm_ch[HDG_CH-1] = heading_us;  //subtract 1, CHs from 1 - N, array bounds from 0 - N-1
143
                        ppm_ch[PIT_CH-1] = pitch_us;
144
                        ppm_ch[ROL_CH-1] = roll_us;
145
                }
146
 
147
 
148
                else // calibration mode - record max/min measurements
149
                {
150
                        //TODO
151
                        //implement calib_test.c
152
 
153
 
154
                        read_data_raw(&a, &m);
155
                        if (m.x < cal_m_min.x) cal_m_min.x = m.x;
156
                        if (m.x > cal_m_max.x) cal_m_max.x = m.x;
157
                        if (m.y < cal_m_min.y) cal_m_min.y = m.y;
158
                        if (m.y > cal_m_max.y) cal_m_max.y = m.y;
159
                        if (m.z < cal_m_min.z) cal_m_min.z = m.z;
160
                        if (m.z > cal_m_max.z) cal_m_max.z = m.z;
161
 
162
 
163
 
164
                }
165
 
166
                _delay_ms(40);
167
        }
168
}  
169