Ripple effect on LOL shield

Hi!

I have a LOL shield (Lots of Led, basically 9x14 Charlieplexed LEDs). You basically light pixels by stating LedSign::Set(x,y,brightness) where brightness can be between 0-7 where 0 is off. LedSign::Clear() clears the board.

On top I have a Nintendo DS Touch Screen and breakout.

I want to create a ripple effect as I tap. I am getting coordinates well but I am having trouble with the programming of the ripple effect. In my coffeescript-version I have it working like below. The first call to the Pulse-function comes with a designated element (which holds x,y).

neighbor = (y,x) ->
	pulses++
	if (pulses < settings.pulses)
		pulse grid[y][x + 1] if x + 1 < xLen
		pulse grid[y][x - 1] if x - 1 >= 0
		pulse grid[y + 1][x] if y + 1 < yLen
		pulse grid[y - 1][x] if y - 1 >= 0

pulse = (el) ->
	if !isTouch
		unless el.flag
			toggle el,settings
			el.flag = true
			setTimeout (->
				neighbor el.y, el.x
				setTimeout (->
					el.flag = false
				),settings.interval
				return
			),settings.interval
		return

I tried basically porting it to Arduino but unsure about the end result. I am not 100% or even 20% sure on how recursiveness behaves on the Arduino.

I have tried setting a 2d array with 0/1 so i can check which led's have been lit. But the actual ripple effect does not come across very well..

Here is my ported code which does not work properly.

void loop() {
	/*x1++;
	x2--;
	y1++;
	y2--;
	if (grid[x][y] == 0) {
		//grid[x][y] = 1;
		LedSign::Set(x,y,1%SHADES);
		LedSign::Set(x1,y1,1%SHADES);
		LedSign::Set(x1,y2,1%SHADES);
		LedSign::Set(x2,y1,1%SHADES);
		LedSign::Set(x2,y2,1%SHADES);
	}*/
	if (!flag) {
		pulse(x,y);
		flag = true;
	}
}
void pulse(int x,int y) {
	//if (grid[x][y] == 0) {
		//grid[x][y] = 1;
		LedSign::Set(x,y,1%SHADES);
		delay(50);
		neighbor(x,y);
	//}
}
void neighbor(int x,int y) {
	a++;
	if (a < 80) {
		//LedSign::Set(x,y+1,1);
		//LedSign::Set(x,y-1,1);
		//LedSign::Set(x+1,y,1);
		//LedSign::Set(x-1,y,1);
		pulse(x,y+1);
		pulse(x,y-1);
		pulse(x+1,y);
		pulse(x-1,y);
	}
}

Would love some feedback on this.

Thanks.

I am not 100% or even 20% sure on how recursiveness behaves on the Arduino.

Just like it does on any other computer.

I have tried setting a 2d array with 0/1 so i can check which led's have been lit. But the actual ripple effect does not come across very well..

Of what type?

What does the snippet do? What do you expect it to do?

		LedSign::Set(x,y,1%SHADES);
		LedSign::Set(x1,y1,1%SHADES);
		LedSign::Set(x1,y2,1%SHADES);
		LedSign::Set(x2,y1,1%SHADES);
		LedSign::Set(x2,y2,1%SHADES);

Calling the modulus function 5 times is pointless. Calling it at all is, too. If SHADES is 1, then 1/1 = 1, and the remainder is 0. If SHADES is not 1, then 1/n is 0, and the remainder is 1, unless SHADES is 0, in which case the result is undefined.

Where do you test that x and y are still positive and less than the size of the array?

Aside from that fact that you are missing a lot of semicolons,

  if (leds[x][y].flag == false) {

won't work because leds is not a 2D array. Unless there is other code, leds is never initialized, either, so leds[ x ][ y ].flag and leds[ x ][ y ].x are undefined.

With the delay in there, you are going to delay after each LED is turned on. That isn't going to create a ripple effect. You want to delay after lighting all the neighbors. But that means that you need to ditch recursion at the pulse level. It needs to be applied at the neighbor level, as does the delay().

It seems to me that a non-recursive version of the code is needed. The neighbor() function should take a center point and a radius. It should determine which cells are at that distance from the center point, and turn them on or off as appropriate.

So, you are back to using the useless 1%SHADES, I see.

You need to look at every point, and see if the distance from the point to the center is the specified radius or some reasonable ratio of the specified radius. The points to turn on for one radius value may be +/- half that radius away from spot on. If it is, turn the LED at that point on. Once all the points are scanned, and acted on (turned on or off), then delay() as longs as you want. Then, increment radius and repeat.

			int dist = abs(i - x0) + abs(j - y0);
			if (dist == radius) {

Pythagorus might disgree with you.

Now if if I get a fading trail

Whatever that means...