Continue to Site

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.

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

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

Status
Not open for further replies.
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:
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}

  }
  }
  }
}
 
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....
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!
 
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!
 
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 :)
 
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! :)
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
  }
  }
  }
  }
  }
}
 
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:
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:
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;}
 
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?
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();
}
 
\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
 
Thanks doggy, I stumbled upon this handy command:
C:
String.toCharArray(array, size);

And that allowed using strings and converting them to char array! Thanks! :)
 
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:
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);
   }
}
 
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...
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();
}
 
wee, got it too working! I didn't know that strtok() destroys string while reading, will post even further improved code soonish!
 
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);
  }
*/
 
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:
https://embedded-lab.com/blog/wifi-enabled-scrolling-led-matrix-display/
I hope I didn't forgot any relevant information.
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
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);
  }
*/

 
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:
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:
C:
before buffer:  10 //line feed!
at buffer, received in ASCII:    //nothing, since, LN is ignored
and, with esp:
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:
C:
before buffer:  104
going to buffer:  104
before buffer:  10
at buffer, received in ASCII:  h
esp:
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!)
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:
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
 

Attachments

  • _74595_matrix.zip
    5.1 KB · Views: 308
  • _74595_sevenSegment.zip
    4.5 KB · Views: 314
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top