Hat sich erledigt....Programmier Frage... habe ich selbst rusgefunden :-)

:slight_smile: :)Hallo Forum

Ich habe ja schon einmal hier im Forum meine Exquinox Clock vorgestellt. Nun erstelle ich mir mit Processing ein desktop Menü und möchte meine Projekte darüber steuern. Am Ende des Tread`s hänge ich ein Bild des Menüs an , so das man es besser versteht was ich meine. Also bei der oberen Ledleiste im bild ist alles ok. da kann ich über das Haupt Menü (LED Aneige mit der maus anwählen, ob ein Lauflicht, Blinken oder sonstige Effekte ausgeführt werden, sowol auf den Desktop als auch an meiner Ledleiste zum Testen. Meine Schwierigkeiten sind folgende : Ich möchte mir meine Equinox auf dem Desktop Menü auch ausführen lassen. Der Kranz der Equinox ist schon auf dem Bild zusehen und wird mit folgenden Skech aufgebaut.

void uhrkranz()
{
stroke(50,100,200,5);
frameRate(50);
colorMode(HSB);
fill(180);
ellipse(600,380,50,35);
fill(0);
textSize(20);
if (tik < 10) {text("0",587,388);text(tik,600,388);}
  else
  {text(tik,587,388);} 
;
if(frameCount<61) {
translate(width/1.7,height/2);
strokeWeight(frameCount/4);
rotate(radians(frameCount*6));
fill(255,255,0);
ellipse(120,120,15,15);
fill(255,255,255);
ellipse(120,120,5,5);
}
}
void setup()
{
 colorMode(HSB); 
 background(175,255,255);  // Hintergrund Farbe
 size(displayWidth, displayHeight); // Größe der Arbeitsfläche
 font = loadFont("Arial-Black-48.vlw"); //weist dem Objekt font die Grafiken für die einzelnen Buchstaben zu
 textFont(font); //estellt ein Objekt textFont mit dem Parameter font
 }
void draw() {
       
  Uhrzeit();  // Uhrenfunktion laufen lassen
  menue1();   // Menue1 ausgaben
  ledanzeige(); //Led Anzeige ausführen
  lauflicht();
  uhrkranz();
}

Uhr und Datum im Oberen Bereich laufen auch.
Wenn ich jetzt aber den Kran der Uhr im Loop()/Draw() aufbauen lasse , wird die Funktion jedesmal durchlaufen. jetzt möchte ich in dem Kranz anders Farbig die Sekunden , Minuten und Stunden anzeigen lassen, jedoch werden diese Optionen jedesmal durch den neu Aufbau des Kranzes überschrieben und somit nicht mehr sichtbar. Wie stelle ich es an das der Kranz nur 1x aufgebaut wird und die farben der Zeiger für Sekunden,Minuten und Stunden sichtbar sind. Gibt es einen Befehl s das der Kranz aufgebaut wird und dann erst jedesmal wieder wenn die Sekunden voll sind und kann ich die Funktion nach dem Aufbau verlassen? mit noLoop() kann ich die Funktion zwar verlassen aber dann steht alles andere auch, wie UHR und DATUM. Und wenn es eine Möglichkeit gibt, kann ich die Funktion uhrkranz(); auch aus andere Funktionen aufrufen.

Ich mache das immer so:

void zeichneDisplaymaske()
{

hier wird das "Grundgerüst" der Anzeige gezeichnet, halt alles, was sich im Betrieb eh nie ändert
Bsp.:
display.print("Akku: ");
}

void aktualisiereDisplay()
{
hier rein kommen die Sachen, die sich im Betrieb ändern können, da werden Ausgaben überschrieben und
neu gezeichnet usw.
z.B.:
display.print(akkuSpannung); // wobei hier manchmal erstmal der alte Wert mit Hintergrundfarbeüberschrieben werden muss
}

Bei Bedarf kann man zeichneDisplaymaske() auch im Programm jederzeit aufrufen, wenn man z.B. Menüs hat, die gelegentlich erscheinen oder so.
Wenn man das sehr gut durchdacht macht, schafft mans sogar mit nem Arduino und nem TFT, erstaunlich vieles, flüssig auszugeben.

Danke Rabenauge

Ja so habe ich es jetzt auch erstellt, ich wusste nur nicht das man sagen wir mal XXXXX.(); von Void XXXXX() oder eine anderen Funktion aufrufen kann. Ich dachte man könnte die Funktion nur aus der LooP() aufrufen kann, so kann man sich auch zum Vorteil irren :slight_smile: Danke noch einmal , jetzt klappt es

Wenn du grössere Programme schreibst wirst du das zu schätzen wissen.
Ich erledige in der Hauptschleife, soweit es nur geht, nur noch solche Unterprogramm-Aufrufe.
Die dann wiederum Unterprogramme aufrufen..manchmal.
Bestes Beispiel ist eine ISR: da setze ich, wenn immer es geht, lediglich ne Variable, die dann in der loop() abgefragt wird, und wenn sie gesetzt ist wird die entsprechende Funktion abgearbeitet.

Vorteil: wenns irgendwo mal hakt, kann man einfach in der loop() nen ganzen Programmteil mal eben schnell auskommentieren.
Und: insgesamt werden die Programme weit übersichtlicher, alles, was zuverlässig läuft, pack ich weit nach unten.
Zudem schreib ich das dann immer so:

void machMalwas() //**************** Machmalwas ****************************************
{
}

void machWasanderes() // ********* was anderes machen *************************************
{
}
So hab ich im Editor schön Unterteilungen, und finde die entsprechenden Unterprogramme schnell.

malerlein:
Danke Rabenauge

Ja so habe ich es jetzt auch erstellt, ich wusste nur nicht das man sagen wir mal XXXXX.(); von Void XXXXX() oder eine anderen Funktion aufrufen kann. Ich dachte man könnte die Funktion nur aus der LooP() aufrufen kann, so kann man sich auch zum Vorteil irren :slight_smile: Danke noch einmal , jetzt klappt es

Es besteht kein Unterschied zwischen den Funktionen von C, jenen von Arduino und denen die Du selbst schreibst. Du kannst in jeder Funktion x-beliebige andere Funktionen aufrufen. Das einzige wo man aufpassen muß ist vermeiden, daß eine Funktion sich selbst aufruft. Das sollte man eigentlich nicht machen (außer in einigen Sonderfällen die Dir ein Informtiker erklähren kann). Die Gefahr besteht eines Stack-Überlaufs mit unerklährlichen Symptomen ähnlich einem vollen RAM und einer Endlosschleife.
Als Wissenserweiterung: man kann auch Zeiger auf Funktionen erzeugen und diese zum Aufruf von Funktionen verwenden....

Grüße Uwe

hi,

sicher wundern sich die elektroniker hier oft, welche fragen wir nichtelektroniker hier stellen können. genauso kommt man als programmierer garnicht auf die idee, daß jemand nicht weiß, daß man funktionen an beliebiger stelle, also auch aus anderen funktionen heraus aufrufen kann.

jürgen, mit diesem wissen kannst Du Deine programme wunderschön strukturieren und viel übersichtlicher machen. kein spaghetticode mehr.

die nächste stufe wäre dann, klassen zu erstellen, in denen Du funktionen und variablen, die zusammengehören, zusammenfaßt. teilweise arbeitest Du ja jetzt schon damit, ohne es zu merken. wenn Du zb. RTC.datumstellen oder RTC.zeitholen (nur zur anschauung, weiß jetzt die funktionsnamen nicht auswendig) benutzt.

Das einzige wo man aufpassen muß ist vermeiden, daß eine Funktion sich selbst aufruft.

beispiele für solche sonderfälle (rekursive funktionen) findest Du im gerade laufenden thread übers sortieren.

gruß stefan

Eisebaer:

Das einzige wo man aufpassen muß ist vermeiden, daß eine Funktion sich selbst aufruft.

beispiele für solche sonderfälle (rekursive funktionen) findest Du im gerade laufenden thread übers sortieren.
gruß stefan

Das rekursive aufrufen von Funktionen ist fast genauso exotisch wie das sinnvolle benutzen von goto :wink: :wink: :wink:
Grüße Uwe

Auf einem µC ist es wahrscheinlich selten. Aber auf dem PC fallen einige der negativen Eigenschaften der Rekursion - wie der Stack Verbrauch - manchmal nicht so sehr ins Gewicht.

Eine typische und häufige Anwendung ist die Traversierung von Binärbäumen. Das kann man natürlich auch auch iterativ machen, aber das artet dann regelrecht in Arbeit aus. Oder eben Quicksort, wo sich die Funktion selbst mit einem neuen Teil-Array aufruft. Binär-Suche arbeitet ähnlich. Die Traversierung einer Ordner/Datei-Struktur ist vielleicht ein praktischeres Beispiel.
Um manche dieser Algorithmen iterativ zu implementieren muss man einen Stack in Software schreiben, was genauso Speicher und Zeit kostet.

Das hängt aber auch sehr stark von der Programmiersprache ab. In funktionalen Sprachen gibt es Konstrukte, die das Stack-Problem umgehen (da man nicht jedesmal den kompletten Stack Frame abspeichern muss wenn der rekursive Funktionsaufruf die letzte Anweisung in einer Methode ist), wodurch die Kosten von Funktionsaufrufen sinken.

Das rekursive aufrufen von Funktionen ist fast genauso exotisch wie das sinnvolle benutzen von goto

uwe, uwe, äpfel mit birnen..

Du weißt nicht, wie oft Du rekursive funktionen benutzt, ohne es zu merken. ob Du jetzt den windows-explorer öffnest, eine internetseite anzeigst oder ein word-dokument (ab office 2010) betrachtest, das steckt überall dahinter.

gruß stefan

uwe, uwe, äpfel mit birnen..

Ja ich unterscheide das was andere machen und kontrollieren ob es funktioniert und das was ich mache. :wink: :wink: :wink:
Und beim Programmieren gilt nichts Rekursivaufrufe (in anderen Programmen) zu benutzen sondern Rekursivaufrufe im eigenen sketch zu schreiben. :wink: :wink: :wink:
grüße Uwe