Pages: [1] 2   Go Down
Author Topic: array mit variablen  (Read 1086 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
God Member
*****
Karma: 0
Posts: 696
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,
muss in einem array, dass vor den voids definiert wird, konstante werte enthalten?
Ich habe ien array folgend angelegt:
Code:
const int PWMchannel[15] [24] = { { m[0][0], m[0][1], m[0][2], m[0][3], m[0][4], m[0][5], sd[0], 3500, 1500,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0, ss[0], m[0][21], m[0][22], m[0][23] },
                                  { m[1][0], m[1][1], m[1][2], m[1][3], m[1][4], m[1][5], sd[1], 3500, 1500,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0, ss[1], m[1][21], m[1][22], m[1][23] }, 
....

jetzt teste ich grad und merke, dass zB ss[0] nicht verändert wird, bzw. kein wert erkannt wird (also immer =0)

ist das richtig so? Wie kann ich das dann machen?
Logged

Offline Offline
Edison Member
*
Karma: 21
Posts: 1397
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sind denn die Werte von m[0][0] oder ss[0] schon vorher definiert? Dann sollten auch in PWMchannel[][] die gleichen Werte drin stehen.
Falls Du aber willst, das m[0][0] oder ss[0] in der Definition von PWMchannel[][] quasi Verweise auf Werte sind, die an einer anderen Stelle definiert sind, funktioniert das so nicht.

Du hast zwei Möglichkeiten. Entweder Du verwendest im Array PWMchannel[][] Zeiger die auf die tatsächlichen Werte zeigen, dann musst Du aber anders auf die Werte zugreifen (Stichwort dereferenzieren), oder Du kopierst die Werte bei jeder Änderung im Deinen Arrays m[][] und s[] auch gleichzeitig wieder an die passende Stelle in PWMchannel[][].
Mario.
Logged

Offline Offline
God Member
*****
Karma: 0
Posts: 696
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

die Werte m[0][0] etc. verändern sich im Laufe einer Stunde. Also es sind nicht die gleichen Werte.

Was meinst du mit kopieren? Mach ich das nicht indirekt indem ich irgendwo im code m[0][0] = 12345 definiere?
Werde mal nach dereferenzieren googlen.

VG
Logged

Offline Offline
Edison Member
*
Karma: 21
Posts: 1397
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

die Werte m[0][0] etc. verändern sich im Laufe einer Stunde. Also es sind nicht die gleichen Werte.
Was meinst du mit kopieren? Mach ich das nicht indirekt indem ich irgendwo im code m[0][0] = 12345 definiere?
Nein, machst Du nicht. Bei der Zuweisung der Daten in Dein Array PWMchannel[][] werden die aktuellen Werte aus m[][] und s[] an die Stellen kopiert. Der Wert existiert dann zwei Mal im Speicher. Einmal an der Stelle wo z.B. das Array s[] ihn speichert und einmal an der Stelle wo das Array PWMchannel[][] ihn speichert. Änderst Du nun einen der Werte, hat das keinen Einfluss auf den anderen Wert.

Mit Kopieren meine ich folgendes. Du definierst Dir eine Funktion "void fillPWMchannel()" der Du die beiden aktuellen Arrays s[] und m[][] übergibst (am besten als Zeiger oder Referenz, wegen des Speicherverbrauchs) und das dann Deine bisher "statische" Zuweisung entsprechend ausführt und die Werte von s[] und m[][] an die passenden Stellen von PWMchannel[][] schreibt.
Logged

Germany
Offline Offline
Faraday Member
**
Karma: 49
Posts: 2734
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ich rate mal, du willst mit einem Array von Pointern auf andere Stellen (anderen Arrays) zeigen, so dass, wenn sich dort was ändert ( Beispiel m[0][0] ) ,
auch der Wert  PWMChannel[0][0] ändert ???


Das mit dem Array von Zeigern ist machbar, aber so wie du fragst, lass lieber die Finger davon ( oder du wirst in den nächsten Wochen c-Guru smiley-wink

Wenn PWMChannel Zeiger sind, musst du sie als int* definieren und mit *PWMChannel[ i ][ j ] den Wert abfragen. ( Das meint mkl mit "dereferenzieren" )

Umkopieren, wenn sich ein Wert ändert, macht nicht viel Sinn, finde ich.
Aber für jede Zahl einen Zeiger definieren, braucht den doppelten Speicher... und Konstanten ( 3500 ) wären dann auch Zeiger auf Konstanten.

Warum willst / kanst du nicht die Original-Variablen-Namen ( ss[0] ) nehmen ?

Und, was meinst du mit > "vor den voids definiert " in deinem ersten Post  ???
Vielleicht erzählst du, was das Ganze soll smiley  ?

edit: [ i ] braucht Leerzeichen, wenn's als solches gemeint ist  ; )
« Last Edit: July 01, 2012, 07:38:48 am by michael_x » Logged

Offline Offline
Edison Member
*
Karma: 21
Posts: 1397
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Vor den voids bedeutet vermutlich vor der Definition von "void setup()" und "void loop()".
Logged

Offline Offline
God Member
*****
Karma: 0
Posts: 696
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,
ok, ist wohl doch etwas komplexer, also kurz ein paar mehr Details:

Mein code funktioniert so, dass ich RTC gesteuert stündlich 2 Dimmwerte abfrage: z.B. pwmchannel[0][hour] und pwmchannel[0][hour+1].
Dahinter liegt dann eine Methode, die meine LED uhrzeitgesteuert hoch/runterdimmt, indem die beiden Werte verglichen werden:
Sieht so aus:
Code:
void fadeLight() {
  for (pinCount=0; pinCount<15; pinCount++) {
    if (hour<23) bruch[pinCount] = (float)3600 / (PWMchannel[pinCount][hour+1] - PWMchannel[pinCount][hour]);
    if (hour==23) bruch[pinCount] = (float)3600 / (PWMchannel[pinCount][0] - PWMchannel[pinCount][hour]);
    i[pinCount] = PWMchannel[pinCount][hour] + ((3600 - (3600 - ((mins * 60) + (sec * 1)))) / bruch[pinCount]);
  }
}

Was damit allerdings nicht geht, ist dass ich quasi auf minutenbasis dimme, sprich ich möcht zu bestimmten Stunden noch etwas genauer dimmen, also in 10 Minuten Abständen bestimmte Werte angeben können.
Dazu habe ich mir eine neue FUnktion und entsprehcendes Array gebaut:
Code:
                                //  0   | 10  | 20  | 30  | 40  | 50
const int SunSetValues[5] [6] = { { 3500, 3600, 4095, 4095, 4095, 4095 },
                                  { 3500, 3600, 3700, 4095, 4095, 4095 },
                                  { 3500, 3600, 3700, 3800, 4095, 4095 },
                                  { 3500, 3600, 3700, 3800, 3900, 4095 },
                                  { 3500, 3600, 3700, 3800, 3900, 3950 } };

void SunSet() {
  if (mins<50) {
    for (pinCount=0; pinCount<5; pinCount++) {
      if (mins==0 || mins%10==0) {
        bruchss[pinCount] = (float)600 / (SunSetValues[pinCount][(mins/10)+1] - SunSetValues[pinCount][(mins/10)]);
        valuess[pinCount] = SunSetValues[pinCount][(mins/10)]; /// Zwischenlagerung des Wertes für mins/10
      }
      ss[pinCount] = valuess[pinCount] + ((600 - (600 - (((mins%10) * 60) + (sec * 1)))) / bruchss[pinCount]); //mins%10 => was bei mins = 0?? oder 1???
    }
  }
  if (mins>=50) {
    for (pinCount=0; pinCount<5; pinCount++) {
      if (pinCount<4) ss[pinCount] = 4095;
      if (pinCount==4) {
        if (mins%10==0) {
          bruchss[pinCount] = (float)600 / (m[4][hour] - SunSetValues[pinCount][(mins/10)]);
          valuess[pinCount] = SunSetValues[pinCount][(mins/10)];
        }
        ss[pinCount] = valuess[pinCount] + ((600 - (600 - (((mins%10) * 60) + (sec * 1)))) / bruchss[pinCount]);
      }
    }
  }
}

Die ganze Berechnung und soweiter funktioniert perfekt. Nur halt nicht dass die Werte in meine Hauptarray übergeben werden. Daran scheitert es.

VG


Logged

Germany
Offline Offline
Faraday Member
**
Karma: 49
Posts: 2734
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
wohl doch etwas komplexer
  Meine volle Zustimmung smiley-wink
Was ich verstanden hab:
- PWMchannel enthält Stundenwerte, lineares Interpolieren ist dir aber zu grob.

Was ich nicht verstanden habe:
 - bruch ist nur eine temporäre Variable, warum ein array, warum global, warum float ?
 - das Ergebnis von fadeLight wird in einem globalen Array namens i abgelegt. Das glaub ich nicht ?!
- was ist dein "Hauptarray" 
- Damit du eine feinere Auflösung kriegst, willst du dynamisch diese Stundenwerte ändern ?


Funktionen heissen Funktionen, weil sie aus Eingangswerten etwas berechnen und das als Ergebnis zurückliefern.

Ich könnte mir gut eine Funktion  int fadeLight(const int * PWMHours, int hour, int minute)  vorstellen, die du für jeden Channel einmal aufrufst und die gar keine globalen Variablen braucht, weil sie die benötigten Stundenwerte gleich mitgeliefert bekommt und dadurch für jeden Channel verwendbar ist.
Logged

Offline Offline
God Member
*****
Karma: 0
Posts: 696
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,
also was mir wichtig war bei der Funktion: Wenn der arduino mal ausfällt und wieder angeht, soll er direkt mit dem korrekten PWM Wert starten. Darum hab ich das in Abhängigkeit von der RTC gemacht. Das nur am Rande, das funktioniert super.

Im Array PWM Channel habe ich die Start/Endzeiten pro Stunde gespeichert. SO kann der Arduino um 17:11:25 sich den korrekten Wert ziehen, der zwischen 17 und 18h errechnet wird. Das wird hier linear interpoliert, das ist richtig.

allerdings möchte ich gerne zu bestimmten Uhrzeiten den Fade etwas feiner gestalten. Daher habe ich da ne Variable eingefügt, die dann widerrum über eine 2te FUnktion errechnet wird.

Zu deinen Fragen:
- bruch ist in der tat temporär. Ich definiere irgendwie immer alle variablen global. Ist das kontraproduktiv? Float musste sein, da die zwischenergebnisse auch nachkommastellen liefern. Hatte da hin und her probiert und nur mit float klappte es.

- was meinst du mit "glaub ich nicht"? Ist das nicht sinnvoll? i[] ist der Wert, der dann an den TLC weitergegeben wird.

- das Hauptarray ist das PWM Channel

- genau - an bestimmten Zeiten will ich nen feineren Sonnenauf/untergang simulieren.  (das ganze ist für ne Aquariumbeleuchtung)

VG

Logged

Offline Offline
God Member
*****
Karma: 0
Posts: 696
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Funktionen heissen Funktionen, weil sie aus Eingangswerten etwas berechnen und das als Ergebnis zurückliefern.

Ich könnte mir gut eine Funktion  int fadeLight(const int * PWMHours, int hour, int minute)  vorstellen, die du für jeden Channel einmal aufrufst und die gar keine globalen Variablen braucht, weil sie die benötigten Stundenwerte gleich mitgeliefert bekommt und dadurch für jeden Channel verwendbar ist.

so ganz seh ich den vorteil noch nicht... das array bleibt doch dann inkl. der arrays/variablen im array?

Wie ist der Ansatz hier?

Code:
void PWMvalue() {
  for (pinCount=0; pinCount<15; pinCount++) {
    i[pinCount] = fadeLight(mins, sec, PWMchannel[pinCount][hour+1], PWMchannel[pinCount][hour]);
  }
}
 
int fadeLight(int minute, int sekunde, const int* PWMvaluebald, const int* PWMvaluejetzt) {
  float bruch = (float)3600 / WMvaluebald - PWMvaluejetzt;
  int result;
  result = PWMvaluejetzt + ((3600 - (3600 - ((minuten * 60) + (sekunden * 1)))) / bruch);
  return result;
}
Logged

Germany
Offline Offline
Faraday Member
**
Karma: 49
Posts: 2734
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
so ganz seh ich den vorteil noch nicht
Der Vorteil liegt im Verständnis des Ganzen.
Quote
Ich definiere irgendwie immer alle variablen global. Ist das kontraproduktiv?
Du hast natürlich recht, in der Arduino Umgebung ist es strenggenommen egal. Die Funktionen werden nur nacheinander aufgerufen, und können daher auch mit globalen Variablen arbeiten.

Üblich ist das nicht smiley-wink
Puristen kommen (fast) ganz ohne globale Variable aus, andere verwenden sie für Sachen, die globale Bedeutung haben.
i ist ein schöner Name für einen Schleifenzähler, dessen Wert man nach 3 Zeilen Code nicht mehr braucht, und der danach auch nicht mehr definiert ist.
Generell sollten Variable nur dort sichtbar sein, wo sie gebraucht werden. Das hilft, das Programm verständlicher zu halten und vermeidet manchmal schwer zu findende Fehler.

Einer Funktion y = f(x); sieht man sofort an, dass sie - abhängig von dem Wert von x, einen Ergebnis-Wert für y ermittelt, der danach dort drin steht.
Dass in Wirklichkeit f() irgendwas geheimes macht - in einer globalen Variablen mit dem sehr aussagekräftigen Namen i , etwas abspeichert, kann man nicht so leicht erraten.

Quote
Wenn der arduino mal ausfällt und wieder angeht, soll er direkt mit dem korrekten PWM Wert starten
Das ist schon der richtige Ansatz.
Aber eigentlich ist die Aufgabe doch einfach, dann sollte man auch versuchen, eine einfache Lösung zu finden...
Ich finde, fadeLight() sieht schon einfacher aus als vorher smiley-wink
Wenn ich jetzt noch verstehe, wofür du PWMvalue() brauchst ( bzw. das i[] Array ) ?
Wann werden denn die 5 Channels miteinander verknüpft ?
Logged

Offline Offline
God Member
*****
Karma: 0
Posts: 696
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

also i[] ist dann die Ausgabe an den TLC, ein array, da ich 14 Kanäle nutze.
Code:
void setLight() {
  for (pinCount=0; pinCount<14; pinCount++) {
      Tlc.set(LED[pinCount], i[pinCount]);
      Tlc.update();
      brightness[pinCount]=map(i[pinCount], 0, 4095, 100, 0);
  }
}  
Ich habe das bewusst in eine eigene void (und nicht mit in fadeLight) geschrieben. Wenn ich zB manuell alle blauen LEDs einschalten möchte, dann soll trotzdem im Hintergrund noch die normale fadeLight weiterlaufen.

PWMvalue wäre jetzt der PWM Wert, der aus meinem großem array übergeben werden soll an die FUnktion. Also der PWMwert der aktuellen Stunde und der Stunde+1.

Ganz genau habe ich das mit dem int* noch nicht verstanden - ist das hier notwendig? (const int* PWMvaluebald)
« Last Edit: July 02, 2012, 02:55:17 am by currymuetze » Logged

Germany
Offline Offline
Faraday Member
**
Karma: 49
Posts: 2734
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Ganz genau habe ich das mit dem int* noch nicht verstanden


Du übergibst ein Array aus mehreren int, das ist für die aufgerufene Funktion das gleiche ein Zeiger auf das erste Element.


const ist nur ein Hinweis, dass die Adresse nicht verwendet wird, um dort etwas zu überschreiben. Das kann dann schon der Compiler überwachen.

Quote
Wenn ich zB manuell alle blauen LEDs einschalten möchte, dann soll trotzdem im Hintergrund noch die normale fadeLight weiterlaufen.
Dann ist i also der zentrale Speicher, in dem der jeweilige Zustand pro Pin abgelegt wird, egal wer es gerade ändert?!

Da ist eine globale Variable nicht schlecht ( wenn man kein Purist ist ; ). 
Das "Hauptarray", das du mal erwähnt hast, ich aber nicht so ganz verstanden hab ?

Ein toller Name !  Nur noch von einer Variable namens  _  zu toppen  ---  Hoffe du bist nicht eingeschnappt smiley-wink

Eine Funktion, die diesen Wert ändert, kann trotzdem als


const int pinCount=15;
...
for (pin=0; pin<pinCount; pin++)
   i[pin] = PMValue(pin);

geschrieben werden. Aber - wie schon vorher erwähnt - in der Arduino Umgebung ist es strenggenommen egal.
Logged

Offline Offline
God Member
*****
Karma: 0
Posts: 696
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Ein toller Name !  Nur noch von einer Variable namens  _  zu toppen  ---  Hoffe du bist nicht eingeschnappt

Du meinst PWMchannel[][] ?? Was ist daran so schlimm als variable namen?
Eingeschnappt? Nö - ich freu mich ja eher über TIpps und Lösungsvorschläge, dann gerne auch Verbesserungen smiley-wink

Ich glaube aber, dass ich mit der Funktion mehr oder weniger klar komme (int fadelight)....
Allerdings im VOrfeld eine Frage dazu:
Kann ich in einem FUnktionsaufruf, wo ich die Variablen übergebe (zB int funktion (a,b,c,d) ) bereits eine weitere FUnktion aufrufen, um den Wert zu bekommen? Also:
int funktion (a,b,funktion2(a,b,c,d), d) ???
Gruß
Logged

Germany
Offline Offline
Faraday Member
**
Karma: 49
Posts: 2734
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ich meinte  i[pinCount]


Quote
Kann ich in einem FUnktionsaufruf, wo ich die Variablen übergebe (zB int funktion (a,b,c,d) ) bereits eine weitere FUnktion aufrufen, um den Wert zu bekommen? Also:
int funktion (a,b,funktion2(a,b,c,d), d) ???

Ja, wenn's keine void funktion2 ist und der Ergebnis-Typ passt
Logged

Pages: [1] 2   Go Up
Jump to: