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. Dr_Doggy

    Dr_Doggy Well-Known Member

    Joined:
    Aug 11, 2007
    Messages:
    1,715
    Likes:
    37
    yes, the mirror is example of another potential rotation axis , this structure will work for basic 90/180/270 degree rotations, more may be required depending on the level of complexity you want, how you want to issue rotation instruction, and how often you want to rotate.... by putting it here in charput, we are rotating per character...

    Code (text):

    void charput(int  ch, int x, int y, int z, int simple_axis)  //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)
      {

           if (simple_axis==1){   pixel(z, x + x1, y + y1, 0); // OR the pixel to the display buffer}
    else if (simple_axis==2){   pixel(y + y1, z, x + x1, 0); // OR the pixel to the display buffer}
    else if (simple_axis==3){   pixel(x + x1, y + y1, z, 0); // OR the pixel to the display buffer}

    else if (simple_axis==4){   pixel(x + x1, y + y1, (7-z), 0); // OR the pixel to the display buffer}

      }
      }
      }
    }

     
     
  2. fezder

    fezder Well-Known Member

    Joined:
    Dec 11, 2011
    Messages:
    1,665
    Likes:
    100
    Location:
    Mikkeli, Finland
    Doggy, thanks for those. They're bit off however, took photos how they look (generally, it draws characters correctly, but see for yourself :) very close!:
    first, code if you don't mind, I tidied it so starts from 0 :): also, I dunno if if....if.....if array is better or worse than if....else if....
    Code (c):

    void charput(int ch, int x, int y, int z, int simple_axis)  //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)
      {
      if (simple_axis == 0) //bottom, normal, so ok!
      {
      pixel(x + x1, y + y1, z, 0); // OR the pixel to the display buffer}
      }

      if (simple_axis == 1) // left wall, but inverted vertically
      {
      pixel(z, x + x1, y + y1, 0); // OR the pixel to the display buffer}
      }

      if (simple_axis == 2) //face wall, opposite of cable-in
      {
      pixel(y + y1, z, x + x1, 0); // OR the pixel to the display buffer}
      }
      if (simple_axis == 3)  //top wall, ceiling, ok. So as numver #0 but counts from up->down
      {
      pixel(x + x1, y + y1, (7 - z), 0); // OR the pixel to the display buffer}
      }
      }
      }
      }
    }
     
    Now then, results (number in picture represents if() situation in pixel() for clarity!. In each picture, cable input is upwards^)
    0, pulled it to z=7 to take better picture:
    IMG_1473.jpg
    1, left wall, vertically mirrored
    IMG_1474.jpg
    2, face, but in z=0, draws in back, not big deal! Only character is 90' CCW, if looked from front face.
    IMG_1475.jpg
    and 3, draws as 0, but counts from top->bottom
    IMG_1476.jpg
    finally, 0-2pulled to frontal faces
    IMG_1477.jpg
    These prove handy still!
     
  3. Dr_Doggy

    Dr_Doggy Well-Known Member

    Joined:
    Aug 11, 2007
    Messages:
    1,715
    Likes:
    37
    iififif will check each one, else if wont check the others after one "if" is true, so else if is a bit faster, for this example switch(select)case would be good too since it only checks once, i just posted example few, by using the pixel function as such we can set up all the walls, and call rotation as we want, also that backwards 2 is not backwards, its just on the wrong wall... we can also adjust this by changing the z value to something like (7 - z)

    or the upside down 1 can be corrected like this: (7 - y + y1) , and if it backwards to 7 - x + x1 , its difficult to see exactly whats going on, so feel free to setup the if s how you want, this method can be used to flip along the surfaces how ever you choose, but its looking good!
     
  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

    Lol, again, I tested and 7-(x+x1) were one of those I didn't test.....I even tested it in z-axis and I was pleased to see that character was drawn inside cube :p I like this cube more and more! And, I didn't know that speed improvement between if/else and if/if. Any bit of improvement is always welcome! The more time micro has to do something, they all add up. And I've learnt SO much to squeeze power out of this chip, still using arduino btw :)
     
  6. fezder

    fezder Well-Known Member

    Joined:
    Dec 11, 2011
    Messages:
    1,665
    Likes:
    100
    Location:
    Mikkeli, Finland
    Here we go, pretty much all covered with this, only needs bit of optimization perhaps since I used ton of if/if/if structures....I'll take video later! :)
    Code (c):

    void charput(byte ch, signed char x, signed char y, signed char z, byte plane, byte rotation)  //relies on pixel!
    {
      signed char x1, y1;
      byte disp;
      byte 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)
      {
      if (plane == 0) //layer walls
      {
      if (rotation == 0)
      {
      pixel(x + x1, y + y1, 7 - z, 0); //0 degrees, readable from front
      }
      if (rotation == 1)
      {
      pixel((y + y1), 7 - (x + x1), 7 - z, 0); //90 degrees CCW, readable from right
      }
      if (rotation == 2)
      {
      pixel(7 - (x + x1), 7 - (y + y1), 7 - z, 0); //180 degrees CCW, readable from back
      }
      if (rotation == 3)
      {
      pixel(7 - (y + y1), (x + x1), 7 - z, 0); //90 degrees CW, readable from left
      }
      }

      if (plane == 1) //face wall
      {
      if (rotation == 0)
      {
      pixel((x + x1), 7 - z, 7 - (y + y1), 0); //0 degrees, readable from front
      }
      if (rotation == 1 )
      {
      pixel(y + y1, 7 - z, x + x1, 0); //90 degrees CCW, readable from front, flipped to left
      }
      if (rotation == 2)
      {
      pixel(7 - (x + x1), 7 - z, y + y1, 0); //180 degrees CCW,readable from front
      }
      if (rotation == 3)
      {
      pixel(7 - (y + y1), 7 - z, 7 - (x + x1), 0); //90 degrees CW, readable from front, flipped to right
      }
      }

      if (plane == 2) //back wall
      {
      if (rotation == 0)
      {
      pixel(7 - (x + x1), z, 7 - (y + y1), 0); //0 degrees, readable rom back
      }
      if (rotation == 1)
      {
      pixel(7 - (y + y1), z, x + x1, 0); //90 degrees cCW, readable from back, flipped to left
      }
      if (rotation == 2)
      {
      pixel((x + x1), z, (y + y1), 0); //180 degrees CCW, readable rom back
      }
      if (rotation == 3)
      {
      pixel((y + y1), z, 7 - (x + x1), 0); //90 degrees cCW, readable from back, flipped to right
      }
      }

      if (plane == 3) // left wall
      {
      if (rotation == 0)
      {
      pixel(z, x + x1, 7 - (y + y1), 0); //0 degrees, readable from left wall
      }
      if (rotation == 1)
      {
      pixel(z, y + y1, x + x1, 0);//90 degrees CCW, readable from left wall, flipped to left
      }
      if (rotation == 2)
      {
      pixel(z, 7 - (x + x1), y + y1, 0); //180 degrees CCW, readable from left wall
      }
      if (rotation == 3)
      {
      pixel(z, 7 - (y + y1), 7 - (x + x1), 0); //90 degrees CW, readable from left wall, flipped to right
      }
      }

      if (plane == 4)  //right wall
      {
      if (rotation == 0)
      {
      pixel(7 - z, 7 - (x + x1), 7 - (y + y1), 0); //0 degrees, readable from right-wall
      }
      if (rotation == 1)
      {
      pixel(7 - z, 7 - (y + y1), (x + x1), 0); //90 degrees CW, readable from right wall, flipped to left
      }
      if (rotation == 2)
      {
      pixel(7 - z, x + x1, y + y1, 0); //  180 degrees CCW, readable right-wall
      }
      if (rotation == 3)
      {
      pixel(7 - z, (y + y1), 7 - (x + x1), 0); //90 degrees CW, readable from right wall, flipped to right
      }
      }
      }
      }
      }
    }
     
     
  7. Dr_Doggy

    Dr_Doggy Well-Known Member

    Joined:
    Aug 11, 2007
    Messages:
    1,715
    Likes:
    37
    Another thing i learned the hard way was about what a stack overflow is(besides the website), and every time you go if(){if(){if(){}}} or while or anything, you use a "layer of stack", the pic uC I had was very small and only supported 10 layers, not sure about arduino...
    Speed improvement a good coder will always say is #1, i say its more important on the "lower levels" of the code since those are the ones that get called the most,.
    I always start my code like that if,if,if but one thing i have noticed is that when done patterns emerge across the differences. sometimes you can size it down with an equation or less if's just by grouping properly, or maybe some of those rotations will never be called so they can be cut out too, If you are good with the math I would recommend reading about Bedmas, Boolean Algebra, and K-maps.

    for example, Im not too sure yet that we can compress the "plane" variable too much, but we can compress rotation buy doing something like this:

    Code (text):

    if (disp2 <= 0)  { return;}  // saves one stack

    if (rotation ==0){x =7-x;}
    if (rotation ==2){y =7-y;}
    if (rotation ==3){z =7-z;}


      if (plane == 0) //layer walls
      {
      pixel(x + x1, y + y1,  z, 0); //0 degrees, readable from front
      }

      if (plane == 1) //face wall
      {
      pixel((x + x1), 7 - z,  (y + y1), 0); //0 degrees, readable from front
      }

      if (plane == 2) //back wall
      {
      pixel( (x + x1), z,  (y + y1), 0); //0 degrees, readable rom back
      }

      if (plane == 3) // left wall
      {
      pixel(z, x + x1,  (y + y1), 0); //0 degrees, readable from left wall
    }

      if (plane == 4)
      {
    pixel( z,  (x + x1),  (y + y1), 0);
      }

     
    This is only example though, since it is all subjective to how you want it, ie,
    1)do you want rotation=0 to always mean that the letter is straight and right side up at front and back of cube when you are looking from front?
    2) or does rotation = 0 mean that the letter is straight and right side up, only if you are looking at the surface closest to you?
    3) or does rotation = 0 mean there is no rotation, 1 = upside down, 3=flipped

    again all subjective , are you just rotating to correct the alignment , or will you use it down the road and if so how do you want it to work?
     
    Last edited: Aug 15, 2016
  8. djsfantasi

    djsfantasi Member

    Joined:
    Mar 15, 2011
    Messages:
    161
    Likes:
    21
    Location:
    Metro Boston
    Umm, (7-x+x1) is not the same
    as 7-(x+x1)...
     
    • Agree Agree x 2
  9. Dr_Doggy

    Dr_Doggy Well-Known Member

    Joined:
    Aug 11, 2007
    Messages:
    1,715
    Likes:
    37
    ah good eye!, this is also wrong then too, it should be:
    if (rotation ==0){x =7-x;}
    if (rotation ==2){y =7-y;}
    if (rotation ==3){z =7-z;}
     
  10. fezder

    fezder Well-Known Member

    Joined:
    Dec 11, 2011
    Messages:
    1,665
    Likes:
    100
    Location:
    Mikkeli, Finland
    Doggy, again I could use help. I'm trying to show Serial data, as text, but problem Is I can't neither use String, as text() function excpects chars, so I can't null-terminate char array either since that makes char array to string, correct?
    I've managed to make this far, but now trouble is, I can't empty char array. Any clues?
    Code (c):

    //this sketch allows to scroll text and data on 8x8 matrises. When changing matrix size, change matrises value and OCR1A in setup. However, OCR1A is initially se-up for bigger displays, and it works in smaller too so no need change unless screen doesn't update fast enought; increase value then.
    /*
      to display text = text("text here",x-pos,y-pos, rot(optional));
      to display values in numbers= value(value, x-pos,y-pos, rot(optional));
      to display pixels=pixel(x-pos,y-pos,mode);  (useful for drawing lines and graphs, use for() loop to create lines better

      BIG thanks for dr.doggy from ETO (electro tech online)

      signed char/char= 1 byte(8 bits), -127->127
      unsigned char/byte= 1 byte(8 bits), 0->255
      int= 2 byte(16 bits), -32768->32767
      unsigned int= 2 byte(16 bits), 0-> 65535
      long = 4 byte(32 bits), -2,147,483,648->2,147,483,647
      unsigned long= 4 byte (32 bits), 4,294,967,295



    */

    #include "FontMap.h"  //font is in external file
    #define matrises 4  //define number of matrises, 4-22
    #define columns matrises*8  //calculate columns based how many matrises are in use
    byte displayPointer = 0;  //for interrupt use...
    byte buffer1[columns];  // buffer for screen,4x8=32
    const byte power[8] = {128, 64, 32, 16, 8, 4, 2, 1}; //for each column B10000000->B00000001
    char data[20];
    byte index = 0;
    char c;
    byte Length = 0;

    void draw()
    {
      setcolumn(displayPointer);  //column scanning
      setdata(buffer1[displayPointer]);  //bit banging shift registers
      bitSet(PORTD, 3); //blit latch, high->low
      bitClear(PORTD, 3);
      if (++displayPointer == columns)  //32 LED row sections in total
      { displayPointer = 0;
      }
    }



    void setcolumn(byte col)  //loop that takes care of column scanning
    {
      int pos;
      for (pos = columns; pos > -1; pos--)
      {
      if (col == pos)
      {
      bitSet(PORTD, 2);  //data high
      }
      else
      {
      bitClear(PORTD, 2); //data low
      }
      bitSet(PORTD, 4);  //blit clock high->low
      bitClear(PORTD, 4);
      }
    }

    void setdata(byte dat)
    {
      byte pos;
      for (pos = 0; pos < 8; pos++)
      {
      if (dat & 128)
      {
      dat -= 128;
      bitSet(PORTD, 2);  //data high
      }
      else
      {
      bitClear(PORTD, 2); //data low
      }
      dat = dat << 1;  //dat <<1==dat *2;
      bitSet(PORTD, 4);  //blit clock
      bitClear(PORTD, 4);

      }
    }




    void clr()  //clear display buffer
    {
      byte addr;
      for (addr = 0; addr < columns; addr++) // Empty display buffer
      buffer1[addr] = 0;
    }

    void pixel(signed char x, signed char y, byte cond)
    {
      byte pix, msk;
      if (x < 0 || y < 0)
      {
      return; // outside drawing limits negative
      }
      if (x > (columns - 1) || y > 7)
      {
      return; // outside drawing limits positive, x=32, y=8
      }
      pix = power[y];
      msk = buffer1[x]; // get exsisting data


      if (cond == 2)
      pix ^= msk; //XOR data to screen
      if (cond == 1)
      {
      pix = ~pix;
      pix &= msk; // AND data to screen
      }
      if (cond == 0)
      pix |= msk; // OR data to screen
      buffer1[x] = pix; // apply changes
    }




    void value(char ch, signed char x, signed char y, byte rotation)
    {
      byte x1, y1;
      byte disp, disp2;
      for ( x1 = 0; x1 < 8; x1++) // eight rows
      {
      disp = font[x1 + (ch << 3)]; //look data from fontmap, (ch<<3)==(ch *8)
      for (y1 = 0; y1 < 8; y1++) // eight pixels
      {
      disp2 = disp & power[y1];
      if (disp2 > 0)
      {
      if (rotation == 0)
      {
      pixel(x + x1, y + y1, 0); //0 degrees
      }
      if (rotation == 1)
      {
      pixel(7 - (y + y1), (x + x1), 0); //90 degrees, flip to left
      }
      if (rotation == 2)
      {
      pixel(7 - (x + x1), 7 - (y + y1), 0);
      }
      if (rotation == 3)
      {
      pixel(y + y1, 7 - (x + x1), 0); //90 degrees, flip to right
      }
      }
      }
      }
    }





    void text(char* ch, signed char x, signed char y, byte rotation)  //strput relies on charput
    {
      while (*ch )
      {
      value(*ch++, x, y, rotation); //write a string to the display buffer
      x += 7;
      }
    }



    void setup() //setup runs once
    {
      DDRD = DDRD | B11111100; //port registers used to set pin directions
      Serial.begin(9600);
    }


    void loop() //just sitting here
    {


      do
      {
      if (Serial.available() > 0)
      {

      c = Serial.read();
      if (c != '\n' && c != '\r')
      {
      data[index++] = c;
      }
      }
      }
      while (c != '\n');
      index = 0;
      clr();
      text(data, 0, 0, 0);
      draw();
    }
     
     
  11. Dr_Doggy

    Dr_Doggy Well-Known Member

    Joined:
    Aug 11, 2007
    Messages:
    1,715
    Likes:
    37
    \r\n = char 13 & char 10 ,, from the ascii table.

    have you included <strings.h> ?

    I recently just did code similar , will post when i get home
     
  12. fezder

    fezder Well-Known Member

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

    fezder Well-Known Member

    Joined:
    Dec 11, 2011
    Messages:
    1,665
    Likes:
    100
    Location:
    Mikkeli, Finland
    Thanks doggy, I stumbled upon this handy command:
    Code (c):

    String.toCharArray(array, size);
     
    And that allowed using strings and converting them to char array! Thanks! :)
     
  14. Dr_Doggy

    Dr_Doggy Well-Known Member

    Joined:
    Aug 11, 2007
    Messages:
    1,715
    Likes:
    37
    this was some code i just wrote few weeks ago to read data from an internal array block called sensorbuffer, lol but i forget exactly how its encoded, as you can see it will eventually be able to write to the sensorbuffer array too, but not there yet!
    From what i can tell, it looks for the command string , checks for get instruction, checks for the element number wanted, then returns said block... still need a few lines for the set instruction to work, i think its something like this:
    #AQUA GET 3 \r\n


    this line is looking for the command string and the "Line Feed" terminator "\n", in string form it looks like "\n" but really its only 1 byte long, so only 1 char, and as you can see from ascii table it is char 10:
    if (readString1.startsWith(command_string) & c == 10)
    .... when you hit the enter on your keyboard you are sending \r\n which is "Carriage Return" & "Line Feed"
    (sorry if i was confusing, \n is how PC uses operators and terminaors inside strings, idk, dont think it works for arduino strings)

    Code (text):


    void loop(){serialListener();doStuff();}

    void serialListener(void)
    {
       String dir, command_string = "#AQUA";
       int  headPos;
       while (Serial.available())
       {
         char c = Serial.read();     readString1 += c;
         if (readString1.length() == 10){}
         if (readString1.startsWith(command_string) & c == 10)
         {
           readString1.replace(command_string, "");
           if (readString1.startsWith(" ")){ readString1.remove(0, 1); }
           for (int i = 0; i < readString1.length(); i++) {
             if (readString1.substring(i, i + 1) == " ") {
               dir = readString1.substring(0, i);
               headPos = readString1.substring(i + 1).toInt();
               break;
             }
           }

           // for debugging
           Serial.print((String)dir + "," + headPos + "\r\n");
           Serial.print(readString1);
           Serial.print("\r\n");
          // for debugging



           if (dir == "get" || dir == "GET") { Serial.print((String)SensorBuffer[headPos] + "\r\n"); }    
    // not coded yet!!
    // if (dir == "set" || dir == "SET") { Serial.print((String)SensorBuffer[headPos] + "\r\n"); }
           readString1 = "";
         }
         delay(10);
       }
    }


     
     
  15. fezder

    fezder Well-Known Member

    Joined:
    Dec 11, 2011
    Messages:
    1,665
    Likes:
    100
    Location:
    Mikkeli, Finland
    I managed to ditch Strings and use array of chars now, this allows to change text AND rotation form serial. Only need to make code that allows text, rotation, and plane for 8-cube...
    Code (c):

    //this sketch allows to scroll text and data on 8x8 matrises. When changing matrix size, change matrises value and OCR1A in setup. However, OCR1A is initially se-up for bigger displays, and it works in smaller too so no need change unless screen doesn't update fast enought; increase value then.
    /*
       SERIAL INPUT!
      to display text = text("text here",x-pos,y-pos, rot(optional));
      to display values in numbers= value(value, x-pos,y-pos, rot(optional));
      to display pixels=pixel(x-pos,y-pos,mode);   (useful for drawing lines and graphs, use for() loop to create lines better

      BIG thanks for dr.doggy from ETO (electro tech online)

      signed char/char= 1 byte(8 bits), -127->127
      unsigned char/byte= 1 byte(8 bits), 0->255
      int= 2 byte(16 bits), -32768->32767
      unsigned int= 2 byte(16 bits), 0-> 65535
      long = 4 byte(32 bits), -2,147,483,648->2,147,483,647
      unsigned long= 4 byte (32 bits), 4,294,967,295
    */

    #include "FontMap.h"  //font is in external file
    #define matrises 4          //define number of matrises, 4-22
    #define columns matrises*8  //calculate columns based how many matrises are in use
    byte displayPointer = 0;                       //for interrupt use...
    byte buffer1[columns];                              // buffer for screen,4x8=32
    const byte power[8] = {128, 64, 32, 16, 8, 4, 2, 1}; //for each column B10000000->B00000001

    char string[40]; //array to store incoming data
    char c;
    byte index;
    byte textlength; //for dynaminc scroll length
    char * vout; //used with strtok()
    byte Rotation; //optional rotation command, not needed for normal scrolling

    void draw()
    {
      setcolumn(displayPointer);            //column scanning
      setdata(buffer1[displayPointer]);    //bit banging shift registers
      bitSet(PORTD, 3); //blit latch, high->low
      bitClear(PORTD, 3);
      if (++displayPointer == columns)          //32 LED row sections in total
      { displayPointer = 0;
      }
    }



    void setcolumn(byte col)         //loop that takes care of column scanning
    {
      int pos;
      for (pos = columns; pos > -1; pos--)
      {
        if (col == pos)
        {
          bitSet(PORTD, 2);  //data high
        }
        else
        {
          bitClear(PORTD, 2); //data low
        }
        bitSet(PORTD, 4);      //blit clock high->low
        bitClear(PORTD, 4);
      }
    }

    void setdata(byte dat)
    {
      byte pos;
      for (pos = 0; pos < 8; pos++)
      {
        if (dat & 128)
        {
          dat -= 128;
          bitSet(PORTD, 2);  //data high
        }
        else
        {
          bitClear(PORTD, 2); //data low
        }
        dat = dat << 1;  //dat <<1==dat *2;
        bitSet(PORTD, 4);     //blit clock
        bitClear(PORTD, 4);

      }
    }




    void clr()                          //clear display buffer
    {
      byte addr;
      for (addr = 0; addr < columns; addr++) // Empty display buffer
        buffer1[addr] = 0;
    }

    void pixel(signed char x, signed char y, byte cond)
    {
      byte pix, msk;
      if (x < 0 || y < 0)
      {
        return; // outside drawing limits negative
      }
      if (x > (columns - 1) || y > 7)
      {
        return; // outside drawing limits positive, x=32, y=8
      }
      pix = power[y];
      msk = buffer1[x]; // get exsisting data


      if (cond == 2)
        pix ^= msk; //XOR data to screen
      if (cond == 1)
      {
        pix = ~pix;
        pix &= msk; // AND data to screen
      }
      if (cond == 0)
        pix |= msk; // OR data to screen
      buffer1[x] = pix; // apply changes
    }




    void value(char ch, signed char x, signed char y, byte rotation)
    {
      byte x1, y1;
      byte disp, disp2;
      for ( x1 = 0; x1 < 8; x1++) // eight rows
      {
        disp = font[x1 + (ch << 3)]; //look data from fontmap, (ch<<3)==(ch *8)
        for (y1 = 0; y1 < 8; y1++) // eight pixels
        {
          disp2 = disp & power[y1];
          if (disp2 > 0)
          {
            if (rotation == 0)
            {
              pixel(x + x1, y + y1, 0); //0 degrees
            }
            if (rotation == 1)
            {
              pixel(7 - (y + y1), (x + x1), 0); //90 degrees, flip to left
            }
            if (rotation == 2)
            {
              pixel(7 - (x + x1), 7 - (y + y1), 0);
            }
            if (rotation == 3)
            {
              pixel(y + y1, 7 - (x + x1), 0); //90 degrees, flip to right
            }
          }
        }
      }
    }





    void text(char* ch, signed char x, signed char y, byte rotation)  //strput relies on charput
    {
      while (*ch )
      {
        value(*ch++, x, y, rotation); //write a string to the display buffer
        x += 7;
      }
    }



    void setup() //setup runs once
    {
      DDRD = DDRD | B11111100; //port registers used to set pin directions
      Serial.begin(115200);
    }


    void loop() //just sitting here
    {

      if (Serial.available() > 0)
      {
        c = Serial.read();

        if ((c != '\r') && (c != '\n')) //Keep these out of our buffer
        {
          string[index++] = c; //Add whatever we receive to the buffer
        }

        else
        {
          textlength = index * 8 + 32;  // *8, since matrises are 8-wide, and 32 to scroll whole screen.
          string[index++] = '\0';//Converts the array into a string
          index = 0; //next time we start from beginning index
          vout = strtok(string, ",");   //array is ready, time to parse

          while (vout != NULL)
          {
            Rotation = atoi(vout);
            vout = strtok(NULL, " .");
          }
        }
      }
      clr();
      text(string, 31 - millis() / 100 % textlength, 0, Rotation);
      draw();
    }
     
     
  16. fezder

    fezder Well-Known Member

    Joined:
    Dec 11, 2011
    Messages:
    1,665
    Likes:
    100
    Location:
    Mikkeli, Finland
    wee, got it too working! I didn't know that strtok() destroys string while reading, will post even further improved code soonish!
     
  17. fezder

    fezder Well-Known Member

    Joined:
    Dec 11, 2011
    Messages:
    1,665
    Likes:
    100
    Location:
    Mikkeli, Finland
    Code (c):

    //this sketch allows to scroll text and data on 8x8 matrises. When changing matrix size, change matrises value and OCR1A in setup. However, OCR1A is initially se-up for bigger displays, and it works in smaller too so no need change unless screen doesn't update fast enought; increase value then.
    /*
       SERIAL INPUT!
      to display text = text("text here",x-pos,y-pos, rot(optional));
      to display values in numbers= value(value, x-pos,y-pos, rot(optional));
      to display pixels=pixel(x-pos,y-pos,mode);   (useful for drawing lines and graphs, use for() loop to create lines better

      BIG thanks for dr.doggy from ETO (electro tech online)

      signed char/char= 1 byte(8 bits), -127->127
      unsigned char/byte= 1 byte(8 bits), 0->255
      int= 2 byte(16 bits), -32768->32767
      unsigned int= 2 byte(16 bits), 0-> 65535
      long = 4 byte(32 bits), -2,147,483,648->2,147,483,647
      unsigned long= 4 byte (32 bits), 4,294,967,295
    */



    #include "FontMap.h"  //font is in external file
    #define matrises 4          //define number of matrises, 4-22
    #define columns matrises*8  //calculate columns based how many matrises are in use
    byte displayPointer = 0;                       //for interrupt use...
    byte buffer1[columns];                              // buffer for screen,4x8=32
    const byte power[8] = {128, 64, 32, 16, 8, 4, 2, 1}; //for each column B10000000->B00000001

    char string[40]; //array to store incoming data
    char textFromPc[40]; //array to store actual text to show on matrix

    char c;
    byte index;
    byte textlength; //for dynaminc scroll length
    char * strtokIndx; // this is used by strtok() as an index


     byte Yoffset = 0;
    byte Rotation = 0;


    void draw() //draw loop,DON'T TOUCH!
    {
      setcolumn(displayPointer);            //column scanning
      setdata(buffer1[displayPointer]);    //bit banging shift registers
      bitSet(PORTD, 3); //blit latch, high->low
      bitClear(PORTD, 3);
      if (++displayPointer == columns)          //32 LED row sections in total
      { displayPointer = 0;
      }
    }



    void setcolumn(byte col)         //loop that takes care of column scanning DON'T TOUCH!
    {
      int pos;
      for (pos = columns; pos > -1; pos--)
      {
        if (col == pos)
        {
          bitSet(PORTD, 2);  //data high
        }
        else
        {
          bitClear(PORTD, 2); //data low
        }
        bitSet(PORTD, 4);      //blit clock high->low
        bitClear(PORTD, 4);
      }
    }


    void setdata(byte dat)
    {
      byte pos;
      for (pos = 0; pos < 8; pos++)
      {
        if (dat & 128)
        {
          dat -= 128;
          bitSet(PORTD, 2);  //data high
        }
        else
        {
          bitClear(PORTD, 2); //data low
        }
        dat = dat << 1;  //dat <<1==dat *2;
        bitSet(PORTD, 4);     //blit clock
        bitClear(PORTD, 4);

      }
    }




    void clr()                          //clear display buffer
    {
      byte addr;
      for (addr = 0; addr < columns; addr++) // Empty display buffer
        buffer1[addr] = 0;
    }

    void pixel(signed char x, signed char y, byte cond)
    {
      byte pix, msk;
      if (x < 0 || y < 0)
      {
        return; // outside drawing limits negative
      }
      if (x > (columns - 1) || y > 7)
      {
        return; // outside drawing limits positive, x=32, y=8
      }
      pix = power[y];
      msk = buffer1[x]; // get exsisting data


      if (cond == 2)
        pix ^= msk; //XOR data to screen
      if (cond == 1)
      {
        pix = ~pix;
        pix &= msk; // AND data to screen
      }
      if (cond == 0)
        pix |= msk; // OR data to screen
      buffer1[x] = pix; // apply changes
    }




    void value(char ch, signed char x, signed char y, byte rotation)
    {
      byte x1, y1;
      byte disp, disp2;
      for ( x1 = 0; x1 < 8; x1++) // eight rows
      {
        disp = font[x1 + (ch << 3)]; //look data from fontmap, (ch<<3)==(ch *8)
        for (y1 = 0; y1 < 8; y1++) // eight pixels
        {
          disp2 = disp & power[y1];
          if (disp2 > 0)
          {
            if (rotation == 0)
            {
              pixel(x + x1, y + y1, 0); //0 degrees
            }
            if (rotation == 1)
            {
              pixel(7 - (y + y1), (x + x1), 0); //90 degrees, flip to left
            }
            if (rotation == 2)
            {
              pixel(7 - (x + x1), 7 - (y + y1), 0);
            }
            if (rotation == 3)
            {
              pixel(y + y1, 7 - (x + x1), 0); //90 degrees, flip to right
            }
          }
        }
      }
    }





    void text(char* ch, signed char x, signed char y, byte rotation)  //strput relies on charput
    {
      while (*ch )
      {
        value(*ch++, x, y, rotation); //write a string to the display buffer
        x += 7;
      }
    }



    void setup() //setup runs once
    {
      DDRD = DDRD | B11111100; //port registers used to set pin directions
      Serial.begin(115200);
    }


    void loop() //just sitting here
    {

      if (Serial.available() > 0)
      {
        c = Serial.read();

        if ((c != '\r') && (c != '\n')) //Keep these out of our buffer
        {
          string[index++] = c; //Add whatever we receive to the buffer
        }

        else
        {
          textlength = index * 8 + 32;  // *8, since matrises are 8-wide, and 32 to scroll whole screen.
          string[index++] = '\0';//Converts the array into a string
          index = 0; //next time we start from beginning index
          parseData(); //time to parse data received
          //showParsedData(); //for debugging!

        }
      }
      clr();
      text(textFromPc, 31 - millis() / 100 % textlength, Yoffset, Rotation);
      draw();
    }




    void parseData()  //function for splitting the array
    {

      strtokIndx = strtok(string, ",");     // get the first part - the TEXT PART
      strcpy(textFromPc, strtokIndx); // copy it to messageFromPC

      strtokIndx = strtok(NULL, ",");
      Yoffset = atoi(strtokIndx);

      strtokIndx = strtok(NULL, ",");
      Rotation = atoi(strtokIndx);

    }


    /*
      void showParsedData()
      {
      Serial.print("text ");
      Serial.println(textFromPc);
      Serial.print("plane ");
      Serial.println(Yoffset);
      Serial.print("rotation ");
      Serial.println(Rotation);
      }
    */


     
     
  18. fezder

    fezder Well-Known Member

    Joined:
    Dec 11, 2011
    Messages:
    1,665
    Likes:
    100
    Location:
    Mikkeli, Finland
    Again I must keep this thread alive, since I ran to problem when I try to feed data from ESP8266 via server....I really have no idea, why. I just copy my topic from arduino forum...I posted this alsoi in ESP-forums but no help yet. Moderator still has my post lol...
    Arduino part of code processes serial data, works in wired serial as well as bluetooth. But, now when I try to add ESP-01 to control from browser, something odd is happening.

    But, when I try to use ESP-01, text only "blinks" very quickly when shot from browser, and MDNS-part of code is shown on screen once, before sending any data. It looks like extra line feed is fed.
    But, according to serial monitor, no extra LN is received on arduino part.
    I have feeling esp-part of code is culprit, since bluetooth serial and wired serial works fine
    First, ESP:code (program using arduino IDE)
    Full article I found this code from and mangled bit:
    http://embedded-lab.com/blog/wifi-enabled-scrolling-led-matrix-display/
    I hope I didn't forgot any relevant information.
    Code (c):


    #include <ESP8266WiFi.h>
    #include <WiFiClient.h>
    #include <ESP8266WebServer.h>
    #include <ESP8266mDNS.h>

    MDNSResponder mdns;

    // Replace with your network credentials
    const char* ssid = "KONIG_WS01";
    const char* password = "admin";

    ESP8266WebServer server(80);

    String webPage = "";


    void setup(void) {

      webPage += "<h1>ESP8266 Web Server</h1>";
      webPage +=   "<form action='msg'><p>Type your message <input type='text' name='msg' size=100 autofocus> <input type='submit' value='Submit'></form>";


      delay(1000);
      Serial.begin(115200);
      WiFi.begin(ssid, password);
      Serial.println("");

      // Wait for connection
      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
      }
      Serial.println("");
      Serial.print("Connected to ");
      Serial.println(ssid);
      Serial.print("IP address: ");
      Serial.println(WiFi.localIP());

      if (mdns.begin("esp8266", WiFi.localIP())) {
        Serial.println("MDNS responder started");
      }

      server.on("/", []() {
        server.send(200, "text/html", webPage);
      });

        server.on("/msg", []() {
        server.send(200, "text/html", webPage);
      String msg = server.arg("msg");
      Serial.println(msg);    delay(1000);
      });


      server.begin();
      Serial.println("HTTP server started");
    }

    void loop(void) {
      server.handleClient();
    }
     
    And then the pro-mini part
    Code (c):

    //this sketch allows to scroll text and data on 8x8 matrises. When changing matrix size, change matrises value and OCR1A in setup. However, OCR1A is initially se-up for bigger displays, and it works in smaller too so no need change unless screen doesn't update fast enought; increase value then.
    /*
       SERIAL INPUT!
      to display text = text("text here",x-pos,y-pos, rot(optional));
      to display values in numbers= value(value, x-pos,y-pos, rot(optional));
      to display pixels=pixel(x-pos,y-pos,mode);   (useful for drawing lines and graphs, use for() loop to create lines better

      BIG thanks for dr.doggy from ETO (electro tech online)

      signed char/char= 1 byte(8 bits), -127->127
      unsigned char/byte= 1 byte(8 bits), 0->255
      int= 2 byte(16 bits), -32768->32767
      unsigned int= 2 byte(16 bits), 0-> 65535
      long = 4 byte(32 bits), -2,147,483,648->2,147,483,647
      unsigned long= 4 byte (32 bits), 4,294,967,295
    */



    #include "FontMap.h"  //font is in external file
    #define matrises 4          //define number of matrises, 4-22
    #define columns matrises*8  //calculate columns based how many matrises are in use
    byte displayPointer = 0;                       //for interrupt use...
    byte buffer1[columns];                              // buffer for screen,4x8=32
    const byte power[8] = {128, 64, 32, 16, 8, 4, 2, 1}; //for each column B10000000->B00000001

    char string[40]; //array to store incoming data
    char textFromPc[40]; //array to store actual text to show on matrix

    char c;
    byte index;
    byte textlength; //for dynaminc scroll length
    char * strtokIndx; // this is used by strtok() as an index


    byte Yoffset = 0;
    byte Rotation = 0;


    void draw() //draw loop,DON'T TOUCH!
    {
      setcolumn(displayPointer);            //column scanning
      setdata(buffer1[displayPointer]);    //bit banging shift registers
      bitSet(PORTD, 3); //blit latch, high->low
      bitClear(PORTD, 3);
      if (++displayPointer == columns)          //32 LED row sections in total
      { displayPointer = 0;
      }
    }



    void setcolumn(byte col)         //loop that takes care of column scanning DON'T TOUCH!
    {
      int pos;
      for (pos = columns; pos > -1; pos--)
      {
        if (col == pos)
        {
          bitSet(PORTD, 2);  //data high
        }
        else
        {
          bitClear(PORTD, 2); //data low
        }
        bitSet(PORTD, 4);      //blit clock high->low
        bitClear(PORTD, 4);
      }
    }


    void setdata(byte dat)
    {
      byte pos;
      for (pos = 0; pos < 8; pos++)
      {
        if (dat & 128)
        {
          dat -= 128;
          bitSet(PORTD, 2);  //data high
        }
        else
        {
          bitClear(PORTD, 2); //data low
        }
        dat = dat << 1;  //dat <<1==dat *2;
        bitSet(PORTD, 4);     //blit clock
        bitClear(PORTD, 4);

      }
    }




    void clr()                          //clear display buffer
    {
      byte addr;
      for (addr = 0; addr < columns; addr++) // Empty display buffer
        buffer1[addr] = 0;
    }

    void pixel(signed char x, signed char y, byte cond)
    {
      byte pix, msk;
      if (x < 0 || y < 0)
      {
        return; // outside drawing limits negative
      }
      if (x > (columns - 1) || y > 7)
      {
        return; // outside drawing limits positive, x=32, y=8
      }
      pix = power[y];
      msk = buffer1[x]; // get exsisting data


      if (cond == 2)
        pix ^= msk; //XOR data to screen
      if (cond == 1)
      {
        pix = ~pix;
        pix &= msk; // AND data to screen
      }
      if (cond == 0)
        pix |= msk; // OR data to screen
      buffer1[x] = pix; // apply changes
    }




    void value(char ch, signed char x, signed char y, byte rotation)
    {
      byte x1, y1;
      byte disp, disp2;
      for ( x1 = 0; x1 < 8; x1++) // eight rows
      {
        disp = font[x1 + (ch << 3)]; //look data from fontmap, (ch<<3)==(ch *8)
        for (y1 = 0; y1 < 8; y1++) // eight pixels
        {
          disp2 = disp & power[y1];
          if (disp2 > 0)
          {
            if (rotation == 0)
            {
              pixel(x + x1, y + y1, 0); //0 degrees
            }
            if (rotation == 1)
            {
              pixel(7 - (y + y1), (x + x1), 0); //90 degrees, flip to left
            }
            if (rotation == 2)
            {
              pixel(7 - (x + x1), 7 - (y + y1), 0);
            }
            if (rotation == 3)
            {
              pixel(y + y1, 7 - (x + x1), 0); //90 degrees, flip to right
            }
          }
        }
      }
    }





    void text(char* ch, signed char x, signed char y, byte rotation)  //strput relies on charput
    {
      while (*ch )
      {
        value(*ch++, x, y, rotation); //write a string to the display buffer
        x += 7;
      }
    }



    void setup() //setup runs once
    {
      DDRD = DDRD | B11111100; //port registers used to set pin directions
      Serial.begin(115200);
    }


    void loop() //just sitting here
    {

      if (Serial.available() > 0)
      {
        c = Serial.read();

        if ((c != '\r') && (c != '\n')) //Keep these out of our buffer
        {
          string[index++] = c; //Add whatever we receive to the buffer
        }

        else
        {
          textlength = index * 8 + 32;  // *8, since matrises are 8-wide, and 32 to scroll whole screen.
          string[index++] = '\0';//Converts the array into a string
          index = 0; //next time we start from beginning index
          parseData(); //time to parse data received
          //showParsedData(); //for debugging!

        }
      }
      clr();
      text(textFromPc, 31 - millis() / 100 % textlength, Yoffset, Rotation);
      draw();
    }




    void parseData()  //function for splitting the array
    {

      strtokIndx = strtok(string, ",");     // get the first part - the TEXT PART
      strcpy(textFromPc, strtokIndx); // copy it to messageFromPC

      strtokIndx = strtok(NULL, ",");
      Yoffset = atoi(strtokIndx);

      strtokIndx = strtok(NULL, ",");
      Rotation = atoi(strtokIndx);

    }


    /*
      void showParsedData()
      {
      Serial.print("text ");
      Serial.println(textFromPc);
      Serial.print("plane ");
      Serial.println(Yoffset);
      Serial.print("rotation ");
      Serial.println(Rotation);
      }
    */

     

     
  19. fezder

    fezder Well-Known Member

    Joined:
    Dec 11, 2011
    Messages:
    1,665
    Likes:
    100
    Location:
    Mikkeli, Finland
    Aha! Seems I have bug In my code, since I debugged bit with serial monitor.
    This is code I used to debug, arriving data, what is going to buffer, and what is in buffer:
    Code (c):


    char string[40]; //array to store incoming data
    char textFromPc[40]; //array to store actual text to show on matrix

    char c;
    byte index;
    byte textlength; //for dynaminc scroll length


    void setup() //setup runs once
    {
      Serial.begin(9600);
    }


    void loop() //just sitting here
    {

      if (Serial.available() > 0)
      {
        c = Serial.read();
        Serial.print("before buffer:  ");
        Serial.println(c, DEC);

        if ((c != '\r') && (c != '\n')) //Keep these out of our buffer
        {
          string[index++] = c; //Add whatever we receive to the buffer
          //Serial.print("going to buffer:  ");
          //Serial.println(c, DEC);
        }
        else
        {
          textlength = index * 8 + 32;  // *8, since matrises are 8-wide, and 32 to scroll whole screen.
          string[index++] = '\0';//Converts the array into a string
          //Serial.print("at buffer, received in ASCII:  ");
          //Serial.println(string);
          index = 0; //next time we start from beginning index
        }
      }
    }
     
    Normal, written straight from monitor,when pressed enter:
    Code (c):

    before buffer:  10 //line feed!
    at buffer, received in ASCII:    //nothing, since, LN is ignored
     
    and, with esp:
    Code (c):

    before buffer: 13    //hmm, carrion return?
    at buffer, received in ascii:
    before buffer :10
    at buffer, received in ascii:
     
    and same test, with character "h":
    normal:
    Code (c):

    before buffer:  104
    going to buffer:  104
    before buffer:  10
    at buffer, received in ASCII:  h
     
    esp:
    Code (c):

    before buffer: 104
    going to buffer:104
    before buffer: 13
    at buffer , received in ASCII: h
    before buffer: 10
    at buffer, received in ASCII:
     
    WHILE writing this, I found bug in my arduino part, so this fixed: (LN wasn't terminator in my code!)
    Code (c):


        if(c=='\n')
        {
          textlength = index * 8 + 32;  // *8, since matrises are 8-wide, and 32 to scroll whole screen.
          string[index++] = '\0';//Converts the array into a string
          //Serial.print("at buffer, received in ASCII:  ");
          //Serial.println(string);
          index = 0; //next time we start from beginning index

          parseData(); //time to parse data received
          //showParsedData(); //for debugging!

        }
     
     
    Last edited: Dec 7, 2016
  20. fezder

    fezder Well-Known Member

    Joined:
    Dec 11, 2011
    Messages:
    1,665
    Likes:
    100
    Location:
    Mikkeli, Finland
    Here, wrapped matrix to handy library!
    Had to use slow digitalWrite since I don't knot how to allocate pins for portmanipulation on the fly.
    Also, array is not set dynamically etiher, but It works on some degree!

    Also attatched version for 7-segment
     

    Attached Files:

    Last edited: Dec 18, 2016
    • Like Like x 1

Share This Page