Difference between revisions of "LEDLightDistrict/DesignA"

From Technologia Incognita
Jump to: navigation, search
(Created page with " =Overview= The goal of this design is to write either monochrome or colour images to an N by N screen, built up out of LEDs. LEDs have a brightness, so PWM is required. To ...")
 
m (Link to project-page)
 
(9 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 +
Part of the documentation of [[LEDLightDistrict]].
  
 
=Overview=
 
=Overview=
Line 8: Line 9:
 
=Mapping pixels in memory to the 2D surface=
 
=Mapping pixels in memory to the 2D surface=
  
==monochrome--
+
==monochrome==
  
 
The image is stored in a basic one dimensional array.
 
The image is stored in a basic one dimensional array.
Line 27: Line 28:
  
 
0 5 6
 
0 5 6
 +
 
1 4 7
 
1 4 7
 +
 
2 3 9
 
2 3 9
 +
  
 
Where the number illustrates the position in the array.
 
Where the number illustrates the position in the array.
Line 59: Line 63:
  
 
r 0  17  18
 
r 0  17  18
 +
 
g 1 16  19
 
g 1 16  19
 +
 
b 2 15  20
 
b 2 15  20
 +
  
 
r 3  14  21
 
r 3  14  21
 +
 
g 4 13  22
 
g 4 13  22
 +
 
b 5 12  23
 
b 5 12  23
 +
  
 
r 6  11  24
 
r 6  11  24
 +
 
g 7 10  25
 
g 7 10  25
 +
 
b 8  9  26
 
b 8  9  26
  
Line 77: Line 89:
  
 
     index = 9 + 8 = 17 ;
 
     index = 9 + 8 = 17 ;
 
  
 
=Electronics, mapping pixels to screen=
 
=Electronics, mapping pixels to screen=
Line 86: Line 97:
 
=Computing PWM=
 
=Computing PWM=
  
to be continued tomorrow morning
+
Code that works runs on a nanode for a colour screen of 16by 17 pixels with 7 brightness levels at 40fps: https://github.com/guidocalvano/PwmShiftRegister/blob/master/pwmShiftRegister.ino
 +
 
 +
rough overview of how it works:
 +
 
 +
    while( true )
 +
        frameDuration = beforeFrame - timeInMillis() ;
 +
        beforeFrame = timeInMillis() ;
 +
   
 +
        for( brightnessLevel = 0 ; brightnessLevel < brightnessLevelCount ; brightnessLevel++ )
 +
            for( i in pixelArray )
 +
       
 +
                pixelHigh = ( ( timeInMillis() ) % frameDuration ) < pixelBrightness ? true : false
 +
               
 +
                pushToScreen( pixelHigh )
 +
   
 +
            openLatch() ;
 +
 
 +
 
 +
==tractability==
 +
 
 +
This is a tractability computation of a colour screen with colour and 7 brightness levels per pixel:
 +
 
 +
computationCount = pixelCount * COLOURS_PER_PIXEL  * brightnessLevels * frameRate
 +
 
 +
pixelCount = WIDTH * HEiGHT
 +
 
 +
computationCount = 17 * 16 * 3 * 7 * 60 = 342 720
 +
 
 +
This is totally feasible.

Latest revision as of 09:49, 7 August 2012

Part of the documentation of LEDLightDistrict.

Overview

The goal of this design is to write either monochrome or colour images to an N by N screen, built up out of LEDs. LEDs have a brightness, so PWM is required.

To create an image it is necessary to map colour values from memory, to electronics, to a 2D surface. Each mapping must be understood, to understand how the whole approach will work. But to get a good understanding of how the electronics map the image in memory to the 2D surface, it is practical to learn how the image in memory maps to the 2D surface first.

Mapping pixels in memory to the 2D surface

monochrome

The image is stored in a basic one dimensional array.

To find a pixel's index based on its surface coordinates:


   rowStartIndex           = x * HEIGHT ;
   
   if( x % 2 )
       relativeColumnIndex = y ;
   else
       relativeColumnIndex = HEIGHT - 1 - y ;
   index = rowStartIndex + relativeColumnIndex ;

To illustrate for a 3 by 3 screen an example:

0 5 6

1 4 7

2 3 9


Where the number illustrates the position in the array.

To find (1,0) do:

   rowStartIndex = 1 * HEIGHT = 3 ;
   relativeColumnIndex = HEIGHT - 1 - 0 = 2
  
   index = 3 + 2 = 5 ;


Colour

The image is stored in a basic one dimensional array.


To find a subpixel's index based on its surface coordinates:


rowStartIndex = COLOUR_COUNT * x * HEIGHT ;

   if( x % 2 )
       relativeColumnIndex = y + subPixel ; // sub pixel is either 0 for red, 1 for green or 2 for blue
   else
       relativeColumnIndex =  COLOUR_COUNT * HEIGHT - 1 - y - subPixel ;
   
   index = rowStartIndex + relativeColumnIndex ;
   

To illustrate for a 3 by 3 screen an example:

r 0 17 18

g 1 16 19

b 2 15 20


r 3 14 21

g 4 13 22

b 5 12 23


r 6 11 24

g 7 10 25

b 8 9 26


To find (1,0), 0 (i.e. red) do:

   rowStartIndex =  COLOUR_COUNT *  1 * HEIGHT = 9 ;
   relativeColumnIndex = COLOUR_COUNT * WIDTH - 1 - 0 = 8
   index = 9 + 8 = 17 ;

Electronics, mapping pixels to screen

The pixels can be addressed through a series of shift registers, that are all connected in series. Each position in the shift register corresponds to the position in the array described above. LEDs of the right colour are attached to the concatenated shift registers in the precise order described above.


Computing PWM

Code that works runs on a nanode for a colour screen of 16by 17 pixels with 7 brightness levels at 40fps: https://github.com/guidocalvano/PwmShiftRegister/blob/master/pwmShiftRegister.ino

rough overview of how it works:

   while( true )
       frameDuration = beforeFrame - timeInMillis() ;
       beforeFrame = timeInMillis() ;
   
       for( brightnessLevel = 0 ; brightnessLevel < brightnessLevelCount ; brightnessLevel++ )
           for( i in pixelArray )
       
               pixelHigh = ( ( timeInMillis() ) % frameDuration ) < pixelBrightness ? true : false
               
               pushToScreen( pixelHigh )
   
           openLatch() ;


tractability

This is a tractability computation of a colour screen with colour and 7 brightness levels per pixel:

computationCount = pixelCount * COLOURS_PER_PIXEL * brightnessLevels * frameRate

pixelCount = WIDTH * HEiGHT

computationCount = 17 * 16 * 3 * 7 * 60 = 342 720

This is totally feasible.