Subversion Repositories svnkaklik

Rev

Details | Last modification | View Log

Rev Author Line No. Line
141 kakl 1
#include ".\camerus.h"
136 kakl 2
 
154 kakl 3
#USE FAST_IO (C)     // Brana C je ve FAST_IO modu, aby slo rychle cteni z kamery
136 kakl 4
 
180 kakl 5
// A/D vstupy
6
#define  DALKOMER 4  // AN4/RA5 - dalkomer na cihlu
7
#define  CERNA    3  // AN3/RA3
8
#define  CERVENA  2  // AN2/RA2 - cervene kroutitko
9
#define  ZELENA   1  // AN1/RA0 - zelene kroutitko
10
#define  MODRA    0  // AN0/RA1 - modre kroutitko
150 kakl 11
 
12
// I/O
154 kakl 13
#define HREF   PIN_C5      // Signal HREF z kamery (v H po celou dobu radku)
14
#define PIX    PIN_C6      // Vstup pro body z kamery (za trivstupim hradlem OR (dig. komparator))
176 kakl 15
#define SERVO  PIN_B4      // Vystup na servo (1 az 2ms po cca 20ms (synchronizovano snimkovym kmitoctem))
154 kakl 16
#define MOT_L  PIN_B5      // Smer otaceni leveho motoru; druhy pol je RC2
17
#define MOT_R  PIN_B6      // Smer otaceni praveho motoru; druhy pol je RC1
179 kakl 18
#define DATA   PIN_B2      // K modulu LEDbar data
19
#define CP     PIN_B1      // K modulu LEDbar hodiny
180 kakl 20
#define ODO    PIN_A4      // Ze snimace z odometrie z praveho kola
184 kakl 21
//#define CIHLA  PIN_B0      // Vstup INT, generuje preruseni pri prekazce
186 kakl 22
#define IRLED  PIN_C0      // Modulovani vysilaci IR LED na detekci prekazky
176 kakl 23
 
179 kakl 24
#define CASMIN 6           // Rozsah radku snimace
25
#define CASMAX 192
26
#define CASAVR ((CASMAX+CASMIN) / 2)
27
 
184 kakl 28
#byte INTCON      = 0x0B         // Interrupt configuration register
29
   #bit GIE       = INTCON.7
30
   #bit PEIE      = INTCON.6
31
   #bit TMR0IE    = INTCON.5
32
   #bit INT0IE    = INTCON.4
33
   #bit RBIE      = INTCON.3
34
   #bit TMR0IF    = INTCON.2
35
   #bit INT0IF    = INTCON.1
36
   #bit RBIF      = INTCON.0
37
 
38
enum stavy {start,rozjezd,jizda,cihla,cil};
39
stavy stav;    // Kde jsme na trati
40
int8 cas;      // Cas hrany bila/cerna v radce
41
 
42
void SetServo(int8 angle)
43
{
44
   int8 n, offset;
186 kakl 45
 
184 kakl 46
   for(n=0; n<20; n++)
47
   {
48
      set_adc_channel(MODRA);    // Kroutitko na vystredeni predniho kolecka
49
      Delay_ms(1);
50
      offset=read_adc();
51
 
52
      output_high(SERVO);        // Odvysilani impuzu 1 az 2ms pro servo
53
      delay_us(1000);
54
      delay_us(offset);
55
      delay_us(offset);
56
      delay_us(offset);
57
      delay_us(angle);
58
      delay_us(angle);
59
      output_low(SERVO);
60
      delay_ms(18);
186 kakl 61
   }
184 kakl 62
}
63
 
64
#int_EXT
65
EXT_isr()   // Preruseni od prekazky
66
{
67
   set_pwm1_duty(0);    // reverz (zabrzdi)
68
   set_pwm2_duty(0);
69
   output_high(MOT_L);
70
   output_high(MOT_R);
71
   delay_ms(400);
72
   output_low(MOT_L); // zastav
73
   output_low(MOT_R);
74
   if (stav==cihla) while(true); // Zastav na furt
75
   if(stav==jizda)
76
   {
77
      int n;
78
 
186 kakl 79
      SetServo(CASAVR-CASMIN);
184 kakl 80
      set_pwm1_duty(40); // pomalu couvej
81
      set_pwm2_duty(40);
82
      output_high(MOT_L);
83
      output_high(MOT_R);
84
      n=0;
85
      while(true)
86
      {
87
         while(input(ODO));
88
         while(!input(ODO));
89
         n++;
90
         if(n==6) break;
91
      }
92
      set_pwm1_duty(255);    // reverz (zabrzdi)
93
      set_pwm2_duty(255);
94
      output_low(MOT_L);
95
      output_low(MOT_R);
96
      delay_ms(100);
97
      set_pwm1_duty(0);  // Zastav
98
      set_pwm2_duty(0);
99
      output_low(MOT_L);
100
      output_low(MOT_R);
101
      delay_ms(1000);
102
 
186 kakl 103
      SetServo((CASAVR-CASMIN)-20);   // doleva
184 kakl 104
      set_pwm1_duty(150);  // vpred
105
      set_pwm2_duty(200);
106
      output_low(MOT_L);
107
      output_low(MOT_R);
108
      stav=cihla;
109
      n=0;
110
      while(true)
111
      {
112
         while(input(ODO));
113
         while(!input(ODO));
114
         n++;
115
         if(n==10) break;
116
      }
117
      set_pwm1_duty(0);    // reverz (zabrzdi)
118
      set_pwm2_duty(0);
119
      output_high(MOT_L);
120
      output_high(MOT_R);
121
 
186 kakl 122
      SetServo((CASAVR-CASMIN));   // rovne
184 kakl 123
      set_pwm1_duty(140);  // vpred
124
      set_pwm2_duty(140);
125
      output_low(MOT_L);
126
      output_low(MOT_R);
127
      stav=cihla;
128
      n=0;
129
      while(true)
130
      {
131
         while(input(ODO));
132
         while(!input(ODO));
133
         n++;
134
         if(n==10) break;
135
      }
136
      set_pwm1_duty(0);    // reverz (zabrzdi)
137
      set_pwm2_duty(0);
138
      output_high(MOT_L);
139
      output_high(MOT_R);
140
      delay_ms(200);
141
      set_pwm1_duty(150);  // Zastav
142
      set_pwm2_duty(150);
143
      output_high(MOT_L);
144
      output_high(MOT_R);
145
      delay_ms(1000);
146
 
186 kakl 147
      SetServo(CASMIN);   // max. doleva
184 kakl 148
      set_pwm1_duty(0);  // vzad
149
      set_pwm2_duty(20);
150
      output_low(MOT_L);
151
      output_high(MOT_R);
152
      stav=cihla;
153
      n=0;
154
      while(true)
155
      {
156
         while(input(ODO));
157
         while(!input(ODO));
158
         n++;
159
         if(n==10) break;
160
      }
161
      set_pwm1_duty(0);    // reverz (zabrzdi)
162
      set_pwm2_duty(255);
163
      output_low(MOT_L);
164
      output_low(MOT_R);
165
      delay_ms(100);
166
      set_pwm1_duty(0);  // Zastav
167
      set_pwm2_duty(0);
168
      output_low(MOT_L);
169
      output_low(MOT_R);
170
      delay_ms(500);
171
 
172
 
186 kakl 173
      SetServo((CASAVR-CASMIN)+5);   // mirne doprava
184 kakl 174
      set_pwm1_duty(180);  // vpred
175
      set_pwm2_duty(180);
176
      output_low(MOT_L);
177
      output_low(MOT_R);
178
      stav=cihla;
179
      n=0;
180
      while(true)
181
      {
182
         while(input(ODO));
183
         while(!input(ODO));
184
         n++;
185
         if(n==10) break;
186
      }
187
      set_pwm1_duty(0);  // Zastav
188
      set_pwm2_duty(0);
189
      output_low(MOT_L);
190
      output_low(MOT_R);
191
      delay_ms(500);
192
 
193
 
194
      cas=CASMIN;  // Cara je vlevo
186 kakl 195
 
184 kakl 196
      stav=cihla;
197
   }
198
}
199
 
179 kakl 200
// Zobrazeni jednoho byte na modulu LEDbar
176 kakl 201
void disp(int8 x)
202
{
203
   int n;
204
 
205
   x=~x;
206
   for(n=0;n<=7;n++)
207
   {
208
      if (x & 1 == 1) output_high(DATA); else output_low(DATA);
209
      output_high(CP);
210
      x>>=1;
211
      output_low(CP);
212
   }
213
}
214
 
179 kakl 215
// Blikani LEDbarem ve stilu Night Rider
184 kakl 216
void NightRider(int8 x)
176 kakl 217
{
218
   int n,i,j;
219
 
220
   for(j=0;j<x;j++)
221
   {
222
      i=0x01;
223
      for(n=0;n<7;n++)
224
      {
225
         disp(i);
226
         rotate_left(&i, 1);
184 kakl 227
         delay_ms(40);
176 kakl 228
      }
229
      for(n=0;n<7;n++)
230
      {
231
         disp(i);
232
         rotate_right(&i, 1);
184 kakl 233
         delay_ms(40);
176 kakl 234
      }
235
   }
236
   disp(i);
184 kakl 237
   delay_ms(40);
176 kakl 238
   i=0;
239
   disp(i);
240
}
241
 
184 kakl 242
 
136 kakl 243
void main()
244
{
154 kakl 245
   int8 offset;   // Promena pro ulozeni ovsetu
246
   int8 rr;       // Promenna na ulozeni Rozumne rychlost
247
   int8 r1;       // Rychlost motoru 1
248
   int8 r2;       // Rychlost motoru 2
180 kakl 249
   int16 trasa;   // Pocitadlo ujete vzdalenosti
136 kakl 250
 
154 kakl 251
   setup_adc_ports(ALL_ANALOG);              // Zapnuti A/D prevodniku pro cteni kroutitek
136 kakl 252
   setup_adc(ADC_CLOCK_INTERNAL);
154 kakl 253
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);  // Casovac pro mereni casu hrany W/B v radce
136 kakl 254
   setup_timer_1(T1_DISABLED);
154 kakl 255
   setup_timer_2(T2_DIV_BY_16,255,1);        // Casovac PWM motoru
256
   setup_ccp1(CCP_PWM); // RC1               // PWM pro motory
136 kakl 257
   setup_ccp2(CCP_PWM); // RC2
176 kakl 258
   setup_comparator(NC_NC_NC_NC);
136 kakl 259
   setup_vref(FALSE);
260
 
154 kakl 261
   set_tris_c(0b11111000);     // Nastaveni vstup/vystup pro branu C, protoze se nedela automaticky
176 kakl 262
 
153 kakl 263
   set_pwm1_duty(0);   // Zastav motory
264
   set_pwm2_duty(0);
265
   output_low(MOT_L);
266
   output_low(MOT_R);
267
 
186 kakl 268
   output_low(IRLED);   // Zapni LED na detekci prekazky
269
 
176 kakl 270
   NightRider(1);    // Aby se poznalo, ze byl RESET
271
                     // Musi se pockat, nez se rozjede kamera, nez se do ni zacnou posilat prikazy
136 kakl 272
 
176 kakl 273
   //... Nastaveni kamery ...
154 kakl 274
   i2c_start();      // Soft RESET kamery
275
   i2c_write(0xC0);        // Pro single slave musi mit vsechny zapisy adresu C0h
276
   i2c_write(0x12);        // Adresa registru COMH
277
   i2c_write(0x80 | 0x24); // Zapis ridiciho slova
136 kakl 278
   i2c_stop();
279
 
280
   i2c_start();      // BW
281
   i2c_write(0xC0);
282
   i2c_write(0x28);
283
   i2c_write(0b01000001);
284
   i2c_stop();
285
 
176 kakl 286
/*
136 kakl 287
   i2c_start();      // Contrast
288
   i2c_write(0xC0);
289
   i2c_write(0x05);
176 kakl 290
   i2c_write(0xA0);  // 48h
136 kakl 291
   i2c_stop();
181 kakl 292
 
136 kakl 293
   i2c_start();      // Brightness
294
   i2c_write(0xC0);
295
   i2c_write(0x06);
181 kakl 296
   i2c_write(0x0);  // 80h //9Ah
136 kakl 297
   i2c_stop();
298
 
299
   i2c_start();      // Band Filter
300
   i2c_write(0xC0);
301
   i2c_write(0x2D);
302
   i2c_write(0x04 | 0x03);
303
   i2c_stop();
304
*/
181 kakl 305
 
306
   i2c_start();      // Fame Rate
307
   i2c_write(0xC0);
308
   i2c_write(0x2B);
309
   i2c_write(0x00);  // cca 17ms (puvodni hodnota 5Eh = 20ms)
310
   i2c_stop();
311
 
136 kakl 312
   i2c_start();      // VSTRT
313
   i2c_write(0xC0);
314
   i2c_write(0x19);
181 kakl 315
   i2c_write(118);   // prostredni radka
136 kakl 316
   i2c_stop();
317
 
318
   i2c_start();      // VEND
319
   i2c_write(0xC0);
320
   i2c_write(0x1A);
181 kakl 321
   i2c_write(118);
136 kakl 322
   i2c_stop();
323
 
179 kakl 324
   NightRider(1);    // Musi se dat cas kamere na AGC a AEC
152 kakl 325
 
181 kakl 326
{ // Kalibrace kamery
327
   int8 t1,t2;
184 kakl 328
 
181 kakl 329
   for(offset=0;offset<=255;offset+=0x04) // Cita porad dokola
330
   {
331
      i2c_start();      // Brightness
332
      i2c_write(0xC0);
333
      i2c_write(0x06);
334
      i2c_write(offset);  // 80h default
335
      i2c_stop();
336
      disp(offset);
184 kakl 337
      delay_ms(50);
181 kakl 338
 
339
      t1=0;
340
      t2=0;
341
      while(!input(HREF));    // Cekej nez se zacnou posilat pixely z radky
184 kakl 342
      delay_ms(5);
181 kakl 343
      while(!input(HREF));    // Cekej nez se zacnou posilat pixely z radky
344
      set_timer0(0);          // Vynuluj pocitadlo casu
345
      if(!input(PIX)) continue;
346
      while(input(PIX));
347
      t1=get_timer0();    // Precti cas z citace casu hrany
184 kakl 348
      set_timer0(0);          // Vynuluj pocitadlo casu
181 kakl 349
      while(!input(PIX));
184 kakl 350
      t2=get_timer0();
351
 
181 kakl 352
      if((t1>60) && (t1<140) && (t2>5) && (t2<=10)) break;
184 kakl 353
 
181 kakl 354
      delay_ms(2);
355
   }
356
}
357
 
358
delay_ms(1000);
359
 
184 kakl 360
   cas=CASAVR-CASMIN;  // Inicializace promenych, aby neslo servo za roh a aby se to rozjelo jeste dneska
180 kakl 361
   stav=start;
362
   trasa=0;
181 kakl 363
 
154 kakl 364
   // ... Hlavni smycka ...
136 kakl 365
   while(true)
366
   {
179 kakl 367
      int8 pom;
180 kakl 368
      int8 n;
181 kakl 369
 
179 kakl 370
      pom=0;
154 kakl 371
      while(!input(HREF));    // Cekej nez se zacnou posilat pixely z radky
372
      set_timer0(0);          // Vynuluj pocitadlo casu
373
      while(input(HREF))      // Po dobu vysilani radky cekej na hranu W/B
149 kakl 374
      {
179 kakl 375
// !!!!Dodelat rozpoznani cerne cary napric pro zastaveni
184 kakl 376
         if(!input(PIX))   // Pokud se Xx za sebou precetla CERNA
152 kakl 377
         if(!input(PIX))
181 kakl 378
//         if(!input(PIX))
152 kakl 379
         {
176 kakl 380
            pom=get_timer0();    // Precti cas z citace casu hrany
152 kakl 381
            break;
382
         };
149 kakl 383
      };
179 kakl 384
      while(input(HREF));      // Pockej na shozeni signalu HREF
150 kakl 385
 
179 kakl 386
      if((pom<CASMAX) && (pom>CASMIN)) cas=pom;  // Orizni konce radku
387
      // Na konci obrazovaho radku to blbne. Jednak chyba od apertury
388
      // a vubec to nejak na kraji nefunguje.
389
 
154 kakl 390
      set_adc_channel(MODRA);    // Kroutitko na vystredeni predniho kolecka
150 kakl 391
      Delay_ms(1);
392
      offset=read_adc();
176 kakl 393
 
154 kakl 394
      output_high(SERVO);        // Odvysilani impuzu 1 az 2ms pro servo
152 kakl 395
      delay_us(1000);
150 kakl 396
      delay_us(offset);
152 kakl 397
      delay_us(offset);
184 kakl 398
      delay_us(offset);
149 kakl 399
      delay_us(cas);
400
      delay_us(cas);
152 kakl 401
      output_low(SERVO);
154 kakl 402
 
179 kakl 403
      set_adc_channel(ZELENA);   // Kroutitko pro vykon motoru
153 kakl 404
      Delay_ms(1);
179 kakl 405
      rr=read_adc()>>2; //!!! // 0-31
176 kakl 406
 
179 kakl 407
      // Elektronicky diferencial
180 kakl 408
      if(cas<CASAVR) {r1=cas-CASMIN; r2=CASAVR-CASMIN;}; // Normovani vystupni hodnoty radkoveho snimace
179 kakl 409
      if(cas==CASAVR) {r1=cas-CASMIN; r2=cas-CASMIN;};   // pro rizeni rychlosti motoru
410
      if(cas>CASAVR) {r1=CASAVR-CASMIN; r2=CASMAX-cas;}; // Rozsah 1 az 92
180 kakl 411
 
179 kakl 412
      if (r1>(CASAVR-CASMIN-rr)) r1=(r1<<1)+rr-(CASAVR-CASMIN);     // Neco jako nasobeni
180 kakl 413
      if (r2>(CASAVR-CASMIN-rr)) r2=(r2<<1)+rr-(CASAVR-CASMIN);
176 kakl 414
 
179 kakl 415
//      r1<<=1;     // Rychlost je dvojnasobna
416
//      r2<<=1;     // Rozsah 2 az 184
154 kakl 417
 
184 kakl 418
      if ((stav==jizda)||(stav==cihla))      // Jizda
154 kakl 419
      {
179 kakl 420
         set_pwm1_duty(r1);
421
         set_pwm2_duty(r2);
180 kakl 422
         trasa++;
153 kakl 423
      }
424
      else
425
      {
154 kakl 426
         set_pwm1_duty(0);       // Zastaveni
153 kakl 427
         set_pwm2_duty(0);
428
      }
180 kakl 429
 
430
      set_adc_channel(DALKOMER);   // Prepni A/D prevodnik na detektor cihly
431
      Delay_ms(1);
184 kakl 432
 
433
      if((stav==jizda)&&(trasa>50)) // musi to alespon 1s jet
180 kakl 434
      {
184 kakl 435
         ext_int_edge(H_TO_L);         // Nastav podminky preruseni od cihly
436
         INT0IF=0;                     // Zruseni predesle udalosti od startera
437
         enable_interrupts(INT_EXT);
438
         enable_interrupts(GLOBAL);
439
      };
440
 
441
      if(stav==start)
442
      if(read_adc()<128)
443
      {
444
         disp(0x55);
445
         while(read_adc()<128); // Cekej, dokud starter neda ruku pryc
446
         set_pwm1_duty(255);
447
         set_pwm2_duty(255);
448
         disp(0xAA);
449
         delay_ms(200);
450
         stav=jizda;
180 kakl 451
      }
452
 
184 kakl 453
      pom=0x80;
181 kakl 454
      for(n=CASMAX/8; n<cas; n+=CASMAX/8)
455
      {
456
         pom>>=1;
457
      }
458
      disp(pom);
184 kakl 459
 
136 kakl 460
   };
461
}