1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

(Solved)Again problem with matrix, this time 8x32

Discussion in 'Arduino' started by fezder, Jan 4, 2016.

  1. fezder

    fezder Well-Known Member

    Joined:
    Dec 11, 2011
    Messages:
    1,665
    Likes:
    100
    Location:
    Mikkeli, Finland
    Yeah, I too thinked It's similar since It's "only" 3-matrix after all.
    I didn't draw schematic, but I can if It's REALLY needed, but there's huge chore, but hopefully these'll give enough info:
    'Same way as earlier in matrix, but this time each layer x-y axes are controlled by 8 pc's of 74595's . Last shifter controls what layers are powered, by grounding them via darlington.
    8x8x8_cube_block_diagram.jpg IMG_1462.jpg
    And code that allows to do something, manipulate whole matrix precisely what led is lit, so best thus far (did try to manipulate our, or yours , how you think it, 8x32 matrix no luck)
    Code (c):

    //test code for 8x8x8 cube
    int dataPin = 2;  //IC 14  //Define which pins will be used for the Shift Register control
    int latchPin = 3;  //IC 12
    int clockPin = 4;  //IC 11
    #define data 2
    #define latch 3
    #define clock 4
    //OE-GND

    int buffer[8][9] = //each layer data stored as 8 times 8-bits  [layer][data].
    { //layers, rows0,Rows1......Rows7
      {B00000001, B00000000, B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000001},
      {B00000010, B00000001, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000001},
      {B00000100, B00000001, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000001},
      {B00001000, B00000001, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000001},
      {B00010000, B00000001, B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000001},
      {B00100000, B00000001, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000001},
      {B01000000, B00000001, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000001},
      {B10000000, B00000001, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000001},
    };
    //int screen[8][9]; //screen data, both what layer is on as well as layer data [layer][data], same as above but tidier....

    //int power[8] = {1, 2, 4, 8, 16, 32, 64, 128}; //for layers on/off
    long previousMillis = 0;  // will store last time LED was updated

    void setup()
    {
      DDRD = DDRD | B00011100;
      /*
      for (int i = 0; i < 8; i++)
      {
      screen[i][0] = power[i]; //fill first element of arrays with layer command
      }

      for (int i = 1; i < 9; i++)
      {
      screen[i][i] = 0; //fill rest elements zeros to clear out funny stuff
      }
    */


    }

    void loop()
    {
    /*
      unsigned long currentMillis = millis();
      if (currentMillis - previousMillis > 2000)
      {
      previousMillis = currentMillis;
      for (int n = 0; n < 8; n++)
      {
      for (int i = 1; i < 9; i++) //not from beginning since first element is for layer select!
      {
      screen[n][i] = random() % 255; //fill rest elements with dummy data
      }
      }
      }
      //delay(100);
    */



      for (int i = 0; i < 8; i++) //first layers....
      {
      for (int n = 0; n < 9; n++) //.....then, whatever is waiting at layer elements
      {
      shiftOut(data, clock, MSBFIRST, buffer[i][n]);  //used shfitOut for now, but bit-bang would give more freedom
      }
      latchup();   //time to show up cube
      }

    }
    void latchup()
    {
      digitalWrite(latch, HIGH);
      digitalWrite(latch, LOW);
    }
     

    And Yes, mono-colour for now :)....argh, forgot to comment relevant stuff, fixed now^
     
    Last edited: Aug 5, 2016
  2. fezder

    fezder Well-Known Member

    Joined:
    Dec 11, 2011
    Messages:
    1,665
    Likes:
    100
    Location:
    Mikkeli, Finland
    Hehee, got pixel(), function working, allows better control of what led is lit, not that well working, still bit stuff to do, it works on all other axes when drawing line, but not on y-axis:
    Code (c):

    //test code for 8x8x8 cube
    int dataPin = 2;  //IC 14  //Define which pins will be used for the Shift Register control
    int latchPin = 3;  //IC 12
    int clockPin = 4;  //IC 11
    #define data 2
    #define latch 3
    #define clock 4
    //OE-GND
    /*
      int buffer[8][9] = //each layer data stored as 8 times 8-bits  [layer][data].
      { //layers, rows0,Rows1......Rows7
      {B00000001, B00000000, B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000001},
      {B00000010, B00000001, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000001},
      {B00000100, B00000001, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000001},
      {B00001000, B00000001, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000001},
      {B00010000, B00000001, B10000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000001},
      {B00100000, B00000001, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000001},
      {B01000000, B00000001, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000001},
      {B10000000, B00000001, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000001},
      };
    */


    int screen[8][9]; //screen data, both what layer is on as well as layer data [layer][data]

    int power[8] = {1, 2, 4, 8, 16, 32, 64, 128}; //for layers on/off
    long previousMillis = 0;  // will store last time LED was updated
    int k = 0;
    int n = 0;
    void setup()
    {
      DDRD = DDRD | B00011100;

      for (int i = 0; i < 8; i++)
      {
      screen[i][0] = power[i]; //fill first element of arrays with layer command
      }

      for (int i = 1; i < 9; i++)
      {
      screen[i][i] = 0; //fill rest elements zeros to clear out funny stuff
      }


    }

    void loop()
    {




      pixel(0, 0, 0); //x,y,z


      for (int i = 0; i < 8; i++)
      {
      for (int n = 0; n < 9; n++)
      {
      shiftOut(data, clock, MSBFIRST, screen[i][n]);
      }
      latchup();
      }
    }


    void pixel(int x, int y, int z)
    {
      screen[z][x + 1] = 1 << y;  //crude way to force bit in byte, but works in some degree....
    }

    void latchup()
    {
      digitalWrite(latch, HIGH);
      digitalWrite(latch, LOW);
    }
     
     
    Last edited: Aug 5, 2016
  3. Dr_Doggy

    Dr_Doggy Well-Known Member

    Joined:
    Aug 11, 2007
    Messages:
    1,715
    Likes:
    37
    hmm, well its best to start from ground up,
    the first thing to consider is that the cathode is 8 bits long,
    and the anodes are 64 bit long,
    so our matrix needs to reflect that, and modify shiftout to reflect that....
    so first we would shift out the 8 bit cathode instruction set , then we need to shift out 64 bits for all the anode registers

    also now will be a good time to consider what we will be doing with this, ie, how do you want to draw the data to the cube, and what kind of things is it going to be doing, ie animations...ect...

    may take me a bit of thought to elaborate with code.....
     
    Last edited: Aug 5, 2016
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. fezder

    fezder Well-Known Member

    Joined:
    Dec 11, 2011
    Messages:
    1,665
    Likes:
    100
    Location:
    Mikkeli, Finland

    I was thinking of using this in same manner as that matrix, only 3d (so memory problem will rise at some point, at least with RAM)
    I didn't use unsigned long, since I found it would be easier to tackle with 8-bits, instead of 2x32 bits. Then again, I did use 16-bits with 14-segment too. Fonts would be cool addition too, but they might look odd since leds are small compared to spacing...
     
  6. Dr_Doggy

    Dr_Doggy Well-Known Member

    Joined:
    Aug 11, 2007
    Messages:
    1,715
    Likes:
    37
    sry deleted that about long, prolly does add the same in mem anyway,

    take out that part in buffer about layer it can be calculated by position in the buffer
    layer = 1<< i % 8;

    and try this:


    for (int i = 0; i < 8; i++) //layers
    {
    layer = 1<< i % 8;
    shiftOut(data, clock, MSBFIRST, layer); //layer

    for (int n = 0; n < 8; n++) // column
    {
    shiftOut(data, clock, MSBFIRST, buffer[n]); /// row
    }
    latchup(); // Latching now needs to be done per layer, plus a delay so you see each of the layer light up, but fast enough that all the layers look lit up
    }


    so you want letters to fly across it? which angle do you want to look at it from to be able to see the letter?


    also i recommend using buffer for testing, and set all to 0 in setup, i have a feeling those for loops are setup wrong and not really passing how you want:
    screen [ i i] = 0;= 0; < i,i creates a diagonal line of off's, not the whole image
     
    Last edited: Aug 5, 2016
  7. Dr_Doggy

    Dr_Doggy Well-Known Member

    Joined:
    Aug 11, 2007
    Messages:
    1,715
    Likes:
    37
    also this:

    void pixel(int x, int y, int z)
    {
    screen[z][x] += 1 << y; //crude way to force bit in byte, but works in some degree.... // the plus sign wont erase previous data, but add to it
    }
     
  8. fezder

    fezder Well-Known Member

    Joined:
    Dec 11, 2011
    Messages:
    1,665
    Likes:
    100
    Location:
    Mikkeli, Finland
    Thanks doggy, good advices! I learnt while coding too that some stuff didn't work, but those are obvious now you pointed them out....hehe.
    Here's bit improved code, came tidier. Pixel funtion differs when used as in here code; x and z axis draw lines, but y xis shows as stationary dot at last led:
    Code (c):

    //test code for 8x8x8 cube
    int dataPin = 2;  //IC 14  //Define which pins will be used for the Shift Register control
    int latchPin = 3;  //IC 12
    int clockPin = 4;  //IC 11
    #define data 2
    #define latch 3
    #define clock 4
    //OE-GND


    int screen[8][8]; //screen data, both what layer is on as well as layer data [layer][data]

    void setup()
    {
      DDRD = DDRD | B00011100;  //pinmodes

      for ( int z = 0; z < 8; z++) //forgot this earlier, z-axis
      {
      for (int i = 0; i < 8; i++)
      {
      screen[z][i] = 0; //fill elements with zeros to clear out funny stuff
      }
      }
    }

    void loop()
    {


      for (int n = 0; n < 8; n++)
      {
      pixel(0, n, 0);
      }
      for (int i = 0; i < 8; i++)
      {
      shiftOut(data, clock, MSBFIRST, B00000001 << i);  //layer switch
      for (int n = 0; n < 8; n++)
      {
      shiftOut(data, clock, MSBFIRST, screen[i][n]);
      }
      latchup();

      }
    }


    void pixel(int x, int y, int z)
    {
      screen[z][x] = B00000001<<y; //crude way to force bit in byte, but works in some degree....
    }

    void latchup()
    {
      digitalWrite(latch, HIGH);
      digitalWrite(latch, LOW);
    }
     
    and, tested with millis instead of for():
    Code (c):

    //draws line in x-axis between lowest layer, slowly adds up more lit leds
     int n=millis()/100%8;
      pixel(n, 0, 0);
     
    Code (c):

    //moving dot, not line stays, but more of knight-rider
     int n=millis()/100%8;
      pixel(0, n, 0);
     
    Code (c):

    //same as x-axis, only in z-axis, draws line towards up
     int n=millis()/100%8;
      pixel(0, 0,n);
     
     
  9. fezder

    fezder Well-Known Member

    Joined:
    Dec 11, 2011
    Messages:
    1,665
    Likes:
    100
    Location:
    Mikkeli, Finland
    Doggy, I got pixel() now working as intended, with this modification :
    Code (c):

    void pixel(int x, int y, int z)
    {
      screen[z][x] |= 1 << y; //crude way to force bit in byte, but works in some degree....
    }
     
    and made also few other simple draw-commands. And as for font, all directions would be best but phew, that takes ton of memory if there are many fontmaps, unless if there is some trick to swap bits around in one fontmap:
    Code (c):

    //test code for 8x8x8 cube
    /*
      layerfullon(x)=turns on x layer
      horizontalfullon(x)=turns on horizontal wall x
      verticalfullon(x)=turns on vertical wall x
      pixel(x,y,z)=draw pixel at coordinates, also can be used to draw lines too, so can replace above but above are simpler to draw "flat" walls.
    */

    int dataPin = 2;  //IC 14  //Define which pins will be used for the Shift Register control
    int latchPin = 3;  //IC 12
    int clockPin = 4;  //IC 11
    #define data 2
    #define latch 3
    #define clock 4
    //OE-GND


    int screen[8][8]; //screen data, both what layer is on as well as layer data [layer][data]

    void setup()
    {
      DDRD = DDRD | B00011100;  //pinmodes

      for ( int z = 0; z < 8; z++) //forgot this earlier, z-axis
      {
      for (int i = 0; i < 8; i++)
      {
      screen[z][i] = 0; //fill elements with zeros to clear out funny stuff
      }
      }
    }

    void loop()
    {
      layerfullon(millis()/100%8);

      for (int i = 0; i < 8; i++)
      {
      shiftOut(data, clock, MSBFIRST, B00000001 << i);  //layer switch
      for (int n = 0; n < 8; n++)
      {
      shiftOut(data, clock, MSBFIRST, screen[i][n]);
      }
      latchup();
      }

      alloff();
    }


    void pixel(int x, int y, int z)
    {
      screen[z][x] |= 1 << y; //crude way to force bit in byte, but works in some degree....
    }


    void layerfullon(int z)
    {
      for (int k = 0; k < 8; k++)

      {
      screen[z][k] = B11111111;
      }
    }

    void horizontalfullon(int y)
    {
      for (int z = 0; z < 8; z++)
      {
      for (int x = 0; x < 8; x++)
      {
      screen[z][x] = 1 << y;
      }
      }
    }


    void verticalfullon(int x)
    {
      for (int z = 0; z < 8; z++)
      {
      screen[z][x] = B11111111;
      }
    }

    void allon()
    {
      for (int z = 0; z < 8; z++)
      {
      for (int i = 0; i < 8; i++)
      {
      screen[z][i] = B11111111; //fill rest elements zeros to clear out funny stuff
      }
      }
    }

    void alloff()
    {
      for (int z = 0; z < 8; z++)
      {
      for (int i = 0; i < 8; i++)
      {
      screen[z][i] = B00000000; //fill rest elements zeros to clear out funny stuff
      }
      }
    }

    void latchup()
    {
      digitalWrite(latch, HIGH);
      digitalWrite(latch, LOW);
    }
     
     
    Last edited: Aug 6, 2016
  10. Dr_Doggy

    Dr_Doggy Well-Known Member

    Joined:
    Aug 11, 2007
    Messages:
    1,715
    Likes:
    37
    yr rite, i forgot it was or, not + !,
    first I should mention that with my cube i had 12mb of eXt eeprom so i did not worry about memory and uploaded pre drawn pixel images without compression

    so it may be a good idea to see if anyone else has ideas....
    but "me" looking at it right now would roll with the pixel function..

    a quick way to do a rotation would be like this:
    pixel(x, y, z);
    pixel(z, x, y);
    pixel(y, z, x);
    .... if memory serves!

    in vb I created a vector object which was made of 3 float variables: obj = (x,y,z), unfortunately i dont think(or know) that we can pack them like this in arduino

    one of the things we could do off the top of my head is compress the fontmap data differently, so that only the 1's are recorded, so for an X the fontmap would look like:
    (1,1,0),(2,2,0),(3,3,0),(4,4,0),(5,5,0),(1,5,0),(2,4,0),(4,2,0),(5,1,0) // with out the brackets in actual array // the 0's could be cut out too if your letters are 2d flat
    or a colon ( : ) would look like this (3,2,0),(3,4,0) <---only 6 bytes used here!(plus 1 for size of array block)
    ... this may not work in 2d array though

    but the problem doing it like that is either you need as many place holders in array as the "most number of pixels "
    or else a point in the array that tells the number of variables in that letter to read/or skip over if looking for next.

    another way to compress that is that since we only use 0-7, we could pack 2 numbers per byte, but that would require some code to compress and decomp .... if there is no such thing as a 4bit variable

    again back to the 3D VB we used a "rotation" and "translation" matrix...
    the translation matrix is simple addition to the matrix(the whole array seg)

    the rotation matrix was called like: gl.rotate(angle,x,y,z); // where x&y&z is the rotation axis and if x or y or z =1 , that variable is multiplied by the rotation angle, something about sin & cos & tan maybe, there is examples on google how to do the math, idk if/how this will work with only 5 pixels and whole numbers and rounding off, as i had decimals and fractions to work with, but it may help that you only have 8 options for rotation_angle
     
    Last edited: Aug 7, 2016
  11. fezder

    fezder Well-Known Member

    Joined:
    Dec 11, 2011
    Messages:
    1,665
    Likes:
    100
    Location:
    Mikkeli, Finland
    Memory Isn't going to be problem since I'm placing teensy to control this cube :) Thanks for tips, again!
     
  12. fezder

    fezder Well-Known Member

    Joined:
    Dec 11, 2011
    Messages:
    1,665
    Likes:
    100
    Location:
    Mikkeli, Finland
    This got mine attention:
    ^what does cutting zeros off from array?
     
  13. fezder

    fezder Well-Known Member

    Joined:
    Dec 11, 2011
    Messages:
    1,665
    Likes:
    100
    Location:
    Mikkeli, Finland
    BTW, I tested that pixel rotation...it worked! Phew, I was almost going to make fontmaps for all axes!
    Only I couldn't figure out at least yet how to change angle via command like pixel(x,y,z,axis), but this crude way worked, only smaller would be better:
    tried with like:
    z=x;
    x=y;
    y=z;
    but no idea why it didn't work...
    Code (c):

    void loop()
    {
      pixel(1, 1, 0);
      pixel(2, 2, 0);
      pixel(3, 3, 0);
      pixel(4, 4, 0);
      pixel(5, 5, 0);
      pixel(1, 5, 0);
      pixel(2, 4, 0);
      pixel(4, 2, 0);
      pixel(5, 1, 0);

     
      pixel2(1, 1, 0);
      pixel2(2, 2, 0);
      pixel2(3, 3, 0);
      pixel2(4, 4, 0);
      pixel2(5, 5, 0);
      pixel2(1, 5, 0);
      pixel2(2, 4, 0);
      pixel2(4, 2, 0);
      pixel2(5, 1, 0);

      pixel1(1, 1, 0);
      pixel1(2, 2, 0);
      pixel1(3, 3, 0);
      pixel1(4, 4, 0);
      pixel1(5, 5, 0);
      pixel1(1, 5, 0);
      pixel1(2, 4, 0);
      pixel1(4, 2, 0);
      pixel1(5, 1, 0);
      draw();


    }


    void pixel(int x, int y, int z)
    {
      screen[z][x] |= 1 << y; //crude way to force bit in byte, but works in some degree....
    }

    void pixel1(int z, int x, int y)
    {
      screen[z][x] |= 1 << y; //crude way to force bit in byte, but works in some degree....
    }

    void pixel2(int y, int z, int x)
    {
      screen[z][x] |= 1 << y; //crude way to force bit in byte, but works in some degree....
    }
     
     
    Last edited: Aug 9, 2016
  14. Dr_Doggy

    Dr_Doggy Well-Known Member

    Joined:
    Aug 11, 2007
    Messages:
    1,715
    Likes:
    37
    z=x; // the true value of z is lost when written over with x
    x=y;
    y=z; // at this point z is the x val written 2 lines ago so now z and y equal x

    a = z; // need a temp place for z
    z=x;
    x=y;
    y = a;

    for rotation:

    pixel(x,y,z,a,b,c,q)
    where q is the angle, ie, how much to rotate by
    a, b, c is the axis to rotate by, ie, which way
    x,y,z is the point

    ... again that is just the GL way of doing it
     
  15. fezder

    fezder Well-Known Member

    Joined:
    Dec 11, 2011
    Messages:
    1,665
    Likes:
    100
    Location:
    Mikkeli, Finland
    'duh, of course if we place only 1's then rest are automatically zeros....stupid me :D
    I read something of changing values of variables by using pointers, any thoughts of that? I noticed that we used pointer in strput() command earlier, but not with charput(), why is that?
     
  16. Dr_Doggy

    Dr_Doggy Well-Known Member

    Joined:
    Aug 11, 2007
    Messages:
    1,715
    Likes:
    37
    nope,lol, i said the same thing when i found out ...."very tricky!"

    i dont get pointers too well yet...
     
  17. fezder

    fezder Well-Known Member

    Joined:
    Dec 11, 2011
    Messages:
    1,665
    Likes:
    100
    Location:
    Mikkeli, Finland
    Hehe!
    Here, slowly getting somewhere, pixel() is now bit better and I can also draw characters:
    Code (c):

    void pixel(int x, int y, int z, int cond)
    {
      if (x < 0 || y < 0 || z < 0) //out of negative borders?
      {
      return; //if yes, get outta here
      }
      if (x > 7 || y > 7 || z > 7) //out of positive borders?
      {
      return; //if yes,get outta here
      }
     
      int pix, msk;
      pix = 1 << y;
      msk = screen[z][x]; //check previous data to compare.

      if (cond == 2)
      {
      pix ^= msk; //XOR data to screen, pix= pix ^msk;
      }

      if (cond == 1)
      {
      pix = ~pix;
      pix &= msk; // AND data to screen, pix= pix & msk;
      }

      if (cond == 0)
      {
      pix |= msk;
      }
      screen[z][x] = pix; //apply changes finally!
    }
     
    Code (c):

      for (int i = 0; i < 8; i++)
      {
      int n = 1;
      screen[0][i] = cubefont[i + (n * 8)];
      }
     
    That matrix code is good to compare, piece by piece getting there! :) and learning ton while doing so...
     
  18. Dr_Doggy

    Dr_Doggy Well-Known Member

    Joined:
    Aug 11, 2007
    Messages:
    1,715
    Likes:
    37
    lol, the fun never stops!

    yes, the zeros, but also if your font map is only 2d (so far it is) , ie, each part of the letter is all on the same plane, ie all: z=0 , then you dont need to mention that in array, cause they are all z=0, so instead depth value is constant, and changes can be set when calling the pixel function,.. or maybe you dont want the parts of the letters all on the same layer
     
  19. fezder

    fezder Well-Known Member

    Joined:
    Dec 11, 2011
    Messages:
    1,665
    Likes:
    100
    Location:
    Mikkeli, Finland
    Would 3d-array be better then? how is that initialized? like:
    Code (c):

    int buffer[z][x][y];
     
    or more like:
    Code (c):

    int buffer[8][8][8];
     
    And, I did try with 1d-buffer too, works in some way. Tried to convert that 8x32 matrix code but even with array filled with zeros, some leds are still lit....quess It's that 64 anodes that fool around:
    Code (c):

    //test code for 8x8x8 cube
    /*
      layerfullon(x)=turns on x layer
      horizontalfullon(x)=turns on horizontal wall x
      verticalfullon(x)=turns on vertical wall x
      pixel(x,y,z, cond)=draw pixel at coordinates, also can be used to draw lines too, so can replace above but above are simpler to draw "flat" walls.
      strput(val,x,y,z) = show values like integers as numbers
      charput("text", x,y,z) = show text as human-readable-text
    */

    #include "cubefont.h"
    const int dataPin = 2;  //IC 14  //Define which pins will be used for the Shift Register control
    //latchpin is only used in latch() so It's PORTD3
    const int clockPin = 4;  //IC 11
    #define data 2
    #define latch 3
    #define clock 4
    //OE-GND


    int screen[8]; //screen data, both what layer is on as well as layer data [layer][data]

    void setup()
    {
      DDRD = DDRD | B00011100;  //pinmodes

      for (int i = 0; i < 8; i++)
      {
      screen[i] = 0; //fill elements with zeros to clear out funny stuff
      }
    }

    void loop()
    {
      /*
      for (int i = 0; i < 8; i++)
      {
      int n = 1;
      screen[0][i] = cubefont[i + (n * 8)];
      }
      */

      strput("0", 0, 0, 0);
    }


    void strput(const char* ch, signed char x, signed char y, signed char z) //strput relies on charput AND pixel!
    {
      int addr;
      while (*ch )
      {
      charput(*ch++, x, y, z); //write a string to the display buffer
      x += 7;
      }
    }





    void charput(int  ch, int x, int y, int z)  //relies on pixel!
    {
     
      int x1, y1;
      int disp;
      int disp2;
      for ( x1 = 0; x1 < 8; x1++) // eight rows
      {
      disp = cubefont[x1 + (ch * 8)]; //look data from fontmap,
      for (y1 = 0; y1 < 8; y1++) // eight pixels
      {
      disp2 = disp & 1 << y1;
      if (disp2 > 0)
      {
      pixel(x + x1, y + y1, z, 0); // OR the pixel to the display buffer
      }
      }
      }
    }


    void pixel(int x, int y, int z, int cond)
    {
    /*
    int a = z; // need a temp place for z
    z=x;
    x=y;
    y = a;
    */

    /*
    int a = z; // need a temp place for z
    z=y;
    y=x;
    x = a;
    */

      if (x < 0 || y < 0 || z < 0) //out of negative borders?

      {
      return; //if yes, get outta here
      }
      if (x > 7 || y > 7 || z > 7) //out of positive borders?
      {
      return; //if yes,get outta here
      }

      int pix, msk;
      pix = 1 << y;
      msk = screen[x]; //check previous data to compare.

      if (cond == 2)
      {
      pix ^= msk; //XOR data to screen, pix= pix ^msk;
      }

      if (cond == 1)
      {
      pix = ~pix;
      pix &= msk; // AND data to screen, pix= pix & msk;
      }

      if (cond == 0)
      {
      pix |= msk; //OR data to screen, pix= pix | msk;
      }

      screen[x] = pix; //apply changes finally!
      draw(z);
    }

    /*
    void layerfullon(int z)
    {
      for (int k = 0; k < 8; k++)

      {
      screen[z][k] = B11111111;
      }
    }

    void horizontalfullon(int y)
    {
      for (int z = 0; z < 8; z++)
      {
      for (int x = 0; x < 8; x++)
      {
      screen[z][x] = 1 << y;
      }
      }
    }


    void verticalfullon(int x)
    {
      for (int z = 0; z < 8; z++)
      {
      screen[z][x] = B11111111;
      }
    }

    void allon()
    {
      for (int z = 0; z < 8; z++)
      {
      for (int i = 0; i < 8; i++)
      {
      screen[z][i] = B11111111; //fill rest elements zeros to clear out funny stuff
      }
      }
    }

    void alloff()
    {
      for (int z = 0; z < 8; z++)
      {
      for (int i = 0; i < 8; i++)
      {
      screen[z][i] = B00000000; //fill rest elements zeros to clear out funny stuff
      }
      }
    }*/

    void draw(int z)
    {
      shiftOut(data, clock, MSBFIRST, B00000001 << z);  //layer switch

     
      for (int n = 0; n < 8; n++)
      {
      shiftOut(data, clock, MSBFIRST, screen[n]);
      }
      latchup();
     
    }

    void latchup()
    {
      bitSet(PORTD, 3); //1202/137
      bitClear(PORTD, 3);
    }
     
     
  20. Dr_Doggy

    Dr_Doggy Well-Known Member

    Joined:
    Aug 11, 2007
    Messages:
    1,715
    Likes:
    37
    i tried it and 3darrays seem to compile ok, however since there is no brightness pixel and each led is either on or off , and since memory is not a problem so the 2d array you were using is fine, compression isn't really required

    sorry to be confusing , but i was just saying that in this example, and in your font map: (1,1,0) all z values are the same, not required at all unless you want your bits of the letters to change layers as it goes

    if you just want to repeat letters on layers i would do that when calling charput, just do it per layer

    if post 416 works then roll with it!, this should light up all 8 corners of the cube, if shifted a bit , just add some +or- 1's in the pixel function:

    pixel(0,0,0);
    pixel(0,7,0);
    pixel(7,0,0);
    pixel(7,7,0);
    pixel(0,0,7);
    pixel(0,7,7);
    pixel(7,0,7);
    pixel(7,7,7);

    if that works than charput should too, and its time to redo font map, I like the idea of 2d map cause drawing these fonts will be alot easier, eg:


    { // calling this font number will actually display how its drawn here, in this example its a box!
    B11111111,
    B10000001,
    B10000001,
    B10000001,
    B10000001,
    B10000001,
    B10000001,
    B11111111
    }

    im still thinking about how to rotate , and thinking it may be best implemented in the charput function, but lets make sure that works before tinkering!
     
    Last edited: Aug 12, 2016
  21. fezder

    fezder Well-Known Member

    Joined:
    Dec 11, 2011
    Messages:
    1,665
    Likes:
    100
    Location:
    Mikkeli, Finland
    Doggy, pixel worked as you quessed; each corner was lit.
    And it seems we don't need to redo fontmap; initially, fonts were mirrored, but with this small change, they appear as intended, and pixel coordinates still work as intended, only x and y are inverted, before pixel(0,0,0); was in bottom left, now It's upper left, so not big deal.
    Also, I found minor but of course relevant bug in mine strput; I accidentaly wrote TWICE to screenbuffer, which caused that scrolling wasn't possible:
    so, changes to this newie:
    Code (c):

    void draw()
    {
      for (int i = 0; i < 8; i++)
      {
      shiftOut(data, clock, MSBFIRST, B00000001 << i);  //layer switch
      for (int n = 0; n < 8; n++)
      {
      shiftOut(data, clock, LSBFIRST, screen[i][n]);   //this was earlier MSBFIRST
      }
      latchup();
      }
    }
     
    Code (c):

    void charput(int  ch, int x, int y, int z)  //relies on pixel!
    {
      int x1, y1;
      int disp;
      int disp2;
      for ( x1 = 0; x1 < 8; x1++) // eight rows
      {
      disp = cubefont[x1 + (ch * 8)]; //look data from fontmap,   //this disp here was screen[z][x1]
      for (y1 = 0; y1 < 8; y1++) // eight pixels
      {
      disp2 = disp & 1 << y1;    //and this disp too!
      if (disp2 > 0)
      {
      pixel(x + x1, y + y1, z, 0); // OR the pixel to the display buffer
      }
      }
      }
    }
     
    and full code
    Code (c):

    //test code for 8x8x8 cube
    /*
      layerfullon(x)=turns on x layer
      horizontalfullon(x)=turns on horizontal wall x
      verticalfullon(x)=turns on vertical wall x
      pixel(x,y,z, cond)=draw pixel at coordinates, also can be used to draw lines too, so can replace above but above are simpler to draw "flat" walls.
      strput(val,x,y,z) = show values like integers as numbers
      charput("text", x,y,z) = show text as human-readable-text
    */

    #include "cubefont.h"
    const int dataPin = 2;  //IC 14  //Define which pins will be used for the Shift Register control
    //latchpin is only used in latch() so It's PORTD3
    const int clockPin = 4;  //IC 11
    #define data 2
    #define latch 3
    #define clock 4
    //OE-GND


    int screen[8][8]; //screen data, both what layer is on as well as layer data [layer][data]

    void setup()
    {
      DDRD = DDRD | B00011100;  //pinmodes

      for ( int z = 0; z < 8; z++) //forgot this earlier, z-axis
      {
      for (int i = 0; i < 8; i++)
      {
      screen[z][i] = 0; //fill elements with zeros to clear out funny stuff
      }
      }
    }

    void loop()
    {
      alloff();//acts as clr();

      //commands here in between!
      draw(); //acts as blit();

    }


    void strput(const char* ch, signed char x, signed char y, signed char z) //strput relies on charput AND pixel!
    {
      int addr;
      while (*ch )
      {
      charput(*ch++, x, y, z); //write a string to the display buffer
      x += 7;
      }
    }





    void charput(int  ch, int x, int y, int z)  //relies on pixel!
    {
      int x1, y1;
      int disp;
      int disp2;
      for ( x1 = 0; x1 < 8; x1++) // eight rows
      {
      disp = cubefont[x1 + (ch * 8)]; //look data from fontmap,
      for (y1 = 0; y1 < 8; y1++) // eight pixels
      {
      disp2 = disp & 1 << y1;
      if (disp2 > 0)
      {
      pixel(x + x1, y + y1, z, 0); // OR the pixel to the display buffer
      }
      }
      }
    }


    void pixel(int x, int y, int z, int cond)
    {

      if (x < 0 || y < 0 || z < 0) //out of negative borders?

      {
      return; //if yes, get outta here
      }
      if (x > 7 || y > 7 || z > 7) //out of positive borders?
      {
      return; //if yes,get outta here
      }

      int pix, msk;
      pix = 1 << y;
      msk = screen[z][x]; //check previous data to compare.

      if (cond == 2)
      {
      pix ^= msk; //XOR data to screen, pix= pix ^msk;
      }

      if (cond == 1)
      {
      pix = ~pix;
      pix &= msk; // AND data to screen, pix= pix & msk;
      }

      if (cond == 0)
      {
      pix |= msk; //OR data to screen, pix= pix | msk;
      }

      screen[z][x] = pix; //apply changes finally!
    }


    void layerfullon(int z)
    {
      for (int k = 0; k < 8; k++)

      {
      screen[z][k] = B11111111;
      }
    }

    void horizontalfullon(int y)
    {
      for (int z = 0; z < 8; z++)
      {
      for (int x = 0; x < 8; x++)
      {
      screen[z][x] = 1 << y;
      }
      }
    }


    void verticalfullon(int x)
    {
      for (int z = 0; z < 8; z++)
      {
      screen[z][x] = B11111111;
      }
    }

    void allon()
    {
      for (int z = 0; z < 8; z++)
      {
      for (int i = 0; i < 8; i++)
      {
      screen[z][i] = B11111111; //fill rest elements zeros to clear out funny stuff
      }
      }
    }

    void alloff()
    {
      for (int z = 0; z < 8; z++)
      {
      for (int i = 0; i < 8; i++)
      {
      screen[z][i] = B00000000; //fill rest elements zeros to clear out funny stuff
      }
      }
    }

    void draw()
    {
      for (int i = 0; i < 8; i++)
      {
      shiftOut(data, clock, MSBFIRST, B00000001 << i);  //layer switch
      for (int n = 0; n < 8; n++)
      {
      shiftOut(data, clock, LSBFIRST, screen[i][n]);
      }
      latchup();
      }
    }


    void latchup()
    {
      bitSet(PORTD, 3); //1202/137
      bitClear(PORTD, 3);
    }
     
    Only need to figure out how to change rotation....
     
    Last edited: Aug 13, 2016

Share This Page