Integerwerte aus einem Array zerlegen und durch Schleifen laufen lassen

#5495073
Lesenswert?

Guten Abend

Nachdem mir mein erster, dynamischer, Ansatz zu komplex ist,
würde ich es gerne erstmal so versuchen:
1
  const uint8_t lauflicht[18][2] = {
2
    {100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100},
3
    {010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010}
4
  };
5

6
  for (int j = 0; j <= 1; j++) {
7
    for (int i = 1; i <= 18; i++) {
8

9
      setPWM(j, lauflicht[i][j].substring(0, 1), lauflicht[i][j].substring(0, 1), lauflicht[i][j].substring(0, 1));
10
    }
11
   delay(1000);
12
  }

Was soll der Code machen?

Die Funktion setPWM() erwartet 4 Parameter.
Der erste ist die ID der RGB Leiste (1-18), die nächsten drei die 
Helligkeit der einzelnen Farben von 0-9.

So kann in dem Array ein "komplexes" Lauflicht programmiert werden.

Was macht der Code?
Nix, der Compiler (ArduinoIDE) meckert schon bei dem Array:
too many initializers for 'const uint8_t [2] {aka const unsigned char 
[2]}'

Dabei habe ich doch nur ein funktionierendes Array erweitert.

Könnte mir da jemand helfen?
#5495085
Lesenswert?

OK, die Initialiesierung muss andersherum.
Das Beispiel war eine 3x3 Matrix ;-)

1
  int lauflicht[6][18] = {
2
    {100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100},
3
    {010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010},
4
    {100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100},
5
    {010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010},
6
    {100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100},
7
    {010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010}
8
  };
9

10
  for (int j = 0; j <= 1; j++) {
11
    for (int i = 1; i <= 18; i++) {
12

13
      setPWM(j, lauflicht[i][j].substring(0, 1), lauflicht[i][j].substring(0, 1), lauflicht[i][j].substring(0, 1));
14
    }
15
   delay(1000);
16
  }

So passt zumindest das Array :-)

Johannes S. schrieb:
> und substrings auf ein uint8_t geht auch nicht so wie du möchtest.

Stimmt!
Verstehe ich jetzt auch.

Muss ich die Zahl jetzt erst in ein String wandeln,
oder kann ich die "010" auch als Integer zerlegen?
Modulo fällt ja wegen der führenden Nullen weg...

Danke schomal
Gast #5495093
Lesenswert?

Vorschlag: Array von Strukturelementen benutzen.
1
typedef  struct {
2
  uint8_t stripeIndex;
3
  uint8_t intensityRed;
4
  uint8_t intensityGreen;
5
  uint8_t intensityBlue;
6
} RGBITEM;
7

8
const RGBITEM rgbItems[] = {
9
  {0, 1, 0, 0 },
10
  {1, 255, 128, 42 }     // und noch viele mehr
11
};
12

13
void setRGBItem(uint16_t index) {
14
  setPWM(rgbItems[index].stripeIndex,
15
         rgbItems[index].intensityRed,
16
         rgbItems[index].intensityGreen,
17
         rgbItems[index].intensityBlue);
18
}
#5495096
Lesenswert?

Johannes S. schrieb:
> Vorschlag: Array von Strukturelementen benutzen.

Das ist mir leider nicht anschaulich genug.
Aber prinzipiell verstehe ich , was du meinst.

Für das einfachere programmieren des Lichteffektes hätte ich gerne jeden 
Frame in einer Zeile.

Sollte ja auch funktionieren, wenn ich nur die "010" in R=0, G=1, B=0 
zerlegt bekommen würde.

Aber auch dir danke für die Idee!
Gast #5495097
Lesenswert?

Kolja L. schrieb:
> Modulo fällt ja wegen der führenden Nullen weg...

Wieso, dann wird halt 0 übergeben:
1
setPWM(j, lauflicht[i][j] / 100, (lauflicht[i][j] / 10) % 10, lauflicht[i][j] % 10);
So werden die 3 Ziffern auseinander gedröselt und einzeln übergeben. Das 
ist allerdings ziemlich ineffizient, weil die meisten Prozessoren solche 
Divisionen nicht direkt können. Effizienter wäre z.B. so:
1
  uint16_t lauflicht[6][18] = {
2
    {0x100, 0x100, 0x100 ...},
3
    {0x010, 0x010, 0x010, ...},
4
    ...
5
  };
6

7
setPWM(j, lauflicht[i][j] / 256, (lauflicht[i][j] / 16) % 16, lauflicht[i][j] % 16);
Divisionen/Modulo mit 2-erPotenzen werden als Bits-Operationen 
kompiliert und sind viel schneller. Dazu werden die Zahlen hexadezimal 
definiert. Außerdem sollte man den Typ des Arrays als uint16_t 
definieren, damit er nicht unnötig groß ist (int kann z.B. auch 32bit 
groß sein, obwohl die Zahl nie größer 4095 wird), und um negative Zahlen 
ganz auszuschließen. Du könntest due setPWM Funktion so umbauen dass sie 
Zahlen von 0-15 nimmt; dann hast du gleich eine höhere Auflösung. Auf 
Computern im 10er-System zu rechnen ist generell nicht so optimal.
Alternativ kann man die 3 Farbwerte in 3 einzelne uint8_t packen, das 
braucht aber 50% mehr Speicher.
Warum speicherst du überhaupt zig mal die gleichen Werte im Array? Das 
ist sinnlos...

Als Schleifenzähler (i, j) sollte man size_t nehmen, weil dies 
vorzeichenlos ist und auf allen Plattformen groß genug für alle Arrays; 
"int" kann z.B. auf AMD64 zu klein sein.
Gast #5495105
Lesenswert?

Kolja L. schrieb:
> Das ist mir leider nicht anschaulich genug.
> Aber prinzipiell verstehe ich , was du meinst.

Mit den Strukturelementen kann R,G, und B jeweils 0...255 sein. Man kann 
das auch in einen Hexadezimalwert schreiben, dann wäre es z.B. 
0xiirrggbb kodiert. Dann kann ii der Stripindex sein und der Rest die 
Farbwerte. Kommt aufs gleiche raus, aber mit der Struktur ist der 
Zugriff besser lesbar, aus dem uint32_t musst die Element maskieren und 
schieben, für rr z.B. ((value & 0x00ff0000) >> 16;
#5495121
Lesenswert?

Dr. Sommer schrieb:
> uint16_t lauflicht[6][18] = {
>     {0x100, 0x100, 0x100 ...},
>     {0x010, 0x010, 0x010, ...},
>     ...
>   };

Das möchte ich, auch wenn es vielleicht albern ist,
der Übersichtlichkeit wegen nicht verwenden.

Dr. Sommer schrieb:
> setPWM(j, lauflicht[i][j] / 100, (lauflicht[i][j] / 10) % 10,
> lauflicht[i][j] % 10);

Wenn das funktionieren würde, ware ja super!

Leider gibt dieser Code:
1
void loop() {
2

3
  int lauflicht[6][18] = {
4
    {100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100},
5
    {010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010},
6
    {100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100},
7
    {010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010},
8
    {100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100},
9
    {010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010}
10
  };
11

12

13
  for (int j = 1; j <= 6; j++) {
14
    
15
    for (int i = 1; i <= 18; i++) {     
16
      Serial.print("J:");      Serial.print(j);      Serial.print(" I: ");      Serial.print(i); 
17
      Serial.print(" R:");      Serial.print(lauflicht[j][i] / 100); 
18
      Serial.print(" G:");      Serial.print((lauflicht[j][i] / 10) % 10); 
19
      Serial.print(" B:");      Serial.println(lauflicht[j][i] % 10);      
20
      setPWM(j, lauflicht[j][i] / 100, (lauflicht[j][i] / 10) % 10, lauflicht[j][i] % 10);
21
    }
22
    
23
    delay(1000);
24
    
25
  }
26

27

28
  
29
} // loop

Diese Ausgabe:
1
J:1 I: 1 R:0 G:0 B:8
2
J:1 I: 2 R:0 G:0 B:8
3
J:1 I: 3 R:0 G:0 B:8
4
J:1 I: 4 R:0 G:0 B:8
5
J:1 I: 5 R:0 G:0 B:8
6
J:1 I: 6 R:0 G:0 B:8
7
J:1 I: 7 R:0 G:0 B:8
8
J:1 I: 8 R:0 G:0 B:8
9
J:1 I: 9 R:0 G:0 B:8
10
J:1 I: 10 R:0 G:0 B:8
11
J:1 I: 11 R:0 G:0 B:8
12
J:1 I: 12 R:0 G:0 B:8
13
J:1 I: 13 R:0 G:0 B:8
14
J:1 I: 14 R:0 G:0 B:8
15
J:1 I: 15 R:0 G:0 B:8
16
J:1 I: 16 R:0 G:0 B:8
17
J:1 I: 17 R:0 G:0 B:8
18
J:1 I: 18 R:1 G:0 B:0
19
J:2 I: 1 R:1 G:0 B:0
20
J:2 I: 2 R:1 G:0 B:0
21
J:2 I: 3 R:1 G:0 B:0
22
J:2 I: 4 R:1 G:0 B:0
23
J:2 I: 5 R:1 G:0 B:0
24
J:2 I: 6 R:1 G:0 B:0
25
J:2 I: 7 R:1 G:0 B:0
26
J:2 I: 8 R:1 G:0 B:0
27
J:2 I: 9 R:1 G:0 B:0
28
J:2 I: 10 R:1 G:0 B:0
29
J:2 I: 11 R:1 G:0 B:0
30
J:2 I: 12 R:1 G:0 B:0
31
J:2 I: 13 R:1 G:0 B:0
32
J:2 I: 14 R:1 G:0 B:0
33
J:2 I: 15 R:1 G:0 B:0
34
J:2 I: 16 R:1 G:0 B:0
35
J:2 I: 17 R:1 G:0 B:0
36
J:2 I: 18 R:0 G:0 B:8

Werde mir trotzdem nochmal die Modulo Funktion anschauen.
#5495144
Lesenswert?

Aber so:
1
void loop() {
2

3
  uint16_t  lauflicht[2][18] = {
4
    {0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100},
5
    {0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010}
6
  };
7

8

9
  for (int j = 1; j <= 2; j++) {
10
    
11
    for (int i = 1; i <= 18; i++) {     
12
      Serial.print("J:");      Serial.print(j);      Serial.print(" I: ");      Serial.print(i); 
13
      Serial.print(" R:");      Serial.print(lauflicht[j][i] / 256); 
14
      Serial.print(" G:");      Serial.print((lauflicht[j][i] / 16) % 16); 
15
      Serial.print(" B:");      Serial.println(lauflicht[j][i] % 16);      
16
      setPWM(j, lauflicht[j][i] / 256, (lauflicht[j][i] / 16) % 16, lauflicht[j][i] % 16);
17
    }
18
    
19
    delay(2000);
20
    
21
  }
22

23

24
  
25
} // loop

Funktioniert es leider auch nicht:

J:1 I: 1 R:0 G:1 B:0
J:1 I: 2 R:0 G:1 B:0
J:1 I: 3 R:0 G:1 B:0
J:1 I: 4 R:0 G:1 B:0
J:1 I: 5 R:0 G:1 B:0
J:1 I: 6 R:0 G:1 B:0
J:1 I: 7 R:0 G:1 B:0
J:1 I: 8 R:0 G:1 B:0
J:1 I: 9 R:0 G:1 B:0
J:1 I: 10 R:0 G:1 B:0
J:1 I: 11 R:0 G:1 B:0
J:1 I: 12 R:0 G:1 B:0
J:1 I: 13 R:0 G:1 B:0
J:1 I: 14 R:0 G:1 B:0
J:1 I: 15 R:0 G:1 B:0
J:1 I: 16 R:0 G:1 B:0
J:1 I: 17 R:0 G:1 B:0
J:1 I: 18 R:239 G:15 B:14
J:2 I: 1 R:254 G:14 B:15
J:2 I: 2 R:147 G:11 B:0
J:2 I: 3 R:63 G:15 B:14
J:2 I: 4 R:0 G:0 B:15
J:2 I: 5 R:0 G:0 B:0
J:2 I: 6 R:0 G:0 B:0
J:2 I: 7 R:0 G:0 B:0
J:2 I: 8 R:0 G:0 B:0
J:2 I: 9 R:0 G:0 B:0
J:2 I: 10 R:239 G:15 B:14
J:2 I: 11 R:254 G:14 B:15
J:2 I: 12 R:0 G:0 B:0
J:2 I: 13 R:0 G:0 B:0
J:2 I: 14 R:0 G:0 B:0
J:2 I: 15 R:0 G:0 B:0
J:2 I: 16 R:0 G:0 B:1
J:2 I: 17 R:0 G:0 B:0
J:2 I: 18 R:0 G:4 B:0


Vielleicht reden wir aneinander vorbei?
#5495208
Lesenswert?

Dr. Sommer schrieb:
> Unwahrscheinlich. Zeig den korrigierten Code.

Mea culpa, da war ein "j" wo ein "i" sein sollte...:
1
void loop() {
2

3
  uint16_t  lauflicht[2][18] = {
4
    {0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100, 0x100},
5
    {0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010}
6
  };
7

8

9
  for (int j = 0; j <= 1; j++) {
10
    
11
    for (int i = 0; i <= 17; i++) {     
12
      Serial.print("J:");      Serial.print(j);      Serial.print(" I: ");      Serial.print(i); 
13
      Serial.print(" R:");      Serial.print(lauflicht[j][i] / 256); 
14
      Serial.print(" G:");      Serial.print((lauflicht[j][i] / 16) % 16); 
15
      Serial.print(" B:");      Serial.println(lauflicht[j][i] % 16);      
16
      setPWM(i, (lauflicht[j][i] / 256) * 400, ((lauflicht[j][i] / 16) % 16) * 400, (lauflicht[j][i] % 16) *400);
17
    }
18
    
19
    delay(2000);
20
    
21
  }
22

23

24
  
25
} // loop

das funktioniert schon mal, Danke!

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren