Labels

Tuesday, July 9, 2013

What Problems Do I Now Know on the LED Cube

The test slice implementation revealed a number of issues that I had not really considered.  First of all, it is starting to appear that there are some timing issues that I will need to deal with if I decide to use Python as the programming language for the LED Cube.  Python, being an interpreted language, does make calls directly into libraries which speed up the execution.  However, it will show some issues with things like loops and execution times.  I find it weird that it doesn't have an array in the normal sense of the word as part of the language; but relies on a separate library to define such things.  There are a number of things that Python does that are kind of neat like threads and interrupt handling which might be able to get around some of the more formidable timing problems.

Secondly, there is a definite problem with addressing that needs to be addressed.  I need to access 16+ MCP23017 chips for an 8x8x8 LED Cube and each chip only provides for eight separate addresses.  Therefore, I will be forced to use another chip which will break the I2C bus into 4 or 8 separate buses.  This will add some overhead to the timing as well.  Update: the chip I have in mind is from Philips; the PCA9546 or PCA9548.

Thirdly, I have had to use a bi-level circuit between the RPi and the proto-board in order to get the I2C pulses to be recognized.  I want to run the proto-board on 5 volts, not 3.3 volts. There did not appear to be any way of getting the MCP23017s to be recognized by the RPi without the bi-level circuit.  That has to be worked into the final product.

My first blush tells me that I will need to access a four dimensional array in order to independently address all of the RGB LEDs and address each color independently.  I was thinking of a Row Major form addressing scheme:

Psuedo Code for LED Cube Addressing

Assumptions: the player will be fed the total LED address space while the next frame is being built

define NUMSTACKS # total number of stacks along a slice (x component) - for test, 4
define NUMLEVELS # total number of levels along a slice (y component) - for test, 4
define NUMSLICES # total number of slices in the cube (z component) - for test, 1

# the array will be NUMSTACKS x NUMLEVELS x NUMSLICES x 3 dimensions, the last being RGB color space
# this is a zero-based indice

# for tuple (a,b,c,d) where:
#   a is the stack number; 0 -> NUMSTACKS-1
#   b is the level number; 0 -> NUMLEVELS-1
#   c is the slice number; 0 -> NUMSLICES-1
#   d is R, G, or B; 0 -> 3-1

# position is d + 3*(c + NUMSLICES*(b + NUMLEVELS*a))

get_position(a,b,c,d) = d + 3*(c + NUMSLICES*(b + NUMLEVELS*a))


The next blush indicates to me that I will need to display a frame at a time.  Translation: it will be like a movie being generated, one frame at a time with a frame display player playing the last known setup while computing the next frame.  The k parameter might seem weird at first but it has to do with dicing the displayed time into 16 increments to provide a duty cycle of on and off time for the RGB components, sort of a 16 colors for Red, 16 for Green, etc.:

Psuedo Code for Frame Display

Assumptions: the frame display player will be fed the total LED address space while the next
frame is being built

for (i=0, i<NUMSLICES, i=i+1)
   for (j=0, j<NUMLEVELS, j=j+1)
      for (k=0, k<16, k=k+1)
         for (l=0, l<NUMSTACKS)

            # at this point we grab Red value for the LED and set the values accordingly
            index = get_position(l, j, i, 0)
            value = LED[index]
            # check to see if we have exceeded our allotment
            if (value <= k) then
               set red at position on
            else
               set red at position off
            endif

            # at this point we grab Green value for the LED and set the values accordingly
            index = get_position(l, j, i, 1)
            value = LED[index]
            # check to see if we have exceeded our allotment
            if (value <= k) then
               set green at position on
            else
               set green at position off
            endif

            # at this point we grab Blue value for the LED and set the values accordingly
            index = get_position(l, j, i, 2)
            value = LED[index]
            # check to see if we have exceeded our allotment
            if (value <= k) then
               set blue at position on
            else
               set blue at position off
            endif

         endfor
      endfor
   endfor
endfor


At least I have the first bit of the logic worked up.  Now I need to code it up and check out the timing - I really need to be in the KHz range for changing.