mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Richtungsbestimmung mit 2 Lichtschranken


Autor: Harald (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

Ich möchte mittels zweier Lichtschranken,  die Bewegungsrichtung der die 
LS passierenden Personen ermitteln. Person geht herein bzw.geht heraus.

Das ganze soll mit einem ATMega8 und Bascom realisiert werden. Da ich 
Bascom-Anfänger bin, hoffe ich auf ein paar Tipps zur Programmierung.


L.G. Harald

Autor: Timmo H. (masterfx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du musst doch einfach nur gucken welche Lichtschranke zuerst ausgelöst 
wurde.
L1    L2
--------> Rein
<-------- Raus

Wenn L1 und L2 NULL waren und L1 EINS wird und anschließend L2 EINS 
wird, dann geht er rein. Wenn L2 EINS wird und anschließend L1 EINS wird 
geht er raus. Alle anderen Kombinationen sind sind ungültig.

Ist doch einfach nur ein bissl speichern von Werten und die Auswertung 
mit ein paar ifs

Autor: Matthias Lipinsky (lippy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Ist doch einfach nur ein bissl speichern von Werten und die Auswertung
>mit ein paar ifs

Das wird Spaghetticode! Mach ne Schrittkette mit CASE.

Autor: Timmo H. (masterfx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nö, sind eigentlich nur zwei Ifs. Spaghetticode wirds durch Bascom so 
oder so ;-)

Autor: Carsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Versuch es mal mit ein paar Threads zu Drehencodern. Die machen meißt 
auch eine Richtungsbestimmung.

Autor: Matthias Lipinsky (lippy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>nur zwei Ifs.

Das wird nicht reichen. Machs mal richtig. Da wirst du sehen, das sich 
das schnell aufbläst. Du musst ja auch beachten, dass man zwischen 
beiden Lichtschranken umdrehen kann bzw entsprechende Timeouts 
miteinbauen...

Autor: Frank (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die vom OP nachgefragte Logik ist von der Programmiersprache unabhängig 
und man kann in jeder Programmiersprache übersichtliche Programme oder 
Spaghetti-Code schreiben ... Ich würde das Problem mit einer Art 
Zustandsautomat lösen.

- Ich würde zunächst in einer Schleife darauf warten, dass eine der 
Lichtschranken unterbrochen wird.
- wenn eine unterbrochen wird, dann merken welche und gleichzeitig einen 
Timer starten
- Timer dient dem Timeout. Wenn jemand in der Schranke stehen bleibt 
oder umkehrt, die ganze Aktion nach einer Weile abbrechen und in die 
Schleife zu Anfang zurückkehren
- wenn innerhalb der erlaubten Zeit die zweite Schranke unterbrochen 
wird, ist die Richtung schon mal fast klar
- nun muss man noch darauf warten, ob, wann und in welcher Reihenfolge 
die Lichtschranken wieder frei gegeben werden, erst dann ist ein 
Messvorgang eindeutig

Zum Schluss muss man sich noch überlegen, was man mit den nicht 
eindeutigen Unterbrechungen macht: verwerfen und vergessen oder neben 
Rein und Raus als "nicht eindeutig" getrennt speichern ...

Frank

Autor: faraday (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das mit mittendrin stehenbleiben leuchtet mir nicht ein.
Die können doch in cm-Abstand angebracht werden, oder?

Autor: Matthias Lipinsky (lippy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>das mit mittendrin stehenbleiben leuchtet mir nicht ein.
>Die können doch in cm-Abstand angebracht werden, oder?

Trotzdem ist sowas zu beachten. Sonst ist die Lösung nicht sauber.

Autor: Rudi Ratlos (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, ich hole das Thema mal wieder hoch, denn ich stehe genau vor der 
selben Aufgabe. Es gilt die Richtung mit Hilfe zweier Lichtschranken zu 
bestimmen.

Ich habe folgendes entworfen:

Die Lichtschranken sind bei Unterbrechung High (1).
Der Abstand der Lichtschranken beträgt null, d.h. sie sind direkt 
nebeneinander angeordnet.

Als Beispiel für die Richtung "Out" ergibt sich theoretisch folgender 
Ablauf:
----->
L1  L2
0   0
1   0
1   1
0   1
0   0

Im Programm frage ich mittels Timer alle X ms den Zustand der 
Lichtschranken ab:
#define L2  ((PINC & 1<<PC5)>>PC5)
#define L1  ((PINC & 1<<PC6)>>PC6)
#define L1L2    ((PINC & ((1<<PC5)|(1<<PC6)))>>PC5)

#define OUT    1
#define IN    2
#define INVALID    3

//global deklarierte Variablen
volatile uint8_t out=5, in=8;
volatile uint8_t l1_flag=0, l2_flag=0, direction=INVALID;

ISR( TIMER0_COMP_vect )
{
... //hier wird noch anderer Kram erledigt

    switch (L1L2)
    {
      case 2:  if( l2_flag )
                 direction = IN;
               else 
                 l1_flag = 1;
               break;

      case 1: if( l1_flag )
                direction = OUT;
              else
                l2_flag = 1;
              break;

      case 0: if( l1_flag && direction == OUT )
              {
                out++;
                in--;
                direction = INVALID;
              }
              else if( l2_flag && direction == IN )
              {
                out--;
                in++;
                direction = INVALID;
              }
              break;

      case 3:  break;
      default:break;
    }
}

Aber so einfach scheint es nicht zu funktionieren. :-( Es ändert sich 
der Zustand von out und in nicht, wenn ich die Lichtschranken teste. Ich 
stehe z.Z. auf dem Schlauch.
Danke!
Ist das Konzept zu schlecht?
Was habe ich übersehen?
Gibt es bessere Lösungsansätze, wenn ja welche? Die Abfrage mittels 
Timer ISR sollte schon als Basis dienen.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
faraday schrieb:
> das mit mittendrin stehenbleiben leuchtet mir nicht ein.
> Die können doch in cm-Abstand angebracht werden, oder?

In welcher Höhe machst du denn die Lichtschranken :-)

Zu hoch oben geht nicht, sonst erwischt du Kinder nicht.
Zu tief drunten geht auch nicht, sonst unterbricht dir so manche Person 
die Lschtschranke zweimal (weil man ja 2 Beine hat). In der Mitte ist es 
noch schlimmer, da kann dir jede Person die Lichtschranke 3 mal 
durchbrechen (weil ja die Arme auch schwingen). Und zu guter letzt kann 
es natürlich auch sein, dass die Anzahl der Unterbrechungen auf einer 
Lichtschranke anders ist als auf der anderern.

Alles in allem: Mit Lichtschranken funktioniert das einigermassen super 
bei Postpaketen (solange keiner sein Fahrrad einpackt). Bei Menschen mit 
ihrer bescheuerten Angewohnheit beim Gehen die Beine zu bewegen und dann 
auch noch mit den Armen mitzuschwingen ist das aber gar nicht so 
einfach.

Edit: Hab gerade gesehen, dass der Thread himmelalt ist.
Bitte, hol nicht so olle Kamellen hervor. Fang in Zukunft einen neuen 
Thread an.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rudi Ratlos schrieb:
> Hallo, ich hole das Thema mal wieder hoch, denn ich stehe genau vor der

> Aber so einfach scheint es nicht zu funktionieren. :-( Es ändert sich
> der Zustand von out und in nicht, wenn ich die Lichtschranken teste. Ich
> stehe z.Z. auf dem Schlauch.

Dann lass dir doch mal die Zwischenstati (Zwischenergebnisse ausgeben)
Dann weißt du mehr.

Edit:
Und ich würde mal damit anfangen, mir hier

   switch (L1L2)

den Wert von L1L2 anzusehen. Die Tatsache, dass du die höherwertigen 
Bits nicht wegmaskierst

#define L1L2    ((PINC & ((1<<PC5)|(1<<PC6)))>>PC5)

lässt mich Schlimmes vermuten.

Autor: Rudi Ratlos (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
@Karl heinz

Sorry, dass ich den alten Thread hoch geholt habe. Aber ich dachte mir 
da er relativ klein ist, haben die Leute die vor ähnlichem Problem 
stehen, einen einfachen Überblick. OK, nächstes mal immer einen Neuen 
aufmachen. :-)

Also ich zähle keine Menschen. Der Testaufbau der Lichtschranken sieht 
wie im Foto aus. Ich schiebe dort einfach einen einen kleinen Gegenstand 
durch. Die Lichtschranken sind ausgerichtet und funktionieren.

Karl heinz Buchegger schrieb:
> den Wert von L1L2 anzusehen. Die Tatsache, dass du die höherwertigen
> Bits nicht wegmaskierst
>
> #define L1L2    ((PINC & ((1<<PC5)|(1<<PC6)))>>PC5)

Hm, werden die höherwertigen Bits nicht schon durch die &-Verknüpfung 
maskiert? Ist ja quasi eine Pinabfrage wie z.B. PINC & (1<<PC5), nur 
dass ich das mit zwei Eingängen gleichzeitig mache und das Ergebnis 
nochmal linksbündig schiebe.

Autor: Rudi Ratlos (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rudi Ratlos schrieb:
> Ist ja quasi eine Pinabfrage wie z.B. PINC & (1<<PC5), nur
> dass ich das mit zwei Eingängen gleichzeitig mache und das Ergebnis
> nochmal linksbündig schiebe.

Ich meine natürlich rechtsbündig

Autor: Rudi Ratlos (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe zwei Fehler gefunden: Lichtschranken sind an Pin 6 und 7 
angeschlossen. Flags müssen zurück gesetzt werden.

Jetzt zählt er schon mal. :-)
Ich werde natürlich noch testen wie fehleranfällig die Methode ist.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.