array verbesserung

Hi,
arbeite gerade an einer verbesserung meiner lichtsteuerung. Ziel: wenn ich den arduino mal vom strom nehme (n muss), möchte ich, dass er im anschluss wieder einen uhrzeitabhängigen PWM Wert liefert. Dazu habe ich folgende FOrmel überlegt:

Hier definiere ich in einem Array je PWM Kanal die einzelnen Lichtstufen je Stunde:

const byte LED[] =                       {      5,     0,     1,    14,    11,     4,     9,     6,     7,    10,     2,    12,    13,     8,     7,    13};
int i[16];                               // blau1| blau2| blau3| blau4| blau5| weiß1| weiß2| weiß3| weiß4| weiß5| rotli| rotre| 420li| 420re| 400nm|  Mond//
                                         
                  //  0   | 1   | 2   | 3   | 4   | 5   | 6   | 7   | 8   | 9   | 10  | 11  | 12  | 13  | 14  | 15  | 16  | 17  | 18  | 19  | 20  | 21  | 22  | 23  
const int Blau1[] = { 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 3500, 1500,    0,    0,    0,    0,    0,    0,    0,    0,    0, 1500, 3500, 4095,    0,    0} 
const int Blau2[] = { 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 3500, 1500,    0,    0,    0,    0,    0,    0,    0,    0,    0, 1500, 3500, 4095,    0,    0}  
const int Blau3[] = { 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 3500, 1500,    0,    0,    0,    0,    0,    0,    0,    0,    0, 1500, 3500, 4095,    0,    0}  
const int Blau4[] = { 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 3500, 1500,    0,    0,    0,    0,    0,    0,    0,    0,    0, 1500, 3500, 4095,    0,    0}  
const int Blau5[] = { 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 3500, 1500,    0,    0,    0,    0,    0,    0,    0,    0,    0, 1500, 3500, 4095,    0,    0}

DIe Formel sieht wie folgt aus:

void fadeLight() {
    if (hour<23) {
      i[0] = Blau1[hour] + ((3600000 - (3600000 - ((mins * 60000) + (sec * 1000)))) / (3600000 / (Blau1[hour+1] - Blau1[hour])));
      i[1] = Blau2[hour] + ((3600000 - (3600000 - ((mins * 60000) + (sec * 1000)))) / (3600000 / (Blau2[hour+1] - Blau2[hour])));
      i[2] = Blau3[hour] + ((3600000 - (3600000 - ((mins * 60000) + (sec * 1000)))) / (3600000 / (Blau3[hour+1] - Blau3[hour])));
      i[3] = Blau4[hour] + ((3600000 - (3600000 - ((mins * 60000) + (sec * 1000)))) / (3600000 / (Blau4[hour+1] - Blau4[hour])));

Da die FOrmel immer gleich ist, eben nur eine Variabel/Ziffer ändert (Blau1, Blau2, etc), kann man das sicherlich auch in ein Array verpacken. Leider komm ihc nicht drauf, wie ich das machen muss.

Hier wir dann der Lichtwert gesetzt:

void setLight() {
  for (pinCount=0; pinCount<18; pinCount++) {
    if (pinCount<14) {
      Tlc.set(LED[pinCount], i[pinCount]);
      Tlc.update();
    }
  }
}

Zur Info: Das ist noch nicht compiled.....also die eine oder andere Klammer mag noch falsch sein, aber darum gehts hier auch nicht.

Wie wäre es mit einem mehrdimensionalen Array?

const int values[5][24] = {   { 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 3500, 1500,    0,    0,    0,    0,    0,    0,    0,    0,    0, 1500, 3500, 4095,    0,    0} ,
                                    { 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 3500, 1500,    0,    0,    0,    0,    0,    0,    0,    0,    0, 1500, 3500, 4095,    0,    0} ,
                                    { 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 3500, 1500,    0,    0,    0,    0,    0,    0,    0,    0,    0, 1500, 3500, 4095,    0,    0} ,
                                    { 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 3500, 1500,    0,    0,    0,    0,    0,    0,    0,    0,    0, 1500, 3500, 4095,    0,    0} ,
                                    { 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 3500, 1500,    0,    0,    0,    0,    0,    0,    0,    0,    0, 1500, 3500, 4095,    0,    0} };

Der Zugriff erfolgt dann z.b. über values[1][12]

void fadeLight() {
    if (hour<23) {
      for(row=0;row<5;row++)
          i[row] =values[row][hour] + ((3600000 - (3600000 - ((mins * 60000) + (sec * 1000)))) / (3600000 / (Blau1[hour+1] - Blau1[hour])));

sieht gut aus - kannte ich so noch nicht.
Ist row noch zu definieren oder ist das eine vorgegeben variabel?

row ist eine Variable die ich in der Schleife definiert habe, um die einzelnen "Zeilen" des Arrays zu zählen. Das Array kannst Du im Prinzip wie eine Tabelle betrachten. Der erste Wert steht für die Zeile und der zweite Wert für die Spalte. Arrays können auch mehr als 2 Dimensionen haben, wenn es notwendig ist. z.b. für Koordinaten mit x,y und z Wert.

Hi,

soweit klappt es schon mal.

void fadeLight() {
  if (millis()-delayfade>1000){
    for (pinCount=0; pinCount<15; pinCount++) {
      if (hour<23) i[pinCount] = PWMchannel[pinCount][hour] + ((3600000 - (3600000 - ((mins * 60000) + (sec * 1000)))) / (3600000 / (PWMchannel[pinCount][hour+1] - PWMchannel[pinCount][hour])));
      if (hour==23) i[pinCount] = PWMchannel[pinCount][hour] + ((3600000 - (3600000 - ((mins * 60000) + (sec * 1000)))) / (3600000 / (PWMchannel[pinCount][0] - PWMchannel[pinCount][hour])));
    }
  delayfade=millis();
  }
}

die LEDs springen wie verrückt. Heißt, ein PWM FAde sieht wie folgt aus, zB für i[0] ab 2000 hoch gefaded:
2000
2001
2002
2003
2004
.
.
.
2046
2047
und dann plötzlich
1982
1983
1984
.
.
.

Sehr merkwürdig, ich vermute mal es liegt an der RTC? Aber wirklich finden tu ich den fehler nicht. Vielleicht jemand eine Idee?
Gruß

zu kleiner Datentyp? Das würde den Neustart bei 2048 Werten erklären. Bei Int ist bei +/-32768 Schluss

Hi Marcus,

sorry, hätte den Part mitporsten sollen. Nutze bereits int variablen, und ich glaube das mit 2048 ist nur zufall, ich habe den wert wild gewählt, ist nicht immer 2048:

byte pinCount;
const byte LED[] = {      5,     0,     1,    14,    11,     3,     9,     6,     7,    10,     2,    12,    13,     8,     7,    13};
                   // blau1| blau2| blau3| blau4| blau5| weiß1| weiß2| weiß3| weiß4| weiß5| rotli| rotre| 420li| 420re| 400nm|  Mond//
                   
                                //  0   | 1   | 2   | 3   | 4   | 5   | 6   | 7   | 8   | 9   | 10  | 11  | 12  | 13  | 14  | 15  | 16  | 17  | 18  | 19  | 20  | 21  | 22  | 23  
const int PWMchannel[15] [24] = { { 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 3500, 1500,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0, 2500, 4095, 4095, 4095}, 
                                  { 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 3500, 1500,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0, 2500, 4095, 4095, 4095},  
                                  { 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 3500, 1500,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0, 2500, 4095, 4095, 4095}, 
                                  { 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 3500, 1500,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0, 2500, 4095, 4095, 4095},  
                                  { 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 3500, 1500,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0, 2500, 4095, 4095, 4095},  
                                  { 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 2500, 1500,    0,    0,    0,    0,    0,    0, 3500, 4095, 4095, 4095, 4095, 4095},  
                                  { 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 2500, 1500,    0,    0,    0,    0,    0,    0, 3500, 4095, 4095, 4095, 4095, 4095}, 
                                  { 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 2500, 1500,    0,    0,    0,    0,    0,    0, 3500, 4095, 4095, 4095, 4095, 4095},  
                                  { 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 2500, 1500,    0,    0,    0,    0,    0,    0, 3500, 4095, 4095, 4095, 4095, 4095},  
                                  { 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 2500, 1500,    0,    0,    0,    0,    0,    0, 3500, 4095, 4095, 4095, 4095, 4095},  
                                  { 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095,    0,    0, 1500, 3500, 4095, 4095, 4095}, 
                                  { 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095,    0,    0, 1500, 3500, 4095, 4095, 4095},  
                                  { 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 1500,    0,    0,    0,    0,    0,    0,    0,    0,    0, 4095, 4095, 4095}, 
                                  { 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 1500,    0,    0,    0,    0,    0,    0,    0,    0,    0, 4095, 4095, 4095},
                                  {    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,  255,  255,  255,  255,  255,    0,    0,    0,    0,    0,    0} }; 

int i[16];

Nein. Ich meinte, dass der Int zu klein ist. Schließlich rechnest du mit den Werten - und wenn ein Zwischenschritt über die 32767 rausgeht, gehts wieder bei 0 los. Versuch mal nen long stattdessen beziehungsweise nen unsigned Int - wenn du dir sicher, dass bist keine Negativwerte (auch in den Rechenschritten) benötigst

Hi Marcus,

alles klar-wobei es mich wundern würde, ist für die int nicht das Ergebnis relevant (welches dann ja zwischen 0 und 4095 liegt)?
Zudem hab ich noch mit einer long i[] getestet, damit hätt es ja gehen müssen (-2147483648 bis +2147483647) Klappte aber auch nicht.

Werd mal die Werte um 3 Nullen kürzen, habe nachgerechnet und das Ergbenis passt dann noch.
ALso aus 3600000 mach 3600 und aus 60000 mach 60 etc.
Dann arbeitet der Ardu schon mal mit kleineren Werten. Ob das des Rätsels Lösung ist seh ich dann heut Abend.

W

An Deiner Stelle würde ich erst einmal die Formeln aufräumen, also aus

PWMchannel[pinCount][hour] + ((3600000 - (3600000 - ((mins * 60000) + (sec * 1000)))) / (3600000 / (PWMchannel[pinCount][hour+1] - PWMchannel[pinCount][hour])));

zunächst

PWMchannel[pinCount][hour] + (mins * 60000 + sec * 1000) / (3600000 / (PWMchannel[pinCount][hour+1] - PWMchannel[pinCount][hour])));

Dann sieht man schon klarer was los ist. Deine Zwischenergebnisse sind viel zu groß. Der Punkt ist, daß nicht nur der Typ der Ergebnisvariable auseichen muß sondern auch der für die Zwischenergebnisse. Du hast vermutlich nur die Ergebnisse auf long gesetzt. Damit die Zwischenergebnisse auch noch hinkommen muss aber auch dort alles reinpassen.

Also

PWMchannel[pinCount][hour] + ((long)mins * 60000L + (long)sec * 1000L) / (3600000L / (PWMchannel[pinCount][hour+1] - PWMchannel[pinCount][hour])));

Wenn das auch nicht hilft, dann nimm zur Not floats, aber eigentlich sollte das nicht nötig sein.

Hi Udo,

geb ich dir recht.
Ich habe mal gerade mit float getestet, da dieser Bereich meistens eine Kommazahl ergibt:

bruch[pinCount] = (3600 / (PWMchannel[pinCount][hour+1] - PWMchannel[pinCount][hour]));

(Bruch als float definiert)

Trotzdem erhalte ich bei der seriellen ausgabe nur 1er:

  Serial.println(bruch[1], 5);  
  Serial.println(bruch[10], 4);  
  Serial.println(bruch[12], 3);

Da muss der Fehler liegen, da ich hier immer 1 oder -1 erhalte und nie das richtige Ergebnis hinterm Komma.
Was ist denn falsch definiert?
Den Fehler find ich einfach nicht

Oh man - darauf muss man erst mal kommen, jetzt hab ichs:

bruch[pinCount] = (float)3600 / (PWMchannel[pinCount][hour+1] - PWMchannel[pinCount][hour]);
if (hour<23) i[pinCount] = PWMchannel[pinCount][hour] + ((3600 - (3600 - ((mins * 60) + (sec * 1)))) / bruch[pinCount]);

@ Udo, mit deinem code klappt es nicht ganz, werd daher meine version nutzen.
Trotzdem danke

Hi,

ich möchte hier noch mal etwas optimieren:
Aktuell nutze ich die Stunde, die ich über RTC auslese, um meinen PWM Wert (TLC5940) zu setzen. Das ist so programmiert, dass wenn ich den Arduino ein/ausschalte, ich sofort wieder einen Uhrzeitabhängigen PWM Wert für meine Leuchte habe.
Funktioniert soweit super, hier mal der Code:

                                //  0   | 1   | 2   | 3   | 4   | 5   | 6   | 7   | 8   | 9   | 10  | 11  | 12  | 13  | 14  | 15  | 16  | 17  | 18  | 19  | 20  | 21  | 22  | 23  
const int PWMchannel[15] [24] = { { 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 3500, 1500,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0, 3800, 4095, 4095, 4095}, 
                                  { 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 3500, 1500,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0, 3200, 4095, 4095, 4095},  
                                  { 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 3500, 1500,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0, 2600, 4095, 4095, 4095}, 
                                  { 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 3500, 1500,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0, 2000, 4095, 4095, 4095},  
                                  { 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 3500, 1500,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0, 1400, 4095, 4095, 4095},  
                                  { 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 2500, 1500,    0,    0,    0,    0,    0,    0, 3500, 4095, 4095, 4095, 4095, 4095},  
                                  { 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 2500, 1500,    0,    0,    0,    0,    0,    0, 3500, 4095, 4095, 4095, 4095, 4095}, 
                                  { 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 2500, 1500,    0,    0,    0,    0,    0,    0, 3500, 4095, 4095, 4095, 4095, 4095},  
                                  { 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 2500, 1500,    0,    0,    0,    0,    0,    0, 3500, 4095, 4095, 4095, 4095, 4095},  
                                  { 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 2500, 1500,    0,    0,    0,    0,    0,    0, 3500, 4095, 4095, 4095, 4095, 4095},  
                                  { 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095,    0,    0, 1500, 3500, 4095, 4095, 4095}, 
                                  { 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095,    0,    0, 1500, 3500, 4095, 4095, 4095},  
                                  { 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 1500,    0,    0,    0,    0,    0,    0,    0,    0,    0, 4095, 4095, 4095}, 
                                  { 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 4095, 1500,    0,    0,    0,    0,    0,    0,    0,    0,    0, 4095, 4095, 4095},
                                  {    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,  255,  255,  255,  255,  255,    0,    0,    0,    0,    0,    0} }; 




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]);
  } 
  i[15]=Moon/2;
}

Nachteil: Alle Channels können immer nur zur vollen Stunde starten/enden. Das würde ich gerne auf Minutenbasis bzw. wenn es einfacher ist, auf 10-Schritten-Minutenbasis (also 10,20,30,40,50,0) erweitern, doch ich muss sagen, dass ich hier gerade NULL weiter komme.
Ich würde dazu ja auch den RTC Wert nutzen wollen.
Hat ggfs. jemand direkt einen Ansatz / eine Idee?
Das würde mir zum Einstieg vermutlich schon helfen.

BG
Thorsten