Subversion Repositories Projects

Rev

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

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