Subversion Repositories svnkaklik

Rev

Details | Last modification | View Log

Rev Author Line No. Line
2 kaklik 1
#include "tank.h"
2
 
3
#define DEBUG
4
 
5
#define  TXo PIN_A3           // To the transmitter modulator
6
#include "AX25.c"             // podprogram pro prenos telemetrie
7
 
8
unsigned int8 sensors;        // pomocna promenna pro cteni cidel na caru
9
unsigned int8 line;           // na ktere strane byla detekovana cara
10
unsigned int8 speed;          // rychlost zataceni
11
unsigned int8 rovinka;        // pocitadlo pro zjisteni rovneho useku
12
unsigned int8 last;           // kde byla cara, kdyz byly minule cidla mimo
13
unsigned int8 movement;       // obsahuje aktualni smer zataceni
14
unsigned int8 dira;           // pocita dobu po kterou je ztracena cara
15
unsigned int8 cihla;          // urcuje za jak dlouho muze byt znova detekovana cihla
16
 
17
// Konstanty pro dynamiku pohybu
18
#define T_DIRA       85      // po jakem case zataceni se detekuje dira
19
#define INC_SPEED    1        // prirustek rychlosti v jednom kroku
20
#define FW_POMALU    230      // trochu mimo caru vnitrni pas
21
#define FW_ZATACKA   200      // rychlost vnejsiho kola pri zataceni
22
#define FW_STREDNE   240      // trochu mimo caru vnejsi pas
23
#define COUVANI      600      // couvnuti zpet na caru, po detekci diry
24
#define PRES_DIRU    150
25
#define MAX_ROVINKA  (255-FW_STREDNE)
26
#define TRESHOLD     10        // rozhodovaci uroven komparatoru, 0xF = 0.75*Vdd
27
#define BUMPER_TRESHOLD 128
28
#define CIK_CAK      20000
29
#define T_CIHLA      100      // perioda detekce cihly
30
 
31
//motory            //Napred vypnout potom zapnout!
32
#define FR         output_low(PIN_B5); output_high(PIN_B4)  // Vpred
33
#define FL         output_low(PIN_B7); output_high(PIN_B6)
34
#define BR         output_low(PIN_B4); output_high(PIN_B5)  // Vzad
35
#define BL         output_low(PIN_B6); output_high(PIN_B7)
36
#define STOPR      output_low(PIN_B4);output_low(PIN_B5)    // Zastav
37
#define STOPL      output_low(PIN_B6);output_low(PIN_B7)
38
 
39
#define L 0b10  // left
40
#define R 0b01  // right
41
#define S 0b11  // straight
42
 
43
//cidla
44
#define RSENSOR    C2OUT      // Senzory na caru
45
#define LSENSOR    C1OUT
46
#define BUMPER     PIN_A4     // Senzor na cihlu
47
 
48
#define DIAG_SERVO      PIN_B3   // Propojka pro diagnosticky mod
49
#define DIAG_SENSORS    PIN_B2   // Propojka pro diagnosticky mod
50
 
51
#DEFINE SOUND_HI   PIN_A6     // komplementarni vystupy pro piezo pipak
52
#DEFINE SOUND_LO   PIN_A7
53
 
54
char AXstring[40];   // Buffer pro prenos telemetrie
55
 
56
// makro pro PWM
57
#define GO(motor, direction, power) if(get_timer0()<=power) \
58
{direction##motor;} else {stop##motor;}
59
 
60
#int_TIMER2
61
void TIMER2_isr()
62
{
63
   if (speed<255) speed+=INC_SPEED;
64
   if (rovinka<MAX_ROVINKA) rovinka++;
65
   if (dira<=T_DIRA) dira++;
66
   if (cihla>0) cihla--;
67
}
68
// Primitivni Pipani
69
void beep(unsigned int16 period, unsigned int16 length)
70
{
71
   unsigned int16 nn;
72
 
73
   for(nn=length; nn>0; nn--)
74
   {
75
     output_high(SOUND_HI);output_low(SOUND_LO);
76
     delay_us(period);
77
     output_high(SOUND_LO);output_low(SOUND_HI);
78
     delay_us(period);
79
   }
80
}
81
/******************************************************************************/
82
void diagnostika()
83
{
84
   unsigned int16 n;
85
 
86
   while (input(DIAG_SERVO))   // Propojka, ktera spousti diagnostiku
87
   {
88
      for (n=500; n<800; n+=100)
89
      {
90
         beep(n,n); //beep UP
91
      };
92
      Delay_ms(1000);
93
      //zastav vse
94
      STOPL; STOPR;
95
      //pravy pas
96
      FR; Delay_ms(1000); STOPR; Delay_ms(1000);
97
      BR; Delay_ms(1000); STOPR; Delay_ms(1000);
98
      Beep(880,100); Delay_ms(1000);
99
      //levy pas
100
      FL; Delay_ms(1000); STOPL; Delay_ms(1000);
101
      BL; Delay_ms(1000); STOPL; Delay_ms(1000);
102
      Beep(880,100); Delay_ms(1000);
103
      //oba pasy
104
      FL; FR; Delay_ms(1000); STOPL; STOPR; Delay_ms(1000);
105
      BL; BR; Delay_ms(1000); STOPL; STOPR; Delay_ms(1000);
106
   };
107
   while (input(DIAG_SENSORS))
108
   {
109
      int ls, rs;
110
		while(!input(BUMPER)){beep(1100,100); Delay_ms(50);}
111
      set_adc_channel(RSENSOR);
112
      Delay_us(20);
113
      rs=read_adc();
114
      set_adc_channel(LSENSOR);
115
      Delay_us(20);
116
      ls=read_adc();
117
      sprintf(AXstring,"L: %U  R: %U\0", ls, rs);  // Convert DATA to String.
118
      SendPacket(&AXstring[0]);
119
      delay_ms(1000);
120
   };
121
}
122
///////////////////////////////////////////////////////////////////////////////
123
void cikcak()
124
{
125
unsigned int16 n;
126
 
127
   line = RSENSOR;         // cteni senzoru na caru
128
   line |= LSENSOR << 1;
129
   if (line!=0) return;
130
 
131
   n=0;
132
	switch(movement)									// podivej se na druhou stranu nez se jelo
133
	{
134
	case L:
135
				FL;BR;
136
				movement=R;
137
			break;
138
	case R:
139
				FR;BL;
140
				movement=L;
141
			break;
142
	case S:
143
				FL;BR;
144
				movement=R;
145
            n=CIK_CAK/2;
146
			break;
147
	}
148
	while (0==(RSENSOR|LSENSOR))       // zkontroluj caru
149
	{
150
		if (n==CIK_CAK)							// zmen smer zataceni
151
		{
152
			n=0;
153
			switch(movement)
154
			{
155
			case L:
156
						FL;BR;
157
						movement=R;
158
					break;
159
			case R:
160
						FR;BL;
161
						movement=L;
162
					break;
163
			}
164
		}
165
		n++;
166
	}
167
   switch(movement)
168
   {
169
   case L:
170
            FL;BR;
171
            movement=R;
172
         break;
173
   case R:
174
            FR;BL;
175
            movement=L;
176
         break;
177
   }
178
   Delay_ms(50);
179
	STOPL;STOPR;												// nasli jsme caru
180
	line=S;
181
}
182
///////////////////////////////////////////////////////////////////////////////
183
void objizdka()                     // objede cihlu
184
{
185
unsigned int16 n;
186
 
187
	BL;BR;Delay_ms(200);
188
	STOPR;STOPL;
189
	beep(900,1000);
190
   movement=S;
191
   cikcak();
192
 
193
   BR; FL; Delay_ms(215);           // otoc se 70° do prava
194
 
195
   FR; FL; Delay_ms(600);           // popojed rovne
196
 
197
   BL; Delay_ms(50);               // otoc se 90° do leva
198
   STOPL; FR; Delay_ms(550);
199
 
200
   FR; FL; Delay_ms(100);           // popojed rovne na slepo
201
   for(n=600;n>0;n--)               // popojed rovne ale kontroluj caru
202
   {
203
      line = RSENSOR;         // cteni senzoru na caru
204
      line |= LSENSOR << 1;
205
      if (line!=0) {Delay_ms(50); break;}
206
      Delay_ms(1);
207
   }
208
 
209
   BR;                              // otoc se 60° do prava
210
   for(n=600;n>0;n--)
211
   {
212
      line = RSENSOR;         // cteni senzoru na caru
213
      line |= LSENSOR << 1;
214
      if (line!=0) break;
215
      Delay_ms(1);
216
   }
217
   STOPR; STOPL;
218
 
219
   movement=R;
220
   cikcak();
221
   cihla=T_DIRA;
222
   dira=0;
223
}
224
///////////////////////////////////////////////////////////////////////////////
225
void prejeddiru()                    // vyresi diru
226
{
227
unsigned int16 n;
228
 
229
   STOPL;STOPR;
230
   beep(800,500);
231
   switch (movement)                            //vrat se zpet na caru
232
   {
233
   case L:
234
         for (n=COUVANI;n>0;n--) {GO(R,B,speed); Delay_ms(1);}
235
         STOPL;STOPR;
236
      break;
237
   case R:
238
         for (n=COUVANI;n>0;n--) {GO(L,B,speed); Delay_ms(1);}
239
         STOPL;STOPR;
240
      break;
241
   case S:
242
         goto sem;
243
      break;
244
   }
245
   beep(800,500);
246
   FR;FL; Delay_ms(PRES_DIRU);   // popojedem dopredu mozna tam bude cara
247
sem:
248
   STOPL; STOPR;
249
   movement=S;
250
   cikcak();                                    // najdi caru
251
   cihla=T_DIRA;
252
   dira=0;
253
}
254
///////////////////////////////////////////////////////////////////////////////
255
void main()
256
{
257
   unsigned int16 n; // pro FOR
258
 
259
   STOPL; STOPR;     // prepne vystupy na ovladani motoru na output a zastavi
260
 
261
   setup_oscillator(OSC_4MHZ|OSC_INTRC);     // 4 MHz interni RC oscilator
262
 
263
   port_b_pullups(TRUE);      // pullups pro piano na diagnostiku
264
   setup_spi(FALSE);
265
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);  // Casovac pro PWM
266
 
267
   setup_timer_2(T2_DIV_BY_4,255,10);    // Casovac pro regulaci
268
                                         // preruseni kazdych 10ms
269
   setup_adc_ports(sAN2|VSS_VDD);      // nastaveni A/D prevodniku pro naraznik
270
   setup_adc(ADC_CLOCK_INTERNAL);
271
   set_adc_channel(2);
272
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);   // Casovac pro naraznik
273
   setup_ccp1(CCP_COMPARE_RESET_TIMER);
274
   CCP_1=(2^10)-1;                        // prevod kazdou 1ms
275
 
276
   setup_comparator(A0_VR_A1_VR);   // inicializace komparatoru pro cidla cary
277
   setup_vref(VREF_HIGH|TRESHOLD);        // 32 kroku od 0.25 do 0.75 Vdd
278
 
279
   Beep(1000,200);     //double beep
280
   Delay_ms(50);
281
   Beep(1000,200);
282
   Delay_ms(1000);      // 1s
283
 
284
         // povoleni rizeni rychlosti zataceni pres preruseni
285
   enable_interrupts(INT_TIMER2);
286
   enable_interrupts(GLOBAL);
287
 
288
/*---------------------------------------------------------------------------*/
289
   sensors=S;
290
   line=S;
291
   last=S;
292
   movement=S;
293
   speed=FW_POMALU;
294
 
295
   diagnostika();
296
   cikcak();     // toc se, abys nasel caru
297
   Delay_ms(500);
298
   Beep(1000,200);
299
   Delay_ms(500);
300
 
301
   while(true)       // hlavni smycka (jizda podle cary)
302
   {
303
      sensors = RSENSOR;         // cteni senzoru na caru
304
      sensors |= LSENSOR << 1;
305
 
306
      if ((read_adc(ADC_READ_ONLY)<BUMPER_TRESHOLD) && (cihla==0)) objizdka();
307
 
308
      switch (sensors)  // zatacej podle toho, kde vidis caru
309
      {
310
         case S:                          // rovne
311
            FL; FR;  // pokud se jede dlouho rovne, tak pridej
312
            dira=0;
313
            movement=S;
314
            continue;
315
         case L:                          // trochu vlevo
316
            GO(L, F, FW_POMALU+rovinka); GO(R, F, FW_STREDNE+rovinka);
317
            line=L;
318
            dira=0;
319
            movement=L;
320
            continue;
321
         case R:                          // trochu vpravo
322
            GO(R, F, FW_POMALU+rovinka); GO(L, F, FW_STREDNE+rovinka);
323
            line=R;
324
            dira=0;
325
            movement=R;
326
            continue;
327
         default:       // kdyz jsou obe cidla mimo caru, tak pokracuj dal
328
      }
329
   rovinka=0;
330
      if (dira>=T_DIRA) prejeddiru();
331
      if (last!=line)     // pokud si prejel caru z jedne strany na druhou stranu, tak zabrzdi
332
      {
333
         last=line;
334
         speed=FW_ZATACKA;
335
      }
336
      if (L==line)  // kdyz jsou obe cidla mimo caru, zatoc na caru
337
      {
338
         STOPL;
339
         GO(R, F, speed);
340
         movement=L;
341
      }
342
      else
343
      {
344
         STOPR;
345
         GO(L, F, speed);
346
         movement=R;
347
      }
348
   } // while(true)
349
}
350