Forum: Mikrocontroller und Digitale Elektronik LED AN/AUS Programm will nicht so recht mit BASCOM


von Bernd (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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


von Karl H. (kbuchegg)


Lesenswert?

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

von Sebastian (Gast)


Lesenswert?

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

von Sebastian (Gast)


Lesenswert?

Ups,
zu langsam geschrieben...

von Johann K. (hansi)


Lesenswert?

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.

von Marco (Gast)


Lesenswert?

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.

von Paul Baumann (Gast)


Lesenswert?

Schreib mal nach der DO-Anweisung : "debounce Pina.0"

Das ist der Befehl zum  Entrpellen.

MfG Paul

von Karl heinz B. (kbucheg)


Lesenswert?

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

von Bernd (Gast)


Lesenswert?

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

von Marco (Gast)


Lesenswert?

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

von Marc M. (bytewood) Benutzerseite


Lesenswert?

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

von Bernd (Gast)


Lesenswert?

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

von Marc M. (bytewood) Benutzerseite


Lesenswert?

@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

von Hannes L. (hannes)


Lesenswert?

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

...

von Marco (Gast)


Lesenswert?

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

von Hannes L. (hannes)


Lesenswert?

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?

...

von Marc M. (bytewood) Benutzerseite


Lesenswert?

@ 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

von Hannes L. (hannes)


Lesenswert?

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

...

von Marc M. (bytewood) Benutzerseite


Lesenswert?

Macht ja nichts, war mein Fehler.

von Marco (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Hannes L. (hannes)


Lesenswert?

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

...

von Hannes L. (hannes)


Lesenswert?

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
Noch kein Account? Hier anmelden.