RGB-LED Farbe durch Ultraschallsensor ändern

Hallo liebe Leute,

ich bin ein Neuling im Arduino Bereich und habe mir von Funduino ein Set bestellt um mich langsam in die Thematik einzuarbeiten.

Nun hatte ich die Idee, dass ich bei einer RGB-LED die Farbe von einem Grün in ein Rot änder, je mehr ich an den Sensor herankomme (á la Rückfahrwarner).
Allerdings bleibt mein Arduino einfach hängen, sobald ich mich dem Sensor nähere.

Hier wollte ich erstmal lediglich testen, ob das ändern der Farbe durch simples einsetzen der Entfernung in die setcolor() Methode funktioniert.

Bei weiten Entfernungen klappt dies auch, sobald ich aber näher rangehe, bleibt er einfach hängen, was ich an der Ausgabe im Serial Monitor sehe.

Hier mal der Code:

//Variablen für RGB-LED
int redPin = 11;
int greenPin = 10;
int bluePin = 9;

//Ultra
int trigger = 5;
int echo = 6;
long dauer = 0;
long entfernung = 0;

void setup()
{
  //RGB
  pinMode(redPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT);

  pinMode(trigger, OUTPUT);
  pinMode(echo, INPUT);
}

void loop()
{
  delay(100);
  digitalWrite(trigger, LOW);
  delay(5);
  digitalWrite(trigger, HIGH);
  delay(10);
  digitalWrite(trigger, LOW);
  dauer = pulseIn(echo, HIGH);
  entfernung = (dauer/2) / 29.1;

  if (entfernung >= 500 || entfernung <= 0)
  {
    Serial.println("Kein Messwert");
  }
  else
  {    
    Serial.print(entfernung);
    Serial.println(" cm");
    
    setColor(entfernung, 255, 200); 
  }

}

void setColor(int red, int green, int blue)
{
if(red > 255 || red < 0){
    red = 0;
  }
  if(green > 255 || green < 0){
    green = 0;
  }
  if(blue > 255 || blue < 0){
    blue = 0;
  }

  analogWrite(redPin, red);
  analogWrite(greenPin, green);
  analogWrite(bluePin, blue);
}

Kann mir da jemand eventuell helfen ?

besk:
Bei weiten Entfernungen klappt dies auch, sobald ich aber näher rangehe, bleibt er einfach hängen, was ich an der Ausgabe im Serial Monitor sehe.

Was für eine RGB-LED?
Bei Lowpower-LED die Vorwiderstände für die RGB-Farben richtig bemessen?
Oder als Highpower-LED mit passender Konstantstromquelle betrieben?

Und warum triggerst Du Deinen Ultraschallsensor um ein tausendfaches langsamer als üblich?

Zum Triggern der Sensoren ist eher ein Triggerimpuls von 10 Mikrosekunden üblich und nicht ein Triggerimpuls von 10 Millisekunden:

  digitalWrite(TRIGGERPIN, LOW);
  delayMicroseconds(2); 
  digitalWrite(TRIGGERPIN, HIGH);
  delayMicroseconds(10); 
  digitalWrite(TRIGGERPIN, LOW);

Allerdings bleibt mein Arduino einfach hängen, … was ich an der Ausgabe im Serial Monitor sehe.

D.h. es kommt gar nichts mehr auf Serial raus ?
Auch nicht, wenn du wieder weiter weg gehst ?

Hmm, es gibt eine pulseIn Variante mit Timeout, weiss aber nicht ob das hilft.
Dann könnte man dauer und entfernung als [b]unsigned long[/b] definieren, aber das sollte es eigentlich auch nicht sein.
Spart die “< 0” Abfrage.
Ausserdem sollte (dauer/2) / 29.1 bei Integer-Variablen keinen großen Unterschied zu dauer / 58 machen.

@jurs:

was das für eine RGB-LED ist, kann ich dir leider nicht sagen. Die war im Funduino - Starter Kit mit bei.
Wenn ich die RGB-LED alleine betreibe, funktioniert auch alles !
Und die Code-Beispiele habe ich aus den Tutorials und habe probiert diese zu kombinieren

@michael_x:

ja, es kommt nicht mehr raus.
Der bleibt sogar bei dem 'c' in 'cm' stecken.

EDIT:

beides einzeln funktioniert auch ohne probleme !
Ich habe da die Vermutung, dass das ansprechen der analogPins und DigitalPins direkt nacheinander vllt zu problemem führt

besk:
was das für eine RGB-LED ist, kann ich dir leider nicht sagen. Die war im Funduino - Starter Kit mit bei.

Also wohl eine LowPower RGB-LED (3*20mA).

besk:
Wenn ich die RGB-LED alleine betreibe, funktioniert auch alles !

Ja klar, und wenn Du bei einem Hochhaus mit 22 Etagen vom Dach springst, funktioniert beim Weg abwärts auch für 21 Etagen alles!

Wenn Du LEDs direkt und ohne Vorwiderstand an digitale Outputs anschließt, fabrizierst Du eine extrem starke Stromüberlastung. Die LED leuchtet viel zu hell und aus den Outputs saugst Du viel zu viel Strom, so dass Dir der Controller auf dem Board (und natürlich auch die LED) durchbrennen kann.

Für Deine RGB-LED brauchst Du drei geeignete Vorwiderstände, einen für rot, einen für grün und einen für blau.

Was meinst Du weshalb die Dir im Set die Widerstände beigelegt haben?

Hast Du kein Tutorial zu Deinem Set dazubekommen?

Schaue es Dir z.B. hier mal an mit einer RGB-LED und einem Breadboard, falls Du schaltungstechnisch irgendwelche Defizite beim Verständnis hast, wie Du eine LowPower RGB-LED an einen Mikrocontroller anzuschließen hast:

Entschuldige, da habe ich mich nicht genau ausgedrückt.

Wenn ich die RGB-LED alleine betreibe, funktioniert auch alles !

Damit meinte ich, dass wenn ich die RGB-LED ohne den Ultraschallsensor benutze, kann ich programmatisch die Farbe ohne Probleme wechseln. Habe denen natürlich einen Widerstand vorgesetzt und zwar so wie hier beschrieben Adafruit Learning System.

Mein Problem ist beide zusammen zu benutzen.

....
if (entfernung >= 500 || entfernung <= 0)
  {
    Serial.println("Kein Messwert");
  }
  else
  {    
    Serial.print(entfernung);
    Serial.println(" cm");
    
    setColor(entfernung, 255, 200);  //<-- dies ist die Problem Stelle
  }

...

Wie im Code beschrieben ist dies die Stelle, an der er zu scheitern scheint.
Nehme ich die setColor-Methode raus, funktioniert alles einwandfrei.
Nehme ich die Methode rein und lass den Ultraschallsensor zwischen 100 - 200 cm schwanken, funktioniert auch alles und man sieht auch de Veränderung an der LED. Verringert man jedoch den Abstand mit der Hand zum Ultraschallsensor noch weiter, bleibt er irgendwann einfach hängen und muss mit einem Reset neu gestartet werden.

Hier nochmal die setColor Methode

void setColor(int red, int green, int blue)
{
if(red > 255 || red < 0){
    red = 0;
  }
  if(green > 255 || green < 0){
    green = 0;
  }
  if(blue > 255 || blue < 0){
    blue = 0;
  }

  analogWrite(redPin, red);
  analogWrite(greenPin, green);
  analogWrite(bluePin, blue);
}

Nehme ich die setColor-Methode raus, funktioniert alles einwandfrei.

Sehe das Problem auch nicht.

void loop() 
{
    static int entfernung = 300;
    if (entfernung > 0)
    {
      Serial.print (entfernung); Serial.println( " cm");
      setcolor(entfernung, 255, 200);
      entfernung -=2;
      delay(100);
      if (entfernung == 0) 
         Serial.println ("Fertig. Reset erforderlich!");
    }
}

Das sollte nach gut 20 sec, bei “254 cm”, den Rot-Anteil einschalten und dann wieder langsam runterdimmen.
Läuft das durch bis zur “Fertig” - Meldung ?

Edit : kompiliert das jetzt, ???

Serial println ("Fertig. Reset erforderlich");
Dem Serial darfste gerne noch einen . verpassen :wink:

Thank you for bringing this to our attention

War nur PseudoCode :wink:

Hallo,
probiere es einmal so:

if ((entfernung >= 500) || (entfernung <= 0))

dann in die Schleifen ein:

Serial.println (“erste Schleife”);

if((red > 255) || (red < 0))

{
red = 0;
Serial.println (“erste Schleife”);
}

Dann kannst Du “sehen” in welcher Schleife es hängt.
Gruß und Spaß
Andreas

besk:
Habe denen natürlich einen Widerstand vorgesetzt und zwar so wie hier beschrieben Adafruit Learning System.

Dein Sketch ist soweit in Ordnung und er sollte dann auch laufen, wenn Du den Controller nicht durch falsche Beschaltung überlastest und noch einen dicken Fehler im Sketch beseitigtst:
Offenbar fehlt in Deinem eingangs geposteten Sketch die Serial-Initialisierung mit:

  Serial.begin(9600);

in der setup()-Funktion.

Normalerweise sollte auf Serial dann gar nichts passieren, d.h. weder sollte irgendwas ausgegeben werden noch sollte der Sketch bei Ausgabe bestimmter Werte abstürzen. Vielleicht versuchst Du es mal mit Serial.begin(9600); im setup und schaust nach, wie sich das Programm dann verhält.

Hallo,
das kannst Du auch noch einmal probieren:

digitalWrite(trigger, LOW);  
  delayMicroseconds(2);
 
  digitalWrite(trigger, HIGH);  
  delayMicroseconds(10);
 
  digitalWrite(trigger, LOW);
  dauer = pulseIn(echo, HIGH);
  dauer = (dauer/2);
  entfernung = dauer / 29.1;

Gruß und Spaß
Andreas

SkobyMobil:

digitalWrite(trigger, LOW);  

delayMicroseconds(2);

digitalWrite(trigger, HIGH);  
 delayMicroseconds(10);

digitalWrite(trigger, LOW);
 dauer = pulseIn(echo, HIGH);
 dauer = (dauer/2);
 entfernung = dauer / 29.1;

Das war es, hat tatsächlich an dem delay gelegen.
Danke auch an jurs, hätte ich es doch mal gleich ausprobiert :slight_smile:

PS: muss ich den Thread hier selber schließen ?