Arduino LED nur an wenn andere LED an und Schalter gedrückt?

OP #4180391
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
OP #4180414
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.
OP #4180450
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
Gast #4180471
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().
OP #4180486
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"
Gast #4180490
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
#4180503
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
}
OP #4180506
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.
#4180517
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.
Gast #4180525
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.
OP #4180763
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
Gast #4180777
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.
OP #4180783
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.
Gast #4180791
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.
#4180822
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.
Gast #4181532
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
#4181746
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!
#4181762
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren