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
:
Bearbeitet durch User
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 | static uint16_t old; |
2 | uint16_t new, 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 :)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.