Subversion Repositories svnkaklik

Rev

Rev 186 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log

Rev Author Line No. Line
141 kakl 1
#include ".\camerus.h"
136 kakl 2
 
188 kakl 3
#USE FAST_IO (C)     // Brana C je ve FAST_IO modu, aby slo rychle cist z kamery
136 kakl 4
 
180 kakl 5
// A/D vstupy
188 kakl 6
#define  DALKOMER 4  // AN4/RA5 - proximity sensor na ruku startera
180 kakl 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
188 kakl 21
#define IRRX   PIN_B0      // Vstup INT, generuje preruseni pri prekazce
22
#define IRTX   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
{
188 kakl 67
   // Ujistime se, ze prijaty signal je z naseho IR vysilace
68
   output_high(IRTX);   // Vypni LED na detekci prekazky
69
   set_pwm1_duty(0);    // Vypni motory
70
   set_pwm2_duty(0);
71
   output_low(MOT_L);
72
   output_low(MOT_R);
73
   delay_ms(2);
74
   if (!input(IRRX)) return;
75
   output_low(IRTX);    // Zapni LED na detekci prekazky
76
   delay_ms(10);
77
   if (input(IRRX)) return;
78
 
184 kakl 79
   set_pwm1_duty(0);    // reverz (zabrzdi)
80
   set_pwm2_duty(0);
81
   output_high(MOT_L);
82
   output_high(MOT_R);
83
   delay_ms(400);
84
   output_low(MOT_L); // zastav
85
   output_low(MOT_R);
86
   if (stav==cihla) while(true); // Zastav na furt
87
   if(stav==jizda)
88
   {
89
      int n;
188 kakl 90
/*
186 kakl 91
      SetServo(CASAVR-CASMIN);
184 kakl 92
      set_pwm1_duty(40); // pomalu couvej
93
      set_pwm2_duty(40);
94
      output_high(MOT_L);
95
      output_high(MOT_R);
96
      n=0;
97
      while(true)
98
      {
99
         while(input(ODO));
100
         while(!input(ODO));
101
         n++;
102
         if(n==6) break;
103
      }
104
      set_pwm1_duty(255);    // reverz (zabrzdi)
105
      set_pwm2_duty(255);
106
      output_low(MOT_L);
107
      output_low(MOT_R);
108
      delay_ms(100);
109
      set_pwm1_duty(0);  // Zastav
110
      set_pwm2_duty(0);
111
      output_low(MOT_L);
112
      output_low(MOT_R);
188 kakl 113
*/
184 kakl 114
      delay_ms(1000);
115
 
186 kakl 116
      SetServo((CASAVR-CASMIN)-20);   // doleva
184 kakl 117
      set_pwm1_duty(150);  // vpred
118
      set_pwm2_duty(200);
119
      output_low(MOT_L);
120
      output_low(MOT_R);
121
      stav=cihla;
122
      n=0;
123
      while(true)
124
      {
125
         while(input(ODO));
126
         while(!input(ODO));
127
         n++;
128
         if(n==10) break;
129
      }
130
      set_pwm1_duty(0);    // reverz (zabrzdi)
131
      set_pwm2_duty(0);
132
      output_high(MOT_L);
133
      output_high(MOT_R);
134
 
186 kakl 135
      SetServo((CASAVR-CASMIN));   // rovne
184 kakl 136
      set_pwm1_duty(140);  // vpred
137
      set_pwm2_duty(140);
138
      output_low(MOT_L);
139
      output_low(MOT_R);
140
      stav=cihla;
141
      n=0;
142
      while(true)
143
      {
144
         while(input(ODO));
145
         while(!input(ODO));
146
         n++;
147
         if(n==10) break;
148
      }
149
      set_pwm1_duty(0);    // reverz (zabrzdi)
150
      set_pwm2_duty(0);
151
      output_high(MOT_L);
152
      output_high(MOT_R);
153
      delay_ms(200);
154
      set_pwm1_duty(150);  // Zastav
155
      set_pwm2_duty(150);
156
      output_high(MOT_L);
157
      output_high(MOT_R);
158
      delay_ms(1000);
159
 
186 kakl 160
      SetServo(CASMIN);   // max. doleva
184 kakl 161
      set_pwm1_duty(0);  // vzad
162
      set_pwm2_duty(20);
163
      output_low(MOT_L);
164
      output_high(MOT_R);
165
      stav=cihla;
166
      n=0;
167
      while(true)
168
      {
169
         while(input(ODO));
170
         while(!input(ODO));
171
         n++;
172
         if(n==10) break;
173
      }
174
      set_pwm1_duty(0);    // reverz (zabrzdi)
175
      set_pwm2_duty(255);
176
      output_low(MOT_L);
177
      output_low(MOT_R);
178
      delay_ms(100);
179
      set_pwm1_duty(0);  // Zastav
180
      set_pwm2_duty(0);
181
      output_low(MOT_L);
182
      output_low(MOT_R);
183
      delay_ms(500);
184
 
185
 
186 kakl 186
      SetServo((CASAVR-CASMIN)+5);   // mirne doprava
184 kakl 187
      set_pwm1_duty(180);  // vpred
188
      set_pwm2_duty(180);
189
      output_low(MOT_L);
190
      output_low(MOT_R);
191
      stav=cihla;
192
      n=0;
193
      while(true)
194
      {
195
         while(input(ODO));
196
         while(!input(ODO));
197
         n++;
188 kakl 198
         if(n==12) break;
184 kakl 199
      }
200
      set_pwm1_duty(0);  // Zastav
201
      set_pwm2_duty(0);
202
      output_low(MOT_L);
203
      output_low(MOT_R);
204
      delay_ms(500);
205
 
206
 
207
      cas=CASMIN;  // Cara je vlevo
186 kakl 208
 
184 kakl 209
      stav=cihla;
210
   }
211
}
212
 
179 kakl 213
// Zobrazeni jednoho byte na modulu LEDbar
176 kakl 214
void disp(int8 x)
215
{
216
   int n;
217
 
218
   x=~x;
219
   for(n=0;n<=7;n++)
220
   {
221
      if (x & 1 == 1) output_high(DATA); else output_low(DATA);
222
      output_high(CP);
223
      x>>=1;
224
      output_low(CP);
225
   }
226
}
227
 
179 kakl 228
// Blikani LEDbarem ve stilu Night Rider
184 kakl 229
void NightRider(int8 x)
176 kakl 230
{
231
   int n,i,j;
232
 
233
   for(j=0;j<x;j++)
234
   {
235
      i=0x01;
236
      for(n=0;n<7;n++)
237
      {
238
         disp(i);
239
         rotate_left(&i, 1);
184 kakl 240
         delay_ms(40);
176 kakl 241
      }
242
      for(n=0;n<7;n++)
243
      {
244
         disp(i);
245
         rotate_right(&i, 1);
184 kakl 246
         delay_ms(40);
176 kakl 247
      }
248
   }
249
   disp(i);
184 kakl 250
   delay_ms(40);
176 kakl 251
   i=0;
252
   disp(i);
253
}
254
 
184 kakl 255
 
136 kakl 256
void main()
257
{
154 kakl 258
   int8 offset;   // Promena pro ulozeni ovsetu
259
   int8 rr;       // Promenna na ulozeni Rozumne rychlost
260
   int8 r1;       // Rychlost motoru 1
261
   int8 r2;       // Rychlost motoru 2
180 kakl 262
   int16 trasa;   // Pocitadlo ujete vzdalenosti
136 kakl 263
 
154 kakl 264
   setup_adc_ports(ALL_ANALOG);              // Zapnuti A/D prevodniku pro cteni kroutitek
136 kakl 265
   setup_adc(ADC_CLOCK_INTERNAL);
154 kakl 266
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);  // Casovac pro mereni casu hrany W/B v radce
136 kakl 267
   setup_timer_1(T1_DISABLED);
154 kakl 268
   setup_timer_2(T2_DIV_BY_16,255,1);        // Casovac PWM motoru
269
   setup_ccp1(CCP_PWM); // RC1               // PWM pro motory
136 kakl 270
   setup_ccp2(CCP_PWM); // RC2
176 kakl 271
   setup_comparator(NC_NC_NC_NC);
136 kakl 272
   setup_vref(FALSE);
273
 
154 kakl 274
   set_tris_c(0b11111000);     // Nastaveni vstup/vystup pro branu C, protoze se nedela automaticky
176 kakl 275
 
153 kakl 276
   set_pwm1_duty(0);   // Zastav motory
277
   set_pwm2_duty(0);
278
   output_low(MOT_L);
279
   output_low(MOT_R);
280
 
188 kakl 281
   output_low(IRTX);   // Zapni LED na detekci prekazky
282
 
176 kakl 283
   NightRider(1);    // Aby se poznalo, ze byl RESET
284
                     // Musi se pockat, nez se rozjede kamera, nez se do ni zacnou posilat prikazy
136 kakl 285
 
176 kakl 286
   //... Nastaveni kamery ...
154 kakl 287
   i2c_start();      // Soft RESET kamery
288
   i2c_write(0xC0);        // Pro single slave musi mit vsechny zapisy adresu C0h
289
   i2c_write(0x12);        // Adresa registru COMH
290
   i2c_write(0x80 | 0x24); // Zapis ridiciho slova
136 kakl 291
   i2c_stop();
292
 
293
   i2c_start();      // BW
294
   i2c_write(0xC0);
295
   i2c_write(0x28);
296
   i2c_write(0b01000001);
297
   i2c_stop();
298
 
176 kakl 299
/*
188 kakl 300
   i2c_start();      // Contrast (nema podstatny vliv na obraz)
136 kakl 301
   i2c_write(0xC0);
302
   i2c_write(0x05);
176 kakl 303
   i2c_write(0xA0);  // 48h
136 kakl 304
   i2c_stop();
181 kakl 305
 
188 kakl 306
   i2c_start();      // Band Filter (pokud by byl problem se zarivkama 50Hz)
136 kakl 307
   i2c_write(0xC0);
308
   i2c_write(0x2D);
309
   i2c_write(0x04 | 0x03);
310
   i2c_stop();
311
*/
181 kakl 312
 
313
   i2c_start();      // Fame Rate
314
   i2c_write(0xC0);
315
   i2c_write(0x2B);
316
   i2c_write(0x00);  // cca 17ms (puvodni hodnota 5Eh = 20ms)
317
   i2c_stop();
318
 
136 kakl 319
   i2c_start();      // VSTRT
320
   i2c_write(0xC0);
321
   i2c_write(0x19);
181 kakl 322
   i2c_write(118);   // prostredni radka
136 kakl 323
   i2c_stop();
324
 
325
   i2c_start();      // VEND
326
   i2c_write(0xC0);
327
   i2c_write(0x1A);
181 kakl 328
   i2c_write(118);
136 kakl 329
   i2c_stop();
330
 
179 kakl 331
   NightRider(1);    // Musi se dat cas kamere na AGC a AEC
152 kakl 332
 
188 kakl 333
   { // Mereni expozice
334
      int8 t1,t2;
335
 
336
      i2c_start();      // Brightness, zacni od uplne tmy
181 kakl 337
      i2c_write(0xC0);
338
      i2c_write(0x06);
188 kakl 339
      i2c_write(0);  // 80h default
181 kakl 340
      i2c_stop();
184 kakl 341
      delay_ms(50);
188 kakl 342
 
343
      for(offset=0x60;offset<=254;offset+=0x04)   // Zacni od jasu 60h
344
      {
345
         i2c_start();      // Brightness
346
         i2c_write(0xC0);
347
         i2c_write(0x06);
348
         i2c_write(offset);  // 80h default
349
         i2c_stop();
350
         disp(offset);
351
         delay_ms(50);
352
 
353
         t1=0;
354
         t2=0;
355
         while(!input(HREF));    // Cekej nez se zacnou posilat pixely z radky
356
         delay_ms(5);
357
         while(!input(HREF));    // Cekej nez se zacnou posilat pixely z radky
358
         set_timer0(0);          // Vynuluj pocitadlo casu
359
         if(!input(PIX)) continue;
360
         while(input(PIX));
361
         t1=get_timer0();    // Precti cas z citace casu hrany
362
         set_timer0(0);          // Vynuluj pocitadlo casu
363
         while(!input(PIX));
364
         t2=get_timer0();
365
 
366
         if((t1>60) && (t1<140) && (t2>5) && (t2<=10)) break; // Vidis, co mas?
367
 
368
         delay_ms(2);   // Preskoc druhou radku z kamery
369
      };
370
      delay_ms(1000);   // Nech chvili na displayi zmerenou hodnotu
181 kakl 371
   }
372
 
188 kakl 373
   set_adc_channel(CERVENA);   // --- Kroutitko pro jas ---
374
   delay_ms(1);
375
   offset=read_adc()>>1;   // 0-127
376
   offset &= 0b11111100;   // Dva nejnizsi bity ignoruj
377
   disp(offset);
378
   i2c_start();            // Brightness
379
   i2c_write(0xC0);
380
   i2c_write(0x06);
381
   i2c_write(offset+0x70);  // 80h default
382
   i2c_stop();
383
   delay_ms(1000);   // Nech hodnotu chvili na displayi
384
 
385
   set_adc_channel(ZELENA);   // --- Kroutitko pro vykon motoru ---
386
   delay_ms(1);
387
   rr=read_adc()>>2; // 0-31  // Pokud by se zvetsil rozsah, tak zkontrolovat jakonasobeni !!!
181 kakl 388
 
184 kakl 389
   cas=CASAVR-CASMIN;  // Inicializace promenych, aby neslo servo za roh a aby se to rozjelo jeste dneska
180 kakl 390
   stav=start;
391
   trasa=0;
181 kakl 392
 
154 kakl 393
   // ... Hlavni smycka ...
136 kakl 394
   while(true)
395
   {
179 kakl 396
      int8 pom;
180 kakl 397
      int8 n;
181 kakl 398
 
179 kakl 399
      pom=0;
154 kakl 400
      while(!input(HREF));    // Cekej nez se zacnou posilat pixely z radky
401
      set_timer0(0);          // Vynuluj pocitadlo casu
402
      while(input(HREF))      // Po dobu vysilani radky cekej na hranu W/B
149 kakl 403
      {
188 kakl 404
// !!!!Dodelat rozpoznani cerne cary napric pro zastaveni ?
405
         if(!input(PIX))   // Pokud se X-krat za sebou precetla CERNA
152 kakl 406
         if(!input(PIX))
181 kakl 407
//         if(!input(PIX))
152 kakl 408
         {
176 kakl 409
            pom=get_timer0();    // Precti cas z citace casu hrany
152 kakl 410
            break;
411
         };
149 kakl 412
      };
179 kakl 413
      while(input(HREF));      // Pockej na shozeni signalu HREF
150 kakl 414
 
179 kakl 415
      if((pom<CASMAX) && (pom>CASMIN)) cas=pom;  // Orizni konce radku
416
      // Na konci obrazovaho radku to blbne. Jednak chyba od apertury
417
      // a vubec to nejak na kraji nefunguje.
418
 
154 kakl 419
      set_adc_channel(MODRA);    // Kroutitko na vystredeni predniho kolecka
150 kakl 420
      Delay_ms(1);
421
      offset=read_adc();
176 kakl 422
 
154 kakl 423
      output_high(SERVO);        // Odvysilani impuzu 1 az 2ms pro servo
152 kakl 424
      delay_us(1000);
150 kakl 425
      delay_us(offset);
152 kakl 426
      delay_us(offset);
184 kakl 427
      delay_us(offset);
149 kakl 428
      delay_us(cas);
429
      delay_us(cas);
152 kakl 430
      output_low(SERVO);
154 kakl 431
 
179 kakl 432
      // Elektronicky diferencial
180 kakl 433
      if(cas<CASAVR) {r1=cas-CASMIN; r2=CASAVR-CASMIN;}; // Normovani vystupni hodnoty radkoveho snimace
179 kakl 434
      if(cas==CASAVR) {r1=cas-CASMIN; r2=cas-CASMIN;};   // pro rizeni rychlosti motoru
435
      if(cas>CASAVR) {r1=CASAVR-CASMIN; r2=CASMAX-cas;}; // Rozsah 1 az 92
180 kakl 436
 
179 kakl 437
      if (r1>(CASAVR-CASMIN-rr)) r1=(r1<<1)+rr-(CASAVR-CASMIN);     // Neco jako nasobeni
180 kakl 438
      if (r2>(CASAVR-CASMIN-rr)) r2=(r2<<1)+rr-(CASAVR-CASMIN);
176 kakl 439
 
179 kakl 440
//      r1<<=1;     // Rychlost je dvojnasobna
441
//      r2<<=1;     // Rozsah 2 az 184
154 kakl 442
 
184 kakl 443
      if ((stav==jizda)||(stav==cihla))      // Jizda
154 kakl 444
      {
179 kakl 445
         set_pwm1_duty(r1);
446
         set_pwm2_duty(r2);
180 kakl 447
         trasa++;
153 kakl 448
      }
449
      else
450
      {
154 kakl 451
         set_pwm1_duty(0);       // Zastaveni
153 kakl 452
         set_pwm2_duty(0);
453
      }
180 kakl 454
 
455
      set_adc_channel(DALKOMER);   // Prepni A/D prevodnik na detektor cihly
456
      Delay_ms(1);
184 kakl 457
 
458
      if((stav==jizda)&&(trasa>50)) // musi to alespon 1s jet
180 kakl 459
      {
184 kakl 460
         ext_int_edge(H_TO_L);         // Nastav podminky preruseni od cihly
461
         INT0IF=0;                     // Zruseni predesle udalosti od startera
462
         enable_interrupts(INT_EXT);
463
         enable_interrupts(GLOBAL);
464
      };
465
 
188 kakl 466
      if(stav==start)         // Snimkuje, toci servem a ceka na start
184 kakl 467
      if(read_adc()<128)
468
      {
188 kakl 469
         disp(0x80);
184 kakl 470
         while(read_adc()<128); // Cekej, dokud starter neda ruku pryc
188 kakl 471
         set_pwm1_duty(255);    // Rychly rozjezd  !!! Zkontrolovat na oscyloskopu 
184 kakl 472
         set_pwm2_duty(255);
188 kakl 473
         disp(0x1);
474
         delay_ms(200);       
184 kakl 475
         stav=jizda;
180 kakl 476
      }
477
 
188 kakl 478
      pom=0x80;    // Zobrazeni pozice cary na displayi
479
      for(n=CASMAX/8; n<cas; n+=CASMAX/8) pom>>=1;
181 kakl 480
      disp(pom);
136 kakl 481
   };
482
}