0

I am trying to drive an LED matrix and have an issue with shifting the whole display down. My end goal is to shift all of the rows and hopefully eventually implement a wrap around. The problem is that the first row is copied every time each row gets shifted.

The code that i used is as follows:

for (int i = (LAYERS - 1); i >= 0; i-- ) {
            for(int z = 0; z < BYTES; z++) {
                LED_Buffer[i+1][z] = LED_Buffer[i][z];
            }
        }
schnaader
  • 49,103
  • 10
  • 104
  • 136
RytisBe
  • 69
  • 8
  • 2
    What are the declared dimensions of array `LED_Buffer`? I'm suspicious that you are writing past its end. – John Bollinger Apr 18 '19 at 13:05
  • 1
    Other than that, though, what do you expect? The first row (index 0) is copied to the second, but nothing in the code presented modifies the first. So yes, after that, the first and second rows will be the same. – John Bollinger Apr 18 '19 at 13:06
  • unsigned char LED_Buffer[15][4] I agree with you and understand why is this, but is there a neat way to overcome this? I could just delete the first row. – RytisBe Apr 18 '19 at 13:10
  • 1
    What you mean with "delete"? Do you then also "delete" the LEDs? – Paul Ogilvie Apr 18 '19 at 13:12
  • Sorry ment to say "Switch it off" – RytisBe Apr 18 '19 at 13:13
  • 1
    What is the actual issue you are trying to solve? Too much copying? Too much code you have to write? Setting the first row to zeros? What would your ideal code look like? – Eric Postpischil Apr 18 '19 at 13:14
  • Regarding the declaration: thanks, I think. I guess I was expecting a declaration in terms of `BYTES` and `LAYERS`, so with that not being what was presented, the next question is how are those two defined? – John Bollinger Apr 18 '19 at 13:17
  • As for a way to overcome the problem, if you don't want the first row to match the second after you are done, then you must write different value into it. It sounds like perhaps you want those to be the values that were previously in the last row, but in that case you'll need some kind of temporary storage for those values, because you replace them with different ones earlier on. – John Bollinger Apr 18 '19 at 13:21
  • I actually hardcoded the 2D array size there, it is LED_Buffer[LAYERS][BYTES] The issue is that if i draw an animation that occupies some of the top row LEDs i want to be able to move them too. – RytisBe Apr 18 '19 at 13:21
  • So then yes, my suspicions are confirmed. In the first iteration of your loop, when `i` is equal to `LAYERS - 1`, you are writing to elements of `LED_Buffer[LAYERS]`, which is past the end of `LED_Buffer`. The valid indices are `0` to `LAYERS - 1`. – John Bollinger Apr 18 '19 at 13:23
  • I know that the last row was being dummped outside the buffer size. This is the bottom up approach, I can't do it from top down though, cause I will be rewriting the following row with the same pattern, correct? – RytisBe Apr 18 '19 at 13:38
  • 1
    I don't understand, or perhaps you don't. **IT IS NOT OK to write outside the bounds of the array.** If you want to preserve the contents of the last row when you copy the previous one over it, then you need to put those contents *somewhere else*. Or you could even just declare the array larger to be able to accommodate. This is a specific case of the general one described in Lundin's answer, which provides for a separate variable to temporarily hold the first-replaced value. – John Bollinger Apr 18 '19 at 13:50

1 Answers1

1

You'll need some manner of temporary variable for the wrap-around.

The general algorithm for shifting elements one position down the array, given some array foobar[size], is:

tmp = foobar[size-1];
for(int i=size-1; i>0; i--) // note i>0, don't include first item
{
  foobar[i] = foobar[i-1];
}
foobar[0] = tmp;

where the size-1 comes from 0-indexed arrays. Now simply apply the same to your specific case.

Lundin
  • 195,001
  • 40
  • 254
  • 396