Forum: Mikrocontroller und Digitale Elektronik Beginner: Taster Frage


von Andreas S. (xevious)


Lesenswert?

Hi!

Ich hab folgendes Programm für eine Lesiesteuerung geschrieben, 
funktioniert soweit, 3 Taster steuern 3 Leds und 2 Ausgänge 
(Led1(Aus),Ausgang1+Led2(Slow), Ausgang2+Led3(Fast)).

Wenn ich aber jetzt schnell den Taster 2 oder 3 auf meinem 
Simulatorboard (Pollin Board- 33kOhm Pulldown) hintereinander drücke 
geht auch manchmal die Led1 an, die ja eigentlich nur angehen sollte, 
wenn man Taster1 drückt.
(In Wahrheit sind das keine Taster zur Steuerung sondern Schalter, 
deshalb die anfängliche Auswertung der Schalterzustände)

Ich kann zwar damit leben, aber wüsste doch gerne warum das so ist.

Anbei der Code (für einen Atmega8, sollte aber auf allen laufen, die 
einen PortD und PortB haben- oder Irre ich mich hier?)






#include <avr/io.h>


int main(){
DDRD=0xFF;//Alle Pins von PortD auf Ausgang
DDRB=0b11111000;//Bit0-2 von PortB auf Eingang
int volatile SCHALTER1, SCHALTER2, SCHALTER3;
SCHALTER1=(PINB & (1<<PINB0));
SCHALTER2=(PINB & (1<<PINB1));
SCHALTER3=(PINB & (1<<PINB2));
AUS();

while(1){
//Wird Schalter gedrückt?
if (SCHALTER1!=(PINB&(1<<PINB0))){
  AUS();
  SCHALTER1=(PINB&(1<<PINB0));//Schalter1 = neue Schalterstellung
  }
if (SCHALTER2!=(PINB&(1<<PINB1))){
  SLOW();
  SCHALTER2=(PINB&(1<<PINB1));//Schalter2 = neue Schalterstellung
  }
if (SCHALTER3!=(PINB&(1<<PINB2))){
  FAST();
  SCHALTER3=(PINB&(1<<PINB2));//Schalter3 = neue Schalterstellung
  }
}
}

AUS(){
  PORTD &= ~(1<<PORTD0);//Ausgang1 ausschalten
  PORTD &= ~(1<<PORTD1);//Ausgang2 ausschalten
  PORTD |= (1<<PORTD2);//LED1 einschalten
  PORTD &= ~(1<<PORTD3);//LED2 auschalten
  PORTD &= ~(1<<PORTD4);//LED3 auschalten
  }

SLOW(){
  PORTD |= (1<<PORTD0);//Ausgang1 einschalten
  PORTD &= ~(1<<PORTD1);//Ausgang2 ausschalten
  PORTD &= ~(1<<PORTD2);//LED1 auschalten
  PORTD |= (1<<PORTD3);//LED2 einschalten
  PORTD &= ~(1<<PORTD4);//LED3 auschalten
  }

FAST(){
  PORTD &= ~(1<<PORTD0);//Ausgang1 ausschalten
  PORTD |= (1<<PORTD1);//Ausgang2 einschalten
  PORTD &= ~(1<<PORTD2);//LED1 auschalten
  PORTD &= ~(1<<PORTD3);//LED2 auschalten
  PORTD |= (1<<PORTD4);//LED3 einschalten
  }



Danke für etwaige Erklärungen!

von Edi (Gast)


Lesenswert?

Wenn Du einen Taster betätigst bzw. die Schalterstellung wechselst, dann 
wird die entsprechende Routine (AUS, SLOW oder FAST) immer aufgerufen, 
egal, ob der Kontakt geschlossen oder geöffnet wird. Ist das so 
beabsichtigt?

Dem Kommentar ("Wird Schalter gedrückt?") und der Beschreibung nach 
möchtest Du die Routine nur dann aufrufen, wenn der Kontakt geschlossen 
wird, aber nicht, wenn er geöffnet wird. Also könnte Deine 
Kontaktabfrage z. B. so ausschauen (hier nur für den ersten Kontakt):
1
if (SCHALTER1!=(PINB&(1<<PINB0))){
2
  if (SCHALTER1) AUS();
3
  SCHALTER1=(PINB&(1<<PINB0));//Schalter1 = neue Schalterstellung
4
  }

von Andreas S. (xevious)


Lesenswert?

Nun, da hab ich mich wohl nicht deutlich genug ausgedrückt.

Das Ganze ist ein Bodenpedal, wo es 3 Schalter gibt (statt Taster- ich 
hatte ursprünglich auch gedacht, das sind einfach 3 Taster).

Das heisst, beim Einschalten des Leslie könnte die Schalterstellung der 
3 Schalter so aussehen:

1.EIN 2.AUS 3.EIN

Das Programm prüft lediglich die Veränderung der jeweiligen Schalter, 
sonst müsste ja bei jedem Umschalten der letzte Schalter wieder auf 
"Aus" gesetzt werden, was natürlich keinen Sinn macht.

Das Programm funktioniert auch.

Die Frage ist nur, warum es seltene Fälle gibt, wo auch die Routine 
"AUS" aufgerufen wird, obwohl nur Schalter2 und Schalter3 gedrückt 
werden.

Das Ganze ist eigentlich kein Problem, da die "AUS"- Led nur hin und 
wieder dazwischen kurz aufleuchtet.

Da ich Anfänger bin, interessieren mich solche Dinge, es könnte ja sein, 
das irgend ein Abfrage Vektor oder sowas ähnliches genau zwischen 
irgendwelche Signale fällt oder ähnliches, vielleicht ist es aber ein 
Problem des Codes.

von Stefan B. (Gast)


Lesenswert?

> vielleicht ist es aber ein Problem des Codes.

Oder der Schalter bzw. davon, dass in deinem Code keine Entprellung 
für die Schalterkontakte vorhanden ist.

von Andreas S. (xevious)


Lesenswert?

Ich denke, damit kanns nicht zu tun haben, weil jeder Schalter ja nur 
mit genau einem bestimmten Eingang verbunden ist, da müsste ja was 
rüberhüpfen sozusagen, was ich nicht glaub, sonst wären ja 
Impulsmessungen kaum möglich oder?

von Stefan B. (Gast)


Lesenswert?

Das Fehlverhalten kann auch bedeuten, dass dein µC in den Reset fällt. 
Beim Reset startet das Programm neu und das heisst bei deinem Code AUS() 
wird ausgeführt und in AUS() wird LED1 angeschaltet. Der Reset beim 
Klimpern auf den Schaltern könnte ich mir durch einen zu großen 
Strombedarf erklären. Der µC fällt dann in den Brownout. Ein 
Schaltplan wäre an der Stelle nicht schlecht. Dann müsste man nicht im 
Trüben fischen.

von Edi R. (edi_r)


Lesenswert?

Irgendwie glaub ich nicht, dass der Controller durch ein schnelles 
Betätigen von Schaltern mit 33 kOhm Pulldown in ein Brownout fällt. Auf 
dem Pollin-Board sind genügend Stützkondensatoren.

Wie das Ganze funktionieren soll, ist mir jetzt klar, und jetzt weiß ich 
auch, dass (und warum) mein Einwand von heute morgen nicht passt. Am 
Code habe ich keine logischen Fehler finden können. Liegt's vielleicht 
doch an der Verdrahtung? Kürzlich habe ich stundenlang nach einem Fehler 
gesucht, weil ich vergessen habe, GND zwischen Controller und LCD zu 
verbinden...

von Peter D. (peda)


Lesenswert?

Edi R. schrieb:
> Irgendwie glaub ich nicht, dass der Controller durch ein schnelles
> Betätigen von Schaltern mit 33 kOhm Pulldown in ein Brownout fällt. Auf
> dem Pollin-Board sind genügend Stützkondensatoren.

Stimmt ja, das Pollin-Board ist für solche Effekte gut bekannt.
Du mußt die Kondensatoren an den Tasten unbedingt auslöten, erst dann 
funktioniert es.
Die bewirken nämlich starke Stromstöße auf der VCC und dann kann der MC 
spinnen.


Peter

von Andreas S. (xevious)


Lesenswert?

Ah danke, werd ich mal auslöten, so zum probieren. Das mit dem Reset 
wäre ein sehr guter Grund.

edit: Ich hab jetzt wie wild dran herumgedrückt, es geht jetzt- ohne 
Kondensatoren!!

Wow kann ich nur sagen und Danke für den Tip!

Wozu sind die überhaupt drin? Als Entprellung? Eine echte Fehlerquelle.

von Kalle (Gast)


Lesenswert?

Kann man diese Stromstöße nicht durch geeignete Kondensatoren am 
Versorgungseingang des µC ausbügeln?
Liegt das Problem nur am Design des Pollinboards?

Ich habe zwar kein Pollinboard nutze aber auch häufig die 
hardwareentprellung per Folienkondensator und möchte da keinen 
generellen Fehler machen.

von Peter D. (peda)


Lesenswert?

Kalle schrieb:
> Kann man diese Stromstöße nicht durch geeignete Kondensatoren am
> Versorgungseingang des µC ausbügeln?

Nehmen wir mal an, für den ESR des Kondis, für die Leiterzüge und die 
Taste je 0,1 Ohm, dann fließt beim Drücken ein 17A-Impuls!

Statt gegen die Wirkung zu kämpfen, ist es wesentlich schlauer, die 
Ursache zu beseitigen, also solche hohen Ströme erst garnicht zur 
erzeugen.

Eine Softwareentprellung ist deutlich bequemer und leistungsfähiger, 
also sind die Kondis überflüssig.

> Liegt das Problem nur am Design des Pollinboards?

Kondis an mechanischen Kontakten ohne Widerstand in Reihe sind immer ein 
Designfehler.


Peter

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.