Subversion Repositories Projects

Rev

Rev 406 | Go to most recent revision | Details | Compare with Previous | 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"
411 killagreg 17
//#include "logging.h"
406 joko 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
        LEDRED_OFF;
67
        LEDGRN_ON;
68
 
69
        // try to initialize the FAT 16 filesystem on the SD-Card
70
        Fat16_Init();
71
 
72
        // initialize the settings
73
        Settings_Init();
74
        // initialize logging (needs settings)
411 killagreg 75
        //Logging_Init();
406 joko 76
 
77
        #ifdef USE_SDLOGGER
78
        printf("\r\n\r\nHW: SD-Logger");
79
        #endif
80
        #ifdef USE_FOLLOWME
81
        printf("\r\n\r\nHW: Follow-Me");
82
        #endif
83
        printf("\r\nFollow Me\n\rSoftware:V%d.%d%c ",VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH + 'a');
84
        printf("\r\n------------------------------");
85
        printf("\r\n");
86
 
87
 
88
        //BeepTime = 2000;
89
 
90
    LCD_Clear();
91
 
92
        FollowMe_Timer = SetDelay(FOLLOWME_INTERVAL);
93
 
94
        while (1)
95
        {
96
                // get gps data to update the follow me position
97
                GPS_Update();
98
 
99
                // check for button action and change state resectively
100
                if(GetButton())
101
                {
102
                        BeepTime = 200;
103
 
104
                        switch(SysState)
105
                        {
106
                                case STATE_IDLE:
107
                                        if(!Error) SysState = STATE_SEND_FOLLOWME; // activate followme only of no error has occured
108
                                        break;
109
 
110
                                case STATE_SEND_FOLLOWME:
111
                                        SysState = STATE_IDLE;
112
                                        break;
113
 
114
                                default:
115
                                        SysState = STATE_IDLE;
116
                                        break;
117
                        }
118
 
119
                }
120
 
121
                // state machine
122
                switch(SysState)
123
                {
124
                        case STATE_SEND_FOLLOWME:
125
                                if(CheckDelay(FollowMe_Timer)) // time for next message?
126
                                {
127
                                        if(FollowMe.Position.Status == NEWDATA)        // if new
128
                                        {   // update remaining data
129
                                                FollowMe_Timer = SetDelay(FOLLOWME_INTERVAL);  // reset timer
130
                                                FollowMe.Heading = -1;                  // invalid heading
131
                                                FollowMe.ToleranceRadius = 1;   // 1 meter
132
                                                FollowMe.HoldTime = 60;         // go home after 60s without any update
133
                                                FollowMe.Event_Flag = 0;        // no event
134
                                                FollowMe.reserve[0] = 0;                // reserve
135
                                                FollowMe.reserve[1] = 0;                // reserve
136
                                                FollowMe.reserve[2] = 0;                // reserve
137
                                                FollowMe.reserve[3] = 0;                // reserve
138
                                                Request_SendFollowMe = 1;       // triggers serial tranmission
139
 
140
                                        }
141
                                        else // now new position avalable (maybe bad gps signal condition)
142
                                        {
143
                                                FollowMe_Timer = SetDelay(FOLLOWME_INTERVAL/4);  // reset timer on higer frequency
144
                                        }
145
                                        LEDGRN_TOGGLE;                                          // indication of active follow me
146
                                        FollowMe_active = 1;
147
                                }
148
                                break;
149
 
150
                        case STATE_IDLE:
151
                                // do nothing
152
                                LEDGRN_ON;
153
                                FollowMe_active = 0;
154
                                break;
155
 
156
                        default:
157
                                // triger to idle state
158
                                SysState = STATE_IDLE;
159
                                break;
160
 
161
                }
162
 
163
 
164
                // restart ADConversion if ready
165
                if(ADReady)
166
                {
167
                        DebugOut.Analog[0] = Adc0;
168
                        DebugOut.Analog[1] = Adc1;
169
                        DebugOut.Analog[2] = Adc2;
170
                        DebugOut.Analog[3] = Adc3;
171
                        DebugOut.Analog[4] = Adc4;
172
                        DebugOut.Analog[5] = Adc5;
173
                        DebugOut.Analog[6] = Adc6;
174
                        DebugOut.Analog[7] = Adc7;
175
 
176
                        #ifdef USE_FOLLOWME
177
                        // AVcc = 5V --> 5V = 1024 counts
178
                        // the voltage at the voltage divider reference point is 0.8V less that the UBat
179
                        // because of the silicon diode inbetween.
180
                        // voltage divider R2=10K, R3=3K9
181
                        // UAdc4 = R3/(R3+R2)*UBat= 3.9/(3.9+10)*UBat = UBat/3.564
182
                        UBat = (3 * UBat + (64 * Adc4) / 368) / 4;
183
                        DebugOut.Analog[8] = UBat;
184
 
185
                        // check for zellenzahl
186
                        if(PowerOn < 100)
187
                        {
188
                                if(UBat<=84) Zellenzahl = 2;
189
                                else Zellenzahl = 3;
190
                                PowerOn++;
191
                        }
192
                        DebugOut.Analog[16] = Zellenzahl;
193
                        DebugOut.Analog[17] = PowerOn;
194
 
195
                        //show recognised Zellenzahl to user
196
                        if(i < Zellenzahl && PowerOn >= 100 && BeepTime == 0 && delay > 1000)
197
                        {
198
                                BeepTime = 100;
199
                                i++;
200
                                delay = 0;
201
                        }
202
                        if(delay < 1500) delay++;
203
 
204
                        // monitor battery undervoltage [...||(UBat<74) as temporary workaround to protect 2s lipo packs]
205
                        if(((UBat < Zellenzahl * CELLUNDERVOLTAGE)||(UBat < 74)) && (PowerOn >= 100))
206
                        {   // sound for low battery
207
                                BeepModulation = 0x0300;
208
                                if(!BeepTime)
209
                                {
411 killagreg 210
                                        //BeepTime = 6000; // 0.6 seconds
406 joko 211
                                }
212
                                Error |= ERROR_LOW_BAT;
213
                        }
214
                        else
215
                        {
216
                                Error &= ~ERROR_LOW_BAT;
217
                        }
218
                        #endif
219
                        ADReady = 0;
220
                        ADC_Enable(); // restart ad conversion sequence
221
                }
222
 
223
                // serial communication
224
                USART0_ProcessRxData();
225
                USART0_TransmitTxData();
226
 
227
                // indicate error, blinking code tbd.
228
                if(Error)       LEDRED_ON;
229
                else            LEDRED_OFF;
230
 
231
    }
232
        return (1);
233
}
234