Lichtsteuerung Mischtechnik teils zeitverzögert

Hallo alle zusammen!

Ich bin noch ganz neu hier deswegen brauche ich etwas Hilfe. XD

Und zwar möchte ich gerne Led´s steuern mit Pausen. Also z.B. einen Kanal mit pulsierendem Licht und einen anderen Kanal der Blinken oder auch pulsiert, aber mit einer anderen Frequenz oder zu anderen Zeiten.
PWM-Kanäle kenn ich. Aber wie krieg ich das mit den Zeiten hin und das nicht das gesammte Programm gestoppt wird?

Vielen Dank schonmal für die Hilfe

alles Gute

Jörg

PS: mit nem Arduino (erstmal)

joerg1972:
Und zwar möchte ich gerne Led´s steuern mit Pausen. Also z.B. einen Kanal mit pulsierendem Licht und einen anderen Kanal der Blinken oder auch pulsiert, aber mit einer anderen Frequenz oder zu anderen Zeiten.
PWM-Kanäle kenn ich. Aber wie krieg ich das mit den Zeiten hin und das nicht das gesammte Programm gestoppt wird?

Vom Prinzip her habe ich für ein nichtblockierendes Programm, das mit unterschiedlicher Taktung verschiedene Aufgaben "gleichzeitig" erledigt, gerade erst vor zwei Tagen ein Beispielprogramm gepostet:
http://forum.arduino.cc/index.php?topic=209388.msg1538364#msg1538364

Die "blinkenden LEDs" sind dabei tatsächlich blinkende LEDs und als "Pulsieren" wird im Beispiel-Sketch mit einer Frequenz von 0,5 Hz ein hin- und herschwenkender Servo angesteuert. Statt des hin- und herschwenkenden Servos könnte man natürlich auch irgendwas anderes pulsieren lassen.

Standardantwort: Schau dir das Beispiel BlinkWithoutDelay.ino an.
Und schön, dass du PWM kennst, aber was solldas damit zu tun haben?

Hi!

Danke schonmal für die superschenllen Antworten. XD

So wie ´s aussieht müßte es mit den millis gehen. Ich werde erstmal "jurs"- Code ausprobieren und meld mich dann ggf. wieder.

Ist ja eigentlich nicht so schwer was ich brauche.
3-4 Kanäle seperat mit faden oder blinken. Mehr nicht. Deswegen das Pwm.
Soweit ich das verstanden hatte sind nur die Pwm Kanäle in der Lage das Signal zum Pulsieren auszugeben.

Ich hab halt noch nicht die Erfahrung - bin aber immer bereit zu lernen. :wink:

schönes Wochenende schonmal

Hi nochmal!

Also, ich denke mal das es sich mit einem konkreten Bsp. am Besten beschreiben läßt.

Ich hätte gerne 3 Kanäle.

Der erste fadet langsam ein und aus wie beim Sinusfading (Bsp. von Minibloque).
Der zweite fadet auch, aber er fängt erst 2 ekunden später an und evtl. auch eine andere Frequenz.
Der dritte blinkt einfach-von Anfang an.

Also, es geht mir einfach darum die Zeit und die Aktion zu steuern. Einzeln kann ich das auch. Aber bisher hab ich nur delay und das stoppt ja das ganze Programm und ich will nur einen Kanal stoppen.

Wäre toll wenn ihr mir da helfen könntet.
Es handelt sich um Lichgeneratoren mit Glasfaserkabeln und auch um seperate led´s. Also eigentlich nichts komplizeirtes. ( Wenn man´s einmal gelernt hat. :wink:

Danke schonmal

Jörg

Es ist ja schon erwähnt worden. Du kannst das alles mit dem Binkwitout delay machen.
Du baust die in dem Programm verschiedene millis-Routinen wie im Blinkwithout delay.

void loop()
{
  unsigned long currentMillis = millis();
 
  if(currentMillis - previousMillis1 > 10) {
    previousMillis1 = currentMillis;   
// hier läuft er alle 10ms rein also z.B. das schnelle Faden
  }
  if(currentMillis - previousMillis2 > 50) {
    previousMillis2 = currentMillis;   
// hier läuft er alle 50ms rein z.B. das langsamere faden
  }
  if(currentMillis - previousMillis3 > 1000) {
    previousMillis3 = currentMillis; 
//hier läuft er 1* pro Sekunde reinhier das Blinken  
  }
//Hier der Code für der jeden Zyklus abgearbeitet wird 
}

Du kannst die einzelnen Zeiten auch über Potis machen z.B. an Analogeingängen 0-2

void loop()
int time1=analogRead(A0);  // direkt ohne umrechung wäre es zwischen 0-1024ms
int time2=analogRead(A1);
int time3=analogRead(A2);

{
  unsigned long currentMillis = millis();
 
  if(currentMillis - previousMillis1 > time1) {
    previousMillis1 = currentMillis;   
// hier läuft er alle in time1 gelesnen ms rein also z.B. das schnelle Faden
  }
  if(currentMillis - previousMillis2 > time2) {
    previousMillis2 = currentMillis;   
// hier läuft er alle in time2 gelesnen ms rein z.B. das langsamere faden
  }
  if(currentMillis - previousMillis3 > time3) {
    previousMillis3 = currentMillis; 
//hier läuft er in time3 gelesnen ms reinhier das Blinken  
  }
//Hier der Code für der jeden Zyklus abgearbeitet wird 
}

Ich persöhnlich würde es mit Merkern machen die ich in den unterschiedlichen millis abfragen auf 1 setzten würde und nachdem ich sie in der normalen Loop abgearbeitet habe auf null setzten und dann wieder gesetzt werden nachdem die Zeit verstrichen ist.

void loop()
int time1=analogRead(A0);  // direkt ohne umrechung wäre es zwischen 0-1024ms
int time2=analogRead(A1);
int time3=analogRead(A2);

{
  unsigned long currentMillis = millis();
 
  if(currentMillis - previousMillis1 > time1) {
    previousMillis1 = currentMillis;   
    merkertime1=true;
  }
  if(currentMillis - previousMillis2 > time2) {
    previousMillis2 = currentMillis;   
    merkertime2=true;
  }
  if(currentMillis - previousMillis3 > time3) {
    previousMillis3 = currentMillis; 
merkertime3=true;
  }

if (merkertime1){
// Hier das machen was in dem Zeitraum time1 willst
merkertime1=false; // setzt den auf false(0) und dann wird dieser Teil nicht mehr ausgefürt bis die
                            // millis abfrage wieder auf 1 setzt
}


if (merkertime2){
// Hier das machen was in dem Zeitraum time1 willst
merkertime2=false;
}


if (merkertime3){
// Hier das machen was in dem Zeitraum time1 willst
merkertime3=false;
}
}

^Das ist trocken code (schönes Wort). Um Variabeln und deren deklartion und das void setup musst du dich kümmern :smiley: ==> learning bei doing

Gruß
DerDani

Hallo Dani!

Danke für die schnelle Antwort.

Ja. Hatte mir das Blinkwithoutdelay angeguckt. Aber da ich noch neu bin hab ichs nicht kapert-konnte es also auch nicht umschreiben.

Bei den Bsp. wurde delay immer si geschrieben als wäre es ne Pause. Aber das es das ganze Programm paust nicht. Gut. Lassen wir das. Worauf ich hinaus will. Warum muß es immer so kompliziert sein. Warum kann man nicht schreiben. Led grün an Ausgang 9. Ausgang 9 fading. Anfangszeit 100 millis.

So was in der Art.
Ich schnall das noch nicht mit dem letzten Status speichern usw. Dafür bin ich noch zu neu. Kannst Du mir das ein bißchen besser verdaulich äherbringen???

Ps.: ich die Sketche noch nicht genau unter die Lupe genommen, da ich ... is ja auch egal warum. Jedenfalls guck ich sie mir späer noch genau an und evtl. lösen sich dann meine Fragen. Auf jeden Fall schonmal vielen Dank. Und vielleich noch ein Hinweis wie ich einen Deek Robot Pro Mini bespiele. Den Link mit dem cp1202 hab ich schon gesehen-ist am Ende bei der Lösung nur nicht klar was er mit Arduino ==> Cp1202 meint.

joerg1972:
Worauf ich hinaus will. Warum muß es immer so kompliziert sein. Warum kann man nicht schreiben. Led grün an Ausgang 9. Ausgang 9 fading. Anfangszeit 100 millis.

So was in der Art.

Sowas in der Art kannst Du doch locker machen.

Die loop-Funktion sähe dann schematisch so aus (für 2 blinkende und 2 fadende LEDs):

void loop()
{
  unsigned long zeit=millis();
  blinkKanal(LEDPIN1, zeit, led1Phasendauer);
  blinkKanal(LEDPIN2, zeit, led2Phasendauer);
  fadeKanal(FADEPIN1, zeit, fade1Phasendauer);
  fadeKanal(FADEPIN2, zeit, fade2Phasendauer);
}

Deine Aufgabe wäre es dann nur, die zwei Funktionen "blinkKanal" und "fadeKanal" zu schreiben, die die gewünschten Aktion zur gewünschten Zeit am gewünschten Pin durchführen, und zwar ohne dass Du in den Funktionen irgendwelche Blockierungen einbaust. Also "delay" ist beispielsweise verboten.

Sondern die Funktion muß sich anhand der als Parameter übergebenen Zeit ausrechnen, was die Funktion in dieser Mikrosekunde mit den Ausgängen machen soll - diese Aktion durchführen - und sich dann blitzschnell wieder selbst beenden und zur aufrufenden loop-Funktion zurückkehren.

Von wo aus die nächste Funktion aufgerufen wird. Und die nächste. Und immer so weiter. Und am Ende der loop wieder alles von vorne, viele tausend mal pro Sekunde.

Das nennt sich "kooperatives Multitasking", und damit das so läuft, mußt Du als Programmierer das entsprechend so programmieren, dass die Funktionen "kooperativ" sind und Zeit für andere Funktionen übrig lassen.

Hallo jurs!

Das ist gut erklärt. Danke schön. Werd ich ausprobieren. :astonished:

Ich hab so lange gesucht nach Arduinocodes die nur für Lichtsteuerung sind. Die Boards können eigentlich viel zu viel für meine Ansprüche. Brauche ja nur ein bißchen faden und Dauerlicht; vielleicht noch blinken und dann wars das auch schon. ...
Wie auch immer. Soll ich mal Bilder oder Videos einstllen??? Geht das?

Vielen Dank nochmal

Jörg

Videos gehen hier nicht direkt, müsstes irgendwo uploaden.

Bezgl. Lichtorgel gibt es hier einie Sachen.

Möchte nur hier mal 2 Sachen von mir reinstellen
Beim ersten ging es um meine ersten Schritte mit dem Arduino
http://forum.arduino.cc/index.php?topic=176291.30

Teil 2 befasst sich hauptsächlich mit den RGB Leds (WS28xx)
http://forum.arduino.cc/index.php?topic=198987.0

Müsstest dich aber evtl. vorab etwas einarbeiten, ist sehr einfach geschrieben, aber ohne die Materie nur ansatzweise zu kennen, wird es schwierig.

Hallo Jurs!

Hm, ich hab gestern noch ein bißchen probiert und versucht mit der Analyse aus anderen Bsp.: herauszufinden wie ich einen blickkanal und einen fadekanal schreiben kann. Dabei hab ich mir das Blinkexampel und das Fadexample rausgesucht. Aber ich hab noch einige Fragen.

Z.Bsp.
muß ich die leds als int angeben oder als const int???

Und im setup als output deklarieren denke ich mal.

Nur hab ich es nicht hinbekommen wo der fadekanal hingehört; setup oder loop.

muß ich dem selber einen Namen geben und dann den Inhalt in Klammern setzen, so dass er dann immer wieder abgerufen werden kann???)

Das sind so Fragen die ich mir selber noch nicht beantworten kann. Es hängt ja manchmal schon an einem Zeichen. Also bitte nicht verzweifeln. Werd ich auch nicht. Es ist nicht mehr weit und dann hab ichs verstanden und kann qualifizierter fragen. :grin:

und schonmal vielen Dank

Jörg

joerg1972:
Hm, ich hab gestern noch ein bißchen probiert und versucht mit der Analyse aus anderen Bsp.: herauszufinden wie ich einen blickkanal und einen fadekanal schreiben kann. Dabei hab ich mir das Blinkexampel und das Fadexample rausgesucht.

Das sind zwei Beispiele, wie sie für die zur Arduino-Software mitgelieferten Programmbeispiele typisch sind: Sie zeigen, wie irgendwas geht, sind aber vom Prinzip her total unbrauchbar für irgendwelche praktischen Zwecke. Die Beispiel sind voll der Griff ins Klo.

Die Unbrauchbarkeit dieser Beispiele kommt von der verwendeten "delay()" Funktion. Delay-Aufrufe blockieren die gesamte Programmausführung für eine bestimmte Zeit. Das mag für einige wenige nicht-interaktive Programme tatsächlich praktikabel sein, aber für Programme, die entweder

  • interaktiv bedienbar sein sollen oder
  • verschiedene Hardware nahezu "gleichzeitig" ansteuern sollen
    ist "delay" eine Funktion, die nicht verwendet werden darf. Interaktive Programme, und Programme die Dinge gleichzeitig tun sollen, dürfen in der Programmausführung nicht blockiert werden, sondern müssen im "kooperativen Multitasking" laufen.

joerg1972:
muß ich die leds als int angeben oder als const int???

Hardware-Pins im Programm, die sich zur Programmlaufzeit nicht ändern, definiere ich immer per #define Makro, z.B.:

#define LEDPIN 13

Im Gegensatz zu einer Variablendeklaration mit "int" oder "const int" belegt das Makro keinen RAM-Speicherplatz. Ein define-Makro funktioniert so, dass vor der eigentlichen Kompilierung ein "Präprozessor" unsichtbar im Hintergrund ein Suchen und Ersetzen über den Quelltext laufen läßt. Dabei würde dann überall wo "LEDPIN" steht, tatsächlich "13" im Quelltext eingesetzt werden und das Programm erst danach kompiliert. Der bearbeitete Quelltext ändert sich dabei nicht.

Als Merkhilfe, dass ein Ausdruck ein Makro und keine Variable ist, bietet es sich an, Makros immer groß zu schreiben. Denn wenn man sich irgendwo vertippt, etwa beim Makro, können sonst im merkwürdige und kaum erklärbare Fehler beim Kompilieren auftreten, wenn man nicht weiß, dass es sich um ein Makro handelt, das man dann überprüfen müßte.

joerg1972:
Und im setup als output deklarieren denke ich mal.

Ausgänge, die per "digitalWrite" geschaltet werden sollen, müssen vorher auf OUTPUT gesetzt werden.
Bei Ausgängen, die per "analogWrite" auf eine PWM-Ausgabe geschaltet werden sollen, ist das aber nicht erforderlich.

joerg1972:
Nur hab ich es nicht hinbekommen wo der fadekanal hingehört; setup oder loop.

muß ich dem selber einen Namen geben und dann den Inhalt in Klammern setzen, so dass er dann immer wieder abgerufen werden kann???)

Arduino-Sketche sind C++ Programme. Du müßtest Dir mal dringend ein paar Grundkenntnisse der Programmierung aneignen.

Programme bestehen aus Funktionen, die aufgerufen werden. Es gibt im Sprachumfang sowohl "eingebaute" Funktionen, die schon vorhanden sind und die Du direkt verwenden kannst, so wie "pinMode" oder "digitalWrite". Aber Du kannst auch Funktionen selber schreiben, dazu wird eine Funktion nach diesem Schema "deklariert":

rückgabewert Funktionsname(parameterliste)
{
}

Wenn eine Funktion keinen Rückgabewert zurückliefern braucht, heißt der Rückgabewert "void", das steht für "nichts". Die Parameterliste ist eine Liste von Variablendeklarationen, die an die Funktion übergeben werden sollen. Und im Anweisungsblock zwischen den geschweiften Klammern stehen die auszuführenden Befehle.

Es gibt zwei Funktionen, die jeder Arduino Sketch haben muß (setup und loop) und beliebig viele eigene Funktionen kannst Du selber schreiben und aufrufen.

Funktionen dienen zur Strukturierung eines Programms.

Du kannst natürlich auch 500 Zeilen Progrmamcode nur in die "loop" schreiben. Sinnvoller ist es aber, ein Programm in kleinere Funktionsblöcke aufzuteilen, die jede für sich eine ganz kleine Einzelaufgabe übernehmen, z.B. in 25 Funktionen zu je 20 Zeilen.

Für Deinen Anwendungsfall hatte ich Dir eine Struktur mit den beiden selbst zu schreibenden Funktionen blinkKanal und fadeKanal vorgeschlagen. Die müssen natürlich geschrieben werden und sie dürfen kein "delay" enthalten. Sonst wird das Programm ja wieder zeitweise blockiert, und kann in der Zeit nichts anderes tun. Ganz oben hatte ich Dir einen Link gepostet auf ein von mir gepostetes Beispielprogramm, das gleichzeitig ein Blinken (an einer LED) und ein Pulsieren (Hin- und Herbewegen eines Servos) realisiert. Das hilft Dir nicht bei der Realisierung Deiner beiden Funktionen zum Blinken und Pulsieren?

Hallo Jurs!

Erstmal nochmal tausend Dank für die ausführliche Antwort.

Mein Problem ist einfach das noch kein gutes Tutorial in deutsch gefunden habe mit Beschreibung und nicht davon ausgegangen wird das man programmieren kann. Werd ich aber alles lernen.

Also, nochmal Danke und schonmal schönes Wochenende.

Jörg :disappointed_relieved:

Im Gegensatz zu einer Variablendeklaration mit ... "const int" belegt das Makro keinen RAM-Speicherplatz

Hallo jurs, schon mal ausprobiert wie toll der avr-gcc Compiler ist ?
Auch ein

const int LEDPIN=13;

belegt erstmal keinen RAM, solange du keine Tricks wie

const int * mypointer  = &LEDPIN; 
const int & myref = LEDPIN;

machst, sondern es nur wie üblich   digitalWrite(LEDPIN, HIGH);     verwendest.

Wie du selbst auch bemerkt hast, ist die Fehlersuche bei #define einfach eklig, wenn man seine Lieblingsfehler noch nicht aberzogen bekommen hat

#define LEDPIN 13; // hier ist kein Fehler, nur da wo's verwendet wird ;)

Sorry Jörg, lass dich nicht verwirren von pointer und ref.

#define LEDPIN 13
const int LEDPIN=13;
const byte LEDPIN=13;

sind ziemlich gleich.
Und ein  int LEDPIN=13; geht genausogut. (erstmal, fast)
Ist jedenfalls keine Frage von "muß".

michael_x:
Hallo jurs, schon mal ausprobiert wie toll der avr-gcc Compiler ist ?

Ne, da bin ich ein Gewohnheitstier.
Aber schön, wenn der Compiler die überflüssigerweise deklarierte Variable dann selbst wieder weg optimieren kann.