Integerwerte aus einem Array zerlegen und durch Schleifen laufen lassen

OP #5495073
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?
Gast
du hast die Initialisierung für ein Array
1
lauflicht[2][18]
definiert.

und substrings auf ein uint8_t geht auch nicht so wie du möchtest.

010 ist eine Konstante im Octalsystem.
OP
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
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
}
OP
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
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
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;
OP
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.
OP
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?
OP
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

Eine eigene Frage? Dieser Thread ist über 8 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.