Lauflicht schaltet kurz fehlerhaft um

Hallo,

ich habe ein erst schneller werdendes und wieder langsamer werdendes Lauflicht gebastelt. Mit 8 LEDs in Reihe nach rechts höherwertig werdend. Er fängt richtig an, beschleunigt in 3 Durchgängen, bleibt richtigerweise an der letzten LED 1sec. stehen und sollte dann nahtlos rückwärts wieder langsamer werden. Klappt fast. Er springt hier kurz zur 1. LED und dann wieder zur 8. und beginnt jetzt erst.
Das heißt beim Übergang von der ersten for Schleife nach dem Delay(1000); in die zweite for Schleife ändert sich seltsamerweise der Inhalt von LED Port.C.
Warum? Ich erkenne keinen Fehler.
Der Inhalt von LED am Port.C wird nur doppelt ausgegeben werden beim Schleifeneintritt, weil ich das so wie es ist übernehme. Danach müßte der Inhalt von LED sofort von 128 auf 64 springen usw. Macht er aber nicht. Er wechselt kurz auf 1 und dann gehts los mit 128 > 64 > 32

Ideen?

// Arduino Mega 2560

 int LED = 1;

int ZeitForward [24] = {576, 529, 484, 441, 400, 361, 324, 289, 256, 225, 196, 169, 144, 121, 100, 81, 64, 49, 36, 25, 16, 9, 4, 1};
int ZeitBackward [24] = {6, 10, 16, 24, 34, 45, 58, 73, 90, 108, 129, 151, 174, 200, 227, 256, 287, 320, 354, 390, 428, 468, 509, 552};

void setup()
{     
   Serial.begin(9600);
   
   DDRC = 255;       // Port.A komplett Ausgang
   PORTC = 255;      // Port.A alles Ein, Funktionstest
   delay(500);
   PORTC = 0;        // Port.A alle Ausgänge Aus
   delay(500);
      
}

void loop()
{
  
  for (int i=0; i <=23; i++)
  {
      PORTC = LED;
      LED = LED << 1;  
      if (LED > 128) {LED = 1;}
      delay(ZeitForward[i]);      
   }

  delay(1000);
    
  for (int i=0; i <=23; i++)
  {
      PORTC = LED;
      LED = LED >> 1;  
      if (LED < 1) {LED = 128;}
      delay(ZeitBackward[i]);      
   }
  
  delay(1000);
  
}

Dann pack mal ein Serial.print an jede Stelle an der LED verändert wird. Das sollte ziemlich schnell Licht ins Dunkel bringen :wink:

hi,

von Deinem problem abgesehen, verstehe ich nicht, daß Du da so elegant mit bitoperationen arbeitest, aber ein array mit potenzen füllst, statt sie einfach dort, wo Du sie brauchst, auszurechnen. also einfach:
pow(i,2);
beim zurückfahren genauso, keine ahnung, warum dort krumme zahlen stehen.

gruß stefan

Doc_Arduino:
Das heißt beim Übergang von der ersten for Schleife nach dem Delay(1000); in die zweite for Schleife ändert sich seltsamerweise der Inhalt von LED Port.C.
Warum? Ich erkenne keinen Fehler.

In Deiner ersten for-loop wird nach je 8 Schleifendurchläufen diese Zeile ausgeführt:
if (LED > 128) {LED = 1;}

Also wird diese Zeile auch nach 24 Schleifendurchläufen ausgeführt. Am Ausgang der ersten for-Schleife ist LED=1 gesetzt worden. Und damit startest Du dann in eine zweite for-Schleife.

Ich erkenne auch keinen Fehler. Das Programm macht genau das, was Du programmiert hast.

Hallo,

a) ich hatte schon Serial.print an mehreren Stellen eingefügt, nur zum posten wieder entfernt, Zwecks Übersicht. Damit sehe ich genau das was ich auch optisch sehe. Er ändert LED von 128 kurz auf 1 und dann wieder auf 128 zurück. Und ich weis nicht warum.

b) ist z.Z. für mich einfacher, ich verbiege die Parabelfunktion in Excel und füge dann per Drag & Drop 24 Werte ins IDE ein. Da muß ich keine Start- und Endwertbedingung programmieren usw. Vielleicht bau ich die die Formel noch ein, vielleicht auch nicht. Wie gesagt, z.Z. so einfacher für mich.

c) jetzt hatte ich hier gerade einen schönen Text geschrieben ... und dann viel mir der auch Fehler auf. Die letzte Port.C Ausgabe liegt ja vor der Bitschieberei und vor der if Bedingung. Die 8. LED muß ja stehen bleiben obwohl sich der Inhalt von LED schon geändert hat.

Danke für die Denkanstöße. :slight_smile:

Wenn Du Parabeln haben willst, dann schau Dir mal das hier an: http://blog.blinkenlight.net/experiments/basic-effects/bouncing-ball.

Hallo,

Deine Funktion bzw. Formel muß ich mir mal in Ruhe anschauen. 1:1 übernehmen geht eh nicht, weil ich 8 Lampen habe die in 3 Durchgängen beschleunigt und abgebremst werden sollen. Deshalb erstmal das Array. Aber Danke für den Hinweis.

Hallo,

Problem gefixt. Ich hoffe das sieht jetzt nicht nach Quick & Dirty aus? :smiley:
Jetzt guck ich mir mal die Formel von Udo an und dann muß das delay raus ... :wink:

void loop()
{
  
  for (int i=0; i <=23; i++)
  {
      PORTC = LED;    
      if (i < 23) {LED = LED << 1;}  
      if (LED > 128) {LED = 1;}
      delay(ZeitForward[i]);
      Serial.print(i); Serial.print("  "); Serial.println(LED);
  }

  delay(1000);
    
  for (int i=0; i <=23; i++)
  {
      PORTC = LED;      
      if (i < 23) {LED = LED >> 1;}        
      if (LED < 1) {LED = 128;}
      delay(ZeitBackward[i]);
      Serial.print(i); Serial.print("  "); Serial.println(LED);
  }
  
  delay(1000);
  
}

Hallo,

jetzt eleganter ... :wink:

@ Udo: Warum nimmst Du die Wurzelfunktion und dann noch doppelt? Welchen anderen Effekt hat das zur Folge? Andere Steilheiten oder? Das habe ich noch nicht rausbekommen. Und wenn ich Deine Formel nachrechne erhalte ich negative delay Werte. Wie geht das denn?

// Arduino Mega 2560

int LED = 1;
int Pause;

void setup()
{     
   Serial.begin(9600);
   
   DDRC = 255;       // Port.C komplett Ausgang
   PORTC = 255;      // Port.C alle Ausgänge Ein - Funktionstest
   delay(500);
   PORTC = 0;        // Port.C alle Ausgänge Aus
   delay(500);
      
}

void loop()
{
  // beschleunigen CW
  for (int i=15; i>=0; i--)
  {
      PORTC = LED;    
      if (i > 0) {LED = LED << 1;}  
      if (LED > 128) {LED = 1;}
      Pause = (sq(i)*5)+6;
      delay(Pause);
      // Serial.print(i); Serial.print("  ");Serial.print(Pause); Serial.print("  "); Serial.println(LED);
  }

  delay(200);
  
  // abbremsen CCW
  for (int i=0; i<=15; i++)
  {
      PORTC = LED;    
      if (i < 15) {LED = LED >> 1;}  
      if (LED < 1) {LED = 128;}
      Pause = (sq(i)*5)+6;
      if (i == 14) {Pause = Pause + 800;}         // letzter Würfelumkippeffekt
      delay(Pause);
      // Serial.print(i); Serial.print("  ");Serial.print(Pause); Serial.print("  "); Serial.println(LED);
  }
 
  
}

Also ich bekomme keine negativen Werte wenn ich das nachrechne. Ich würde sagen Du verrechnest Dich.

Und warum Wurzeln? Ich habe einfach die bekannte Formel h = 1/2 g*t^2 http://de.wikipedia.org/wiki/Wurfparabel nach t umgestellt. Ein StreckenABSCHNITT äußert sich dann eben in der Differenz von zwei Wurzeln. Das steht auch genauso in meinem Blogbeitrag drin.

Hallo,

Du hast doch hier 2x die Wurzel drin? Das ist doch Deine sich änderte Zeitverzögerung je nach LED Position. Oder steh ich mal wieder auf dem Schlauch?

delay((sqrt(((float)20 - pos)/20) - sqrt((19.0 - pos)/20)) * 500);

Muß mich wohl doch verrechnet haben. Du müßtest Dich zwischen Werten von 12,66 und 111,8 bewegen?

Excel Formel:
=SUMME((WURZEL((20 - A1)/20) - WURZEL((19 - A1)/20))*500)
In Spalte A gehts von 0 bis 19

Genau so ist es.

Hallo,

okay, ich nutze einfach die normale Parabelfunktion und den sich daraus ergebenden Werten. Wird bestimmt annähernd der gleiche Effekt rauskommen wenn man die Parabelfunktion noch fein tuned.

Moment, gehört gleich berechnet ... Geduld ... :wink:

Formel wäre =SUMME((A2^2*0,275)+12,66)
Mittelste Spalte sind Deine Werte, rechte Spalte meine Werte. Man sieht, Anfangs und Endwert hauen hin, nur die Krümmung ist eine völlig andere. Cool. 8)

0	12,66	12,66
1	13,00	12,94
2	13,36	13,76
3	13,76	15,14
4	14,20	17,06
5	14,68	19,54
6	15,22	22,56
7	15,81	26,14
8	16,49	30,26
9	17,26	34,94
10	18,14	40,16
11	19,18	45,94
12	20,42	52,26
13	21,94	59,14
14	23,86	66,56
15	26,39	74,54
16	29,96	83,06
17	35,54	92,14
18	46,31	101,76
19	111,80	111,94

Wenn ich meine Spielerei nochmal anpasse auf 8 LEDs, dann komme ich mit der Formel auf einen fast ähnlichen Effekt wie Du.

Pause = sq(i+4)+1;
delay(Pause);

Es macht auf jeden Fall viel Spass sich damit zu beschäftigen und den entstehenden Effekten. Von Deinen DCF77 Effekten bin ich nachwievor begeistert. :slight_smile:

Hallo,

es ist natürlich Unsinn das ich einen fast ähnlichen Effekt habe. Vielleicht nur optisch, weil ich es auf 8 LED's reduzieren muß. Die Parabelkrümmungen sind völlig unterschiedlich. Das zur Korrektur.