Hallo, ich bin hier bereits ein langer stiller Leser in eurem Forum. Nun habe ich auch ein Problem. Ich habe eine Lichtschranke. Mithilfe eines ATtiny 2313 möchte ich ein Relais eine bestimmte Zeit schalten, wenn ein Objekt die Lichtschranke unterbricht. Da ich (Schüler) allerdings noch Anfänger in der Bascom Programmierung bin, habe ich noch ein paar Fragen bei der Gestaltung dieses kleinen Projektes. Ich möchte, egal wie lange die Lichtschranke unterbrochen ist, das Relais bzw. den Port nur eine bestimmte Zeit (ca. 10s) schalten. Ich habe leider noch keinen Ansatz gefunden, wie ich diese Problematik angehen kann. Meine Idee war, einen Timer bei Unterbrechung der Lichtschranke zu starten und diesen hochzählen lasse. Zusätzlich soll der Ausgang eingeschaltet werden. Eine Variable sollte bei jedem Timer-Interrupt um +1 hochgezählt werden, bis ich meine Zeit von ca. 10 Sekunden erreiche. Wenn meine Variable meine 10 Sekunden abgezählt hat, soll sie sich rücksetzen und der Ausgang ausgeschaltet werden. Kann das funktionieren? Habt ihr andere Ideen oder Vorschläge, wie das zu realisieren ist? Ich danke euch schon im Voraus. Gruß Christoph
Hi Timer ist ein Teil. Allerdings da<rfst du den Eingang nicht statisch verarbeiten, sondern musst eine Flanke auswerten. In deinem Fall die erste. Da ich in Assembler spreche, bleib ich mal mit meiner Beschreibung etwas oberflächlich: Eingang einlesen und mit einem alten abgelegten Wert Exclusiv-Oder verknüpfen. Ergebnis ist "1", wenn alt <> neu. Nun noch ein Und mit dem Ergebnis aus der Exclusiv Oder Geschichte und du hast die steigende Flanke. Danach Neu--> Alt. Da die meisten die Eingänge gegen GND schalten, umm die internen Pullup zu nutzen, musst du in diesem Fall evtl. das Bit drehen, um bei einem Signal eine "1" zu erhalten. Das Flankenbit startet nun deine Zeit und schaltet das Relais ein. Danach löscht du das Flankenbit. Ist die Zeit abgelaufen, fällt das Relais ab und es ist ein erneuter Wechsel mit einer entsprechenden Flanke des Signales erforderlich, um diesen Vorgang erneut zu starten. In Assembler sieht's etwa so aus
1 | In R16, Portx ; Port lesen |
2 | COM R16 ; evtl. drehen |
3 | ANDI R16, 0b00011100 ; Maske für gültige Eingängge |
4 | LDS R17, old_In |
5 | EOR R17, R16 ; Exclusiv Oder, Ergebnis in R17 |
6 | AND R17, R 16 ; Neues Bit Wechsel auf "1" |
7 | STS Flanken, R17 |
8 | STS Old_In, R16 |
Aud die Entprellerei hab ich hier mal verzichtet. Wird eine Entprellroutine erforderlich, macht es Sinn, die Zeile "In R16, Portx" durch eine Anweisung "LDS R16, Neu_In" zu ersetzen und die Variable "Neu_In" aus dem gelesenen Port und der Entprellroutine zu bilden. In der Programmschleife wird dann das Flankenbit bearbeitet:
1 | LDS R16, Flanke |
2 | ANDI R16, 0b00001000 ; z.B. Bit 3 |
3 | BREQ Ende ; keine Flanke, dann ende Subroutine |
4 | LDI R 16, 10 ; Zeit = 10 sek. |
5 | STS Relaiszeit, R16 |
6 | In R 16, PortX ; kann auch anders gelöst werden |
7 | ORI R16, 0b00000001 ; Relais ein |
8 | OUT Portx, R16 ; aber ich arbeite auch hier oft mit Variablen |
9 | LDS R16, Flanke |
10 | ANDI R16, 0b11110111 ; Flankenbit löschen |
11 | STS Flanke, R16 |
12 | Ende: |
Bleibt noch das Abschalten des Relais. Dazuu generieerst du dir einen Sekundentakt und setzt dafür auch ein Bit. Ich nenne diese Bits "TimeFlags". Das ist ein Byte, in das die Zeitereignisse, die innerhalb einer Timer_ISR erfasst werden, eingetragen werden. In der Programmschleife werden diese dann bearbeitet, ohne die ISR zu belasten.
1 | LDS R16, Timeflags |
2 | ANDI R16, 0b00100000 ; Sekundenbit abfragen |
3 | BREQ ende1 ; kein Bit gesetzt, dann Ende |
4 | LDS R16, TimeFlags |
5 | ANDI R16, 0b11011111 ; Sekundenbit löschen |
6 | STS Timeflags, R16 |
7 | LDS R16, Relaiszeit |
8 | DEC R16 ; Relaiszeit runterzählen |
9 | STS Relaiszeit, R16 |
10 | BRNE Ende1 ; wenn nicht "0" dann ende |
11 | LDS R16, Portx |
12 | ANDI R16, 0b11111110 ; Relais aus |
13 | Out Portx, R16 |
14 | Ende1: |
Statt einen direkten Portzugriff setze ich hier meist auch Variablen ein und weise dann aam Schluss der Programmschleife die Ausgänge zu. Du kannst hier auch direkt die Portbits setzen oder löschen. Gruß oldmax
Evtl. tut es auch ein Monoflop, ggf. retriggerbar.. (nicht für alles braucht man einen uC :-)
Hi Rainer Unsinn schrieb: > Evtl. tut es auch ein Monoflop, ggf. retriggerbar.. (nicht für alles > > braucht man einen uC :-) >Mithilfe >eines ATtiny 2313 möchte ich ein Relais eine bestimmte Zeit schalten Natürlich braucht man für alles einen µC. Da kommt doch in der Regel noch was hinterher..... Gruß oldmax
Hi oldmax, Zuerst einmal vielen Dank, dass du dir die Mühe gegeben hast, mir einen Code zu stricken und ihn so schön zu kommentieren. :) Das hat mir das verstehen des Assembler-Codes um einiges erleichtert. Da ich mir aber noch nicht ganz sicher bin, möchte ich deine Idee noch einmal zusammenfassen: Zuerst wird der Port ausgelesen, welches Signal (logisch 0 oder 1) anliegt. Man könnte auch sagen, dass auf eine positive Flanke „gewartet“ wird. Sorry, wenn ich frage, aber eine z.B. positive Flanke ist ja eine Änderung des Ports von 0 auf 1, oder? In deinem Programm wird der alte Wert des Eingangs mit dem Neuen verglichen. Könntest du bitte das mit dem „Neu--> Alt“ nochmal genauer erläutern? Im nächsten Teil schaltest du dann das Relais an, wenn eine Flanke vorliegt? Sehe ich das richtig mit meinen beschränkten Kenntnissen? Das Ausschalten erfolgt dann, wenn die Zeit abgelaufen ist. Ich schätze das Entprellen wird nicht notwendig sein, da es sich um eine Lichtschranke (effector OC5208) mit Transistor handelt. Rainer Unsinn schrieb: > Evtl. tut es auch ein Monoflop, ggf. retriggerbar.. (nicht für alles > braucht man einen uC :-) Das kann gut sein dass das reichen würde, aber wie oldmax schon vermutete, werden noch mehrere Funktionen implementiert. :) Ich danke euch nochmals im Voraus für eure schnelle Hilfe. Gruß Christoph
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.