Page 1 of 1
Forum

Welcome to the Tweaking4All community forums!
When participating, please keep the Forum Rules in mind!

Topics for particular software or systems: Start your topic link with the name of the application or system.
For example “MacOS X – Your question“, or “MS Word – Your Tip or Trick“.

Please note that switching to another language when reading a post will not bring you to the same post, in Dutch, as there is no translation for that post!




Multi dimensional a...
 
Share:
Notifications
Clear all

[Solved] Multi dimensional array

8 Posts
2 Users
0 Likes
2,881 Views
(@spike)
Active Member
Joined: 8 years ago
Posts: 9
Topic starter  

Hi Everyone,

First of all, massive thanks to Hans for fantastic info and tutorials.

I have 3D printed this Star in preparation for Christmas http://www.thingiverse.com/thing:816216

The thing is, I wanted to make it more attractive than the standard code that is there currently.

My thoughts are that I would like to have each arm of the star controllable in their own right, ie to flash each arm sequentially to have a rotating effect.

I would also like to be able to light each 'ring' independently to, for a scrolling outward/inward effect.

Having read the tutorials here, I though 2 dimensional arrays were my answer ... or have I got that wrong?

I have succesfully tested the one dimensional array and it works great, more importantly, I have learnt a lot.

I then progressed to trying the 2D array, thats where it has all gone pear shaped :-)

I have a string of 18 WS2811 layed out in a zig zag grid formation, I wanted to be able to have a row light up and scroll down, and the same for columns.

Would you have a minute to look through my code below and perhaps offer some pointers.

Thank you so much for your time

#include <Adafruit_NeoPixel.h>

#define arms 5

#define lightPerArm 4

#define PIN 6

Adafruit_NeoPixel strip = Adafruit_NeoPixel(19, PIN, NEO_RGB + NEO_KHZ800);

void setup() {

  

  int Star[arms][lightPerArm] = { { 0,1,2,3 },

                                             { 4,5,6,7 },

                                             { 8,9,10,11},

                                             { 12,13,14,15},

                                             { 8,9,10,11 }};

  strip.begin();

  strip.setBrightness(40); //adjust brightness here

  strip.show(); // Initialize all pixels to 'off'                                     

                              

  for(int arm=0; arm<=arms-1; arm++) { // Count ARMS

// strip.setPixelColor(Star[arm], strip.Color(0, 0, 0)); // Background pixel colour

    for(int light=0; light<=arms-1; light++) { // Count LIGHTS per ARM

      strip.setPixelColor(Star[(lightPerArm+arm+1)%19], strip.Color(5, 250, 200)); //change RGB color value here

    }

  strip.show();

  delay(60);

  }

  

}


   
ReplyQuote
 Hans
(@hans)
Famed Member Admin
Joined: 11 years ago
Posts: 2660
 

Hi Spike,

sorry for a late reply - I have been sick the past week,... 

I do not have an Arduino handy right now, so I had to do some testing with AutoDesk Circuits IO (it's free and everything runs online).  

I think the line

strip.setPixelColor(Star[(lightPerArm+arm+1)%19], strip.Color(5, 250, 200)); //change RGB color value here

is wrong, and should be something like this:

strip.setPixelColor(Star[arm][light], strip.Color(5, 250, 200)); //change RGB color value here

Here an example to test.
I used text output, and remove the strip/led parts - since I don't have any hardware handy. But it might be a great way to test your loops.

#define arms 5
#define lightPerArm 4
void setup() {
  int Star[arms][lightPerArm] = { { 0,1,2,3 },
                                  { 4,5,6,7 },
                                  { 8,9,10,11},
                                  { 12,13,14,15},
                                  { 8,9,10,11 } };
  Serial.begin(9600);
  
  for(int arm=0; arm<arms; arm++) { // Count ARMS
    for(int light=0; light<lightPerArm; light++) { // Count LIGHTS per ARM
      Serial.print("Arm:");
      Serial.print(arm);
      Serial.print(" Light:");
      Serial.print(light);
      Serial.print(" Array: ");
      Serial.println(Star[arm][light]);
      }
  delay(60);
  }
  
}
void loop() { }

   
ReplyQuote
(@spike)
Active Member
Joined: 8 years ago
Posts: 9
Topic starter  

Hi Hans,

Sorry to hear you have been unwell, I hope you are feeling better.

Your code with the substituted text output worked flawlessly, no surprise there 

However, when I try to include the neopixel code, it all fails miserably.

This is the code that compiles, but shows nothing on the pixels;

#include <Adafruit_NeoPixel.h>
#define arms 5
#define lightPerArm 4
#define PIN 6
Adafruit_NeoPixel strip = Adafruit_NeoPixel(19, PIN, NEO_RGB + NEO_KHZ800);

  int Star[arms][lightPerArm] = { { 0,1,2,3 },
                                  { 4,5,6,7 },
                                  { 8,9,10,11},
                                  { 12,13,14,15},
                                  { 8,9,10,11 } };
void setup() {                                 
  Serial.begin(9600);
  strip.begin();
  strip.setBrightness(40); //adjust brightness here
  strip.show(); // Initialize all pixels to 'off'
}
  void loop() {
  for(int arm=0; arm<arms; arm++) { // Count ARMS
// strip.setPixelColor(Star[arm], strip.Color(0, 0, 0)); // Background pixel colour
    for(int light=0; light<lightPerArm; light++) { // Count LIGHTS per ARM
      strip.setPixelColor(Star[arm][light], strip.Color(5, 250, 200)); //change RGB color value here
      Serial.print("Arm:");
      Serial.print(arm);
      Serial.print(" Light:");
      Serial.print(light);
      Serial.print(" Array: ");
      Serial.println(Star[arm][light]);
      }
  delay(600);
  }
  
}

But if I remove the comments at the beginning of the second line in the Void loop, I get the following errors

C:\Users\Gordon\AppData\Local\Temp\arduino_cd3baf0719d48c203973db3c478550bc\Array2dv2.ino: In function 'void loop()':
Array2dv2:22: error: invalid conversion from 'int*' to 'uint16_t {aka unsigned int}' [-fpermissive]
     strip.setPixelColor(Star[arm], strip.Color(0, 0, 0)); // Background pixel colour
                                 ^
In file included from C:\Users\Gordon\AppData\Local\Temp\arduino_cd3baf0719d48c203973db3c478550bc\Array2dv2.ino:1:0:
C:\Users\Gordon\Documents\Arduino\libraries\Adafruit_NeoPixel/Adafruit_NeoPixel.h:131:5: error: initializing argument 1 of 'void Adafruit_NeoPixel::setPixelColor(uint16_t, uint32_t)' [-fpermissive]
     setPixelColor(uint16_t n, uint32_t c),
     ^
exit status 1
invalid conversion from 'int*' to 'uint16_t {aka unsigned int}' [-fpermissive]

Thank you so much for taking the time to help




   
ReplyQuote
 Hans
(@hans)
Famed Member Admin
Joined: 11 years ago
Posts: 2660
 

Hi Spike!

Thanks ...

You could try doing this:

uint16_t Star[arms][lightPerArm] = { { 0,1,2,3 },
                                  { 4,5,6,7 },
                                  { 8,9,10,11},
                                  { 12,13,14,15},
                                  { 8,9,10,11 } };

(replace "int" with "uint16_t")
It seems that the function "setPixelColor(uint16_t n, uint32_t c)" prefers a 16 bit unsigned int, instead of a regular int.

The other error message (after removing the "//" in front of the comment line) is probably because you're calling an entire array row: 

Star[arm]

which should be 

Star[arm][light]

Hope this helps 


   
ReplyQuote
(@spike)
Active Member
Joined: 8 years ago
Posts: 9
Topic starter  

Hi Hans,

Replacing  worked great. Not sure why though, int has worked for my other LED projects ... but they didn't involve arrays so maybe thats why.

Fixed the other issue too, with (Star[arm][lightPerArm]

Now my display works great but for just one loop, but the results from the serial monitor show that the loop is repeating as it should.

After upload (or reset) each arm lights from 1 through 5, but after that, pixels 4, 8, 12, 16 (counting from zero) turn off then on in sequence in a continuous loop.

The altered code is;

#include <Adafruit_NeoPixel.h>
#define arms 5
#define lightPerArm 4
#define PIN 6
Adafruit_NeoPixel strip = Adafruit_NeoPixel(19, PIN, NEO_RGB + NEO_KHZ800);

uint16_t Star[arms][lightPerArm] = { { 0,1,2,3},
                                     { 4,5,6,7},
                                     { 8,9,10,11},
                                     { 12,13,14,15},
                                     { 16,17,18,19} };
void setup() {                                 
  Serial.begin(9600);
  strip.begin();
  strip.setBrightness(40); //adjust brightness here
  strip.show(); // Initialize all pixels to 'off'
  delay(1000);
}
  void loop() {
  for(int arm=0; arm<arms; arm++) { // Count ARMS
    strip.setPixelColor(Star[arm][lightPerArm], strip.Color(0, 0, 0)); // Background pixel colour
    strip.show();
    for(int light=0; light<lightPerArm; light++) { // Count LIGHTS per ARM
      strip.setPixelColor(Star[arm][light], strip.Color(5, 250, 200)); //change RGB color value here
      strip.show();
      Serial.print("Arm:");
      Serial.print(arm);
      Serial.print(" Light:");
      Serial.print(light);
      Serial.print(" Array: ");
      Serial.println(Star[arm][light]);
      }
  delay(1000);
  
  }
  
  
}

 Thank you so much for your support.


   
ReplyQuote


 Hans
(@hans)
Famed Member Admin
Joined: 11 years ago
Posts: 2660
 

You might want to add

strip.show();

Just before the 

delay(1000);

This way the colors will show at the correct, then turn black, and the next "ring" is done. 

You're most welcome! 


   
ReplyQuote
(@spike)
Active Member
Joined: 8 years ago
Posts: 9
Topic starter  

Hi Hans,

Again, thank you so much for all your help. I would have been at it for a very long time without your invaluable support.

Finally, it is doing what I wanted it to do, the final issue was because I had the last commands in the wrong place 

My code now looks like this

#include <Adafruit_NeoPixel.h>
#define arms 5
#define lightPerArm 4
#define PIN 6
Adafruit_NeoPixel strip = Adafruit_NeoPixel(19, PIN, NEO_RGB + NEO_KHZ800);

uint16_t Star[arms][lightPerArm] = { { 0,1,2,3},
                                     { 4,5,6,7},
                                     { 8,9,10,11},
                                     { 12,13,14,15},
                                     { 16,17,18,19} };
void setup() {                                 
  Serial.begin(9600);
  strip.begin();
  strip.setBrightness(40); //adjust brightness here
  strip.show(); // Initialize all pixels to 'off'
}
  void loop() {
  for(int arm=0; arm<arms; arm++) { // Count ARMS
    strip.setPixelColor(Star[arm][lightPerArm], strip.Color(0, 0, 0)); // Background pixel colour   
    for(int light=0; light<lightPerArm; light++) { // Count LIGHTS per ARM
      strip.setPixelColor(Star[arm][light], strip.Color(5, 250, 200)); //change RGB color value here    
      Serial.print("Arm:");
      Serial.print(arm);
      Serial.print(" Light:");
      Serial.print(light);
      Serial.print(" Array: ");
      Serial.println(Star[arm][light]);      
    }
      
   strip.show();    
   delay(50); 
  }   
  
  for(int x=0; x<=18; x++) {    
  strip.setPixelColor(x,0,0,0);
  strip.show(); 
 }
 
 delay(100);
 
}

 

I can now try to tweak it for the rest of the star ... at least I'll do my best 


   
ReplyQuote
 Hans
(@hans)
Famed Member Admin
Joined: 11 years ago
Posts: 2660
 

That's good to hear Spike! Awesome! 

Glad I could help and thanks for posting you final code ... 
Feel free to post here again if you have question.


   
ReplyQuote

Like what you see and you'd like to help out? 

The best way to help is of course by assisting others with their questions here in the forum, but you can also help us out in other ways:

- Do your shopping at Amazon, it will not cost you anything extra but may generate a small commission for us,
- send a cup of coffee through PayPal ($5, $10, $20, or custom amount),
- become a Patreon,
- donate BitCoin (BTC), or BitCoinCash (BCH).

Share: