Ist der Taster richtig angeschlossen (Arduino)?
Oder ist am Code irgendwas falsch?
Die zwei LEDs sollen bei Tastendruck eigentlich angehen, es passiert aber rein garnichts
int ledRot = 9;
int ledGelb = 6;
int Taster = 5;
void setup() {
pinMode(ledRot, OUTPUT);
pinMode(ledGelb, OUTPUT);
pinMode(Taster, INPUT);
}
void loop() {
while (digitalRead(Taster) == LOW) {
}
for (int i = 0; i <= 255; i += 5) {
analogWrite(ledRot, i);
delay(50);
}
for (int x = 0; x <= 255; x += 5) {
analogWrite(ledGelb, x);
delay(50);
}
delay(2000);
digitalWrite(ledRot, LOW);
digitalWrite(ledGelb, LOW);
while (digitalRead(Taster) == HIGH) {
}
delay(100);
}
.
.
3 Antworten
Der Plan ist richtig!
Im Programm fehlt aber das einschalten der Pullups.
Die Pins haben einen sogenannten "weak pullup". Schaltet man den ein, wird intern ein Widerstand nach Plus eingeschaltet. Dadurch wird der Pin "HIGH". Drückt man den Taster, schließt man den Pin nach Masse kurz und man liest ein "LOW" ein.
Die heißen "weak pullup" weil die schwach sind. Damit kann man nur sehr kurze Leitungslängen machen ohne Störungen einzufangen. Für längere Leitungen musst Du selber für Pullups sorgen, also z.B. 10kΩ zwischen Pin und Plus schalten. Bei sehr langen Leitungen solltest Du auf 1kΩ oder sogar noch weniger runter gehen. Dann fließt ordentlich Strom um den Pin auf LOW zu kriegen, mehr als eingestreute Störungen bewirken können.
Um die internen "weak pullups" einzuschalten musst Du nur
pinMode(Taster, INPUT_PULLUP);
schreiben. Das sollte dann so funktionieren.
Aufpassen musst Du aber beim verwendeten Taster, der hat zwei Seiten. Die linken und rechten beiden Pins sind intern miteinander verbunden. Drückt man den Taster, verbindet der links und rechts. Hast Du den um 90° verdreht, dann hast Du Dauer-LOW, denn dann verbindet der immer links und rechts, beim drücken wird dann oben und unten verbunden.
Nimm mal das while mit dem Taster raus (durch // auskommentieren)
Tut sich dann was an den LEDs?
Normal lässt man die LEDs LOW-Aktiv laufen, also Anode an Plus und Kathode an Portpin. Der Pin kann nämlich viel mehr nach Minus schalten als er an Plus ausgeben kann. Das hat technische Gründe.
Aber es sollte bei einer einfachen LED so funktionieren.
Leider habe ich weniger Erfahrung mit Arduinos, ich programmiere die AT µC immer direkt, ohne Arduino Umgebung.
Aber so sollte es eigentlich funktionieren.
Schreib einfach mal ein programm, dass den Zustand des Tasters auf eine (oder beide) LEDs kopiert. Dann siehst DU ob der den Taster lesen kann.
Oder auch per print Befehl den Zustand des Tasters auf der Konsole ausgeben falls die LEDs das Problem sind.
Was mir auffällt, das ist wie Du die while Schleife benutzt für den Helligkeitswert.
der Helligkeitswert ist 8-Bit, Du benutzt aber eine 16-bit Variable. Das ist auf jeden Fall Verschwendung an Rechenzeit und Speicher.
Nimm hier am besten char (für 8.bit) und dann darfst Du nur <255 fragen statt kleiner-gleich, denn die Variable kann ja nur 255 und ist so immer kleiner-gleich 255 egal was man damit macht.
So geht die auf 260, also kommt bei der LED als letztes eine 5 an was sehr klein ist, also praktisch aus.
Ich mach eigentlich alles so wie wir es in der Schule lernen, aber trotzdem danke für den Tipp.
Ich hab das while mit dem Taster rausgenommen, hat aber nichts gebracht.
Ich hab jetzt das hier geschrieben, das soll eine null anzeigen falls der Taster gedrückt wird, mir werden auf dem Seriel Monitor aber nur einsen angezeigt:
int i;
void setup(){
pinMode(4, INPUT_PULLUP);
Serial.begin(9600);
}
void loop(){
i=digitalRead(4);
Serial.println(i);
}
Hab dir ausversehen den falschen geschickt, im richtigen ist pin 5 im code
Hast Du ein Multimeter?
Wenn nicht, hänge einen Vorwiederstand an Plus, die andere Seite auf eine LED (A) und die (K) dann auf den Taster, also zwischen Taster und Pin.
Die sollte dann leuchten wenn der Taster gedrückt ist.
Hab ein Multimeter, wo soll ich das anschließen, kenne mich nicht sonderlich gut damit aus (Und soll ich es auf Spannung, Widerstand, oder Stromstärke einstellen?)
Einfach auf Volt stellen und dann die beiden Seiten des Tasters an die Messpitzen.
Dazu kannst Du zwei Widerstände nehmen und eine Seite um die Messpitze zwirbeln. Dann kannst Du das andere Ende des Widerstandes in das Breadboard stecken.
Da das Multimeter 20MΩ hat, stören kleine WIderstände nicht die Messung. Dann kannst Du sehen ob da Spannung (HIGH) am Portpin liegen oder fast keine Spannung (LOW) wenn er gedrückt ist.
Ich hab die Frage um ein Bild ergänzt, ist das falsch angeschlossen? Ich kann leider nur in der Simulation arbeiten, hab nichts dafür Zuhause
Ja, das scheint richtig zu sein.
Wusste gar nicht, dass es so tolle Simulatoren gibt!
Wenn Du das in Echt machen willst, ein Nano kostet nur ein paar Euro und ein Breadboard mit ein paar Tastern, Widerständen LEDs und Sensoren gibt es auch für €20.
Hier:
https://www.amazon.de/Elegoo-Electronic-Breadboard-Kondensator-Potentiometer/dp/B01J79YG8G/
Und hier der NANO:
https://www.amazon.de/3Pack-MEGA328P-AU-Micro-Controller-Entwicklungsboard-USB-Kabel/dp/B0C4H3LXKN
Billiger ist natürlich ohne fertig eingelötete Leisten.
Ich mach das eigentlich nur für die Schule, da haben wir alles was wir brauchen :)
Ja, haha, macht schon spaß, ich probiere das jetzt noch irgendwie hinzubekommen. Dir danke ich aber trotzdem für deine Hilfe :)
Ich schreib dir nochmal wenn ich es geschafft habe
Gerne. Ich muss auch bald ins Bett. Warte nur noch bis mein PC fertig ist mit Video rendern.
Könnte übrigens ein problem in der Simulation sein.
Steck mal beide Drähte auf eine Seite des Tasters, also beide oben oder beide unten.
Geht das auch nicht (Taster verbindet oben/unten statt links/rechts) steck einen oben links, den anderen unten links. (oder oben rechts und unten rechts).
Ein realer Taster verbindet immer beide Pins links und beide Pins rechts, beim Drücken werden dann alle miteinander verbunden.
Hab mir auch schon gedacht, dass die Simulation schuld ist, da gabs in der Vergangenheit vereinzelt ein paar Probleme. Hab das jetzt gemacht, bringt aber nichts
Dann mach mal eine Brücke über den Taster, dann sollte immer LOW (0) sein.
Einfach eine Drahtbrücke zwischen den beiden Ausgängen des Tasters rein machen, den Taster also einfach kurz schließen.
Oder mal Taster raus und stattdessen eine Brücke.
Wenn du willst kann ich dir einen Link geben, dann kannst du selber mal schauen und bearbeiten, die Simulation geht komplett über die Cloud
Ersetze den taster durch eine Brücke.
Also den Pin direkt an GND anschliessen. Nur um zu sehen ob es ein Problem gibt den simulierten Taster zu aktivieren.
Ich weiss nicht ob Du "Fremden" Zugang dazu geben darfst. Also lieber nicht ;)
Das ist ein Link speziell zum teilen mit "Fremden", aber ich probiere jetzt erstmal kurz das mit der Brücke aus
Aber nicht hier öffentlich im Forum. Nicht dass da einer Angriffe startet und es Ärger gibt.
Mein PC braucht nur noch 3 Minuten.
Können ja morgen abend noch mal gucken.
Das mit der Brücke geht nicht, aber trotzdem danke :)
Mach einen externen Pullup rein, also einen Widerstand zwischen Plus und dem Pin/Taster. 1kΩ
Allerdings sah der ja ein HIGH und der Taster hätte das zu LOW machen müssen.
Ich habe noch mal beide Bilder angeschaut.
Im ersten schaltet der Taster nach Masse, genau so wie er soll.
Im zweiten hast Du den auf Plus geschaltet. Der Pin ist im Ruhezustand bereits Plus (HIGH). Der Taster nach Plus kann daran natürlich nichts ändern.
Der Pin ist also HIGH wenn nichts gemacht wird und soll LOW werden wenn der Taster gedrückt wird. Also wie im ersten Bild anschließen!
Sorry, dass ich nicht geantwortet habe, hab nicht gesehen, dass du noch einen Kommentar geschrieben hast. Ich hab das Problem jetzt gelöst, den Taster hätte ich an 5V, den Pin, und mit einem Widerstand an GND anschließen müssen. Der Code war eigentlich korrekt, nur das PULLUP am anfang hat gefehlt. Nochmals danke für deine Hilfe
Dann ist das ein "Pull Down". Geht auch, aber bevorzugt wird Pull-Up.
Das liegt vor allem daran, dass man wenn man Ausgänge zusammen schalten muss sogenannte "open Collector" Treiberstufen verwendet. Normal schalten die zwischen plus und Minus um, open Kollektor kann nur nach Minus ziehen.
So kann jeder Ausgang die Leitung nach Mnus schalten aber nicht nach Plus was einen Kurzschluss erzeugen würde wenn ein Ausgang Plus, der andere Minus liefert.
Der Pullup sorgt dann für HIGH Pegel wenn kein Ausgang nach Masse zieht.
Die meisten Bussysteme arbeiten so, IDE (PATA), I²C, SATA, Firewire, PS/2 uvm.
Naja, dein trägst verbindet Pin 5 mit GND, du kannst auf Pin 5 keinen Input messen wenn dieser nirgendwo herkommen kann.
Der Taster muss natürlich eine Spannungsquelle mit Pin 5 verbinden, damit du auch ein Signal-high messen kannst.
Ich hab es jetzt umgeändert, sobald ich den Strom anmache fangen die LEDs sofort an zu leuchten. Screenshot davon habe ich in der Frage ergänzt
Ohne den Taster funktioniert es genau wie ich es will, da kann dann ja die for Schleife nicht dran Schuld sein
Dafüpr gibt es die internen "weak pullups". Die werden in dem Programm nicht eingeschaltet.
Einen externen Widerstand braucht man nur gegen Störungen bei sehr langen Leitungen zum Taster. Bis 1m funktioniert das aber zuverlässig mit den internen schwachen Widerständen.
Die Sache mit dem ullup und so wurde ja schon beantwortet...
Aber: Die Ausgabe funktioniert nicht so, wie Du Dir das vorstellst,
digitalWrite() kann einen Port beschreiben, ja, aber nur "An" oder "Aus".
also machst Du da am besten was anderes in Deinem Programm, zum Beispiel:
Das lässt die LEDS blinken und zwar mit einfacher und halbierter Frequenz. Ob der Vergleich da sein muss, ggf reicht ach nur das i&1 bzw i&2
for (i=0;i<255;i++)
{
digitalWrite(LED1,(i&1)>0);
digitalWrite(LED2,(i&2)>0);
delay (1000);
}
Ich hab es jetzt geändert, es tut sich aber immernoch nichts, hier der Code:
int ledRot = 9;
int ledGelb = 6;
int Taster = 5;
void setup() {
pinMode(ledRot, OUTPUT);
pinMode(ledGelb, OUTPUT);
pinMode(Taster, INPUT_PULLUP);
}
void loop() {
while (digitalRead(Taster) == HIGH) {}
for (int i = 0; i <= 255; i += 5) {
analogWrite(ledRot, i);
delay(50);
}
for (int x = 0; x <= 255; x += 5) {
analogWrite(ledGelb, x);
delay(50);
}
delay(2000);
digitalWrite(ledRot, LOW);
digitalWrite(ledGelb, LOW);
while (digitalRead(Taster) == LOW) {}
delay(100);
}