Papa Baer und der Blink

hallo zusammen,

ich bin recht neu in dem Thema und beginne daher mit dem recht einfachen Thema “LED zum blinken bringen”

nun mach ich das Thema mal selbst etwas anspruchsvoller, und schon klemmt die Säge… :frowning:

ich möchte zwei LED`s dimmen, aber gegensätzlich.

mir ist ein dolles Video über den Weg gelaufen, wo man soetwas sehen kann:

ab 1:10 kann man sehen, was ich meine: “tanzende Lichter”

nun hab ich mich schon ein wenig an die Materie getraut, siehe wie folgt:

/*
 Fading gepimpt
*/


int ledPin1 = 9;  
int ledPin2 = 10;  

int loga[18] =
{0,5,10,15,20,30,40,55,70,90,110,130,150,170,190,210,230,255};

void setup() {
  
}

void loop() 
{
  for(int i=0;i<18;i++)                                                
  {                                                                     
   analogWrite(ledPin1, loga[i]);                                       
    delay(60);                                                         
  }                                                                     
  for(int i=17;i>=0;i--)                                               
  {
  analogWrite(ledPin2, loga[i]);
    delay(60);                                                         
  }
                                                
                                                                
  for(int i=17;i>=0;i--)                                               
  {
  analogWrite(ledPin1, loga[i]);
    delay(60);                                                         
  }
  for(int i=0;i<18;i++)  
  {                                                                     
   analogWrite(ledPin2, loga[i]);                                       
    delay(60);                                                         
  }     




  
}

das Problem, soweit erstmal schon ok, aber die Schritte werden nacheinander abgearbeitet, nicht gleichzeitig. Das Delay stört.

hier

int led1Pin = 10;
int led2Pin = 9;

void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:
  for (int leuchtwert = 0; leuchtwert <= 255; leuchtwert++) {
    analogWrite(led1Pin, leuchtwert);
    analogWrite(led2Pin, 255 - leuchtwert);
    delay(20);
  }
  for (int leuchtwert = 255; leuchtwert >= 0; leuchtwert--) {
    analogWrite(led1Pin, leuchtwert);
    analogWrite(led2Pin, 255 - leuchtwert);
    delay(20);
  }

}

habe ich mal was anderes ausprobiert, nachdem ich im Netz mal bissi gestöbert habe.
kein Delay verwendet, aber ob das wirklich gleichzeitig abläuft, kann ich noch nicht sagen

wie würdet ihr an die Sache rangehen?

für einen Hinweis wäre ich dankbar

lg
Thomas

Ich weiß nicht, was bei dir tanzt, aber hier tanzt nichts.
Kein Sketch vorhanden.

hoppala

jetzt sollte es gehn...

der wollte wohl meine codes nicht so wirklich

ein Ohmen^^???

Du musst das ganze in einer for-Schleife abhandeln, dann wir des fast gleichzeitig ausgeführt.

ich würde eher die for-Schleife und das delay ganz rausschmeißen. loop ist ja schon die schleife.

Zustandsautomat, ifs und millis sind dein Freund

hallo erstmal,

wow, das ging ja schnell...

ElEspanol:
...Zustandsautomat, ifs und millis sind dein Freund

ok^^

und was heißt das jetzt auf deutsch? :stuck_out_tongue:

wo kann ich lernen, wie sowas funktioniert? ... was ich dazu machen muss?

Zustandsautomat

Des weiteren nach BlinkWithoutDelay und der Nachtwächtererklärung (kein Witz) suchen.

Gruß Tommy

Danke Tommy56

auf das "BlinkwhithoutDelay" bin ich über meinen Freund Goockel auch grad gestolpert, da gibt's sogar ein feines tube mit Erklärbär...

nun werde ich mich mal an meine Nachtlektüre machen. :wink:

Danke Euch

PS:
die von Tommy angesprochenen Themen findet man hier:

Hallo Thomas,
“Zustandsautomat … und was heißt das jetzt auf deutsch?” ganz einfach finite state machine :grin:
(den konnte ich mir jetzt nicht verkneifen)

Den Ansatz mit Logarithmustabelle habe ich probiert, sieht sehr gut aus! Einen Zustandsautomaten mit switch/case braucht es nicht unbedingt, da man am Ende der Tabelle von Addieren auf Subtrahieren umschalten kann. Das sieht dann recht schlank aus:

const byte led1Pin = 10;
const byte led2Pin = 9;
byte loga[] = {0, 5, 10, 15, 20, 30, 40, 55, 70, 90, 110, 130, 150, 170, 190, 210, 230, 255};
const byte logalaenge = sizeof(loga) / sizeof(loga[0]);
int8_t logaindex, delta = 1;

void setup() {
}

void loop() {
  analogWrite(led1Pin, loga[logaindex]);
  analogWrite(led2Pin, 255 - loga[logaindex]);
  logaindex += delta;
  if ((logaindex >= logalaenge - 1) || (logaindex <= 0)) {
    delta *= -1;
  }
  delay(20);
}

Das delay gegen millis zu tauschen ist nur notwendig, wenn Dein Arduino noch andere Dinge erledigen soll, was ich vermute. Das bekommst Du selbst hin?

Lesestoff:
Anleitung: Endlicher Automat mit millis()
Anleitung Ein Endlicher Automat entsteht

Was Du machst heißt Auf- und Abblenden oder deutsch fade, was nichts mit fadem Geschmack zu tun hat, wie ich anfangs annahm :grin:
(hier schließt sich die humoristische Klammer)

Für den Anfang, wenn nichts anderes gemacht werden soll geht die For-Schleife und das delay() gut.

Du kannst beide LED in der gleichen FOR Schleife dimmen
einfach den Indes so umrechenen daß der eine von 0 bis 17 geht und der andere von 17 bis 0

for(int i=17;i>=0;i--)                                               
  {
  analogWrite(ledPin1, loga[i]);
  analogWrite(ledPin2, loga[17-i]);
  delay(60);                                                         
  }

Danach kannst Du den Sketch umbauen und ohne delay() (brauchst Du immer) und ohne for-Schleife auskommen.

Grüße Uwe

sodele, erstmal vielen Dank für Eure Antworten

@Uwe
…genau das hab ich drei Tage lang versucht…
manchmal könnte es so einfach sein, aber im Wald muss man schon erstmal den richtigen Baum finden :stuck_out_tongue:

hier mal mein Ergebnis, bischen gepimpt, aber kommt dem “tanzen” doch schon recht nah…

int ledPin1 = 9;  
int ledPin2 = 10;  

int loga[15] =
{2,10,20,30,40,55,70,90,110,130,155,180,205,230,255};

void setup() {
  
}

void loop() 
{
  for(int i=0;i<15;i++)                                                
  {                                                                     
   analogWrite(ledPin1, loga[i]); 
   analogWrite(ledPin2, loga[14-i]);                                      
    delay(35);                                                         
  }                                                                     
                                                          
  for(int i=14;i>=0;i--)                                               
  {
  analogWrite(ledPin1, loga[i]);
  analogWrite(ledPin2, loga[14-i]);   
    delay(35);                                                         
  }
 
}

hab da noch bissi was an den Werten und mit dem Delay gespielt…

Aprospros Delay… die “Nachtwächterschaltung” hats mir ja sowas von angetan…

Delay = gewerkschaftliche Pause

seit wann ist es Knechten gestattet, Pausen abzuhalten… :stuck_out_tongue_winking_eye:

@agmue

mit deinem Vorschlag hab ich mich natürlich auch rumgeprügelt, logisch…

ABER… das ist mir noch bissi zu hoch… das scheinen alles Ausdrücke aus dem reinen C++ zu sein, da fehlt mir noch alles, ich verstehe grad nur Bahnhof ^^

ich hab mir trotzdem mal versucht, mit meiner verklemmten Logik einiges zu erklären.

Das Ergebnis hab ich mal als Kommentar hinter jede Zeile geschrieben, einige Stellen sind noch mit Fragezeichen versehen

const byte led1Pin = 10;                                                                        //warum const byte? um eine bessere Fehlersuche zu ermöglichen?
const byte led2Pin = 9;
byte loga[] = {0, 5, 10, 15, 20, 30, 40, 55, 70, 90, 110, 130, 150, 170, 190, 210, 230, 255};   // warum byte loga? was ist der Vorteil?
const byte logalaenge = sizeof(loga) / sizeof(loga[0]);                                         // was meint der zweite Teil nach dem "=" ?
int8_t logaindex, delta = 1;                                                                    // das verstehe ich nicht. ein integer mit Wertebereich + und - ? warum? was sind die Zuweisungen?

void setup() {
}

void loop() {
  analogWrite(led1Pin, loga[logaindex]);
  analogWrite(led2Pin, 255 - loga[logaindex]);
  logaindex += delta;                                                                           // hier wird zum nächsten Wert im Loga gesprungen?
  if ((logaindex >= logalaenge - 1) || (logaindex <= 0))                                        // hier wird für die Schleife verglichen, ...nur was? hier verstehe ich den Inhalt nicht wirklich
  {
    delta *= -1;                                                                                // hier wird das Vorzeichen von +delta in -delta geändert?
  }
  delay(20);                                                                                    // gewerkschaftliche Pause... :P
}

…die millis kann ich ja erst einbauen, wenn ich verstehe, was das prog wann genau macht.

axso, nochmal zur Richtigstellung:

Klugscheißermodusan
…was ich hier mache heißt auf englisch fading, im deutschen allgemein als dimmen bekannt…
KlugscheißermodusganzschnellohneDelaywiederaus

und wenn ich das geschafft habe umzusetzen, gehts mit zusätzlichen LED-Aufgaben weiter…

Ich hoffe, Du verzeihst mir meinen kleinen homoristischen Ausflug.

warum const byte? um eine bessere Fehlersuche zu ermöglichen?
Ja, auch und der Compiler kann eine Konstante "wegoptimieren". Außerdem hat es für mich eine erklärende Wirkung.

warum byte loga? was ist der Vorteil?
int (beim 8 Bit µC) benötigt zwei Bytes, verschwendet Platz und paßt nicht zu analogWrite, wo nur ein Byte erwartet wird.

was meint der zweite Teil nach dem "=" ?
Das ist die automatische Berechnung der Anzahl der Elemente eines Feldes. Die Division ist beim Typ Byte überflüssig, bei int, long usw. aber notwendig.

das verstehe ich nicht. ein integer mit Wertebereich + und - ? warum? was sind die Zuweisungen?
Das ist ein Byte mit acht Bits, aber mit Vorzeichen, also -128 ... +127. Das braucht man, wenn man unter Null gerät.

hier wird zum nächsten Wert im Loga gesprungen?
"gewechselt" anstelle "gesprungen" wäre mir lieber.

nur was?
Hier wird geprüft, ob der obere oder untere Rand des Feldes erreicht wurde.

hier wird das Vorzeichen von +delta in -delta geändert?
Ja.

gewerkschaftliche Pause...
Ganz wichtig, da bestehe ich drauf :slight_smile:

EDIT: -128 ... +127

wow, schon wieder ein Haufen Input...

humoristische Einlagen sind bei mir gern gesehen, die machen das Lernen leichter :wink:

ich glaub, ich brauch jetzt erst mal nen Delay() ...

das geht ja schon dermaßen in die Tiefe... ich bin doch noch Frischling

agmue:
Das ist ein Byte mit acht Bits, aber mit Vorzeichen, also -127 … +127.

Der Wertebereich von signed char ist -128 (0x80) … +127 (0x7F). :wink:

Whandall:
Der Wertebereich von signed char ist -128 (0x80) .... +127 (0x7F). :wink:

Stimmt, danke! Durch das Zweierkomplement vermisse ich die -0 ;D

moinmoin

Whandall:
Der Wertebereich von signed char ist -128 (0x80) … +127 (0x7F). :wink:

Whandall:
Der Wertebereich von signed char ist -128 (0x80) … +127 (0x7F). :wink:

…na ihr habt Sorgen^^ tztztz

ok, auch diese kleinen Fehlerchen können einen Neuling wie mich eventuell mal zur Verzweiflung bringen.
Danke für die Berichtigung

nun habe ich mal versucht, mein “DoppelfadingmitDelay” mit dem “Blink without Delay” zu kreuzen…

^^ Ratlosigkeit

int ledPin1 = 9;  
int ledPin2 = 10;  
unsigned long previousMillis = 0;
const long interval = 35;

int loga[15] =
{2,10,20,30,40,55,70,90,110,130,155,180,205,230,255};

void setup() {
  
}

void loop() 
{
  unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval)
{
  previousMillis = currentMillis;
  
  for(int i=0;i<15;i++)                                                
  {                                                                     
   analogWrite(ledPin1, loga[i]); 
   analogWrite(ledPin2, loga[14-i]);                                      
                                                            
  }                                                                     
                                                          
  for(int i=14;i>=0;i--)                                               
  {
  analogWrite(ledPin1, loga[i]);
  analogWrite(ledPin2, loga[14-i]);   
                                                           
  }
} 

}

logischerweise funktioniert das nicht.

aber wo ist mein Denkfehler?

Danke für eure Hilfe

lg
Thomas

Bist Du Dir sicher, dass Du 35 Millisekunden Intervall meinst?

Gruß Tommy

äääähmmm jo, oder etwa nicht?

das Intervall (der Wert) entspricht dem vorherigen Delay, also alle 35ms soll der auf den nächsten Wert aus dem Array gehen

PapaBaer465:
aber wo ist mein Denkfehler?

Du benutzt for (statt if).

const byte ledPin1 = 9;
const byte ledPin2 = 10;
const unsigned int interval = 35;

byte loga[15] = { 2, 10, 20, 30, 40, 55, 70, 90, 110, 130, 155, 180, 205, 230, 255 };
const byte elms = sizeof(loga);
void setup() {}

void loop() {
  unsigned long currentMillis = millis();
  static unsigned long previousMillis;
  static byte phase;
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    if (phase < elms) {
      analogWrite(ledPin1, loga[phase]);
      analogWrite(ledPin2, loga[14 - phase]);
    } else {
      analogWrite(ledPin2, loga[phase - elms]);
      analogWrite(ledPin1, loga[elms + 14 - phase]);
    }
    if (++phase >= 2 * elms) {
      phase = 0;
    }
  }
}

Meine Variante mit Herzschlag an Pin 13, um die Quasiparallelität zu zeigen:

const byte led1Pin = 10, led2Pin = 9, blinkLed = 13;
const byte loga[] = {2, 10, 20, 30, 40, 55, 70, 90, 110, 130, 155, 180, 205, 230, 255};
const byte logalaenge = sizeof(loga) / sizeof(loga[0]);
uint8_t logaindex;
int8_t delta = 1;
unsigned long fadeMillis = 0, blinkMillis;
const long fadeinterval = 35, blinkintervall = 100;

void setup() {
  pinMode(blinkLed, OUTPUT);
}

void loop() {
  unsigned long currentMillis = millis();
  if (currentMillis - fadeMillis >= fadeinterval)
  {
    fadeMillis = currentMillis;
    analogWrite(led1Pin, loga[logaindex]);
    analogWrite(led2Pin, loga[logalaenge - 1 - logaindex]);
    logaindex += delta;
    if ((logaindex >= logalaenge - 1) || (logaindex == 0)) {
      delta *= -1;
    }
  }

  if (currentMillis - blinkMillis >= blinkintervall)
  {
    blinkMillis = currentMillis;
    digitalWrite(blinkLed, !digitalRead(blinkLed));
  }
}