Subversion Repositories Projects

Rev

Rev 759 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 759 Rev 765
1
#include <avr/boot.h>
1
#include <avr/boot.h>
2
 
2
 
3
#include <avr/io.h>
3
#include <avr/io.h>
4
#include <avr/interrupt.h>
4
#include <avr/interrupt.h>
5
 
5
 
6
#include "main.h"
6
#include "main.h"
7
#include "timer0.h"
7
#include "timer0.h"
8
#include "uart0.h"
8
#include "uart0.h"
9
#include "uart1.h"
9
#include "uart1.h"
10
#include "fat16.h"
10
#include "fat16.h"
11
#include "led.h"
11
#include "led.h"
12
#include "menu.h"
12
#include "menu.h"
13
#include "printf_P.h"
13
#include "printf_P.h"
14
#include "analog.h"
14
#include "analog.h"
15
#include "gps.h"
15
#include "gps.h"
16
#include "button.h"
16
#include "button.h"
17
#include "logging.h"
17
#include "logging.h"
18
#include "settings.h"
18
#include "settings.h"
19
 
19
 
20
#define FOLLOWME_INTERVAL 1000 // 1 second update
20
#define FOLLOWME_INTERVAL 1000 // 1 second update
21
#define CELLUNDERVOLTAGE 32 // lowest allowed voltage/cell; 32 = 3.2V
21
#define CELLUNDERVOLTAGE 32 // lowest allowed voltage/cell; 32 = 3.2V
22
 
22
 
23
#ifdef USE_FOLLOWME
23
#ifdef USE_FOLLOWME
24
int16_t UBat = 120;
24
int16_t UBat = 120;
25
int16_t Zellenzahl = 0;
25
int16_t Zellenzahl = 0;
26
int16_t PowerOn = 0;
26
int16_t PowerOn = 0;
27
int16_t i = 0;
27
int16_t i = 0;
28
int16_t delay = 0;
28
int16_t delay = 0;
29
#endif
29
#endif
30
 
30
 
31
uint16_t Error = 0;
31
uint16_t Error = 0;
32
SysState_t SysState = STATE_UNDEFINED;
32
SysState_t SysState = STATE_UNDEFINED;
33
 
33
 
34
int main (void)
34
int main (void)
35
{
35
{
36
        static uint16_t FollowMe_Timer = 0;
36
        static uint16_t FollowMe_Timer = 0;
37
 
37
 
38
        // disable interrupts global
38
        // disable interrupts global
39
        //cli();
39
        //cli();
40
 
40
 
41
        // disable watchdog
41
        // disable watchdog
42
    MCUSR &=~(1<<WDRF);
42
    MCUSR &=~(1<<WDRF);
43
    WDTCSR |= (1<<WDCE)|(1<<WDE);
43
    WDTCSR |= (1<<WDCE)|(1<<WDE);
44
    WDTCSR = 0;
44
    WDTCSR = 0;
45
 
45
 
46
        // initalize modules
46
        // initalize modules
47
        LED_Init();
47
        LED_Init();
48
        LEDRED_ON;
48
        LEDRED_ON;
49
    TIMER0_Init();
49
    TIMER0_Init();
50
        USART0_Init();
50
        USART0_Init();
51
        UBX_Init();
51
        UBX_Init();
52
        USART1_Init();
52
        USART1_Init();
53
        ADC_Init();
53
        ADC_Init();
54
        Button_Init();
54
        Button_Init();
55
        // enable interrupts global
55
        // enable interrupts global
56
        sei();
56
        sei();
57
 
57
 
58
        // try to initialize the FAT 16 filesystem on the SD-Card
58
        // try to initialize the FAT 16 filesystem on the SD-Card
59
        Fat16_Init();
59
        Fat16_Init();
60
        // initialize the settings
60
        // initialize the settings
61
        Settings_Init();
61
        Settings_Init();
62
        // initialize logging (needs settings)
62
        // initialize logging (needs settings)
63
        Logging_Init();
63
        Logging_Init();
64
 
64
 
65
        LEDRED_OFF;
65
        LEDRED_OFF;
66
        LEDGRN_ON;
66
        LEDGRN_ON;
67
 
67
 
68
        #ifdef USE_SDLOGGER
68
        #ifdef USE_SDLOGGER
69
        printf("\r\n\r\nHW: SD-Logger");
69
        printf("\r\n\r\nHW: SD-Logger");
70
        #endif
70
        #endif
71
        #ifdef USE_FOLLOWME
71
        #ifdef USE_FOLLOWME
72
        printf("\r\n\r\nHW: Follow-Me");
72
        printf("\r\n\r\nHW: Follow-Me");
73
        #endif
73
        #endif
74
        printf("\r\nFollow Me\r\nSoftware:V%d.%d%c ",VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH + 'a');
74
        printf("\r\nFollow Me\r\nSoftware:V%d.%d%c ",VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH + 'a');
75
        printf("\r\n------------------------------");
75
        printf("\r\n------------------------------");
76
        printf("\r\n");
76
        printf("\r\n");
77
 
77
 
78
 
78
 
79
        //BeepTime = 2000;
79
        //BeepTime = 2000;
80
 
80
 
81
    LCD_Clear();
81
    Menu_Clear();
82
 
82
 
83
        FollowMe_Timer = SetDelay(FOLLOWME_INTERVAL);
83
        FollowMe_Timer = SetDelay(FOLLOWME_INTERVAL);
84
 
84
 
85
        while (1)
85
        while (1)
86
        {
86
        {
87
                // get gps data to update the follow me position
87
                // get gps data to update the follow me position
88
                GPS_Update();
88
                GPS_Update();
89
 
89
 
90
                // update logging
90
                // update logging
91
                Logging_Update();
91
                Logging_Update();
92
 
92
 
93
                // check for button action and change state resectively
93
                // check for button action and change state resectively
94
                if(GetButton())
94
                if(GetButton())
95
                {
95
                {
96
                        BeepTime = 200;
96
                        BeepTime = 200;
97
 
97
 
98
                        switch(SysState)
98
                        switch(SysState)
99
                        {
99
                        {
100
                                case STATE_IDLE:
100
                                case STATE_IDLE:
101
                                        if(!Error) SysState = STATE_SEND_FOLLOWME; // activate followme only of no error has occured
101
                                        if(!Error) SysState = STATE_SEND_FOLLOWME; // activate followme only of no error has occured
102
                                        break;
102
                                        break;
103
 
103
 
104
                                case STATE_SEND_FOLLOWME:
104
                                case STATE_SEND_FOLLOWME:
105
                                        SysState = STATE_IDLE;
105
                                        SysState = STATE_IDLE;
106
                                        break;
106
                                        break;
107
 
107
 
108
                                default:
108
                                default:
109
                                        SysState = STATE_IDLE;
109
                                        SysState = STATE_IDLE;
110
                                        break;
110
                                        break;
111
                        }
111
                        }
112
 
112
 
113
                }
113
                }
114
 
114
 
115
                // state machine
115
                // state machine
116
                DebugOut.Analog[9] = SysState;
116
                DebugOut.Analog[9] = SysState;
117
                switch(SysState)
117
                switch(SysState)
118
                {
118
                {
119
                        case STATE_SEND_FOLLOWME:
119
                        case STATE_SEND_FOLLOWME:
120
                                if(CheckDelay(FollowMe_Timer)) // time for next message?
120
                                if(CheckDelay(FollowMe_Timer)) // time for next message?
121
                                {
121
                                {
122
                                        if(FollowMe.Position.Status == NEWDATA)        // if new
122
                                        if(FollowMe.Position.Status == NEWDATA)        // if new
123
                                        {   // update remaining data
123
                                        {   // update remaining data
124
                                                FollowMe_Timer = SetDelay(FOLLOWME_INTERVAL);  // reset timer
124
                                                FollowMe_Timer = SetDelay(FOLLOWME_INTERVAL);  // reset timer
125
                                                FollowMe.Heading = -1;                  // invalid heading
125
                                                FollowMe.Heading = -1;                  // invalid heading
126
                                                FollowMe.ToleranceRadius = 1;   // 1 meter
126
                                                FollowMe.ToleranceRadius = 1;   // 1 meter
127
                                                FollowMe.HoldTime = 60;         // go home after 60s without any update
127
                                                FollowMe.HoldTime = 60;         // go home after 60s without any update
128
                                                FollowMe.Event_Flag = 0;        // no event
128
                                                FollowMe.Event_Flag = 0;        // no event
129
                                                FollowMe.Index = 1;             // 2st wp
129
                                                FollowMe.Index = 1;             // 2st wp
130
                                                FollowMe.reserve[0] = 0;                // reserve
130
                                                FollowMe.reserve[0] = 0;                // reserve
131
                                                FollowMe.reserve[1] = 0;                // reserve
131
                                                FollowMe.reserve[1] = 0;                // reserve
132
                                                FollowMe.reserve[2] = 0;                // reserve
132
                                                FollowMe.reserve[2] = 0;                // reserve
133
                                                FollowMe.reserve[3] = 0;                // reserve
133
                                                FollowMe.reserve[3] = 0;                // reserve
134
                                                Request_SendFollowMe = 1;       // triggers serial tranmission
134
                                                Request_SendFollowMe = 1;       // triggers serial tranmission
135
 
135
 
136
                                        }
136
                                        }
137
                                        else // now new position avalable (maybe bad gps signal condition)
137
                                        else // now new position avalable (maybe bad gps signal condition)
138
                                        {
138
                                        {
139
                                                FollowMe_Timer = SetDelay(FOLLOWME_INTERVAL/4);  // reset timer on higer frequency
139
                                                FollowMe_Timer = SetDelay(FOLLOWME_INTERVAL/4);  // reset timer on higer frequency
140
                                        }
140
                                        }
141
                                        LEDGRN_TOGGLE;                                          // indication of active follow me
141
                                        LEDGRN_TOGGLE;                                          // indication of active follow me
142
                                }
142
                                }
143
                                break;
143
                                break;
144
 
144
 
145
                        case STATE_IDLE:
145
                        case STATE_IDLE:
146
                                // do nothing
146
                                // do nothing
147
                                LEDGRN_ON;
147
                                LEDGRN_ON;
148
                                break;
148
                                break;
149
 
149
 
150
                        default:
150
                        default:
151
                                // triger to idle state
151
                                // triger to idle state
152
                                SysState = STATE_IDLE;
152
                                SysState = STATE_IDLE;
153
                                break;
153
                                break;
154
 
154
 
155
                }
155
                }
156
 
156
 
157
 
157
 
158
                // restart ADConversion if ready
158
                // restart ADConversion if ready
159
                if(ADReady)
159
                if(ADReady)
160
                {
160
                {
161
                        DebugOut.Analog[0] = Adc0;
161
                        DebugOut.Analog[0] = Adc0;
162
                        DebugOut.Analog[1] = Adc1;
162
                        DebugOut.Analog[1] = Adc1;
163
                        DebugOut.Analog[2] = Adc2;
163
                        DebugOut.Analog[2] = Adc2;
164
                        DebugOut.Analog[3] = Adc3;
164
                        DebugOut.Analog[3] = Adc3;
165
                        DebugOut.Analog[4] = Adc4;
165
                        DebugOut.Analog[4] = Adc4;
166
                        DebugOut.Analog[5] = Adc5;
166
                        DebugOut.Analog[5] = Adc5;
167
                        DebugOut.Analog[6] = Adc6;
167
                        DebugOut.Analog[6] = Adc6;
168
                        DebugOut.Analog[7] = Adc7;
168
                        DebugOut.Analog[7] = Adc7;
169
 
169
 
170
                        #ifdef USE_FOLLOWME
170
                        #ifdef USE_FOLLOWME
171
                        // AVcc = 5V --> 5V = 1024 counts
171
                        // AVcc = 5V --> 5V = 1024 counts
172
                        // the voltage at the voltage divider reference point is 0.8V less that the UBat
172
                        // the voltage at the voltage divider reference point is 0.8V less that the UBat
173
                        // because of the silicon diode inbetween.
173
                        // because of the silicon diode inbetween.
174
                        // voltage divider R2=10K, R3=3K9
174
                        // voltage divider R2=10K, R3=3K9
175
                        // UAdc4 = R3/(R3+R2)*UBat= 3.9/(3.9+10)*UBat = UBat/3.564
175
                        // UAdc4 = R3/(R3+R2)*UBat= 3.9/(3.9+10)*UBat = UBat/3.564
176
                        UBat = (3 * UBat + (64 * Adc4) / 368) / 4;
176
                        UBat = (3 * UBat + (64 * Adc4) / 368) / 4;
177
                        DebugOut.Analog[8] = UBat;
177
                        DebugOut.Analog[8] = UBat;
178
 
178
 
179
                        // check for zellenzahl
179
                        // check for zellenzahl
180
                        if(PowerOn < 100)
180
                        if(PowerOn < 100)
181
                        {
181
                        {
182
                                if(UBat<=84) Zellenzahl = 2;
182
                                if(UBat<=84) Zellenzahl = 2;
183
                                else Zellenzahl = 3;
183
                                else Zellenzahl = 3;
184
                                PowerOn++;
184
                                PowerOn++;
185
                        }
185
                        }
186
                        DebugOut.Analog[16] = Zellenzahl;
186
                        DebugOut.Analog[16] = Zellenzahl;
187
                        DebugOut.Analog[17] = PowerOn;
187
                        DebugOut.Analog[17] = PowerOn;
188
 
188
 
189
                        //show recognised Zellenzahl to user
189
                        //show recognised Zellenzahl to user
190
                        if(i < Zellenzahl && PowerOn >= 100 && BeepTime == 0 && delay > 1000)
190
                        if(i < Zellenzahl && PowerOn >= 100 && BeepTime == 0 && delay > 1000)
191
                        {
191
                        {
192
                                BeepTime = 100;
192
                                BeepTime = 100;
193
                                i++;
193
                                i++;
194
                                delay = 0;
194
                                delay = 0;
195
                        }
195
                        }
196
                        if(delay < 1500) delay++;
196
                        if(delay < 1500) delay++;
197
 
197
 
198
                        // monitor battery undervoltage [...||(UBat<74) as temporary workaround to protect 2s lipo packs]
198
                        // monitor battery undervoltage [...||(UBat<74) as temporary workaround to protect 2s lipo packs]
199
                        if(((UBat < Zellenzahl * CELLUNDERVOLTAGE)||(UBat < 74)) && (PowerOn >= 100))
199
                        if(((UBat < Zellenzahl * CELLUNDERVOLTAGE)||(UBat < 74)) && (PowerOn >= 100))
200
                        {   // sound for low battery
200
                        {   // sound for low battery
201
                                BeepModulation = 0x0300;
201
                                BeepModulation = 0x0300;
202
                                if(!BeepTime)
202
                                if(!BeepTime)
203
                                {
203
                                {
204
                                        BeepTime = 6000; // 0.6 seconds
204
                                        BeepTime = 6000; // 0.6 seconds
205
                                }
205
                                }
206
                                Error |= ERROR_LOW_BAT;
206
                                Error |= ERROR_LOW_BAT;
207
                        }
207
                        }
208
                        else
208
                        else
209
                        {
209
                        {
210
                                Error &= ~ERROR_LOW_BAT;
210
                                Error &= ~ERROR_LOW_BAT;
211
                        }
211
                        }
212
                        #endif
212
                        #endif
213
                        ADReady = 0;
213
                        ADReady = 0;
214
                        ADC_Enable(); // restart ad conversion sequence
214
                        ADC_Enable(); // restart ad conversion sequence
215
                }
215
                }
216
 
216
 
217
                // serial communication
217
                // serial communication
218
                USART0_ProcessRxData();
218
                USART0_ProcessRxData();
219
                USART0_TransmitTxData();
219
                USART0_TransmitTxData();
220
 
220
 
221
                // indicate error, blinking code tbd.
221
                // indicate error, blinking code tbd.
222
                if(Error)       LEDRED_ON;
222
                if(Error)       LEDRED_ON;
223
                else            LEDRED_OFF;
223
                else            LEDRED_OFF;
224
 
224
 
225
    }
225
    }
226
        return (1);
226
        return (1);
227
}
227
}
228
 
228
 
229
 
229