jkunimune / NeoPixel_Things

Programs, animations, and interactions for Adafruit NeoPixels.
2 stars 1 forks source link

plz help sir,,,,,i Want to scroll the Array in 8x8 matrix #2

Open LedArts opened 6 years ago

LedArts commented 6 years ago

Hello Dear Master, i want to scroll an Array in this code horizontaly and vertically 8x8 matrix plz help me

include

define PIN 6

define MAX_LED 64

uint32_t LEDColour; unsigned char x = 0; unsigned char Colour[3]; unsigned char heart[10] = {12, 13, 17, 20, 26, 29, 33, 36, 44, 45};

Adafruit_NeoPixel strip = Adafruit_NeoPixel( MAX_LED, PIN, NEO_RGB + NEO_KHZ800 ); void setup() { // put your setup code here, to run once: strip.begin(); // strip.show(); }

void loop() {

for (char number = 0; number < 64; number++) // strip.setPixelColor(number, 0); strip.show();//

// delay(1000); for (char number = 0; number < 10; number++) // strip.setPixelColor(heart[number], 255,0,0); // i want to scroll that heart array strip.show();// delay(1000); }

jkunimune commented 6 years ago

If you want an animation, you'll have to keep a variable and increment it each time the loop runs, so that it can change with each iteration. For example,

...
unsigned char heart[10] = {12, 13, 17, 20, 26, 29, 33, 36, 44, 45};
Adafruit_NeoPixel strip = Adafruit_NeoPixel( MAX_LED, PIN, NEO_RGB + NEO_KHZ800 );
int t; // insert this line to declare t

void setup() {
  t = 0; // insert this line to initialise t
  strip.begin()
  strip.show()
}

void loop() {
  t ++; // insert this line to increment t each loop iteration
  ...

I'm not completely sure what you want to happen after that. If by "scroll", you mean that you want the light sequence to move up the strip, then you just need to increment the position argument of setPixelColor() by t. So replace strip.setPixelColor(heart[number], 255,0,0); with strip.setPixelColor(heart[number]+t, 255,0,0);

As t increases, so will the positions of the red lights.

LedArts commented 6 years ago

thanks a lot for the reply i will try this

8x8 vertical serpentine matrix

Actually i have matrix like this in the image i draw a heart shape by this code in matrix now i have to scroll it horizontally and vertically. so is this solution is applicable on this.

LedArts commented 6 years ago

this is 8x8 vertical serpentine matrix

LedArts commented 6 years ago

sir i try this and you are right its moving one by one but i want to move 8 led column or 8 led shift you are very close to it. plz give me this function

i draw a heart on this matrix heart

and i try it on my level but not get it i do t*8 but one time heart is shown up and one time its down with scrolling.

LedArts commented 6 years ago

hello sir plz reply i am waiting for it.

LedArts commented 6 years ago

sir i try a lot if we do t*16 then it shift 16 led but heart show right. but it shift 2 columns. what should i do that even no. columns are flipped up or led no. 15 become led no. 0 so that again it draw right side.

jkunimune commented 6 years ago

In that case, scrolling would be slightly more complicated. A good way to do it is to first convert the LED indices to x-y coordinates.

With your setup, the x coordinate increases by 1 whenever the LED index increases by 8. That's a good hint that you want to divide by 8. In fact, you'll find that for any index i, x=i/8;. Since integer division truncates, that yields an integer that is 0 for the leftmost row, 1 for the next row, etc. up to 7.

The y coordinate either increases or decreases by 1 whenever the index changes by 1. So in this case, you don't want to divide. You do want to subtract out the most recent multiple of 8 so that the y coordinate does not depend on the column. That's exactly what the modulo operator does: i%8. That returns the correct answer for columns 0, 2, 4, and 6, but an inverted answer for all other columns. So you just need to subtract from 7 in all odd columns.

if (x%2 == 0) // even column
  y = i%8;
else // odd column
  y = 7 - i%8;

With this method, one finds that your {12, 13, 17, 20, 26, 29, 33, 36, 44, 45} becomes the following x-y coordinate pairs: {{1, 3}, {1, 2}, {2, 1}, {2, 4}, {3, 5}, {3, 2}, {4, 1}, {4, 4}, {5, 3}, {5, 2}}

Now, you can easily increment or decrement x or y to shift sideways or vertically. To show the pixels, though, you must convert x and y back to i. Each column before a pixel contributes an additional 8 indices behind it, so x should increase i by 8 (i.e. i = 8*x + f(y)). y can either contribute positively or negatively to i depending on whether the column is odd or even. So either add it directly or subtract y from 7.

if (x%2 == 0) // even column
  i = 8*x + y;
else // odd column
  i = 8*x + 7 - y;

i is then the index of the light to turn on, to go in place of heart[number] in strip.setPixel().

LedArts commented 6 years ago

wow its nice thanks a lot sir can u do one more favour actually i am unable to make this changes in my code because i have some confusions can u plz add this code with my code. plzzzzzzzzzzzzzzzzz

LedArts commented 6 years ago

sir where r u plz help me

LedArts commented 6 years ago

plzzzzz sir.....reply me...

jkunimune commented 6 years ago

You should first replace the heart[] array with a matrix of x-y pairs, since that will be more useful information.

unsigned char[][] heart = {{1, 3}, {1, 2}, {2, 1}, {2, 4}, {3, 5}, {3, 2}, {4, 1}, {4, 4}, {5, 3}, {5, 2}};

Then, I would recommend putting the coordinate conversion code into a method so that you can easily convert x-y coordinates to indices.

int indexOf(int x, int y) {
  if (x%2 == 0) // even column
    i = 8*x + y;
  else // odd column
    i = 8*x + 7 - y;
  return i;
}

Finally, change your call to strip.setPixelColor(). Instead of taking an index straight from heart[], it must read x and y from heart[][], shift them based on t depending on how you want it to move, and then plug the resulting values into your new index method.

int x = heart[num][0];
int y = heart[num][1];
x += t;
strip.setPixelColor(indexOf(x, y), \*other arguments*\);
LedArts commented 6 years ago

thanx a lot .....sir still have some question but i will try first and show you the code.

LedArts commented 6 years ago

sir i try but not get success. please you make it for me......once....i am not so good in programming. i am pasting the program plz see it and overcome the errors and re arrange it for me....its urgent. plz plz plz don't mind.

//Idea -https://www.elecfreaks.com/10544.html

include

define PIN 6

define MAX_LED 64

int t;
uint32_t LEDColour; unsigned char x = 0; unsigned char Colour[3]; unsigned char heart[10] = {12, 13, 17, 20, 26, 29, 33, 36, 44, 45}; unsigned char [][]heart = {{1, 3}, {1, 2}, {2, 1}, {2, 4}, {3, 5}, {3, 2}, {4, 1}, {4, 4}, {5, 3}, {5, 2}}; Adafruit_NeoPixel strip = Adafruit_NeoPixel( MAX_LED, PIN, NEO_RGB + NEO_KHZ800 ); void setup() { // put your setup code here, to run once: strip.begin(); t=0;

strip.show(); }

void loop() { t++; int indexOf(int x, int y) { if (x%2 == 0) // even column i = 8x + y; else // odd column i = 8x + 7 - y; return i; } for (char number = 0; number < 64; number++) // strip.setPixelColor(number, 0); strip.show();//

Colour[0] = random(10 , 20); // Colour[1] = random(0, 20); Colour[2] = random(0, 20); LEDColour = strip.Color(Colour[1], Colour[0], Colour[2]);

int x = heart[10][0]; int y = heart[num][1]; x += t; for (char number = 0; number < 10; number++) // strip.setPixelColor(indexOf(x, y)+(t*8), 255,0,0); strip.show();//

delay(1000); }

jkunimune commented 6 years ago
  1. You can't define a method inside a method in Arduino. You must move the int indexOf(int x, int y) { ... } block to after the last } closing brace.

  2. I don't think Arduino will be happy if you have two variables named heart. You should remove the declaration of the first one, since you never use it.

  3. You'll notice that when you define x, you do it as heart[10][0]. This does not depend on any num, so all of your points will have the same x value. Probably not what you want. Also, 10 is out of bounds for heart[][], which only goes up to 9 if I'm not mistaken. I'm pretty sure what you want is heart[num][0].

  4. You have a +t*(8) hanging around in your .setPixelColor() call from earlier, but it is not necessary anymore, as x += t takes care of the scrolling. You should get rid of that, or else you might get weird results.

LedArts commented 6 years ago

u said-I don't think Arduino will be happy if you have two variables named heart. You should remove the declaration of the first one, since you never use it. but this line is making the heart shape unsigned char heart[10] = {12, 13, 17, 20, 26, 29, 33, 36, 44, 45}; then why we i should remove this.

and What this code stand for unsigned char [][]heart = {{1, 3}, {1, 2}, {2, 1}, {2, 4}, {3, 5}, {3, 2}, {4, 1}, {4, 4}, {5, 3}, {5, 2}}; what is the work or this line and when i use this line in code arduino gives this error expected unqualified-id before '[' token

and when i write this line like unsigned char heart[][] = {{1, 3}, {1, 2}, {2, 1}, {2, 4}, {3, 5}, {3, 2}, {4, 1}, {4, 4}, {5, 3}, {5, 2}}; this to overcome the error it gives another error declaration of 'heart' as multidimensional array must have bounds for all dimensions except the first

LedArts commented 6 years ago

i make changes in program according to u said plz sir check it and guide me.....thanxxxxxxxxxxxxxxxxxxxxx a lot

include

define PIN 6

define MAX_LED 64

int t; uint32_t LEDColour; unsigned char x = 0; unsigned char Colour[3]; //unsigned char heart[10] = {12, 13, 17, 20, 26, 29, 33, 36, 44, 45}; unsigned char heart[][] = {{1, 3}, {1, 2}, {2, 1}, {2, 4}, {3, 5}, {3, 2}, {4, 1}, {4, 4}, {5, 3}, {5, 2}}; Adafruit_NeoPixel strip = Adafruit_NeoPixel( MAX_LED, PIN, NEO_RGB + NEO_KHZ800 ); void setup() { // put your setup code here, to run once: strip.begin(); t=0;

strip.show(); }

void loop() { t++;

for (char number = 0; number < 64; number++) // strip.setPixelColor(number, 0); strip.show();//

Colour[0] = random(10 , 20); // Colour[1] = random(0, 20); Colour[2] = random(0, 20); LEDColour = strip.Color(Colour[1], Colour[0], Colour[2]);

int x = heart[num][0]; int y = heart[num][1]; x += t; for (char number = 0; number < 10; number++) // strip.setPixelColor(indexOf(x, y), 255,0,0); strip.show();//

delay(1000); }

int indexOf(int x, int y) { if (x%2 == 0) // even column i = 8x + y; else // odd column i = 8x + 7 - y; return i; }

jkunimune commented 6 years ago

A quick google reveals that

declaration of 'heart' as multidimensional array must have bounds for all dimensions except the first

means that you must specify bounds for all dimensions except the first when declaring a multidimensional array like 'heart'. In your case, since your second dimension is 2, this means unsigned char heart[][2] = {...

Other than that, it looks good to me.

LedArts commented 6 years ago

sir that error is finished but another error come in line 31 & 32 'num' was not declared in this scope

and if i define int num;

then it finished but another error come in line 46(return i) 'i' was not declared in this scope

what should i do now?

jkunimune commented 6 years ago

That's because num and i were both used, but neither of them were declared. You should declare i before it is used. num should iterate through the heart array, so you should move the num stuff to inside the for (char number... loop and change number to num or num to number; they seem like they're supposed to be the same thing.

LedArts commented 6 years ago

ok sir i declare the num as u said but i don't know how to declare " i ". plz tell me where and how to declare i.

and i am sending one more time the code with changes plz one time u check and compile it.

include

define PIN 6

define MAX_LED 64

int t; uint32_t LEDColour; unsigned char x = 0; unsigned char Colour[3]; //unsigned char heart[10] = {12, 13, 17, 20, 26, 29, 33, 36, 44, 45}; unsigned char heart[][2] = {{1, 3}, {1, 2}, {2, 1}, {2, 4}, {3, 5}, {3, 2}, {4, 1}, {4, 4}, {5, 3}, {5, 2}}; Adafruit_NeoPixel strip = Adafruit_NeoPixel( MAX_LED, PIN, NEO_RGB + NEO_KHZ800 ); void setup() { // put your setup code here, to run once: strip.begin(); t=0;

strip.show(); }

void loop() { t++;

for (char num = 0; num < 64; num++) // strip.setPixelColor(num, 0); strip.show();//

Colour[0] = random(10 , 20); // Colour[1] = random(0, 20); Colour[2] = random(0, 20); LEDColour = strip.Color(Colour[1], Colour[0], Colour[2]); char num; int x = heart[num][0]; int y = heart[num][1]; x += t; for (char num = 0; num < 10; num++) // strip.setPixelColor(indexOf(x, y), 255,0,0); strip.show();//

delay(1000); }

int indexOf(int x, int y) { if (x%2 == 0) // even column i = 8x + y; else // odd column i = 8x + 7 - y; return i; }

jkunimune commented 6 years ago

http://lmgtfy.com/?q=how+to+declare+i+in+arduino

In Arduino, you declare a variable by writing its type, a space, its name, and a semicolon. i is a number representing an index on the pixel strip, and it never needs to be anything but a whole number, so make it an int.

int i;

Variables must be declared before they are used, but they also must be declared in the same scope where they are used. In your case, that means inside the method indexOf(). Therefore, make sure you put the declaration of i inside the indexOf() definition brackets, before you assign any values to it.

LedArts commented 6 years ago

ok sir , i make it int i; but after that one more error i got is unable to find numeric literal operator 'operator""x' in line no. 45

int indexOf(int x, int y) { if (x%2 == 0) // even column int i = 8x + y; else // odd column int i = 8x + 7 - y; //line no 45 return i; }

plz check it.

jkunimune commented 6 years ago

Ah. That was a typo on my part. 8x is not valid Arduino syntax; 8*x is.

LedArts commented 6 years ago

thanx sir, all errors are finished but the program is not working plz check it. i think we don't using this line //unsigned char heart[10] = {12, 13, 17, 20, 26, 29, 33, 36, 44, 45}; and this line is making the heart shape. plz plz plz....do something.

include

define PIN 6

define MAX_LED 64

int t; uint32_t LEDColour; unsigned char x = 0; unsigned char Colour[3]; //unsigned char heart[10] = {12, 13, 17, 20, 26, 29, 33, 36, 44, 45}; unsigned char heart[][2] = {{1, 3}, {1, 2}, {2, 1}, {2, 4}, {3, 5}, {3, 2}, {4, 1}, {4, 4}, {5, 3}, {5, 2}}; Adafruit_NeoPixel strip = Adafruit_NeoPixel( MAX_LED, PIN, NEO_RGB + NEO_KHZ800 ); void setup() { // put your setup code here, to run once: strip.begin(); t=0;

strip.show(); }

void loop() { t++;

for (char num = 0; num < 64; num++) // strip.setPixelColor(num, 0); strip.show();//

Colour[0] = random(10 , 20); // Colour[1] = random(0, 20); Colour[2] = random(0, 20); LEDColour = strip.Color(Colour[1], Colour[0], Colour[2]); char num; int x = heart[num][0]; int y = heart[num][1]; x += t; for (char num = 0; num < 10; num++) // strip.setPixelColor(indexOf(x, y), 255,0,0); strip.show();//

delay(1000); }

int indexOf(int x, int y) { int i; if (x%2 == 0) // even column int i = 8x + y; else // odd column int i = 8x + 7 - y; return i; }

LedArts commented 6 years ago

in this program full display is blank nothing is running.

jkunimune commented 6 years ago

You're using a static num with no value instead of the one that iterates through the array. As I said, the num stuff all has to be inside the for-loop. Move int x = heart[num][0], int y = heart[num]1], and x += t to inside the for (char num... loop, i.e., put them between for (char num = 0; num < 10; num++) and strip.setPixelColor(.... Remember that in Arduino, a for-loop with multiple statements in its body needs curly braces to block it out, like so:

LEDColour = strip.Color(Colour[1], Colour[0], Colour[2]);

for (char num = 0; num < 10; num++) {
  int x = heart[num][0];
  int y = heart[num][1];
  x += t;
  strip.setPixelColor(indexOf(x, y), 255,0,0);
}
strip.show();

You can also delete the first declaration of char num, as you should only have one declaration of a variable called num, and the correct one is the one in the for-loop header.

You don't need //unsigned char heart[10] = {12, 13, 17, 20, 26, 29, 33, 36, 44, 45}; because that stores the heart shape in indices. The following line that replaces it, unsigned char heart[][2] = {{1, 3}, {1, 2}, {2, 1}, {2, 4}, {3, 5}, {3, 2}, {4, 1}, {4, 4}, {5, 3}, {5, 2}};, stores the heart in Cartesian coordinates, which are more useful for scrolling, and are the format that is used in the program.

LedArts commented 6 years ago

thank you sir i done the changes as u said but still its not working. showing blank screen. please check......

include

define PIN 6

define MAX_LED 64

int t; uint32_t LEDColour; unsigned char x = 0; unsigned char Colour[3]; //unsigned char heart[10] = {12, 13, 17, 20, 26, 29, 33, 36, 44, 45}; unsigned char heart[][2] = {{1, 3}, {1, 2}, {2, 1}, {2, 4}, {3, 5}, {3, 2}, {4, 1}, {4, 4}, {5, 3}, {5, 2}}; Adafruit_NeoPixel strip = Adafruit_NeoPixel( MAX_LED, PIN, NEO_RGB + NEO_KHZ800 ); void setup() { // put your setup code here, to run once: strip.begin(); t=0;

strip.show(); }

void loop() { t++;

for (char num = 0; num < 64; num++) // strip.setPixelColor(num, 0); strip.show();//

Colour[0] = random(10 , 20); // Colour[1] = random(0, 20); Colour[2] = random(0, 20); LEDColour = strip.Color(Colour[1], Colour[0], Colour[2]);

for (char num = 0; num < 10; num++) // { int x = heart[num][0]; int y = heart[num][1]; x += t; strip.setPixelColor(indexOf(x, y), 255,0,0); } strip.show();//

delay(1000);

}

int indexOf(int x, int y) { int i; if (x%2 == 0) // even column int i = 8x + y; else // odd column int i = 8x + 7 - y; return i; }

jkunimune commented 6 years ago

You know what I bet it is? You've declared i thrice in the indexOf() method. You only need to declare a variable once to use it; declaring it multiple times creates multiple variables of the same name. It seems like inside each if-statement, you declared a new variable i, inside the scope of that if-statement, that was assigned a value and then immediately destroyed. To fix it, declare it once and then use that same i for the rest of the method.

Also, it looks like you're still writing 8x. That's not valid Arduino syntax. The multiplication operator is *.

int indexOf(int x, int y) {
  int i;
  if (x%2 == 0)
    i = 8*x + y;
  else
    i = 8*x + 7 - y;
  return i;
}
LedArts commented 6 years ago

you mean like this i should declare the i

int indexOf(int x, int y) {
  int i;
  if (x%2 == 0)
    i = 8*x + y;
  else
    i = 8*x + 7 - y;
  return i;
 if (x%2 == 0)
    i = 8*x + y;
  else
    i = 8*x + 7 - y;
  return i;
 if (x%2 == 0)
    i = 8*x + y;
  else
    i = 8*x + 7 - y;
  return i;
}
LedArts commented 6 years ago

plz sir reply or if i am wrong tell me the write method to declare it

jkunimune commented 6 years ago

I'm confused. Why do you have the same code written three times? I said that you had declared i thrice, not that you should initalise i it thrice. I believe the code snippet I included above should be a complete and functional method.

LedArts commented 6 years ago

OMG, sorry sorry sorry sir i had some miss understanding. but now all clear.

i understand what u r saying and i made changes as u said and its working.....thanxxxxxxxxxxxxxxxxxxx a lot yepiiiii

and i have some more question about it plz tell me and sorry for asking so much thing. but u can only help me.....so plz dont mind

first i don't understand how u write this line unsigned char heart[][2] = {{1, 3}, {1, 2}, {2, 1}, {2, 4}, {3, 5}, {3, 2}, {4, 1}, {4, 4}, {5, 3}, {5, 2}}; plz teach me how to write this.

second is the heart shape is scrolling till last line but its not coming again at first line i means i should be again scroll from first line or the same position as it start.(continue scrolling).

LedArts commented 6 years ago

sir i know how you write the array. i understand it. unsigned char heart[][2] = {{1, 3}, {1, 2}, {2, 1}, {2, 4}, {3, 5}, {3, 2}, {4, 1}, {4, 4}, {5, 3}, {5, 2}};

plz don't explain it. sorry for asking

plz only tell me what should i do for continue scrolling.

jkunimune commented 6 years ago

To loop around, just apply a modulo operator to x so that it goes back to zero whenever it reaches 8. Instead of

x += t;

just say

x = (x + t) % 8;

That should cause x to increase each loop, but then reset to zero when it reaches the end. If you want a delay between when it goes off the right side and when it returns on the left, you can use a bigger number than 8, so that it spends a few loops on x-values that are not on screen before wrapping back to 0. e.g.

x = (x + t) % 12;
LedArts commented 6 years ago

ok sir , thank you sooooooo much........ you are great. if u don't mind can i discuss more about upcoming difficulties in future.

LedArts commented 6 years ago

sir i have one more question i want to scroll this code also vertically what should i do ???????? plz help me

LedArts commented 6 years ago

sir one more problem is remain we modify the program for one step scrolling but still it is scrolling with 2 steps (jump 2 led at a time) one step scrolling is possible in this program?

jkunimune commented 6 years ago

It should work if you just add t to y instead of x.

LedArts commented 6 years ago

sir when i am not use this line x = (x + t) % 12; then it scroll correct in one step but when is use it scroll in two steps

and when i use x = (y + t) % 12; only oblique line is running not making proper shape

for (char num = 0; num < 10; num++) //
{
int x = heart[num][0];
int y = heart[num][1];
x += t;
x = (x + t) % 12;
strip.setPixelColor(indexOf(x, y), 255,0,0);
}
strip.show();//
delay(1000);

what should i do now

plz also tell me how to scroll vertically...

thank you

LedArts commented 6 years ago

sir plz reply where r u?

jkunimune commented 6 years ago

As I said last month, you should use x = (x + t) % 12 instead of x += t. That means that you should not have x += t in your code. If you have two lines that both make it go right one pixel each cycle, then it will go right two pixels each cycle.

As I said last week, you should add t to y instead of x. That means you should have y = (y + t) % 12 in your code, and not x = (x + t) % 12. If you want it to move vertically and not horizontally, you need to remove the line that makes it move horizontally.

LedArts commented 6 years ago

but i want to run horizontal and vertical both directions. and i think the code support only one indexof( ) function. now what should i do for both side running in one program?????

jkunimune commented 6 years ago

indexOf() doesn't make the heart move; it just converts Cartesian coordinates to indices. x = (x + t) % 12 makes x change based on time (i.e. it makes it move horizontally), and y = (y + t) % 12 makes y change with time (i.e. it makes it move vertically). To make it move diagonally (i.e. have both x and y change over time), just include both lines.

LedArts commented 6 years ago

hello sir, how r u? sorry for late reply i was stuck in my seasonal work.

today i try again the code as u guide and its work perfectly. A big big big Thanxxxxxxxx to you.

Now i want to add one more thing in this code. i want to draw a colour full heart means in this heart some led should be red and some green and some blue. like multi-colour heart. so is it possible to run it like this???????????????

After this upgrade this project will complete so plz help me one more time.