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.
> 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.
...