Hallo,
mein Lauflicht sieht eigentlich wie im Video aus. Nur das meins entweder immer rechts herum dreht oder links herums. Hat also keinen Anschlag zum Richtungswechsel. Wenn das im Video langsamer laufen würde, bin ich fest der Meinung das es auch optisch ruckt. Also von LED zu LED springen würde.
Mein Code sieht so aus. Für das Lauflicht sind die Funktionen void Kometenschweif_dreht_CW () und void Kometenschweif_dreht_CCW () verantwortlich. Die Geschwindigkeit wird durch das Array bestimmt. Das Array ersetzt zusammen mit millis() die blockierend wirkende delay Funktion. Zur Info das nichts verwechselt wird. Das Lauflicht dient als Showeffekt beim elektronischen LED würfeln.
// Arduino Mega 2560
// Würfelaugen LED Zusammenfassung (Methode von Erik Bartmann, o´reilly Verlag, Arduino entdecken
int GruppeA = 22; // Port.A.22 LED Nr. 4 (mittelste)
int GruppeB = 23; // Port.A.23 LED Nr. 1 + 7
int GruppeC = 24; // Port.A.24 LED Nr. 3 + 5
int GruppeD = 25; // Port.A.25 LED Nr. 2 + 6
int WuerfelAugen = 0; // Wert zwischen 1 und 6
int TASTER = 2; // Start-Taster zum würfeln, im Setup mit internen PullUp Widerstand aktiv
int TasterStatus = HIGH; // Zustand vom Taster
// Geschwindigkeitssteigerung des Kometenschweifs bzw. abbremsen
int PAUSE [32] = {134,139,144,149,154,160,165,170,175,180,185,191,196,201,206,212,217,223,228,233,239,244,250,255,261,266,272,277,283,289,294,300};
int SPEED = 31;
// Anfangsposition vom Kometenschweif
int LEDPOS_1 = 4; // auf sichere LED Position setzen für ersten Durchlauf
int LEDPOS_2 = 5; // auf sichere LED Position setzen für ersten Durchlauf
int LEDPOS_3 = 6; // auf sichere LED Position setzen für ersten Durchlauf
int LAST_LED = 3; // auf sichere LED Position setzen für ersten Durchlauf
int LED_1, LED_2, LED_3; // zum zwischen speichern der LED Position zum umdrehen
unsigned long ZEIT_NEW = 0; // Ersatzvariable für millis() um delay() zu ersetzen
unsigned long ZEIT_OLD = 0; // Ersatzvariable für millis() um delay() zu ersetzen
int LED_H1 = 255; // 255, Helligkeiten der LEDs
int LED_H2 = 96; // 96
int LED_H3 = 16; // 16
boolean TASTER_Pressed = false; // Taster Anfangsstatus definieren ( Wurde Taster gedrückt oder nicht? )
void setup()
{
Serial.begin(9600);
pinMode(TASTER, INPUT); // Start-Taster zum würfeln und
digitalWrite(TASTER, HIGH); // internen PullUp Widerstand aktiviert
// Pins 3 bis 6 für den Kometenschweif setzen
for (int thisPin = 3; thisPin <= 6; thisPin++) {
pinMode(thisPin, OUTPUT);
}
// Pins für die Würfelaugen setzen und kurz einschalten
DDRA = 15; // Port.A, Bit 0 bis 3 Ausgang
PORTA = 15; // Port.A, Bit 0 bis 3 eingeschalten
delay(500);
PORTA = 0; // Port.A alle Ausgänge Aus
// Serial.println("\n[memCheck]");
// Serial.println(freeRAM(), DEC);
}
void loop() {
ZEIT_NEW = millis(); // Millisekunden seit µC Start/Reset abfragen und merken
TasterStatus = digitalRead(TASTER); // Taster abfragen, wenn nicht gedrückt liegt HIGH Signal an
if (TASTER_Pressed == true && TasterStatus == HIGH) {
Schweif_nach_links_umdrehen (); // LEDs werden in der Reihenfolge umgedreht
TASTER_Pressed = false; // Hilfsvariable wird geändert
}
if (TASTER_Pressed == false && TasterStatus == LOW) {
Schweif_nach_rechts_umdrehen (); // LEDs werden in der Reihenfolge umgedreht
TASTER_Pressed = true; // Hilfsvariable wird geändert
}
if (TasterStatus == LOW) { // wenn Taster gedrückt wird liegt LOW Signal an
Kometenschweif_dreht_CW (); // Schweif dreht rechts herum und beschleunigt
WuerfelAugen = random(1,7); // solange Taster gedrückt ist, Zufallszahlen generieren
//Serial.println(WuerfelAugen); // zu Testzwecken
}
if (TasterStatus == HIGH) { // wenn Taster nicht gedrückt wird liegt HIGH Signal an
Kometenschweif_dreht_CCW (); // Schweif dreht links herum und bremst ab
}
if (TASTER_Pressed == true) {
Wuerfel_loeschen (); // Wuerfelaugen Anzeige löschen
}
if (TASTER_Pressed == false) {
Wuerfelzahl_anzeigen (WuerfelAugen); // Zahl der Würfelaugen mittels LEDs anzeigen
}
} // Loop Ende
/* *** Funktionen *** */
void Kometenschweif_dreht_CW () { // Kometenschweif dreht mit Uhrzeigersinn (rechts herum)
if (ZEIT_NEW - ZEIT_OLD > PAUSE[SPEED]) { // vorgegebene Zeit aus Array schon abgelaufen?
if (LEDPOS_1 > 6) { LEDPOS_1 = 3; } // wenn "letzte" LED erreicht, auf Anfangsposition setzen
analogWrite(LEDPOS_1, LED_H1); // 5, Schweifspitze ganz hell
analogWrite(LEDPOS_2, LED_H2); // 4, LED dahinter etwas dunkler
analogWrite(LEDPOS_3, LED_H3); // 3, nächste LED noch dunkler
analogWrite(LAST_LED, LOW); // letzte alte LED ausschalten
LAST_LED = LEDPOS_3; // 3
LEDPOS_3 = LEDPOS_2; // 4
LEDPOS_2 = LEDPOS_1; // 5
LEDPOS_1++; // 6
SPEED--; // Kometenschweif beschleunigen
if (SPEED < 1) { SPEED = 0; } // schnellsten Wert beibehalten
ZEIT_OLD = ZEIT_NEW; // alte Zeit aktualisieren, Ersatz für delay()
}
}
void Kometenschweif_dreht_CCW () { // Kometenschweif dreht entgegen Uhrzeigersinn (links herum)
if (ZEIT_NEW - ZEIT_OLD > PAUSE[SPEED]) { // vorgegebene Zeit aus Array schon abgelaufen?
if (LEDPOS_1 < 3) { LEDPOS_1 = 6; } // wenn "letzte" LED erreicht, auf Anfangsposition setzen
analogWrite(LEDPOS_1, LED_H1); // Schweifspitze ganz hell
analogWrite(LEDPOS_2, LED_H2); // LED dahinter etwas dunkler
analogWrite(LEDPOS_3, LED_H3); // nächste LED noch dunkler
analogWrite(LAST_LED, LOW); // letzte alte LED ausschalten
LAST_LED = LEDPOS_3;
LEDPOS_3 = LEDPOS_2;
LEDPOS_2 = LEDPOS_1;
LEDPOS_1--;
SPEED++; // Kometenschweif abbremsen
if (SPEED > 31) { SPEED = 31; } // langsamsten Wert beibehalten
ZEIT_OLD = ZEIT_NEW; // alte Zeit aktualisieren, Ersatz für delay()
}
}
void Schweif_nach_links_umdrehen ()
{
LED_1 = LAST_LED; //5, LED Positionen zwischen speichern
LED_2 = LEDPOS_3; //6
LED_3 = LEDPOS_2; //7
LEDPOS_1 = LED_1; //5, LED Positionen umdrehen
LEDPOS_2 = LED_2; //6
LEDPOS_3 = LED_3; //7
if (LEDPOS_3 >= 6) { LAST_LED = 3;}
else { LAST_LED = LEDPOS_3 + 1; }
}
void Schweif_nach_rechts_umdrehen ()
{
LED_1 = LAST_LED; // LED Positionen zwischen speichern
LED_2 = LEDPOS_3;
LED_3 = LEDPOS_2;
LEDPOS_1 = LED_1; // LED Positionen umdrehen
LEDPOS_2 = LED_2;
LEDPOS_3 = LED_3;
if (LEDPOS_3 <= 3) { LAST_LED = 6;}
else { LAST_LED = LEDPOS_3 - 1; }
}
// Zahl der Würfelaugen mittels LEDs anzeigen
void Wuerfelzahl_anzeigen (int Augen)
{
if (Augen%2 != 0) {digitalWrite(GruppeA, HIGH);} // ist der Augenwert ungerade ? (Modulo, ist Restwert ungleich 0)
if (Augen > 1) {digitalWrite(GruppeB, HIGH);} // ist der Augenwert größer 1 ?
if (Augen > 3) {digitalWrite(GruppeC, HIGH);} // ist der Augenwert größer 3 ?
if (Augen == 6) {digitalWrite(GruppeD, HIGH);} // ist der Augenwert gleich 6 ?
}
// Würfelaugen löschen
void Wuerfel_loeschen ()
{
digitalWrite(GruppeA, LOW); // Wuerfelaugen löschen
digitalWrite(GruppeB, LOW);
digitalWrite(GruppeC, LOW);
digitalWrite(GruppeD, LOW);
}
int freeRAM() // Funktion im WWW gefunden, zeigt freien Speicher an
{
extern int __heap_start, *__brkval;
int v;
return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}