Subversion Repositories Projects

Rev

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

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