Hallo zusammen,
ich bin neu hier und rätsel jetzt schon eine ganze Zeit an folgendem
Problem:
Ich möchte mit einem ATMega8 die Signale von 10 Lichtschranken
auswerten. Wenn der Lichtstrahl unterbrochen wird liegt am AVR ein
High-Level an, die Schaltung lässt sich aber auch schnell so umbauen,
dass sich ein Low-Level ergibt, falls das in irgendeiner Art helfen
sollte.
Jede dieser Lichtschranken wird jetzt unabhängig von den anderen für
sagen wir ca. 500ms unterbrochen, die genaue Länge der Signale ist
jedoch bei jedem Signal (nicht nur bei jedem Kanal) individuell
unterschiedlich.
Hat jemand eine Idee wie ich die Signale sinnvoll zählen kann? Weil wenn
ich einfach nur jede Lichtschranke abfrage erhalte ich ja je nach Länge
des Signals Mehrfachzählungen, und mit wait kann ich nicht arbeiten, da
in diesem Fall alle Kanäle gestoppt würden...
Meine Idee war den Eingangspin für so lange zu deaktivieren bis er
einmal wieder ein High erhalten hat.
Ich hab das Handbuch schon bemüht, ebenso das Internet, und so langsam
verzweifel ich an dieser Aufgabe.
Ich möchte das ganze gerne in Bascom programmieren, eine andere Sprache
beherrsche ich momentan nicht.
Ich würde eine Flankenerkennung machen. In C könnte das so aussehen, ich
hoffe du kannst damit was anfangen:
1
PORTBnew=PORTB;
2
flankeB=~PORTBold;
3
flankeB=flankeB&PORTBnew;
4
PORTBold=PORTBnew;
5
6
if(flankeB&(1<<1))// RB1
7
{
8
9
}
10
if(flankeB&(1<<2))// RB2
11
{
12
13
}
14
if(flankeB&(1<<4))// RB4
15
{
16
17
}
18
if(flankeB&(1<<0))// RB0:
19
{
20
21
}
~ Bitweiße NOT
& Bitweiße UND
Im Prinzip macht das Programm einfach das Bitweiße UND aus dem neuen
Zusatand von PORTB und dem alten (in PORTBold gespeichert) negiert. Das
Ergebnis ist dann eine 8bit Zahl, ist ein Bit in dieser Zahl gesetzt,
war am entsprechenden Eingang eine Steigende Flanke
Ich glaube ich habe so grob verstanden was du meinst.
Ich werde das die Tage mal in Bascom ausprobieren, auch wenn ich mir
damit im Zweifel das Leben schwerer mache als nötig...
Aber das ist ein Ansatz der mir weiterhilft, danke :)
Arne schrieb:> Ich möchte mit einem ATMega8 die Signale von 10 Lichtschranken> auswerten.> Jede dieser Lichtschranken wird jetzt unabhängig von den anderen für> sagen wir ca. 500ms unterbrochen, die genaue Länge der Signale ist> jedoch bei jedem Signal (nicht nur bei jedem Kanal) individuell> unterschiedlich.> Hat jemand eine Idee wie ich die Signale sinnvoll zählen kann? Weil wenn> ich einfach nur jede Lichtschranke abfrage erhalte ich ja je nach Länge> des Signals Mehrfachzählungen, und mit wait kann ich nicht arbeiten, da> in diesem Fall alle Kanäle gestoppt würden...> Meine Idee war den Eingangspin für so lange zu deaktivieren bis er> einmal wieder ein High erhalten hat.
Im Prinzip ganz richtig gedacht. Aber natürlich willst du nicht den
Eingang "deaktivieren", sondern nur so lange nicht auf den aktiven Pegel
reagieren, bis du nicht wenigstens einmal einen inaktiven Pegel gesehen
hast.
Und dazu mußt du nichts weiter machen, als dir jeweils den letzten
Zustand jedes der 10 Eingänge zu merken. Dein Programm läuft in einer
Endlosschleife. Bei jedem Durchlauf fragt es den neuen Zustand der
Eingänge ab und vergleicht mit dem alten Zustand. Jetzt gibt es 3
Möglichkeiten:
1. der alte und der neue Zustand eines Eingangs sind gleich. Dann hat
sich nichts geändert (die Lichtschranke ist entweder immer noch offen
oder immer noch unterbrochen) und du hast nichts zu tun.
2. der Zustand wechselt von "Lichtschranke offen" zu "Lichtschranke
unterbrochen".
3. der Zustand wechselt von "Lichtschranke unterbrochen" zu
"Lichtschranke offen".
Je nachdem, bei welchem der beiden Übergänge du zählen willst, mußt du
deinen Zähler entweder bei 2. oder bei 3. hochzählen.
Sparsame Programmierer werden sich den Zustand der 10 Eingänge in 10
Bits merken (wie Max oben). Du kannst aber genausogut ein Array mit 10
Einträgen verwenden. Oder sonst irgendwas, das das
Informationsäquivalent von 10 Bits speichern kann.
XL
Du brauchst ne Flankenerkennung.
Die 10 Eingänge in eine 16Bit Variable ablegen und dann mit dem
vorherigen 16Bit-Wert EXORen und mit der gewünschten Flanke verUNDen.
1
staticuint16_told;
2
uint16_tnew,rising_edge,falling_edge;
3
4
new=PINA|(PINB<<8);
5
rising_edge=(new^old)&new;
6
falling_edge=(new^old)&old;
7
old=new;
Und dann für alle gesetzen Bits den Wert hochzählen.
Eine Variable new sollte man besser nicht nutzen, das ist ein
Schlüsselwort in C++ (jaja, in C geht es), es bringt einem aber in den
meisten Editoren ein falschen Syntax Highlighting.
Arne schrieb:> Jede dieser Lichtschranken wird jetzt unabhängig von den anderen für> sagen wir ca. 500ms unterbrochen, die genaue Länge der Signale ist> jedoch bei jedem Signal (nicht nur bei jedem Kanal) individuell> unterschiedlich.> Hat jemand eine Idee wie ich die Signale sinnvoll zählen kann?
Du willst vermutlich eine funktionierende Personenzählung mittels
Lichtschränke. Da haben sich schon wesentlich kompetentere Leute die
Zähne dran ausgebissen. Also gleich vorbeugend: eine perfekt
funktionierende Lösung dafür ist theoretisch und deshalb natürlich auch
praktisch unmöglich. Nur, wenn mittels baulicher Maßnahmen eine
Personenvereinzelung vorgenommen wird, ist eine Lösung realisierbar, die
zumindest solange recht zuverlässig funktioniert, wie es keine Absicht
gibt, diese auszutricksen.
Wie auch immer: Deine Definition ist doch schon fast hinreichend für
eine sinnvolle Zählung (wie gesagt: wenn es eine physische
Personenvereinzelung gibt). Die geforderte Mindestlänge für eine
Unterbrechung soll also 500ms sein. Es fehlt noch die Definition dafür,
wie lange innerhalb so einer Unterbrechung diese Unterbrechung auch mal
wieder aufgehoben sein darf, ohne daß das zu einer Mehrfachzählung
führt. Genau diese beiden Größen sind dann letztlich der Knackpunkt der
Sache. Wenn man clever googelt, gibt es sogar dazu Statistiken zu
finden...
Der Rest ist triviale Programmierung: Flankendetektion, Timeouts und
Statusmaschinen.
> Ich möchte das ganze gerne in Bascom programmieren, eine andere Sprache> beherrsche ich momentan nicht.
Das Verrückte ist: Wenn man programmieren kann (d.h. im Wesentlichen
einfach nur: wenn man logisch denken kann), ist die Sprache weitgehend
egal. Man muß sie halt nur lernen, um sie benutzen zu können, d.h.:
entscheiden zu können, wie man das Problem mit den verfügbaren
Sprachmitteln umsetzen kann. Dazu muß man im Minimum aber wenigstens
alle wichtigen Features der verwendete Sprache kennen...
Du kannst aber offensichtlich nichtmal wirklich BASCOM, denn dein
Problem scheint einfach die Zahl der Lichtschranken zu sein, d.h.: du
hast wohl nicht gelernt, daß sowas wie Datenstrukturen und/oder Felder
existiert und wie man das Zeug sinnvoll benutzt, wenn man dieselbe nicht
völlig triviale Sache für mehr als eine Instanz von Irgendwas tun will.
Wie kannst du das lernen? Ganz einfach: systematisch.
1) Implementiere den Kram erstmal für nur genau eine Lichtschranke mit
dem, was du bisher kannst.
2) Überlege, welche der im Programm verwendeten Variablen für die
Lichtschrankenfunktion selber relevant ist.
3) Fasse diese Variablen zu einer Datenstruktur zusammen.
4) Schreibe dein Programm so um, daß des statt mit den ursprünglichen
Einzelvariablen mit dieser Datenstruktur arbeitet.
5) Lerne, was Arrays sind.
6) Erzeuge ein Array deiner Datenstruktur mit sovielen Elementen, wie es
Lichtschranken gibt. Schreibe deine Datenstruktur auf irgendeine
Arrayposition, bloß nicht auf die erste.
7) Schreibe dein Programm so um, daß es mit der dieser Datenstruktur
irgendwo im Array umgehen kann. Schreibe sie zum Test immer mal wieder
auf irgendeine andere Position. Sorge dafür, daß diese Position
programmweit gültig an genau einer Stelle festgelegt werden kann.
8) Letzter Schritt: Schreibe dein Programm so um, daß es alles, was es
mit dem einen Arrayelement tut, mit allen gleichermaßen tut.
Fertig. Und du hast nebenbei ganz wesentliche Grundlagen des
Programmierens ganz allgemein gelernt. Dann du wirst bald auch
herausfinden, daß auch andere Sprachen Datenstrukturen, Arrays und
Kontrollstrukturen wie If/else/endif oder for/next anbieten, auch wenn
sich die Syntax im Detail unterscheidet, am Ende ist es immer nur wieder
ein- und dieselbe langweilige Soße. Jedenfalls solange du im Bereich der
Anweisungssprachen bleibst...
Mittlerweile läuft es für drei Kanäle, ich denke das auszuweiten auf 10
wird jetzt kein großes Problem mehr sein.
Danke für die ganze umfangreiche Hilfe :)