Forum: Mikrocontroller und Digitale Elektronik Arduino LED nur an wenn andere LED an und Schalter gedrückt?


von Flo D. (floflovaldo)


Lesenswert?

Hallo,

ich will in meinen Code, siehe hier:
1
int X = A0;
2
int Y = A1;
3
int Z = A2;
4
5
void setup()
6
{
7
  Serial.begin(9600);
8
  pinMode(2, OUTPUT);
9
  pinMode(5, INPUT); 
10
}
11
12
void loop()
13
{
14
  static bool first = false;
15
  static int x_old = 0;
16
  static int y_old = 0;
17
  static int z_old = 0;
18
  
19
  int x_new = analogRead(X);
20
  int y_new = analogRead(Y);
21
  int z_new = analogRead(Z);
22
  
23
  Serial.println(x_new);
24
  Serial.println(y_new);
25
  Serial.println(z_new);
26
  Serial.println(" ");
27
 
28
  if((abs(x_new - x_old) > 10 || abs(y_new - y_old) > 10 || 
29
      abs(z_new - z_old) > 10) && first)
30
        {
31
        digitalWrite(2, HIGH);
32
        delay(3000);
33
        digitalWrite(2, LOW);
34
        delay(3000);
35
        }
36
  first = true;
37
  
38
  x_old = x_new;
39
  y_old = y_new;
40
  z_old = z_new;
41
}

es so machen das nur wenn die LED an Digital Pin 2 leuchtet und ein 
Button während dessen gedrückt wird das eine zweite LED angeht. Diese 
dann ca. 5-10 Sekunde (das ist ja aber schnell änderbar) wieder ausgeht. 
Würde mich über schnelle Hilfe sehr freuen.

Viele Grüße

Florian

von Bastler (Gast)


Lesenswert?


von Flo D. (floflovaldo)


Lesenswert?

Das ist mit prinzipiell bewusst. Allerdings war beim anderen das ehr 
nebensächlich. Da das eine Problem mit dem Beschleunigungssensor gelöst 
ist. Ist nur noch dieses Problem gerade vorhanden. Außerdem bin ich 
jetzt weiter hab einen zuverlässigen Code und es fehlt nur noch das mit 
dem Button.

von Michael D. (etzen_michi)


Lesenswert?

if( (PINtaster&(1<<taster)) & (PORTled&(1<<led)) ) {
    Led2an();
}

: Bearbeitet durch User
von Bastler (Gast)


Lesenswert?

Z.B. schau Dir Pin-Interrupt ( attachInterrupt() ) an und ersetze die 
unsäglichen delay() z.B. durch Abfrage von millis().
Ansonsten durchdenke das Ganze mal selbst weiter.

von Flo D. (floflovaldo)


Lesenswert?

@etzen_michi: Danke schon mal. Was ich für die Sachen einsetzten muss 
ist eigentlich klar. Nur wie gebe ich das richtig ab ohne wieder Fehler 
zu bekommen? Led2an ist klar da muss dann digitalWrite(10, HIGH); also 
in meinem Fall. Aber bei den oberen?

von Bastler (Gast)


Lesenswert?

Florian D. schrieb:
> Nur wie gebe ich das richtig ab

Wir sind nicht für Deine Hausaufgaben zuständig.
Tipps wurden Dir gegeben, denken musst Du selber.

von Flo D. (floflovaldo)


Lesenswert?

Tut mir leid wenn ihr denkt das ich nichts machen würde. Allerdings tue 
ich mein bestes und es klappt nicht. Ich würde mich wirklich sehr 
freuen. Ich weiß nicht wie du das Hausaufgaben jetzt gemacht hast, aber 
schulisch ist es nichts. Ich vermute du hast das auch nicht aufs 
schulische bezogen gehabt. Aber ich habe jetzt darüber auf der 
dazugehörigen Arduino Playground Seite gelesen und es aber nicht auf das 
mit dem Taster anwenden können. Würde mich sehr freuen wenn ich doch ein 
bisschen mehr Hilfe bekommen würde

von Bastler (Gast)


Lesenswert?

Biste zu faul um nach Pin-Interrupt zu Googeln?
Da kommt dann z.B. das:

https://www.arduino.cc/en/Reference/AttachInterrupt

Sogar mit Code Beispiel. Damit erkennst Du schon mal ob eine Tatse 
gedrückt wurde. Setze in der Interrupt Routine ein FlagTasteGedrückt. 
Damit machst Du dann in der Main Loop eine UND-Verknüpfung mit der 
LED(Pin2), setze das Flag wieder zurück und lasse die zweite Led 
leuchten. Und ersetze alle delay() noch durch Abfrage von millis().

von Marcel P. (souko)


Lesenswert?

Michael D. schrieb:
> if( (PINtaster&(1<<taster)) & (PORTled&(1<<led)) ) {
>     Led2an();
> }


Hier hat dir doch Michael D. schon die Antwort gegeben die du brauchst.
DU fragst einfach deinen LED-Output als Input ab -> digitalRead(LED)

Das geht ohne Probleme.

von Flo D. (floflovaldo)


Lesenswert?

@ souko Ja aber ich habe das jetzt so eingefügt:
1
int X = A0;
2
int Y = A1;
3
int Z = A2;
4
5
void setup()
6
{
7
  Serial.begin(9600);
8
  pinMode(2, OUTPUT);
9
  pinMode(5, INPUT); 
10
}
11
12
void loop()
13
{
14
  static bool first = false;
15
  static int x_old = 0;
16
  static int y_old = 0;
17
  static int z_old = 0;
18
  
19
  int x_new = analogRead(X);
20
  int y_new = analogRead(Y);
21
  int z_new = analogRead(Z);
22
  
23
  //Serial.println(x_new);
24
  //Serial.println(y_new);
25
  //Serial.println(z_new);
26
  //Serial.println(" ");
27
 
28
  if((abs(x_new - x_old) > 10 || abs(y_new - y_old) > 10 || 
29
      abs(z_new - z_old) > 10) && first)
30
        {
31
       unsigned long start_time = millis();
32
    digitalWrite(2, HIGH);
33
    while((millis() - start_time) < 3000)
34
    {
35
   
36
    if( (PINtaster&(1<<taster)) & (PORTled&(1<<led)) ) {
37
    digitalWrite(10, HIGH);
38
    }
39
    
40
    }
41
    digitalWrite(2, LOW);
42
    digitalWrite(10, LOW);
43
        }
44
  first = true;
45
  
46
  x_old = x_new;
47
  y_old = y_new;
48
  z_old = z_new;
49
}

Stimmt das ansich? Ich weiß nur net was für "PINtaster", "taster", 
"PORTled" und "led" eingesetzt werden soll. Ich hab alles mögliche 
versucht und ehr bringt immer Fehlermeldungen wie z.B. "taster was not 
declared in this scope"

von Marcel P. (souko)


Lesenswert?

Na, so einfach ist es nicht. Du musst die Funktionen und Variablen schon 
auf deinen Code anpassen.

Mir scheint, das du dir deinen Code einfach so aus Bausteinen zusammen 
klickst, ohne überhaupt zu verstehen, was die einzelnen Teile eigentlich 
machen.

du willst doch prüfen, ob deine LED an Pin 2 an ist UND ob dein Taster 
an Pin 5 gedrückt ist, oder ?

du hast DIGITALE Signale
du willst etwas LESEN
du hast Pin 5 (Taster) und Pin 2 (LED)

mit den Infos solltest du doch deine If-Bedingung zusammen bekommen ?

das hier sollte dir helfen:
https://www.arduino.cc/en/Reference/Boolean

von Max H. (hartl192)


Lesenswert?

Marcel P. schrieb:
> du willst doch prüfen, ob deine LED an Pin 2 an ist UND ob dein Taster
> an Pin 5 gedrückt ist, oder ?
Das abfragen ob die LED am Pin 2 an ist kann er sich auch sparen, da die 
if-Abfrage nur ausgeführt wird nachdem Pin 2 auf High gesetzt wurde und 
bevor er wieder auf low geht, also einfach
1
if(digitalRead(TASTER_PIN) == HIGH /*oder auch LOW, je nachdem wie*/)
2
                                   /*der Taster angeschlossen ist */
3
{
4
  digitalWrite(10, HIGH);
5
}

von Flo D. (floflovaldo)


Lesenswert?

1
int X = A0;
2
int Y = A1;
3
int Z = A2;
4
5
void setup()
6
{
7
  Serial.begin(9600);
8
  pinMode(2, OUTPUT);
9
  pinMode(5, INPUT); 
10
}
11
12
void loop()
13
{
14
  static bool first = false;
15
  static int x_old = 0;
16
  static int y_old = 0;
17
  static int z_old = 0;
18
  
19
  int x_new = analogRead(X);
20
  int y_new = analogRead(Y);
21
  int z_new = analogRead(Z);
22
  
23
  //Serial.println(x_new);
24
  //Serial.println(y_new);
25
  //Serial.println(z_new);
26
  //Serial.println(" ");
27
 
28
  if((abs(x_new - x_old) > 10 || abs(y_new - y_old) > 10 || 
29
      abs(z_new - z_old) > 10) && first)
30
        {
31
       unsigned long start_time = millis();
32
    digitalWrite(2, HIGH);
33
    while((millis() - start_time) < 3000)
34
    {
35
   
36
    if (digitalRead(2) == HIGH && digitalRead(5) == HIGH) {
37
    digitalWrite(10, HIGH);
38
    delay(300);
39
    digitalWrite(10, LOW);
40
    }
41
    
42
    }
43
    digitalWrite(2, LOW);
44
    digitalWrite(10, LOW);
45
        }
46
  first = true;
47
  
48
  x_old = x_new;
49
  y_old = y_new;
50
  z_old = z_new;
51
}

So hab ich es gemacht. Allerdings leuchtet sie weder und geht nicht aus. 
Ich weiß das da unten was genau net stimmt. Da wo des zweite mal LOW 
ist. Aber ich habe das mit dem millis noch nicht ganz raus. Ich habs mir 
gerade auch nochmal durchgelesen. Allerdings komme ich da durcheinander 
wenn es um beide Sachen geht. Ich würde mich sehr freuen wenn ich einen 
kleinen Anschubser bekommen würde.

von Flo D. (floflovaldo)


Lesenswert?

@hartl192: Das bringt mich leider nur noch mehr durcheinander. Es sollte 
aber UNBEDINGT so sein dass nur wenn beide Signale auf HIGH stehen das 
es funktioniert.

von Max H. (hartl192)


Lesenswert?

Florian D. schrieb:
> Allerdings leuchtet sie weder und geht nicht aus.
Wenn sie nicht leuchtet kann sie auch nicht aus gehen.
Ist das beide Male die selbe LED?
Vllt. solltest du in der setup(), Pin 10 als Ausgang konfigurieren. 
Normalerweise sind Pins nach dem Reset Eingängen (außer bei Arduino ist 
das anders).

> Aber ich habe das mit dem millis noch nicht ganz raus.
millis() gibt die als rückgabewert, die Zeit in Millisekunden, die seit 
dem Einschalten vergangen ist. Du merkst dir die Zeit, bei der die 
Schleife startet und führst sie so lange aus, wie die Differenz aus 
aktuelle Zeit und Startzeit kleiner 3000ms ist.


BTW: Für C(++) Code bitte die C-Formatierung verwenden:
1
[c]C-Code[/c]
Wenn du konsequent Einrücken würdest, wäre der Code besser lesbar.

: Bearbeitet durch User
von Florian (Gast)


Lesenswert?

@ Florian D.

Bemühe Dich bitte mal ernsthaft eine klare und angemessene Sprache zu 
verwenden. Denken tun wir Menschen in Bildern und Worten. Und wenn die 
Sprache nicht hinhaut, haut auch das Denken nicht hin. Für meinen 
Geschmack hast Du die Methode: "Ich reihe mal ein paar Laute aneinander 
bis sich irgendwer dabei was denken kann" ziemlich überstrapaziert.

von Flo D. (floflovaldo)


Lesenswert?

Ich versuche es morgen nochmals. PC grad ausgemacht. Geb dann Bescheid 
wenns klappt...
Danke. Passt außerdem vergessen Ausgang noch was in dem Code so net was 
auffällt?

Viele Grüße

Florian

von Flo D. (floflovaldo)


Lesenswert?

Tut mir leid wenn das so rüberkommt. Ich bin leider mit dem ganzen ein 
bisschen überfordert. Gebe mir in Zukunft Mühe. Danke für den Hinweis.

von Michael D. (etzen_michi)


Lesenswert?

Zwar ist mir dein Programmierstil unbekannt, aber hier müsste ggf. noch 
was rein:

 Serial.begin(9600);
 pinMode(2, OUTPUT);
 pinMode(5, INPUT);
 pinMode(10, Output);   <-- die LED soll ja an einem Ausgang hängen.

Schaltet dein Taster auf Low oder High?
Wird deine LED auf Low oder High gezogen um zu leuchten?

von Flo D. (floflovaldo)


Lesenswert?

Ja leider war das ein Kopierfehler wegen einem neuen Dokument und da 
habe ich das vergessen. Wenn man Taster gedrückt wird fließt Strom, also 
eigentlich schaltet er auf HIGH. Die LED wird auch HIGH gezogen und dann 
leuchtet sie. Die hängt direkt mit einem Vorwiderstand an Pin 10. Die 
erste LED genau so nur eben an Pin 2. Ich habe das ganze jetzt nochmal 
so gemacht, doch leider geht es immer noch nicht. Vermutlich liegt es 
irgendwo am Code Ende, evtl. bei dem delay.
1
int X = A0;
2
int Y = A1;
3
int Z = A2;
4
5
void setup()
6
{
7
  Serial.begin(9600);
8
  pinMode(2, OUTPUT);
9
  pinMode(10,OUTPUT);
10
  pinMode(5, INPUT); 
11
}
12
13
void loop()
14
{
15
  static bool first = false;
16
  static int x_old = 0;
17
  static int y_old = 0;
18
  static int z_old = 0;
19
  
20
  int x_new = analogRead(X);
21
  int y_new = analogRead(Y);
22
  int z_new = analogRead(Z);
23
  
24
  //Serial.println(x_new);
25
  //Serial.println(y_new);
26
  //Serial.println(z_new);
27
  //Serial.println(" ");
28
 
29
  if((abs(x_new - x_old) > 10 || abs(y_new - y_old) > 10 || 
30
      abs(z_new - z_old) > 10) && first)
31
        {
32
       unsigned long start_time = millis();
33
    digitalWrite(2, HIGH);
34
    while((millis() - start_time) < 3000)
35
    {
36
   
37
    if (digitalRead(2) == HIGH && digitalRead(5) == HIGH) {
38
    digitalWrite(10, HIGH);
39
    delay(300);
40
    digitalWrite(10, LOW);
41
    }
42
43
    }
44
    digitalWrite(2, LOW);
45
    digitalWrite(10, LOW);
46
        }
47
  first = true;
48
  
49
  x_old = x_new;
50
  y_old = y_new;
51
  z_old = z_new;
52
}

Würde mich über Hilfe sehr freuen. Saß jetzt nochmal dran und habe rum 
versucht. Allerdings hat es nicht geklappt.

Viele Grüße

von Marcel P. (souko)


Lesenswert?

Bist du dir sicher das deine Pins an den Tastern auch wieder auf LOW 
gezogen werden wenn du den Taster los lässt ?
Hast du Pull-Down-widerstände drin ?

Besser ist es einen Taster mit GND und dem Portpin zu verbinden und dann 
mit den internen oder auch mit externen Pullup-Widertänden zu arbeiten.

von Flo D. (floflovaldo)


Lesenswert?

Ich habe das ganze so gemacht. Das eine Ende vom Taster mit VCC (5V) 
verbunden. Das andere mit GND über einen 10kOhm Widerstand und noch mit 
einer Drahtbrücke an den Pin.

Habe eine nochmalige Durchgangsmessung durchgeführt. Sobald ich den 
Button drücke fließt Strom und das Multi-Meter fließt. Sonst nicht.

von Marcel P. (souko)


Lesenswert?

Ja, das muss aber nicht heissen, das dein Pin vom AVR auch wieder auf 
LOW geht.
Verschalte das ganze mal so:

Taster an VCC und den 10k an das andere Ende des Taster.
Das zweite Beinchen vom 10k an GND.
Und dann die Verbindung zwischen Taster und 10k an deinen Portpin.

Nochmal Probieren.

EDIT: Vergiss es, das ist ja genau was du gemacht hast... Ich bin wohl 
noch nicht ganz wach.. Sorry...
Dann liegt der Fehler doch im Programm, und ich sehe ihn gerade nicht.

: Bearbeitet durch User
von Flo D. (floflovaldo)


Lesenswert?

Ok. ich vermute es liegt eben irgendwo an dem Code Teil mit dem 
Schalter. Hat jemand noch eine Idee woran es liegen könnte?

Viele Grüße

Florian

von Max H. (hartl192)


Angehängte Dateien:

Lesenswert?

Die LED am Pin 2 funktioniert aber wie sie soll?

PS: Denkst du nicht, der Code wäre so eingerückt wie in Anhang lesbarer?

von Flo D. (floflovaldo)


Lesenswert?

Ja da funktioniert alles. Hab auch nochmal alles überprüft wegen den 
Pins und allem aber passt alles. Und so funktioniert auch alles. Außer 
eben dass die LED zwei net geht

von Max H. (hartl192)


Lesenswert?

Florian D. schrieb:
> Und so funktioniert auch alles. Außer
> eben dass die LED zwei net geht
Das heißt, das "delay" mit dem
1
while((millis() - start_time) < 3000)
funktioniert. Jetzt musst du nur noch rausfinden wieso
1
(digitalRead(2) == HIGH && digitalRead(5) == HIGH)
nie true ist. Du könntest sie dir dazu ja beide per UART ausgeben 
lassen.


Du köntest auch noch
1
  digitalWrite(10, HIGH);
2
  delay(2000);
3
  digitalWrite(10, LOW);
in die Setup schreiben um zu sehen ob die LED überhaupt funktioniert.

: Bearbeitet durch User
von Flo D. (floflovaldo)


Lesenswert?

Das mit dem Ausgaben probier ich mal. Die LEDs funktionieren. Schon 
ausprobiert.

von Michael D. (etzen_michi)


Lesenswert?

Max H. schrieb:
> (digitalRead(2) == HIGH && digitalRead(5) == HIGH)

Weiß jetzt nicht wie das mit den Prioritäten ausschaut .. aber 
vielleicht mal:

( (digitalRead(2)==HIGH) && (digitalRead(5)==HIGH) )

ausprobieren?

Zunot einzeln mal auf "1" schreiben anstelle der Abfragen.

von Ulrich F. (Gast)


Lesenswert?

(digitalRead(2) && digitalRead(5))

von helper (Gast)


Lesenswert?

Florian D. schrieb:
> if((abs(x_new - x_old) > 10 || abs(y_new - y_old) > 10 ||
>       abs(z_new - z_old) > 10) && first)

Dir ist schon klar, dass du hier die Beträge von x ODER y ODER den 
Betrag von z UND first veroderst?

Wenn dein if nur dann true sein soll, wenn first true ist und einer der 
drei Beträge x,y oder z >10 ist, musst du auf
1
first && (abs(x_new - x_old) > 10 || abs(y_new - y_old) > 10 || abs(z_new - z_old) > 10)

abfragen

von Max H. (hartl192)


Lesenswert?

@helper
Dir ist schon klar, dass && kommutativ ist und beide Versionen das 
gleiche machen?

von Karl H. (kbuchegg)


Lesenswert?

Florian D. schrieb:

>        unsigned long start_time = millis();
>     digitalWrite(2, HIGH);

nachdem du hier den Pin 2 auf High gesetzt hast ....

>     while((millis() - start_time) < 3000)
>     {
>
>     if (digitalRead(2) == HIGH && digitalRead(5) == HIGH) {

... ist er hier auch HIGH. Was soll er denn sonst sein?
D.h. diese Abfrage, ob der Pin 2 HIGH ist, die kannst du dir sparen. Die 
verwirrt nur. Es ist eine Bedingung, die trivialerweise sowieso erfüllt 
ist.


Weiters.

Das hier
1
    while((millis() - start_time) < 3000)
2
    {
3
      if (digitalRead(2) == HIGH && digitalRead(5) == HIGH) {
4
        digitalWrite(10, HIGH);
5
        delay(300);
6
        digitalWrite(10, LOW);
7
      }
8
9
      digitalWrite(10, HIGH);
10
      delay(300);
11
      digitalWrite(10, LOW);
12
   }

ist eine while Schleife in der etwas wiederholt wird. Du hast zwar nach 
jedem High-setzen eine Wartezeit drinnen, aber nicht nach dem LOW 
setzen. Das ganze wirkt sich so aus, als ob du deinen Lichtschalter im 
Wohnzimmer einschaltest, eine halbe Stunde wartest, ausschaltest und 
sofort wieder einschaltest. Gut im Wohnzimmer wirst du bemerken, dass 
das Licht mal kurz flackert, aber im wesentlichen ist das Licht ständig 
eingeschaltet.
Aber auf einem µC wirst du kein Flackern bemerken. Ein µC kann die LED 
viel schneller schalten als du gucken kannst. Davon, dass der Ausgang 
zwischendurch mal kurz auf LOW war, wirst du nichts mitkriegen. Das geht 
viel zu schnell für dich als Mensch.

Wenn du etwas blinken lassen willst, dann musst du sowohl nach dem 
Einschalten als auch nach dem Ausschalten eine Pause einlegen!

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Im übrigen ist der ganze Ansatz nicht zielführend, wenn man deine 
ursprüngliche Aufgabenstellung in Betracht zieht.

Diese ganze Warterei ist Unsinn. Was du wirklich willst ist: Wenn der 
Button gedrückt wird, merkst du dir die Zeit an der dies passiert (Zeit 
ist gleichzusetzen mit der Abfrage von millis()) und schaltest die Lampe 
ein. Wenn du bei späteren Aufrufen von millis() bemerkst, dass die 
Einschaltzeit abgelaufen ist, dann schaltest du wieder aus.
So würdest du das auch im täglichen Leben machen. Wenn du ein Gulasch 
auf den Herd stellst, dann bleibst du auch nicht daneben stehen, sondern 
machst irgendwas anderes. Du merkst dir aber die Zeit an der du den 
Hered eingeschaltet hast. Regelmässige Blicke auf die Uhr verraten dir, 
ob die Zeit schon abgelaufen ist. Wenn dem so ist, dann reisst du dich 
von Facebook los, gehst zum Herd un schaltest ihn ab.
1
unsigned long einschaltZeit;
2
3
void loop
4
{
5
  unsigned long now = millis();
6
7
  if( digitalRead( 5 ) == HIGH )         // Taster gedrückt
8
  {
9
    einschaltZeit = now;                 // merken wann das passiert ist
10
    digitalWrite( 10, HIGH );            // und einschalten
11
  }
12
13
  if( now - einschaltZeit > 5000 )      // 5 Sekunden seit dem Einschalten vergangen?
14
    digitalWrite( 10, LOW );            // wieder ausschalten
15
}

so macht man vom Prinzip her eine Zeitverzögerung, die mit einem 
Ereignis (hier: eine gedrückte Taste) gestartet wird. (Und du solltest 
diese Variante erst mal ausprobieren; setup() musst du noch ergänzen).

Löse dich von Warteschleifen und/oder delay(). Diese Varianten sind für 
deine ersten Programme ok, denn irgendwo muss man auch mal anfangen.
Aber sie bringen dich nicht weiter. Das Konzept "aktives Warten auf ein 
Ereignis oder eine Zeit" ist nicht tragfähig genug für eine vernünftige 
Programmierung. Derartige Konzepte sind praktisch nie die Lösung aber 
oft das Problem.
Ein zielführendes Konzept ist es, die wiederkehrenden Aufrufe von loop() 
als das fortschreiten der Zeit anzusehen. 2 nacheinander erfolgende 
Aufrufe von loop() sind dein Konzept für 'vorher' und 'nachher'. 
Dazwischen vergeht ein kleines bischen Zeit. Nicht viel, aber doch. Wenn 
du eine genauere Steuerung der Zeit brauchst, dann ist es die Abfrage 
von millis() nachdem wieder einer dieser kleinen Zeitschritte vergangen 
ist, die das bewerkstelligt. Denn auch viele, viele kleine vergangene 
Zeitspannen (das bedeutet: Aufrufe von loop()) führen im Summe 
irgendwann dazu, dass 1 Millisekunde (oder mehr) vergangen ist.

: Bearbeitet durch User
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.