Forum: Mikrocontroller und Digitale Elektronik LED bleibt nicht an, Wieso nicht? BASCOM


von Bernd (Gast)


Lesenswert?

Hallo,
Mit folgendem eifnachen Programm soll bei Tasten Druck (Pin.0 = 0) eine 
LED eingeschaltet werden, und solange leuchten bis sie durch einen 
Erneuten tastendruck wieder ausgeht.
Genauer geht es darum den Wert Variable Zustand auf 1 bzw. 0 zu setzn.
Hinterher soll nämlich mehr Leuchten als nur die LED:

Ddra = &B0000010
Porta = &B0000011
Dim Zustand As Bit
Zustand = 0

Do

 If Pina.0 = 0 Then


               If Zustand = 0 Then

                              Zustand = 1
               Else

               End If
 Else
 Zustand = 0

 End If


 If Zustand = 1 Then
               Porta.1 = 1

               Else
                Porta.1 = 0

End If


Loop
End


Problem: Die LED leuchtet nur wenn ich den Taster Gedrückt halte. Sie 
bleibt nicht an. Warum auch immer, Zustand scheint sich bei jedem 
Programm durchlauf wieder auf 0 zu setzten.

Kann mir jemand sagen wieso die Variable nicht auf 1 bleibt?

Gruss

Alex

von Werner A. (homebrew)


Lesenswert?

Wieso, steht doch auch da (vereinfacht)

Wenn Taste dann
   Ausgang=1
sonst
   Ausgang=0

setzte Ausgang.

ich denke, du willst eher sowas machen
Wenn Taste dann
   Wenn nicht Ausgang=1 dann
       Ausgang=1
   sonst
       Ausgang=0

setzte Ausgang

Werner

von Stone (Gast)


Lesenswert?

Erstmal kann man des von 13 zeilen auf 3 kürzen

If Pina.0 = 0 Then
toggle Porta.1 = 0
End If

danach würd ich ein wartezeit einbauen sonst prüft er xmal in der 
sekunde ob der taster 1 oder 0 ist

z.B.
If Pina.0 = 0 Then
toggle Porta.1 = 0
waitms 500       -----> dann wartet er ne halbe Sekunde bis er weiter 
macht
End If

Probiers mal aus

MfG Matthias

von Stone (Gast)


Lesenswert?

Erstmal kann man des von 13 zeilen auf 3 kürzen

If Pina.0 = 0 Then
toggle Porta.1 = 0
End If

danach würd ich ein wartezeit einbauen sonst prüft er xmal in der 
sekunde ob der taster 1 oder 0 ist (bei dir hat er warscheinlich immer 
auf 1 aufgehört)

z.B.
If Pina.0 = 0 Then
toggle Porta.1 = 0
waitms 500       -----> dann wartet er ne halbe Sekunde bis er weiter 
macht
End If

Probiers mal aus

MfG Matthias

von Karl H. (kbuchegg)


Lesenswert?

Dürfte ich mal vorschlagen, dass du im Geiste Computer
spielst. So kommt man nämlich logischen Problemen auf
die Schliche.

Also: Du bist jetzt der Computer und ich zünde mal eine
Zigarette an. Bist du hoch? Ja? Gut!

Also. Der Taster ist nicht gedrückt und du arbeitest mal
dein Pgm ab:

Ddra = &B0000010
Porta = &B0000011
Dim Zustand As Bit
Zustand = 0

Also: Die Initialisierung ist erfolgt und Zustand hat den Wert 0.

Do

also eine Schleife.

 If Pina.0 = 0 Then

Wie ist der Status von Pina.0? Der Taster ist nicht gedrückt.
also ist Pina.0 gleich 1, dieser if wird also nicht genommen,
stattdessen kommt der else Zweig drann:

 Else
 Zustand = 0

Aha. Zustand wird auf 0 gesetzt.

 End If

Wie gehts weiter

 If Zustand = 1 Then

Zustand ist nicht gleich 1, sondern 0, also wieder der else

                Porta.1 = 0

Porta.1 auf 0 heist wohl: Led aus

End If
Loop
End

und weiter gehts mit der nächsten Runde in der Schleife. Jetzt
drücken wir mal in Gedanken die Taste. Am Pin ist dann eine 0 zu
sehen.

Do

 If Pina.0 = 0 Then

das trifft jetzt zu also wird der then Zweig ausgeführt:

               If Zustand = 0 Then

Der Inhalt von Zustand war 0 also wird dieser if genommen, und

                              Zustand = 1
Zustand auf 1 gesetzt.
Das wars mit dem if, der ist beendet und ebenso der äussere if.
Weiter gehts.

 If Zustand = 1 Then

Das trifft ja wohl zu, also

               Porta.1 = 1

damit wird dann wohl die Led eingeschaltet.

End If
Loop
End

und die nächste Runde in der Schleife. Die Annahme lautet jetzt,
die Taste wird wieder losgelassen. Am Pina.0 taucht also wieder
eine 1 auf:

 If Pina.0 = 0 Then

das ist also nicht der Fall, es kommt wieder das else zum Zuge:

 Else
 Zustand = 0

und dort wird Zustand wieder auf 0 gesetzt.

 If Zustand = 1 Then

ist nicht der Fall ...

               Else
                Porta.1 = 0

und damit wird die Led wieder ausgeschaltet.

Da haben wirs also. Das was du programmiert hast, schaltet
die Led aus (indem Zustand auf 0 gesetzt wird), sobald die
Taste nicht gedrückt ist.

Damit man das Ganze besser sieht, solltest du dringend anfangen,
den Kraut und Rüben Programmierstil aufzugeben und dein Programm
sauber eingerückt zu schreiben. Nichts gegen Leerzeichen, aber
eine Unmenge von Leerzeilen schadet eher als sie nützen.

Ddra = &B0000010
Porta = &B0000011
Dim Zustand As Bit
Zustand = 0

Do
  If Pina.0 = 0 Then

    If Zustand = 0 Then
      Zustand = 1
    Else
    End If

  Else
    Zustand = 0
  End If

  If Zustand = 1 Then
    Porta.1 = 1
  Else
    Porta.1 = 0
  End If
Loop

End

Jetzt sieht man auch sehr schön, dass das setzen von Zustand
auf 0 nur von einer einzigen Bedingung abhängt: Der Taster
darf nicht gedrückt sein.
Da wirst du wohl noch etwas an deiner Programmlogik arbeiten
müssen.

von Karl H. (kbuchegg)


Lesenswert?

Im übrigen.
Hatten wir nocht exakt das gleiche Problem vor ein
paar Tagen? Sogar die Variablennamen waren identisch.

von Bernd (Gast)


Lesenswert?

Hallo,
Ja, ich hatte das schonmal reingestellt.
Da dachte ich, es würde funktionieren.
Dabei ging es nur wenn ich einen Port getoggelt habe, sobald ich in 
Abhängigkeit von der Variable etwas schalten wollte gings nicht.

@Karl Heinz:

Ich werds mir noch mal in ruhe anschauen!

Gruss

Alex

von Bernd (Gast)


Lesenswert?

@ Karl Heinz

Stimmt, das Zustand = 0 im Else Zweig setzt bei jedem Durchlauf wo der 
Taster nicht gedrückt ist die Variable wieder auf Null. Da hätte ich 
selber drauf kommen können...

Jetzt habe ich es so gemacht, dass nur was beim Tastendruck passiert:

If Pina.0 = 0 Then
              If Zustand = 0 Then
                             Zustand = 1
              Else
              Zustand = 0
              End If
End If

Jetzt müsste beim Drücken die Variable immer von eins nach null bzw von 
null nach eins wechseln.
Das tut sie auch.
Beim Gedrückt halten Wechselt der Wert dann allerdings  mit 1Mhz.
Das ist praktisch wie eine PWM, die LED leuchtet nur schwach.

Wie könnte ich dem Entgegen wirken?

Gruss

Alex


von Ludwig W. (lordludwig)


Lesenswert?

wurde oben schon gesagt:

>waitms 500       -----> dann wartet er ne halbe Sekunde bis er weiter

von Karl H. (kbuchegg)


Lesenswert?

> Wie könnte ich dem Entgegen wirken?

Such dir nochmal den alten Thread raus.
Wenn ich mich recht erinnere, wurde das dort auch
besprochen.

> wurde oben schon gesagt:
>> waitms 500       -----> dann wartet er ne halbe Sekunde bis er weiter

Und wenn ich länger als eine halbe Sekunde auf die Taste drücke,
taucht der Fehler wieder auf. Ergo: Du hast den Fehler nicht
gelöst, sondern nur in bestimmten Fällen kaschiert. Warten
löst selten Probleme. Vor allen dann nicht, wenn es um
externe Ereignisse wie Tastendrücke geht. Das ganze ist sehr
einfach zu lösen. Alles was man tun muss ist: nicht auf
den Tastenpegel gehen, sondern die Pegelflanke rausfischen.
Dazu muss man lediglich den jetzigen Zustand des Tasters mit
dem Zustand des Tasters in der vorhergehenden Runde durch die
Schleife vergleichen. Ändert sich der, dann hat man die
Flanke (also den Zeitpunkt des Umschaltens) gefunden.


von Karl H. (kbuchegg)


Lesenswert?

> Da dachte ich, es würde funktionieren.
> Dabei ging es nur wenn ich einen Port getoggelt habe, sobald ich in
> Abhängigkeit von der Variable etwas schalten wollte gings nicht.

Dann haben wir versagt, denn du hast das Prinzip nicht verstanden.

Dabei ist es simpel:

In der Schleife vergleichst du den Tasterwert vom Port mit
dem Tasterwert vom Port vom vorhergehenden Schleifendurchlauf
(wie schreibt man in BASCOM 'ungleich'? Keine Ahnung, ich nehme
mal einfach <> dafür)


  Vorher = 1

  do
    Jetzt = Pina.0
    if Jetzt <> Vorher then

       ....

    endif
    Vorher = Jetzt
  Loop

Dadurch wird der 'then' Zweig nur dann betreten, wenn sich am
Port was verändert, sprich wenn der Taster entweder gedrückt
oder losgelassen wird. Solange an den Port nichts passiert wird
die Schleife durchlaufen und der if findet in Vorher immer denselben
Wert wie in Jetzt. Das kann entweder 0 oder 1 sein, je nachdem
ob der Taster gedrückt ist oder ob er losgelassen wurde. Beide
Fälle interessieren uns nicht. Was uns interessiert ist der
eigentliche Vorgang des Niederdrückens. Vorher ist zu diesem
Zeitpunkt noch 1 (weil ja der Taster noch nicht gedrückt war)
und bei der nächsten Abfrage ist er plötzlich 0 (weil der Taster
jetzt gedrückt ist). 'Vorher' ist also ungleich 'Jetzt' und das
ist der Auslöser, dass sich genau in diesem Moment der Zustand des
Tasters verändert hat. Wir wissen noch nicht wie, ist der Taster
jetzt gedrückt worden oder ist er losgelassen worden. Aber eines
von beiden ist passiert. Welches da jetzt passiert ist, verrät
uns der jetzige Zustand des Tasters. Ist der 0, dann ist die
Taste gedrückt worden. Ist er 1, dann wurde die Taste losgelassen.

  Vorher = 1

  do
    Jetzt = Pina.0
    if Jetzt <> Vorher then

       if Jetzt = 0 then
         .... Taste wurde gedrückt
       else
         .... Taste wurde losgelassen
       endif

    endif
    Vorher = Jetzt
  Loop

Das ist deine Grundstruktur. Was du bei den einzelnen Fällen
dann machst, welche Aktionen das Niederdrücken bzw. Loslassen
auslöst, ist eine ganz andere Geschichte.

von ------------- (Gast)


Lesenswert?

Hatte keine Lust zu lesen, ob du schon eine Lösung hast:


dim a as Bit

do
if Pina.0 = 1 then
if a=0 then
a=1
Porta.1=1
end if
end if
if Pina.0 = 0 then
if a=1 then
a=0
Porta.1=0
end if
end if
loop




von Besucher (Gast)


Lesenswert?

Eine fertige Lösung zu schreiben bringt den Fragesteller nicht weiter, 
am besten ist es, wenn er selber auf die Lösung kommt.
Aber das ist ja das Problem von Basic Usern, die haben keine Lust zu 
lesen...

Gruß Sebastian

von ------------- (Gast)


Lesenswert?

ich dachte an einer fertigen lösung könnte der Fragensteller die Lösung 
herleiten.
Das Problem bei dem Programm ist ja dass die Led bei jedem Zyklus ein 
geschaltet wird, dadurch leuchtet sie bei Bascom immer nur ganz schwach. 
dadurch, dass überwacht wird, ob die Led berreits angeschaltet ist, trit 
dieser Effekt nicht auf. dass wird ja dadurch realisiert, indem man vor 
dem Einschalten überprüft wird, ob die Led an ist. A ist also der 
Zustand der LED.

von ------------- (Gast)


Angehängte Dateien:

Lesenswert?

vergesst was ich geschrieben habe, das war das ganz falsche Programm

richtiges siehe anhang



bei deinem programm ist das Problem ja, dass sobald der Taster 
losgelassen wir der Zustand durch das else auf 0 geht

ich hoffe du kannst an meinem Progamm den fehler an deinem 
identifizieren ist warscheinlich viel zu lang aber egal

von ------------- (Gast)


Angehängte Dateien:

Lesenswert?

natürlich meine ich das ist das richtige

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.