allo, Ich habe zum Testen mal ein Programm für mein ATMega16 geschrieben: Code: Ddra = &B0000010 Porta = &B0000001 Dim Zustand As Bit Zustand = 0 Do If Pina.0 = 0 Then 'Wenn Taster gedrückt den Zustand Invertieren Toggle Zustand End If If Zustand = 1 Then 'Wenn Zustand = 1 LED an, ansonsten LED aus Porta.1 = 1 Else Porta.1 = 0 End If Loop Das Programm soll die LED mit nach Tastendruck so lange zum leuchten Bringen bis ein erneuter Tastendruck erfolgt. Funktioniert soweit auch, allerdings sehr schlecht, da: -Die LED beim gedrücktgehaltenen Taster dunkel leuchtet - Das ganze nur manchmal funktioniert weil die LED nach dem Tastendruck wieder ausgeht. -Die LED beim ein und aus gehen den Anschein erweckt als sei sie mit einer PWM gedimmt, die geht also nicht sofort aus bzw an. Hat jemand ne Ahnung wieso das nicht richtig funktioniert? Gibt es vielleicht irgendwo ein fertiges "Memory Programm"?? Im Voraus bedankt sich, Alex
> Hat jemand ne Ahnung wieso das nicht richtig funktioniert?
Das was du hier beschréibst, klingt ganz nach einem 'prellenden
Taster':
Ein Taster ist einfach nur eine Kontaktfeder, die an einen 2. Kontakt
gepresst wird. Nun ist es aber nicht so, dass der Kontakt einfach
nur hergestellt wird und fertig. Die Kontaktfeder wird ein bischen
schwingen und kurzzeitig den Kontakt herstellen/unterbrechen/herstellen
/unterbrechen. Erst nach kurzer Zeit ist dann der Kontakt tatsächlich
dauerhaft hergestellt. Nur ist dein Pgm halt schnell genug, dass
es diese Kurzen Kontaktunterbrechungen beim Drücken eines Tasters,
eben das sog. 'Prellen' mitbekommt.
> Die LED beim gedrücktgehaltenen Taster dunkel leuchtet
Das ist klar. Bei gedrücktem Taster liest dein Pgm bei
jedem Schleifendurchlauf den Tasterzustand als 0 ein.
Als Folge davon, wird jedesmal die Bitvariable Zustand
getoggelt und als Folge davon die Led bei jedem Schleifen-
durchlauf ein und beim nächsten wieder ausgeschaltet.
Was du erreichen möchtest ist: Du möchtest den Wechsel des
Tasters von 1 auf 0 erkennen und nur dann die Variable
Zustand auf jeweils den anderen Wert bringen.
Dazu brauchst du noch eine Variable die den Zustand des Tasters
beim letzten Schleifendurchlauf repräsentiert. Nur dann wenn
diese Variable eine 1 enthält und Pina.0 tatsächlich 0 ist,
dann hast du das Drücken des Tasters selbst erfasst und
schaltest die Led um
Vorher = 1
Do
if Pina.0 = 0 and Vorher = 1 then
...
endif
Vorher = Pina.0
loop
So ungefähr. Ich kenne die Details von BASCOM nicht.
sonst mußt Du Dir noch eine Hilfsvariable erstellen, wo Du Dir merkst, ob die Taste losgelassen wurde. Ich kenne zwar Basic nicht, aber überlegmal was passiert, wenn Du den Taster gedrückt hälst. Die LED wird ein und ausgeschaltet und zwar ziemlich schnell, davon kommt diese Dimmfunktion. Du mußt Dir irgendwelche Hilfsvariable definieren, die sich merkt, ob die Taste losgelassen wurde oder nicht etwa so: if (!(tastenport & (1<<TASTE))) { if (!status_taste){ event = 1; status_taste = 1; } } else status_taste = 0; Es macht sich am besten in einem Timeroverflow Interrupt, um das Problem, was Karl-Heinz angesprochen hat umzugehen. Gruß Sebastian
Ich kenne weder Bascom, noch habe ich bisher einen AVR programmiert. Betrachte ich dein Programm aber mit meine C-Kenntnissen muss ich sagen (pardon, schreiben), dass es ein Klasse Lottozahlengenerator ist. Leider kennt er nur die beiden Zahlen 0 und 1. Innerhalb deiner do/while fragst du den Zustand der Taste ab. Ist die Taste 0, dann toggle den Zustand. Danach gib den Zustand an die LED aus. Das Ergebnis: - Wenn die Taste 0, dann PWM-Generator mit 50% DytyCycle. Du togglest ja bei jedem Druchgang. - Wenn die Taste von 0 nach 1 wechselt ist es Glückssache, wo dann gerade dein Programmcounter steht und im Normalfall bleibt dein Zustand auf dem letzten Toggle-Ergebnis stehen. Wie Karl Heinz Buchegger schreibt, musst du dir den vorherigen Zustand der Taste merken, damit du nur auf die Schaltflanke 1 nach 0 ein einziges Mal reagierts! Das mit dem Tastenprellen ist aber dann noch so ein Problem. Deshalb setze ich für die eindeutige Flankenerkennung auch noch einen Zähler, der nach ca 10ms nochmal nachschaut, ob die Taste jetzt wirklich von 1 nach 0 gewechselt hat. Dieser Zähler wird von mir jedesmal wieder auf 0 gesetzt, wenn während des Zählens in der do/while eine 1 von der Taste eingelesen wird. Das selbe Spiel mache ich nochmal für den Wechsel von 0 nach 1. Erst danach ist die Taste für die nächste Flankensuche 1 nach 0 wieder freigegeben. Es lebe die Hysterese; in diesem Fall über die Zeit. Du brauchst für einen vollen Erkennungszyklus 20ms; aber was ist schon dieser Zeitverlust im Vergleich zur Funktion.
Do If Pina.0 = 0 Then Toggle Zustand Waitms 50 'zum entprellen If Zustand = 1 Then Porta.1 = 1 Else Porta.1 = 0 End If Loop PS: http://www.rowalt.de/mc/index.htm Da wird das entprellen auch behandelt PSS: Ich habe die anderen Beiträge, die damit anfingen, das die Bascom nicht kennen, nicht weitergelesen. Sorry, nichts gegen die Verfasser, aber ich sah den Sinn nicht alles zu lesen wenn die Antwort schneller geschrieben ist. Ich denke aber, das die Inhalte sinnvoll waren und das Prinzip des prellen ausführlich und verständlich behandelt haben.
Schreib mal nach der DO-Anweisung : "debounce Pina.0" Das ist der Befehl zum Entrpellen. MfG Paul
> die damit anfingen, das die Bascom > nicht kennen, nicht weitergelesen. Das hättest du mal tun sollen. > If Pina.0 = 0 Then Toggle Zustand Dein Pgm hat das gleiche Problem: Solange die Taste gedrückt ist, toggelt der Ausgangsport wie verrückt.
Hallo, Danke für eure Hilfe, folgendes Programm klappt jetzt: Ddra = &B0000010 Porta = &B0000011 Dim Zustand As Bit Dim Vorher As Bit Debounce Pina.0 , 1 , Label Debounce Pina.0 , 0 , Label Config Debounce = 25 Porta.1 = 0 Zustand = 0 Label: Do If Pina.0 = 0 Then If Zustand = 0 Then Toggle Porta.1 Zustand = 1 End If Else Zustand = 0 End If Loop End Kann mir jemand sagen wieso ich dieses Label brauche? Gruss Alex
>> die damit anfingen, das die Bascom >> nicht kennen, nicht weitergelesen. > >Das hättest du mal tun sollen. > >> If Pina.0 = 0 Then Toggle Zustand > >Dein Pgm hat das gleiche Problem: >Solange die Taste gedrückt ist, toggelt der >Ausgangsport wie verrückt Im Anfangsbeitrag stand ja auch nicht, was die Lösung können soll. Dann wird halt ein INT gebraucht um es zu programmieren. Oder die Entprellzeit anpassen. Mehr als 100mal in der Sekunde schafft es der Mensch auch nicht den Taster zu drücken. Irgendwo muss die Kirche auch mal im Dorf bleiben. Das Label brauchstdu in diesem Fall nicht. Es dient dazu, bei großeren Programmen an eine andere Stelle zu springen.
@Bernd Ich denke Dein Problem lag nicht am Debounce, sondern am Ddra = &B0000010 Porta = &B0000011 Im ersten Post hast Du Ddra = &B0000010 Porta = &B0000001 Lass doch mal die Debounce-Geschichte weg und es müsste trotzdem funktionieren.
Hallo, Ja, es geht auch ohne Debounce, kostet nur Speicherplatz. Das Programm ist schon 700 Bytes groß, wie soll das später auf ein 1kb Tiny draufpassen wenn das Programm für die Blinklichter noch dazu kommt? Gruss Alex
@Bernd Unter den Compilereinstellungen hast Du noch die Option den Code optimiert zu komilieren. Das bringt ein bischen was, dauert nur länger zum kompilieren. Ich habe kürzlich ein Platinchen zum Dimmen mehrerer LEDs auf der Basis eines Tiny13 gebaut, das Prog mit Bascom geschrieben (6 LEDs werden über PWM gedimmt, der über den Timer0 erzeugt wird, 2 Taster für rauf bis max, runter bis aus und 2/3 Helligkeit). Ohne Optimierung 63% Mit optimierung 52% Ich finde die Optimierung bringt schon was, oder mein Code ist so schlecht :-) So Long
Marc Meise wrote: > Ich habe kürzlich ein Platinchen zum Dimmen mehrerer LEDs auf der Basis > eines Tiny13 gebaut, das Prog mit Bascom geschrieben (6 LEDs werden über > PWM gedimmt, der über den Timer0 erzeugt wird, 2 Taster für rauf bis > max, runter bis aus und 2/3 Helligkeit). 6 LEDs und 2 Taster? Hat der Tiny13 unter BASCOM denn mehr I/O-Pins? Unter ASM kann ich leider nur 5 I/O-Pins nutzen, wenn ich mir ISP nicht verbauen möchte... ...
>Unter ASM kann ich leider nur 5 I/O-Pins nutzen, wenn ich mir ISP nicht >verbauen möchte... Man kann ja auch ISP-Pins parallel mit Funktionen belegen. 6 LEDs und 2 Taster sind ja auch nur drei Pins.
Marco wrote: >>Unter ASM kann ich leider nur 5 I/O-Pins nutzen, wenn ich mir ISP nicht >>verbauen möchte... > > Man kann ja auch ISP-Pins parallel mit Funktionen belegen. Mit ISP verbauen meinte ich nicht, dass die ISP-Pins tabu sind, sondern dass der Reset-Pin nicht zum I/O-Pin umgefust wird. Somit hat der Tiny13 5 nutzbare I/O-Pins. > > 6 LEDs und 2 Taster sind ja auch nur drei Pins. Nunja, die Taster lassen sich mit auf die LED-Anschlüsse legen, das ist kein Problem. Aber unter "6 LEDs mit PWM" verstehe ich, dass jede LED einzeln im Tastgrad (von 0 bis 100%) steuerbar ist, und dazu bräuchte jede LED schon ihren eigenen I/O-Pin, oder? ...
@ Hannes Sorry, habe mich nicht präzise genug ausgedrückt: Portpin-----[R]---Transi (Open Collector)---> dimmt 6 LEDs gleichzeitig. Passt auch zum Thread: Ist quasi LED AN/AUS nur etwas schneller und gesteuert :-) Und ein passender Witz dazu: Wie nennt man ein Glühwürmchen, das an Viagr* gelutscht hat? ---> Stehlampe :-) So long
Marc Meise wrote: > Portpin-----[R]---Transi (Open Collector)---> dimmt 6 LEDs gleichzeitig. Das ist natürlich etwas ganz Anderes. Das betrachte ich als eine LED bzw. als eine PWM, auch wenn da über einen entsprechend großen Transistor hunderte LEDs dran hängen würden. Dafür würde man in ASM weniger als 15% des Speichers brauchen und weniger als 15% der verfügbaren Rechenzeit. Und wenn's nur eine PWM ist, kann man die auch noch in Hardware machen, dann wirds noch einfacher. > Passt auch zum Thread: > Ist quasi LED AN/AUS nur etwas schneller und gesteuert :-) Genau. Nur ging ich nicht von 1 Kanal aus, sondern von 6 Kanälen. ;-) Somit ziehe ich meine Frage bezüglich der nutzbaren Portpins zurück... ;-) ...
Ich dachte zuerst ja auch 6 einzelne LEDs. Dann habe ich das mal überschlagen. 6 für LEDs, 2 für die Taster, 2 für Vcc und GND, macht 10. Und das geht ja nicht. Also blieb noch Plan B, alle LEDs auf einmal blinken lassen. Aber bei deiner Beschreibung habe ich nicht dran gedacht, das bei 5 ja auch nur noch Reset nicht genutzt wird.
Prinzipiell würden auch 3 Pins schon reichen. Und das bei beliebig (na ja) vielen Leds. Das Zauberwort heist Schieberegister. Baue grade sowas auf: Ein Mega8 steuert per Software PWM 64 Leds.
Marco wrote: > Ich dachte zuerst ja auch 6 einzelne LEDs. Dann habe ich das mal > überschlagen. 6 für LEDs, 2 für die Taster, 2 für Vcc und GND, macht 10. Naja, die Taster lassen sich über Widerstände im Kiloohm-Bereich parallel zu den LEDs schalten und in der PWM-Pause gegen den internen PullUp abfragen. Die dazu erforderliche PWM-Pause beträgt nur wenige Takte, bei Software-PWM ist das also kein Problem. Aber 6 PWM-Kanäle hätten eben 6 Portpins erfordert. Und das hätte den (bei den meisten AVRs nur eingeschränkt nutzbaren) Reset-Pin gekostet. > Und das geht ja nicht. Also blieb noch Plan B, alle LEDs auf einmal > blinken lassen. Also 4 unabhängige PWMs mit 5 Tastern (4 für Kanal, einer für hoch/runter) wäre machbar. > > Aber bei deiner Beschreibung habe ich nicht dran gedacht, das bei 5 ja > auch nur noch Reset nicht genutzt wird. Das macht nix... ...
Karl heinz Buchegger wrote: > Prinzipiell würden auch 3 Pins schon reichen. Und das > bei beliebig (na ja) vielen Leds. Das Zauberwort heist > Schieberegister. > > Baue grade sowas auf: Ein Mega8 steuert per Software PWM > 64 Leds. Richtig... Da dies aber die Platine verkompliziert, nutze ich die nur, wenn es wirklich sein muss. Bei 32 Tastern und 32 Relais (in einem aktuellen Projekt) nutze ich natürlich auch Schieberegister (auf separaten Platinen zusammen mit den ULN2803 bzw. der Eingangsschutzbeschaltung), aber für ein paar Taster und LEDs an PWM nehme ich lieber einen AVR mit mehr I/Os. ...
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.