ich versuche mit einem Arduino Nano zwei Funktionen parallel auszuführen. Das ganze soll für ein Lego Projekt dienen. Einerseits steuere ich ein Shift Register (74HC595) an, welches zufällig LED's ein- und ausschaltet mit langer Verzögerung.
Die zweite Funktion soll dazu dienen einzelne PIN's via PWM als flackern für ein Feuer zu steuern (schnell). Grundsatzfrage ob das überhaupt funktioniert und wenn ja, wo ist bei meinem Code der Fehler?! Ich benutze kein delay, sondern millis().
Hinweis, wenn ich die Funktion allein ausführefunktionieren sie einzeln wunderbar.
Hier mein Code:
int datapin = 10;
int clockpin = 8;
int latchpin = 9;
int firepin = 6;
int Bit_Folge[] = {0,0,0,0,0,0,0,0};
int Bit_Nr;
int Zufallszahl, i, j, k;
//int delayTime;
unsigned int settimeLED, settimeFIRE;
unsigned int intervalLED, intervalFIRE;
void setup() {
Serial.begin(9600);
randomSeed(analogRead(A0));
pinMode(datapin, OUTPUT);
pinMode(clockpin, OUTPUT);
pinMode(latchpin, OUTPUT);
pinMode(firepin, OUTPUT);
}
void loop() {
looping();
}
void looping() {
// Ausgabe an das Shiftregister
if (millis() - settimeLED >= intervalLED) {
randomLED();
settimeLED = millis();
intervalLED = random(1000,10000);
}
//LED Ausgang 6 flackern
if (millis() - settimeFIRE >= intervalFIRE) {
fireLED();
settimeFIRE = millis();
intervalFIRE = random(10, 180);
}
}
// Einzel LED flackern
void fireLED() {
int brightness = random(10,200);
analogWrite(firepin, brightness);
}
// Funktion zum abschicken an den 74HC595
void send() {
digitalWrite(latchpin, LOW);
for (Bit_Nr=7; Bit_Nr > -1; Bit_Nr--) {
digitalWrite(clockpin, LOW);
digitalWrite(datapin, Bit_Folge[Bit_Nr]);
Serial.print(Bit_Folge[Bit_Nr]);
digitalWrite(clockpin, HIGH);
}
digitalWrite(latchpin, HIGH);
}
//Zufallsfunktion LED Ausgänge
void randomLED() {
for (i = 1; i < 51; i++) {
for (j = 0; j < 8; j++) {
Bit_Folge [i] = 0;
};
Zufallszahl = random(8);
Bit_Folge [Zufallszahl] = 1;
send();
}
}
Ich habe die Variablen deklaration angepasst, aber es änder an dem grundsätzlichem Problem erst einmal nichts. Ich hab den Code aus dem Netz aufgeschnappt und an meine bedürnisse angepasst.
Wie kann ich das ändern? Das übersteigt gerade mein Verständnis :-S
Deine Funktion randomLED blockiert bis die 3 ineinander verknüpften for-Schleifen abgearbeitet sind. In der Zeit kann fireLED nicht ausgeführt werden, wenn du es so lässt.
Dein Array Bit_Folge besteht 8 Elementen. Du greifst aber in Schleife auf 52 Elemente zu. Wie von combie schon gezeigt.
Da steckt ein delay drin, da du nur so schnell schreiben kannst wie die Baudrate (9600 = 1ms/Zeichen) zulässt.
Allerdings brauchst du ein bisschen Zeit für den Schieberegister-Takt
Stimmt, hab es gelöscht, das war zur Kontrolle mal drin.
Okay, aber wie kann ich es besser machen? Ich hab ja selbst bemerkt, das randomLED() blockiert, ich weiß nur nicht wo genau, aber vielleicht sind die for-Schleifen ja das Problem. Nur wie ändern?!
Hab es abgeändert auf 8, zumindest flackert es jetzt schon mal, ich muss nur noch einmal das Shiftregister ausprobieren. Wenn es geht, gebe ich bescheid :-).
So, ich hab mal alles dran geklemmt an meinen Arduino, und es funktioniert leider nicht ganz wie erwartet. Das flackern der einzelnen LED (Feuer) funktioniert jetzt, unabhängig vom Shiftregister. Das macht mir jetzt Probleme. Nach dem hochladen des Scripts funktioniert die Schaltung ganze zweimal danach blitzen alle LED's etwas alle sSekunde einmal auf und das wars. Nach dem Reset blitzen alle dirtekt auf einmal auf und das im Sekundentakt
Mein Code jetzt:
int datapin = 10;
int clockpin = 8;
int latchpin = 9;
int firepin = 6;
int Bit_Folge[] = {0,0,0,0,0,0,0,0};
int Bit_Nr;
int i, j, k;
unsigned int Zufallszahl;
//int delayTime;
using Millis = decltype(millis());
Millis settimeLED, settimeFIRE;
Millis intervalLED, intervalFIRE;
void setup() {
Serial.begin(9600);
randomSeed(analogRead(A0));
pinMode(datapin, OUTPUT);
pinMode(clockpin, OUTPUT);
pinMode(latchpin, OUTPUT);
pinMode(firepin, OUTPUT);
}
void loop() {
//LED Ausgang 6 flackern
fireLED();
// Ausgabe an das Shiftregister
randomLED();
}
// Einzel LED flackern
void fireLED() {
if (millis() - settimeFIRE >= intervalFIRE) {
int brightness = random(10,200);
analogWrite(firepin, brightness);
settimeFIRE = millis();
intervalFIRE = random(10, 180);
}
}
// Funktion zum abschicken an den 74HC595
void send() {
digitalWrite(latchpin, LOW);
for (Bit_Nr=7; Bit_Nr > -1; Bit_Nr--) {
digitalWrite(clockpin, LOW);
digitalWrite(datapin, Bit_Folge[Bit_Nr]);
digitalWrite(clockpin, HIGH);
}
digitalWrite(latchpin, HIGH);
}
//Zufallsfunktion LED Ausgänge
void randomLED() {
if (millis() - settimeLED >= intervalLED) {
for (i = 1; i < 8; i++) {
for (j = 0; j < 8; j++) {
Bit_Folge [i] = 0;
};
Zufallszahl = random(8);
Bit_Folge [Zufallszahl] = 1;
send();
settimeLED = millis();
intervalLED = random(5000,10000);
}
}
}
Ich hatte die IF - milis() -Schleife auch schon im Loop, keine unterschied.
Nicht ganz, "Bit_Folge" wird als Array auf 0 gesetzt, deshalb Variable i und nicht j, und nicht ein einzelnes Bit. So hab ich es verstanden.
Ich verstehe auch deine Frage und würde ich nur eine For-Schleife lassen, würde auch die Schleife funktionieren, nur würde immer nur eine einzelne LED aufleuchten, aber es sollen ja immer zufällig verschiedene aufleuchten, auch mal mehere gleichzeitig usw. deshalb die zweite Schleife.
Dennoch muss irgendwo in der Zeitschleife der Wurm sein, denn Anfangs funktioniert ja die Schleife ein, zweimal, und irfgendwann blitzen die alle LED'S nur noch auf.
Du setzt ein und das gleiche, einzelne Bit acht mal hintereinander auf Null.
Ohne zwischendurch was anderes zu tun. Das ist sinnfrei!
Gaube es, oder glaube es nicht, ist mir egal.
ICH glaube es DIR, sofort!! Und ich liebe dich, denn es funktioniert!!! Perfekt!! Also war mein Ansatz etwas veraltet und Fehlerbehaftet, aber so lernt man doch einiges. Danke an alle die sofort geschrieben haben.
Eine Wissenfrage hab ich dennoch, in jedem Lehrbuch und online in den Einstiegskursen werden die Pins am Anfang mit int deklariert, wieso benutzt du in deinem Lösungsansatz
Trau keinem Tutorial, in dem Pin-Nummern als int deklariert werden
Jedes int trägt den Verdacht in sich, dass der Verfasser mindestens schreibfaul ist.
int ist in der Regel der Datentype, mit dem Berechnungen(und vieles weitere) am schnellsten ausgeführt werden. Das ist ein guter Grund int zu bevorzugen.
Ausnahme: z.B. der 8Bit µC, hier der auf dem Nano.
Weil ich mein schönes dickes C++ Buch gelesen habe.
Somit viele hübsche Features der Sprache kenne, und diese gerne nutze.
Zudem ungerne Byte verplempere, wenn man/ich das ohne nennenswerten Umstand erreichen kann