Subversion Repositories Projects

Rev

Rev 340 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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