Forum: Mikrocontroller und Digitale Elektronik Reaktives Blinklicht mit AT Mega8 und IR-Empfänger


von Torsren W. (deidextra)


Lesenswert?

Hallo liebe Mikrocontroller-Gemeinde,

Ich habe im Studium ein kleines bisschen über Mikrocontroller und 
embedded Systems gelernt und wollte nun mein Wissen anwenden:

Ich bin begeisterter Geocacher und wollte nun mit Freunden einen 
Nachtcache legen. Als eine Station wollten wir ein Nachtaktives 
Reaktivlicht setzen. Weil ich schon mal was von Microcontrollern gehört 
hab, hab ich die Aufgabe übernommen und stehe jetzt vor nem kleinen 
Problem.

Mein kleines Reativlicht soll auf eine Fernbedinung reagieren und als 
Ausgabe den neuen Waypoint in Form eines Morsecodes ausgeben.

Die Schaltung habe ich soweit gelötet und sollte auch so funktionieren.
Ich verwende einen ATMega8-16DIP mit TSOP1738 und normalen LEDs als 
ausgabe.
Ich programmiere mit micropascal for AVR Pro.

Mein Programmcode sieht so aus
1
program geo;
2
3
4
{ Declarations section }
5
6
7
8
{ Declarations section }
9
10
11
// Hauptprogramm (Main)
12
13
  var incoming_IR_yes : boolean   ;
14
15
 // Ausgabe auf die LED´s
16
    procedure Ausgabe  ;
17
    //var       ;
18
      begin
19
20
         PORTB.B5 := 0x00 ;
21
         Delay_ms (3000) ;
22
         PORTB.B3 := 0x00 ;
23
         
24
25
      end;
26
27
28
  //Hauptschleife für Abfrage Infrarot
29
30
    procedure Abfrage_infrarot_eingang  ;      // oder alles als function
31
         var i : integer ;
32
33
34
      begin
35
      
36
37
           PORTC := 0x00 ;     //alles aus auf port c  einga infrarot
38
           PORTB := 0xff ;     //alles aus auf port b
39
40
           PORTB.B5 := 0x00 ;  //rot an
41
           Delay_ms (1000) ;    //pause
42
           PORTB.B5 := 0x01 ;   //rot aus
43
           Delay_ms (1000) ;    //pause
44
           PORTB.B5 := 0x00 ;   //rot an
45
           Delay_ms (1000) ;    //pause
46
           PORTB.B5 := 0x01 ;   //rot aus
47
           Delay_ms (1000) ;    //pause
48
           PORTB.B5 := 0x00 ;   //rot an
49
           Delay_ms (1000) ;    //pause
50
           PORTB.B5 := 0x01 ;   //rot aus
51
           
52
          {while PORTC.B3 <> 0x00 do                                        // unendlich schleife start
53
                 begin
54
55
56
57
                      // if PORTC.B3 <> 0x01 then Ausgabe //else
58
                    {begin     // oder ne braek und er läuft weiter in die nächste function weiß noch nciht genau ob das funst
59
                      Delay_ms (100) ;                        //mit dem delay müssen wir noch mal spielen bzw rechnen weil einmal in der gesamt signallaufzeit reicht mussen ja nur eine 1 erwischen um auzulösen
60
                      PORTB.B1 := 0x00 ;
61
                      Delay_ms (100) ;
62
                      PORTB.B1 := 0x01 ;
63
                      Delay_ms (100) ;
64
65
                      PORTB.B3 := 0x00 ;
66
                      Delay_ms (100) ;
67
                      PORTB.B3 := 0x01 ;
68
                      Delay_ms (100) ;
69
70
                      PORTB.B5 := 0x00 ;
71
                      Delay_ms (100) ;
72
                      PORTB.B5 := 0x01 ;
73
                      end;
74
                      delay_ms (10)
75
                 end;}                                    // unendlich schleife ende
76
                 
77
                   i := 0 ;
78
                 while i <> 0 do
79
                       begin
80
                             i :=  PORTC.B3 ;
81
                             i :=  sbit at PORTC.B3;
82
    
83
                      end;
84
                      Ausgabe;
85
86
      end;
87
88
89
90
 begin
91
      DDRC := 0x00 ;         //port auf eingang
92
      DDRB := 0xff ;        //port auf ausgang
93
      PORTB := 0xff ;       //alle ausgaänge port b aus
94
       Delay_ms (3000) ;
95
96
      incoming_IR_yes := false;
97
       PORTB.B5 := 0x00 ;    //dide 1 an    an is 0x00
98
       PORTB.B3 := 0x00 ;
99
       PORTB.B1 := 0x00 ;
100
       Delay_ms (500) ;
101
       PORTB.B5 := 0x01 ;     //diode aus   aus is 0x01
102
       PORTB.B3 := 0x01 ;
103
       PORTB.B1 := 0x01 ;
104
       Delay_ms (2500) ;
105
106
107
108
      Abfrage_infrarot_eingang;
109
110
111
112
113
end.

Problem ist nun, dass wenn ich auf den Eingang PortB.B3 eine 1 setze, 
wird die Ausgabeprozedur nicht aufgerufen.
Ich hab das erstmal am SKT500 ausprobiert? hat jemand eine Idee,

Ich bin schon ziemlich ratlos, daher auch die vielen auskommentierten 
Codestückchen...

Vielen Dank im Vorraus

von Karl H. (kbuchegg)


Lesenswert?

Torsren Wessling schrieb:

>     procedure Abfrage_infrarot_eingang  ;      // oder alles als

>           {while PORTC.B3 <> 0x00 do
> // unendlich schleife start

Das ist keine unendliche Schleife.
Die Schleife hängt ganz eindeutig von einer Bedingung ab.
Was passiert, wenn die Bedingung nicht mehr, oder noch nicht erfüllt 
ist?

> Ich bin schon ziemlich ratlos, daher auch die vielen auskommentierten
> Codestückchen...

Du hast IMHO falsch angefangen.
Das wichtigste war, dass dein µC am Anfang eine Blinkerei inszeniert, 
damit da was zum schauen hast. Quasi ein 'Willkommen' auf µC Art. Das 
ist als Vortest nicht schlecht, aber im Grunde ist es für dein 
eigentliches Programm völlig unwichtig und raubt dir momentan nur die 
Übersicht.

Fang nochmal an.
Aber diesmal soll dein erster Zwischenschritt sein:

Dein Programm bedient 2 LED
Am Programmanfang wird die eine eingeschaltet und die andere aus.
Dann geht das Programm in die obligatorische Endlosschleife über
  In der Endlosschleife fragt es ständig den Input Pin ab
  Ist der auf 0, dann passiert nichts
  Ist der aber auf 1, dann schaltet dein Programm die beiden LED um.
    Die leuchtende wird ausgeschaltet, die nicht leuchtende ein


Dieser Programmansatz ist klein genug, dass du dir nicht wieder selbst 
die Übersicht raubst.
Und nein. Mach das erst mal ohne procedure. Das sind nur ein paar Zeilen 
Code.

Und wenn das dann funktioniert, dann baust du es aus.

von Karl H. (kbuchegg)


Lesenswert?

Mein Pascal ist schon etwas rostig und auf einem AVR hab ich noch nie 
Pascal benutzt, aber so in etwa müsste das aussehen
1
program geo;
2
3
begin
4
  PORTC := 0x00;     // Port C auf Eingang
5
  PORTB := 0xFF;     // Port B auf Ausgang
6
7
  PORTB.B1 := 1;     // die eine LED ein
8
  PORTB.B5 := 0;     // die andere LED aus
9
10
  while 1 = 1 do begin       // Hauptschleife. Innerhalb dieser
11
                                // Schleife wird die ganze Arbeit gemacht
12
13
    if PINC.C3 = 1 then begin   // ist vom IR was gekommen?
14
      PORTB.B1 := 0;            //   dann die eine LED aus
15
      PORTB.B5 := 1;            //   und die andere LED ein
16
    end;
17
18
  end;
19
end.

von ka-long (Gast)


Lesenswert?

Hi,

Ich weiss, selber bauen macht Spaß.

Aber schau mal hier die Diskussion an:
http://www.geoclub.de/viewtopic.php?f=57&t=40079

Gruß ka-long

von Torsren W. (deidextra)


Lesenswert?

Super, danke für eure schnellen antworten.
@ Karl Heinz:

Das mit dem rumgeblinke ist noch drin geblieben, um zu überprüfen ob ich 
meine Schaltung richtig gelötet habe und jetzt im nachhinnein um 
herauszufinden, ob der Controller in die Ausgabeprozedur springt.

Werde das mal nach deinem Rat schlanker gestallten und mich dann nochmal 
melden, ob das so hingehauen hat!
Danke nochmal!

von Torsren W. (deidextra)


Lesenswert?

Kleines Update hierzu:

Ich habe Euren Rat befolgt und das Programm nochmal ganz von vorne 
angefangen.
Ich konnte das Programm endlich vernünftig struckturieren und habe es 
geschafft die LEDs zum richtigen Blinken zu bekommen!
Danke nochmal für Euren guten Rat!

Und grade weil ihr mir so gut geholfen habt, habe ich nochmal eine 
Bitte!
könntet ihr nochmal über meinen(verkürzten) Code schauen.
Ich habe den extra eingekürzt, weil 200 Zeilen in denen nur LEDs an und 
wieder ausgemacht werden, sind für Euch ja wahrscheinlich uninteressant!

Mein Problem ist folgendes:
Die Aktivierung per IR-Empfänge funktioniert einwandfrei. Nachdem der 
Blinker aktiviert worden ist, soll erstmal eine grüne LED für 2 Sekunden 
leuchten, um den Benutzer darauf vorzubereiten, dass gleich was 
passieren wird. Dannach soll der Morsecode mit der Blauen LED starten. 
dann leuchtet nochmal die grüne LED, denn dannach startet eine rote LED 
mit der Anzeige des anderen Morsecodes. Dannach ist Ende. der Controller 
wartet wieder auf eine erneute Aktivierung.

Es funktioniert fast alles: und mit fast mein ich auch wirklich nur eine 
Kleinigkeit.
Die grüne LED leuchtet am Anfang nicht. es startet sofort die blaue LED 
mit der Übertragung. dannach leuchtet die grüne LED so wie es sein soll, 
und die Rote LED arbeitet auch vernünftig.

Hier mein verkürzter Code: vielleicht findet ihr ja den Grund dafür!
1
program Geocaching;
2
3
{ Declarations section }
4
 (*              //OUTPUTS
5
     //  LED GRÜN  ==  PORTB.B1
6
     //  LED BLAU  ==  PROTB.B3
7
     //  LED ROT   ==  PORTB.B5
8
9
             //INPUT
10
     //  TSOP   == PINC.C3
11
     
12
        *)
13
14
15
begin
16
17
    DDRB := 0xFF;         //Ports B auf Ausgang
18
    
19
    DDRD := 0x00;         //Ports D auf Eingang
20
21
    PortB.B1 := 0x00;
22
    Portb.B0 := 0x00;
23
    Portb.B2 := 0x00;
24
    Portb.B3 := 0x00;      //schaltet alle LED aus
25
    Portb.B4 := 0x00;
26
    Portb.B5 := 0x00;
27
    
28
    
29
    
30
    while TRUE  do
31
    begin
32
33
         if PINC.B3 = 0 then
34
         begin
35
         //Bereit halten mit grüner LED 2Sek
36
         PORTB.B1 := 0x01;                            //Dieser Teil, also das An- und Ausschalten von PORTB.B1, es scheint, als würden diese 3 Zeilen übersprungen, funktioniert nicht! Keine Ahnung warum nicht, aber
37
         delay_ms(2000);
38
         PORTB.B1 := 0x00;
39
         
40
         
41
    //   Übermittlung der Nördlichen Breite
42
    //5
43
               PORTB.B3 :=0x01;
44
              delay_ms(300);          //dit
45
              PORTB.B3 := 0x00;
46
47
              delay_ms(300);          //Symbolabstand                 //funktioniert einwandfrei, hab das nur abgekürzt.
48
49
              PORTB.B3 :=0x01;
50
              delay_ms(300);          //dit
51
              PORTB.B3 := 0x00;
52
53
      (*Hiernach wird mit dem Ein- und Ausschalten der LEDs weiter gemacht.
54
      bis dann das hier folgt.*)
55
56
57
58
   //Bereit halten mit grüner LED 2 Sek
59
         PORTB.B1 := 0x01;
60
         delay_ms(2000);
61
         PORTB.B1 := 0x00;                          //das funktioniert auch einwandfrei
62
63
64
   // Übermittlung der östlichen Länge
65
66
   //0
67
              PORTB.B5 :=0x01;
68
              delay_ms(900);          //dah
69
              PORTB.B5 := 0x00;
70
                                                                        //Funktioniert ebenfalls.
71
              delay_ms(300);          //Symbolabstand
72
73
              PORTB.B5 :=0x01;
74
              delay_ms(900);          //dah
75
              PORTB.B5 := 0x00;
76
77
78
79
80
81
         end;
82
         PORTB.B1 := 0x00;
83
         PORTB.B3 := 0x00;
84
         PORTB.B5 := 0x00;
85
    end;
86
87
88
    
89
end.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.