-
Notifications
You must be signed in to change notification settings - Fork 0
/
PGM_5.c
1403 lines (1319 loc) · 52.1 KB
/
PGM_5.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#include <stdio.h>
#include <stdlib.h>
#include <xc.h>
#include "Init.h"
#include "MLX_read.h"
//#include "MLX_Neu.h" //Muss aktiviert werden, wenn der T-Sensor eine neue Adresse bekommen soll (s.u.))
// CONFIG1
#pragma config FOSC = HS // Oscillator Selection (HS Oscillator, High-speed crystal/resonator connected between OSC1 and OSC2 pins)
#pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = ON // Power-up Timer Enable (PWRT enabled)
#pragma config MCLRE = ON // MCLR Pin Function Select (MCLR/VPP pin function is MCLR)
#pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config BOREN = OFF // Brown-out Reset Enable (Brown-out Reset disabled)
#pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = OFF // Internal/External Switchover (Internal/External Switchover mode is disabled)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is disabled)
// CONFIG2
#pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off)
#pragma config VCAPEN = OFF // Voltage Regulator Capacitor Enable bit (VCAP pin function disabled)
#pragma config STVREN = OFF // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will not cause a Reset)
#pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LPBOR = OFF // Low-Power Brown Out Reset (Low-Power BOR is disabled)
#pragma config LVP = OFF // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)
#define _XTAL_FREQ 20000000
//LATX ist ein Register, das die Ausgabe des zugehörigen PORTX regelt.
//PORTX ist der Zustand an den Pins
//LATX kann also anders sein als PORTX
#define Status LATA4 //Bit 4 des Registers LATA(=PORTA), 0 LED ein, 1 LED aus
#define Taster RD4 //!!!!!!!!!!war davor RC0
//#define vorwaerts LATD = LATD & 0b11110000 | 0b00001010 //Beim Inhalt des Registers
//LATD werden zunächst die unteren 4 Bits gelöscht und dann Bit 1 und 3 gesetzt.
//An PORTD liegt also dann an Pin 22 und 24 fünf Volt an, an Pin RD7..4 liegt der
//Pegel an, der auch vorher angelegen hat
//#define stopp LATD = LATD & 0b11110000
#define vorwaerts LATD = (LATD & 0b11110000)|0b00001010
#define nachhinten LATD = (LATD & 0b11110000)|0b00000101
#define rechts LATD = (LATD & 0b11110000)|0b00000110
#define links LATD = (LATD & 0b11110000)|0b00001001
#define stopp LATD = (LATD & 0b11110000)
#define bissl LATD = (LATD & 0b11110000)|0b00001000
#define bissr LATD = (LATD & 0b11110000)|0b00000010
#define bisslrueck LATD = (LATD & 0b11110000)|0b00000100
#define bissrrueck LATD = (LATD & 0b11110000)|0b00000001
//Definitionen sinnvoll ergänzen: rueckwaerts, rechts_drehen....
#define US_Trigger LATD5 //US-Trigger Pin an RD5, Pin 28
#define pwm_links CCPR1L
#define pwm_rechts CCPR2L
#define servo RB1
#define vornelinks A_D_Wert [0]
#define vornerechts A_D_Wert [3]
#define rechtsvorne A_D_Wert [2]
#define rechtshinten A_D_Wert [5]
#define hintenrechts A_D_Wert [4]
#define hintenlinks A_D_Wert [7]
#define linkshinten A_D_Wert [6]
#define linksvorne A_D_Wert [1]
#define schwarzlinks A_D_Wert [8]
#define schwarzrechts A_D_Wert [9]
#define vornelang A_D_Wert [10]
//#define IR_unten A_D_Wert[9]
//Deklaration der Variabeln, mit Wertzuweisung
char grad_90_1 = 69; //90° Drehung, Anzahl der Ticks am Encoder: einstellen!! // zusammen 84
char grad_90_2 = 12; // 2. langsame teil der Drehung
char grad_90links_1 = 65;// 90 grad drehung links, brauch andere ticks als rechts! //zusammen 77
char grad_90links_2 = 12; // 2. Teil von Links (langsam)
char cm_30 = 134; //30cm fahren, Anzahl der Ticks am Encoder: einstellen!!
const char PIC_Slave = 0x14; //20 PIC-Slave Adresse vom 16F876A
const char PIC_Letter_1 = 0x15; //21 0x15 und 0x16 sind PIC-Slave Adressen von den 16F1827
const char MLX_Slave = 0x5A; //Slave Adresse von einem T-Sensor, der andere hat
//0x5B als Adresse, wird in der MLX-I2C Funktion aufgerufen
//Es stehen 512 Speicherplätze zur Verfügung
//Jeweils 80 Bytes pro Bank, 31 Bänke
//Diese sind in den Speicherplätzen 0x2000 - 0x29AF gespiegelt
//Liegen also hintereinander, was eine indirekte Adressierung vereinfacht
//Deklaration der Variabeln, ohne Wertzuweisung
char A_D_Wert [28]; //28 A/D-Wandler-Pins am 1519
char Channel [11] = {0, 1, 2, 3, 4, 5, 6, 7, 17, 18, 19}; //links vom Master ADKanal 0 - 7, rechts ADKanal 17 - 19
char Channel_Index;
char I2C_Add; //aktuell zu verarbeitende I2C-Adresse
char I2C_Index_w; //Write Index, aktuell zu verarbeitendes Register/Datum-Paar
char I2C_Index_R; //Read Index, aktuell zu verarbeitendes Register/Datum-Paar
bit I2C_Write; //Ist der I2C-Bus gerade mit Schreiben beschäftigt?
bit I2C_Read; //Ist der I2C-Bus gerade mit Lesen beschäftigt?
char I2C_Count; //Zähler der Schritte bei der I2C-Kommunikation
char Count; //Zähler für I2C_Index_w
char Datum_S[20]; //ans LCD zu übertragene Werte
char Datum1_an_Letter;
char Datum2_an_Letter;
bit Flag_kalibrieren;
char Register_S; //LCD Tabulatorstelle
char Datum_R[3]; //vom 16F876A[0] und 16F1827[1] u [2] gelesene Werte
char Register_R_MLX = 0x07; // in 0x07 und 0x08 stehen LO- und HI-Byte der Temperatur
int Tick; //Zähler der TMR0 Überläufe im Interrupt
char m, n; //Zähler im Interrupt
char n_US; //Zähler für US-Trigger, 40ms
char Zeit_US; //Laufzeit des US-Signals
char Abstand_US; //Abstand vom US in cm (ca. 10% ungenau)
bit Flag_LED; //Soll die LED blinken (1) oder an sein (0)
char VAR_ausrichten_durchgaenge;
bit Flag_Zeit1000ms;
bit VAR_von_mitte_bis_wieder_wand ;
bit VAR_von_sensor_VR_bis_mitte ;
bit VAR_schwarz ;
char VAR_Schwarz_ausrichten;
char VAR_bis_wand_zeit ;
int VAR_aus_zeit;
int VAR_bis_mitte_zeit ;
int VAR_zeit_opfer;
bit VAR_schwarz_rechts ;
bit VAR_opfer_aus;
int VAR_rechts_zeit;
int VAR_links_zeit ;
char VAR_omni = 60;
char Var_lang_Ausrichten;
char Ausrichten_Fahren = 5;
char Ausrichten_Stopp = 15;
int Zeit_power_Ausrichten = 100;
char Schwellwert_Ausrichten = 36;
char Schwellwert_Omni = 61 ;
char VAR_im_Kreis_faren = 0 ;
char VAR_links_ist_nichts = 0 ;
char H = 'H';
char VAR_schwarz_ausrichten_merken;
char wand = 38;
char zuweit = 85;
char zunah = 75;
int zeit;
char VAR_cm_f;
char I2C_Add; //aktuell benutzte I2C-Slave-Adresse
char Register_R[2];// = {0x07, 0xFF}; //in 0x07 und 0x08 stehen LO- und HI-Byte der Temperatur
//0x00 oder 0xFF wird an "Letter" übertragen, 0 normal, 255 kalibrieren
char Temperatur_LO_rechts; //Den Wert brauchen wir nicht unbedingt
char Temperatur_LO_links; //Den Wert brauchen wir nicht unbedingt
char Temperatur_HI_rechts; //HI-Teil der Temperatur
char Temperatur_HI_links; //HI-Teil der Temperatur
char Waerme_links = 58;
char Waerme_rechts = 58;
char schwarz = 235;
bit Flag_Hindernis;
bit Flag_T_links;
bit Flag_T_rechts;
bit nicht_rechts = 0 ;
char Encoder; //Anzahl der Motordrehungen, Raddurchmesser 50mm -> ca. 6 Umdrehungen = 1cm
char encodersave;
int Strecke; //Länge des zu fahrenden Wegs in Radumdrehungen
bit Flag_Strecke_erreicht = 0; //die vorgegebene Strecke ist erreicht -> Interrupt
bit Flag_Strecke_messen = 0; //Es wird gerade eine Strecke gemessen -> Interrupt
char z;
void init(void); //Chip initialisieren
void Strecke_fahren(char, char); //(Länge, Richtung)
void Letter_kal(void); //Buchstabensensoren kalibrieren
void Werte_auf_LCD_anzeigen (void);
void interrupt Interrupt(void); //sic
void anderwandlang(void);
void rechts90grad (void);
void links90grad (void);
void ausrichten (void) ;
void vorne_ausrichten (void) ;
void hinten_ausrichten (void) ;
void links_ausrichten (void) ;
void rechts_ausrichten (void) ;
void von_sensor_VR_bis_mitte (void);
void von_mitte_bis_wieder_wand (void);
void von_mitte_bis_wieder_wand_in_schwarzeplatte(void);
void schwarzeplatte (void);
void cm_fahren (void) ;
void opfer (void) ;
void hindernis (void);
void kit_abwerfen (void);
void Power_Ausrichten(void);
void im_Kreis_faren (void);
void hintenausrichtenopfer (void);
void omnifakelinks (void);
void omnifakerechts (void);
void interrupt Interrupt(void); //sic
/*
* Jetzt gehts los
*/
/*Hauptfunktion*/
void main(void) {
init(); //Chip initialisieren, incl. I2C
// while(1) {
// MLX_Neu();
// }
servo=0;
stopp; //Erstmal alle Motoren aus
pwm_links = 255; //werte rumprobieren!
pwm_rechts = 155;
// MLX_Neu(); //Dem Temperatursensor eine neue Adresse geben
//Dazu müssen die Zeile 7 (#include "MLX_Neu.h") und die Zeile hier drüber
//aktiviert werden. Kurz, 1s, den Roboter einschalten und dann alles wieder
//auskommentieren. Es darf dabei natürlich nur ein T-Sensor angeschlossen sein.
//Zum Debuggen können Interrupts ein und aus geschaltet werden:
TMR1IE = 0; //En/Disable TMR1-Interrupt
IOCIE = 1; //En/Disable Interupt on Change, RB7..1/0
TMR0IE = 1; //En/Disable TMR0 Interrupt
SSPIE = 1; //En/Disable SSP Interrupt
INTE = 0; //En/Disable Interrupt on RB0
ADIE = 0; //En/Disable Interrupt on AD-Module
//Flags zurück setzen
I2C_Write = 0; //Ist der I2C gerade mit Schreiben beschäftigt?
I2C_Read = 0; //Ist der I2C gerade mit Lesen beschäftigt?
Flag_LED = 0; //Normales LED-Blinken aus
Register_R[0] = 0x07; //Adresse im T-Sensor in der der T-Wert gespeichert ist
Register_R[1] = 127; //Eigentlich würde ich ja 0 nehmen, aber dann bricht die Übertragung zusammen, k.A. warum
__delay_ms(600); //Allen Sensoren Zeit lassen auf den Anfangswert einzupegeln
GIE = 1; //GeneralInterruptEnable(/disable)
__delay_ms(400); //die ersten Werte holen (dauert natürlich nicht 400ms)
Status = 1;
if(Taster){ //wenn Taster am master gedrückt
__delay_ms(2500); // Pause damit er nicht direkt wieder raus springt
while(!Taster){ //solange Taster NICHT gedrückt wird
Werte_auf_LCD_anzeigen();
kit_abwerfen();
__delay_ms(1000);
}
}
//Für Tests:
//char Z = 0;
//Datum_S[0] = 123;
// while(0) {
// stopp;
// }
/*Hier gehts los, nachdem der Taster am Master gedrückt wurde*/
//Letter_kal();
while (1) { //Endlosschleife
Flag_LED = 0; // LED aus, damit bei opfer an kann
schwarzeplatte();
anderwandlang() ;
Werte_auf_LCD_anzeigen();
opfer();
hindernis();
if (rechtsvorne < wand ) { //ist rechts keine Wand?
Strecke_fahren(3,vorwaerts); //kontrollabfrage
while (!Flag_Strecke_erreicht){
}
stopp;
__delay_ms(50);
if (rechtsvorne < wand ) {//ist da wirklich keine?
VAR_im_Kreis_faren ++ ;
von_sensor_VR_bis_mitte(); //wenn ja -> keine Wand
stopp;
ausrichten();
if (nicht_rechts == 0){ //wird gesetzt nach schwarzer platte
rechts90grad();
while (!Flag_Strecke_erreicht){
//opfer();
}
stopp;
if ((vornelinks < wand)&&(vornerechts < wand)){ //falls er sich dreht und vor eine Wand fahren würde.
ausrichten();
im_Kreis_faren(); //guckt ob er über 6 mal rechts ist und reagiert drauf
von_mitte_bis_wieder_wand(); //fährt bis rechts wand oder ticks zu Ende
}
else{
links90grad();
ausrichten();
}
}
nicht_rechts = 0 ;
}
}
else{
if((vornelinks > wand)&&(vornerechts > wand)){ //ist vorne eine Wand?
stopp;
__delay_ms(50);
if((vornelinks > wand)&&(vornerechts > wand)){//Kontrollabfrage
if (linksvorne > wand){
ausrichten();
stopp;
links90grad();
while (!Flag_Strecke_erreicht);
stopp;
links90grad();
while (!Flag_Strecke_erreicht);
stopp;
ausrichten();
}
else{
VAR_im_Kreis_faren = 0 ; //wennn links, dann fährst du nicht mehr im KReis
ausrichten();
links90grad();
while (!Flag_Strecke_erreicht){
//opfer();
}
stopp;
ausrichten();
}
}
}
}
}
}
/*Kalibrieren der Buchstabensensoren, falls notwendig
Taster am 16F876A einmal drücken -> kalibrieren, nochmal drücken -> es kann los gehen*/
void von_sensor_VR_bis_mitte(void) {
stopp;
Strecke_fahren(77, vorwaerts); //die strecke die er in ticks nacg vorne fährt (idealerweise auf die mitte der platte))
while (!Flag_Strecke_erreicht){
schwarzeplatte();
opfer();
hindernis();
}
stopp;
}
void von_mitte_bis_wieder_wand (void){
VAR_von_mitte_bis_wieder_wand = 1;
Encoder = 0 ;
while ( VAR_von_mitte_bis_wieder_wand == 1){ // == ist Abfrage!
vorwaerts;
if (rechtsvorne > wand){ // ist da eine wand rechts von dir?
stopp;
if (rechtsvorne > wand){ // ist da eine wand?
VAR_von_mitte_bis_wieder_wand = 0 ; //Variable um aus der While zu gehen
stopp ;
}
}
if (vornerechts > 80){ //Ist da eine Wand vor dir?
stopp;
__delay_ms (50);
if (vornerechts > 80){ // ist da eine wand?
VAR_von_mitte_bis_wieder_wand = 0 ;
stopp ;
__delay_ms(500);
}
}
if (Encoder > 40 ){
VAR_von_mitte_bis_wieder_wand = 0 ;
VAR_bis_wand_zeit = 0;
stopp ;
}
schwarzeplatte();
opfer();
hindernis();
}
stopp ;
}
void von_mitte_bis_wieder_wand_in_schwarzeplatte (void){
VAR_von_mitte_bis_wieder_wand = 1;
Encoder = 0 ;
while ( VAR_von_mitte_bis_wieder_wand == 1){ // == ist Abfrage!
if (rechtsvorne > wand){ // ist da eine wand?
Strecke_fahren(2,vorwaerts);
while(!Flag_Strecke_erreicht);
stopp;
__delay_ms (50);
if (rechtsvorne > wand){ // ist da eine wand?
VAR_von_mitte_bis_wieder_wand = 0 ;
stopp ;
}
}
if (vornerechts > wand){
__delay_ms (20);
if (vornerechts > wand){ // ist da eine wand?
VAR_von_mitte_bis_wieder_wand = 0 ;
stopp ;
}
}
if (Encoder > 40 ){
VAR_von_mitte_bis_wieder_wand = 0 ;
VAR_bis_wand_zeit = 0;
stopp ;
}
opfer();
hindernis();
vorwaerts ;
}
stopp ;
}
void rechts90grad (void){
Strecke_fahren(grad_90_1, rechts);
while (!Flag_Strecke_erreicht){
//opfer();
}
stopp;
Strecke_fahren(grad_90_2, rechts);
while (!Flag_Strecke_erreicht){
stopp;
__delay_ms(10);
rechts;
__delay_ms(10);
//opfer();
}
}
void links90grad (void){
Strecke_fahren(grad_90links_1, links);
while (!Flag_Strecke_erreicht){
//opfer();
}
stopp;
Strecke_fahren(grad_90links_2, links);
while (!Flag_Strecke_erreicht){
stopp;
__delay_ms(10);
links;
__delay_ms(10);
//opfer();
}
}
void omnifakelinks(void){
if((linksvorne > Schwellwert_Omni)&&(linkshinten > Schwellwert_Omni)){
VAR_omni = 0;
while((((linksvorne + linkshinten )/2)<=78)&&(!VAR_omni < 6)){ //solange durchschnitt aus lv und lh nicht größer als 80...
bissl; // und die schleife nicht öfter als 6x durch (1x 195ms) mach omni
__delay_ms(50);
stopp;
bissr;
__delay_ms(55);
stopp;
bisslrueck;
__delay_ms(50);
stopp;
bissrrueck;
__delay_ms(50);
stopp;
VAR_omni++;
}
stopp;
VAR_omni = 0;
while((((linksvorne + linkshinten )/2)>=80)&&(!VAR_omni < 6)){
bissr;
__delay_ms(52);
bissl;
__delay_ms(38);
bissrrueck;
__delay_ms(42);
bisslrueck;
__delay_ms(42);
VAR_omni++;
}
VAR_omni = 0;
stopp;
}
}
void omnifakerechts (void){
if((rechtsvorne > Schwellwert_Omni)&&(rechtshinten > Schwellwert_Omni)){
VAR_omni = 0;
while((((rechtsvorne + rechtshinten )/2)<=78)&&(!VAR_omni < 6)){ //solange durchschnitt aus lv und lh nicht größer als 80...
bissr; // und die schleife nicht öfter als 6x durch (1x 195ms) mach omni
__delay_ms(52);
bissl;
__delay_ms(38);
bissrrueck;
__delay_ms(42);
bisslrueck;
__delay_ms(42);
VAR_omni++;
}
stopp;
VAR_omni = 0;
while((((rechtsvorne + rechtshinten )/2)>=80)&&(!VAR_omni < 6)){
bissl;
__delay_ms(50);
bissr;
__delay_ms(55);
bisslrueck;
__delay_ms(45);
bissrrueck;
__delay_ms(45);
VAR_omni++;
}
VAR_omni = 0;
stopp;
}
}
void Letter_kal(void) {
while(!Taster) { //Taster am Master. Wenn gedrückt geht die Arbeitsschleife los
Status = 1; //LED dauernd an
if (!Datum_R[0]){ //Warten auf Taster am 16F876A, ungedrückt HI
while (!Datum_R[0]); //Warten auf Taster loslassen
Datum1_an_Letter = 255; //Letter wird kalibriert
Datum2_an_Letter = 255;
//Zeit, dass sich der Letter-Baustein kalibrieren kann
while (Datum_R[0]) { //Warten auf Taster
Status = 0;; // LED dauernd aus
//Roboter langsam am Strich vorbei fahren lassen
vorwaerts;
__delay_ms(3);
stopp;
__delay_ms(17);
Werte_auf_LCD_anzeigen();
}
while (!Datum_R[0]); //Warten auf Taster loslassen
Datum2_an_Letter = 254; //Warum auch immer: 0 als gesendeter Wert geht nicht
}
Werte_auf_LCD_anzeigen();
}
Datum1_an_Letter = rechtsvorne;
Datum2_an_Letter = rechtshinten;
Flag_kalibrieren = 1;
}
void Werte_auf_LCD_anzeigen (void) {
for(char i = 0; i < 11; i++) { //die ersten 11 sind die AD-Werte
Datum_S[i] = A_D_Wert[i]; //HI-Teil des AD-Registers, s. Interrupt
}
Datum_S[12] = Encoder;
Datum_S[13] = 13; //Datum_R[1] ; //Wert von Letter_1-Sensor TESTWERT GERADE DRIN!
Datum_S[14] = 14; //Datum_R[2]; //Wert von Letter_2-Sensor TESTWERT GERADE DRIN!
Datum_S[15] = Temperatur_HI_rechts;
Datum_S[16] = Temperatur_LO_rechts;
Datum_S[17] = Temperatur_HI_links;
Datum_S[18] = Temperatur_LO_links;
Datum_S[19] = 33; //auch
}
void opfer (void) {
while(0){
if(Flag_T_links == 1){
if (linksvorne > wand){
if (VAR_zeit_opfer > 300){
Flag_LED = 0; // wenn LED = 0 dann blinkt sie, wenn 1 dann aus.
stopp;
Flag_T_links = 0;
stopp;
rechts90grad();
while(!Flag_Strecke_erreicht);
stopp;
kit_abwerfen();
stopp;
links90grad();
while(!Flag_Strecke_erreicht);
stopp;
__delay_ms(5000);
Flag_LED = 0;
VAR_zeit_opfer = 0;
Strecke_fahren(15, vorwaerts);
while(!Flag_Strecke_erreicht);
stopp;
}
else{
Flag_T_links = 0;
}
}
else{
// stopp;
// __delay_ms(1000);
// links90grad();
// while(!Flag_Strecke_erreicht);
// stopp;
// hintenausrichtenopfer();
// while(vornerechts < wand){
// vorwaerts;
// }
// stopp ;
// links90grad();
// while(!Flag_Strecke_erreicht);
// stopp;
// links90grad();
// while(!Flag_Strecke_erreicht);
// stopp;
// kit_abwerfen();
// stopp ;
// Flag_LED =1;
// __delay_ms(5000);
// Flag_LED =0;
// hintenausrichtenopfer();
// while(vornerechts < wand){
// vorwaerts;
// }
// stopp ;
// links90grad();
// while(!Flag_Strecke_erreicht);
// stopp;
Flag_T_links = 0;
}
}
if(Flag_T_rechts == 1){
if(rechtsvorne > wand){
if (VAR_zeit_opfer > 300){
Flag_LED =0; // wenn LED = 0 dann blinkt sie, wenn 1 dann aus.
stopp;
Flag_T_rechts = 0;
stopp;
links90grad();
while(!Flag_Strecke_erreicht);
stopp;
kit_abwerfen();
stopp;
rechts90grad();
while(!Flag_Strecke_erreicht);
stopp;
__delay_ms(5000);
Flag_LED = 0;
VAR_zeit_opfer = 0;
}
else{
Flag_T_rechts = 0;
}
}
else{
Flag_T_rechts = 0;
}
}
}
}
void kit_abwerfen(void) {
GIE = 0; //Interrupt aus, damit delays vong servo nicht kaputt.
for(char i=0; i<6; i++){
servo = 1;
__delay_us(2390);
servo = 0;
__delay_ms(20);
}
__delay_ms(200);
for(char i=0; i<6; i++){
servo = 1;
__delay_us(2110);
servo = 0;
__delay_ms(20);
}
for(char i=0; i<6; i++){
servo = 1;
__delay_us(2390);
servo = 0;
__delay_ms(20);
}
GIE = 1; //Interrupt wieder an!!!!!!!!!!!!
}
void anderwandlang(void){
// mit der Funktion soll er an der Wand lang fahren und richtet sich rechts aus.
//wenn rechts keine Wand ist fährter bis zur mitte der nächsten Platte
if (rechtsvorne >= zunah) { //Sensor rechts vorne zu nah an der Wand?
bissl; //linke Motoren aus, rechte vorwärts
__delay_ms(7); //Diesen Wert anpassen, muss zusammen mit nächstem delay 20ms ergeben
vorwaerts; //Beide Motoren wieder an
__delay_ms(13); //Wir produzieren uns ein einfaches PWM, delta T = 1ms
opfer();
}
if (rechtsvorne <= zuweit) { //Sensor rechts vorne zu weit weg von der Wand?
bissr; //rechte Motoren aus, linke vorwärts
__delay_ms(7); //leichten Bogen nach rechts fahren
vorwaerts; //
__delay_ms(13); //
opfer();
}
if (rechtsvorne < zunah) { //NICHT zu nah an Wand
if (rechtsvorne > zuweit) { //NICHT zu weit von Wand, also genau in dem
//Intervall in dem sich der Roboter bewegen soll
if (rechtsvorne > (rechtshinten -2)) { //rechtsvorne näher, als hinten, Hysterese = 5, evtl. Offset
bissl; //"PWM"
__delay_ms(7); //Werte anpassen
vorwaerts; //
__delay_ms(13); //
opfer();
}
else {
if (rechtsvorne < (rechtshinten +2)) { //rechtshinten näher
bissr; //
__delay_ms(7); //
vorwaerts; //
__delay_ms(13); //
opfer();
}
else{
vorwaerts; //alles im grünen Bereich
__delay_ms(20);
opfer();
}
}
}
}
}
void schwarzeplatte(void){ // >schwarz <weiß
if ((schwarzrechts > schwarz )||(schwarzlinks > schwarz )){ //einer ODER der andere schwarz?
stopp;
Strecke_fahren (30,vorwaerts); //steht jetzt auf der schwarzen platte für kontrollabfrage.
while(!Flag_Strecke_erreicht);
stopp;
if ((schwarzrechts > schwarz )&&(schwarzlinks > schwarz )){
stopp;
VAR_Schwarz_ausrichten=1;
Encoder=0;
while ((schwarzrechts > schwarz )&&(schwarzlinks > schwarz )){ // beide nicht weiß
while ((schwarzrechts > schwarz )&&(schwarzlinks > schwarz )){ //solange beide schwarz fahr nach hinten.
nachhinten;
__delay_ms(20);
stopp;
__delay_ms(12);
}
while ((schwarzrechts > schwarz )&&(schwarzlinks < schwarz )){ //wenn links weiß und rechts schwarz
bisslrueck; //dann dreh dich so dass du grade wirst
__delay_ms(20);
bissr;
__delay_ms(12);
stopp;
}
while ((schwarzrechts < schwarz )&&(schwarzlinks > schwarz )){ //wenn links schwarz und rchts weiß
bissrrueck;
__delay_ms(15);
bissl;
__delay_ms(5);
stopp;
}
}
stopp; //jetzt steht er am Rand von der Platte
__delay_ms(50);
Strecke_fahren(48,nachhinten); //jetzt in der Mitte von der weißen vor der schwarzen
while(!Flag_Strecke_erreicht);
stopp;
__delay_ms(1000);
ausrichten();
links90grad();
while (!Flag_Strecke_erreicht){
opfer();
}
stopp;
ausrichten();
if (vornerechts > wand){ //vorne ist eine Wand
links90grad();
while (!Flag_Strecke_erreicht){
opfer();
}
stopp;
ausrichten();
}
else{ // kaine wand,
stopp;
__delay_ms(50);
von_mitte_bis_wieder_wand_in_schwarzeplatte();
stopp;
__delay_ms(50);
}
}
else{
Strecke_fahren (30,nachhinten);
while(!Flag_Strecke_erreicht);
stopp;
//wenn nur einer in die richtige richtung fakeomnin
}
}
}
void hindernis(void){
if (Flag_Hindernis == 1){
Encoder = encodersave; //encoder merken.
while((vornelinks > 110)&& (vornerechts < wand)){
bissr;
__delay_ms(52);
bissl;
__delay_ms(38);
bissrrueck;
__delay_ms(42);
bisslrueck;
__delay_ms(42);
}
VAR_omni=0;
while (VAR_omni < 2){
bissr;
__delay_ms(52);
bissl;
__delay_ms(38);
bissrrueck;
__delay_ms(42);
bisslrueck;
__delay_ms(42);
VAR_omni++;
}
}
Flag_Hindernis = 0;
VAR_omni = 0;
encodersave = Encoder;
}
void im_Kreis_faren (void) {
if (VAR_im_Kreis_faren > 6){
VAR_links_ist_nichts ++ ;
if (linksvorne > wand ){
links90grad();
while(!Flag_Strecke_erreicht){
}
stopp;
links90grad();
while(!Flag_Strecke_erreicht){
}
stopp;
VAR_im_Kreis_faren = 0 ;
VAR_links_ist_nichts = 0 ;
}
if (VAR_links_ist_nichts > 4){
stopp;
__delay_ms(1000);
VAR_links_ist_nichts = 0 ;
while (vornelinks < wand || rechtsvorne < wand ){
vorwaerts ;
}
stopp;
if (vornerechts > wand){
links90grad();
while (!Flag_Strecke_erreicht){}
stopp ;
}
VAR_im_Kreis_faren = 0 ;
}
}
}
void Power_Ausrichten(void){
// if (VAR_aus_zeit > Zeit_power_Ausrichten){
// Ausrichten_Fahren=15;
// Ausrichten_Stopp=5;
// }
// else{
// Ausrichten_Fahren=7;
// Ausrichten_Stopp=13;
// }
}
void ausrichten (void){
links_ausrichten();
rechts_ausrichten();
vorne_ausrichten(); //richte dich vorne aus, wenn möglich.
//if((vornerechts > Schwellwert_Ausrichten)||(vornelinks > Schwellwert_Ausrichten)){//jetzt guck ob vor dir eine Wand ist (muss ja wenn du dich vorne ausgerictet hast)
hinten_ausrichten(); // falls auf dem eine ODER anderen keine Wand war richte dich nicht aus. sonst ja.
// (in hinten ausrichten guckt er auch noch mal ob da eine wand zum ausrichten ist!)
//}
links_ausrichten();
omnifakelinks();
stopp;
__delay_ms(50);
links_ausrichten();
if((linksvorne < Schwellwert_Ausrichten)||(linkshinten < Schwellwert_Ausrichten)){ // siehe oberhalb ;)
rechts_ausrichten();
omnifakerechts();
stopp;
__delay_ms(50);
rechts_ausrichten();
}
}
void vorne_ausrichten (void) {
if ((vornerechts < wand) && ( vornelinks < wand )){ //wenn da keine Wand ist
if ((vornelang < 111) && (vornelang >68)){
Var_lang_Ausrichten = 0;
while (Var_lang_Ausrichten == 0){
if (vornelang < 89){ //also weiter weg
vorwaerts;
__delay_ms(10);
stopp;
__delay_ms(10);
}
if (vornelang > 89){ //also näher dran
nachhinten;
__delay_ms(10);
stopp;
__delay_ms(10);
}
if ((vornelang > 88)&&(vornelang < 90)){
Var_lang_Ausrichten = 1;
stopp;
__delay_ms(1000);
}
}
}
}
if ((vornerechts > Schwellwert_Ausrichten) && ( vornelinks > Schwellwert_Ausrichten )){
stopp;
VAR_aus_zeit = 0;
stopp;
while ((vornerechts > 81)&&(VAR_aus_zeit <= 3000)){
Power_Ausrichten();
nachhinten;
__delay_ms (Ausrichten_Fahren);
stopp;
__delay_ms (Ausrichten_Stopp);
opfer();
VAR_aus_zeit ++ ;
}
VAR_aus_zeit = 0;
while ((vornerechts < 77)&&(VAR_aus_zeit <= 3000)){
Power_Ausrichten();
vorwaerts;
__delay_ms (Ausrichten_Fahren);
stopp;
__delay_ms (Ausrichten_Stopp);
opfer();
VAR_aus_zeit ++ ;
}
VAR_aus_zeit = 0;
while (vornerechts < (vornelinks +2 ) && (VAR_aus_zeit <= 3000)){
Power_Ausrichten();
bissl;
__delay_ms (Ausrichten_Fahren);
stopp;
__delay_ms (Ausrichten_Stopp);
opfer();
VAR_aus_zeit ++ ;
}
VAR_aus_zeit = 0;
while(vornerechts > (vornelinks + 2)&& (VAR_aus_zeit <= 3000)){
Power_Ausrichten();
bissr;
__delay_ms (Ausrichten_Fahren);
stopp;
__delay_ms (Ausrichten_Stopp);
opfer();
VAR_aus_zeit ++ ;
}
VAR_aus_zeit = 0;
while ((vornerechts < 77)&&(VAR_aus_zeit <= 3000)){
Power_Ausrichten();
vorwaerts;
__delay_ms (Ausrichten_Fahren);
stopp;
__delay_ms (Ausrichten_Stopp);
opfer();
VAR_aus_zeit ++ ;
}
VAR_aus_zeit = 0;
while ((vornerechts > 81)&&(!VAR_aus_zeit <= 3000)){
Power_Ausrichten();
nachhinten;
__delay_ms (Ausrichten_Fahren);
stopp;
__delay_ms (Ausrichten_Stopp);
opfer();
VAR_aus_zeit ++ ;
}
}
}
void hinten_ausrichten (void) {
if ((hintenrechts >Schwellwert_Ausrichten)&&( hintenlinks > Schwellwert_Ausrichten )) {
while ((hintenlinks < 81)&&(VAR_aus_zeit <= 3000)){
Power_Ausrichten();
nachhinten;
__delay_ms (Ausrichten_Fahren);
stopp;
__delay_ms (Ausrichten_Stopp);
opfer();
VAR_aus_zeit ++ ;
}
VAR_aus_zeit = 0;
while ((hintenlinks > 77)&&(VAR_aus_zeit <= 3000)){
Power_Ausrichten();
vorwaerts;
__delay_ms (Ausrichten_Fahren);
stopp;
__delay_ms (Ausrichten_Stopp);
opfer();