Forum: Mikrocontroller und Digitale Elektronik Arduino mit 2 Taster & 1 LED


von Elias H. (eliashu)


Angehängte Dateien:

Lesenswert?

Hallo,

habe begonnen mit einem Arduino, 2 Taster mit je einem 1kOhm Pullup die 
interne LED anzusteuern. Leider funktioniert nur der eine Taster 
ordentlich. Der 2. Taster schaltet die LED an aber lässt sie erst nach 
2-3sek. wieder aus gehen. Ich habe schon einige andere Schleifen 
ausgeführt aber das Ergebnis ist immer das selbe.

void setup()
  {
    PORTD = (0<<PD2); // pullup=off
    DDRD = (0<<DDD2); // schaltet IO | 0= input
    PORTD = (0<<PD3); // pullup=off
    DDRD = (0<<DDD3); // schaltet IO | 0= input
    DDRB = (1<<DDB5); // schaltet LED-Pin auf output
  }

void loop()
  {
    ledschalter();
  }

void ledschalter ()
{
  if ((PIND & (1<<PIND2)) || (PIND & (1<<PIND3)))
  {
    PORTB = (1<<PB5); // schalte Led an
  }
  else
  {
    PORTB = (0<<PB5); // schalte Led aus
  }
  return 0;
}

von H.Joachim S. (crazyhorse)


Lesenswert?

Das Foto vom Gewirr soll den Schaltplan ersetzen?
Ausserdem solltest du an deinem Verständnis der Bitmanipulationen 
arbeiten.
Einiges davon tut nicht das, was du von deinem Code erwartest.

von K. S. (the_yrr)


Lesenswert?

Elias H. schrieb:
> h. Der 2. Taster schaltet die LED an aber lässt sie erst nach
> 2-3sek. wieder aus gehen. Ich habe schon einige andere Schleifen
> ausgeführt aber das Ergebnis ist immer das selbe.

Der Code ist zwar nicht schön aber funktioniert, daher tausch/überprüfe 
mal die Teile am Taster, ich tippe darauf dass der Pull up/down 
Widerstand oder ein Draht dazu nen Wackler hat, dann (ent)lädt sich die 
Kapazität des Eingangspins nur sehr langsam da der Pin ohne tastendruck 
floatend ist.

zum Code:

Elias H. schrieb:
> PORTD = (0<<PD2); // pullup=off
>     DDRD = (0<<DDD2); // schaltet IO | 0= input
>     PORTD = (0<<PD3); // pullup=off
>     DDRD = (0<<DDD3); // schaltet IO | 0= input
>     DDRB = (1<<DDB5); // schaltet LED-Pin auf output
das macht man so nicht, du überschreibst PORTD und DDRD. da du nur 0 mit 
0 überschreibst ist es nicht schlimm. aber jedes Register wird nur 
einmal Initialisiert (oder erst gelesen, und dann nur verändert was muss 
und der Rest wieder original zurückgeschrieben). so gehts richtig:
PORTD = (0<<PD2) | (0<PD3);
oder:
PORTD = (0<<PD2);
PORTD |= (0<PD3); // das ist die Kurzform von PORTD = PORTD | (0<PD3);
was du aber auch komplett weglassen kannst, da die Register mit 0 
initialisiert sind.

> if ((PIND & (1<<PIND2)) || (PIND & (1<<PIND3)))
kann, muss aber nicht: if (PIND & ((1<<PIND2) | (1<<PIND3)))

>     PORTB = (1<<PB5); // schalte Led an
überschreibt alles andere auf PORTB (hier zum glück nichts), richtig 
wäre:
PORTB |= (1<<PB5); // PORTB gleich PORTB oder PB5

>     PORTB = (0<<PB5); // schalte Led aus
überschreibt wieder alle anderen Pins, richtig entsprechend:
PORTB &= ~(1<<PB5); // PORTB gleich PORTB und (nicht PB5)

später willst du irgendwann die Taster entprellen, das wird ein Problem 
wenn du auf einmal viele Tastendrücke im Prgramm erkennst wenn du in 
echt nur einmal drückst, hier wäre das aber etwas zu weit gegriffen.

von zitter_ned_aso (Gast)


Lesenswert?

Elias H. schrieb:
> void ledschalter ()
> {
>   if ((PIND & (1<<PIND2)) || (PIND & (1<<PIND3)))
>   {
>     PORTB = (1<<PB5); // schalte Led an
>   }
>   else
>   {
>     PORTB = (0<<PB5); // schalte Led aus
>   }
>   return 0;

fehlt da nicht eine geschweifte Klammer vor "return"?

von Frank L. (hermastersvoice)


Lesenswert?

der Widerstand vom rechten Taster hängt in der Luft

von K. S. (the_yrr)


Lesenswert?

zitter_ned_aso schrieb:
> fehlt da nicht eine geschweifte Klammer vor "return"?

nö, das ist eine Funktion, da gehört ein return ans Ende und die 
entsprechende Klammer ist auc hdahinter

Frank L. schrieb:
> der Widerstand vom rechten Taster hängt in der Luft
Sicher? für mich sah das so aus als ob der nen Knick im draht hat kurz 
über dem Steckbrett, aber das würde den Fehler erklären. Eventuell sitzt 
auch der Taster nicht richtig, die haben etwas zu kurze Beine für ein 
Steckbrett.

von zitter_ned_aso (Gast)


Lesenswert?

nein, der Widerstand sitzt richtig.

Strg und +  liefern den Beweis ;-)

von K. S. (the_yrr)


Lesenswert?

zitter_ned_aso schrieb:
> nein, der Widerstand sitzt richtig.

dann hab ichs doch richtig gesehen.

Wenn du das rote und gelbe kabel von den Tastern zum Arduino direkt am 
Arduino selber tauscht (also wenn rot PIND2 war dann wird es PIND3 usw.) 
und das Problem dann beim selben Taster bleibt, dann ist der Fehler wie 
schon gesagt im Aufbau, da wird irgendwo ein Wackler sitzten sodass der 
PullDown Widerstand getrennt ist. (eher als Tipp wie man das testet, 
falls der Arduino nicht defekt ist liegts 99,9% sicher am 
Taster/Beschaltung, bei Steckbrett passiert sowas mal)

von zitter_ned_aso (Gast)


Lesenswert?

Aber muss man nicht bei diesem Steckbrett GND und Versorgungsspannung 
mit Hilfe von Drahtbrücken weiterführen?

Bei mir gibt es da nur eine Verbindung von oben/unten bis zur Mitte 
(Zeichen W auf den Steckbrett). Aber nicht von oben bis nach ganz unten.

von K. S. (the_yrr)


Lesenswert?

zitter_ned_aso schrieb:
> Bei mir gibt es da nur eine Verbindung von oben/unten bis zur Mitte
> (Zeichen W auf den Steckbrett). Aber nicht von oben bis nach ganz unten.

das kann gut sein, bei meinen sind die alle durchgängig verbunden, würde 
aber Sinn ergeben, denn sowohl Code als auch Aufbau sind ansonsten zwar 
nicht schön aber auch nicht falsch. und dann hängt auch wirklich nur der 
eine Widerstand in der Luft, dadurch hat der linke Taster den Fehler 
(wäre gut zu Wissen gewesen, genauso wie dass es 1kOhm Pulldowns sind 
und nicht wie fälschlicherweise geschrieben Pullups).

von zitter_ned_aso (Gast)


Angehängte Dateien:

Lesenswert?

Messe mit dem Multimeter nach, ob da die 5V ankommen oder nicht.

(oder stecke den äußeren linken roten Draht nach unten um, zu dem 
anderen blauen(?!) Draht um.

Auf dem Bild habe ich die Drahtbrücken eingezeichnet, die ich oben 
gemeint habe.

von zitter_ned_aso (Gast)


Lesenswert?

zitter_ned_aso schrieb:
> Auf dem Bild habe ich


ja, die Farben habe ich natürlich vertauscht :(  Wenn du rote Drähte 
schon hast, dann solltest du sie lieber zur Spannungsversorgung nehmen. 
Und nicht für die GND-Verbindung.

von K. S. (the_yrr)


Lesenswert?

zitter_ned_aso schrieb:
> ja, die Farben habe ich natürlich vertauscht

sollten passen, gedrückte Taster = VCC (=PINDx high), damit sind das 
Pull Down Widerstände nach GND. Zumindest wenn der Code sonst stimmt.


zitter_ned_aso schrieb:
> Wenn du rote Drähte
> schon hast, dann solltest du sie lieber zur Spannungsversorgung nehmen.
> Und nicht für die GND-Verbindung.
wäre besser, hilft vor allem einem selber, schwarz/blau für gnd, 
rot/orange für Vcc, und der Rest (meist weiß und gelb) für Signale z.b.

von Elias H. (eliashu)


Angehängte Dateien:

Lesenswert?

Danke für die Hilfe,

ich werde es gleich umsetzten. Ich wusste nicht, das die Register mit 0 
initiert werden, wollte hier nur sicher gehen, das der Zustand der Ports 
keinem Zufall entspricht.

Bei if (PIND & ((1<<PIND2) | (1<<PIND3))) war ich mir nicht sicher ob 
für die Bedingung ein logischer Operator zwischen den Zuständen von 
PD2&PD3 oder ein bitweises "Oder" notwendig ist. Aber es macht scheinbar 
keinen Unterschied, da die Bedingung mit "|" als auch mit "||" erfüllt 
ist.


Ich hab alles neu verdrahtet und plötzlich ging es. Scheinbar hing der 
Eingang beim schalten in der Luft und hatte keinen Bezug auf Masse.

von Franz M. (elmo64)


Lesenswert?

Ich vermisse in deinem Quellcode eine Routine zur Entprellung.

Elias H. schrieb:
> Bei if (PIND & ((1<<PIND2) | (1<<PIND3))) war ich mir nicht sicher ob
> für die Bedingung ein logischer Operator zwischen den Zuständen von
> PD2&PD3 oder ein bitweises "Oder" notwendig ist

Hast du schon das AVR-GCC-Tutorial gelesen?

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.