c++ Array Help

Thread Starter

kurtruk

Joined Aug 26, 2012
140
I am working on a project that takes a line of characters typed on a computer and displays them on a 50x8 LED Matrix controlled by an arduino. I am having trouble with the scrolling part.

This is how I would like to do it:
Have two bitmaps a msgbitmap and a bitmap. The msgbitmap is sent to the arduino via serial (I know how to make the msgbitmap, but have not written the code for the serial communications yet). The bitmap would be what is actually displayed on the Matrix at any "point" in time. I am not sure how to shift the msgbitmap gradually into the bitmap.

I know it has to go like this:
1st shift:
bitmap[0][49] = msgbitmap [0][0]
bitmap[1][49] = msgbitmap [1][0]
bitmap[2][49] = msgbitmap [2][0]
bitmap[3][49] = msgbitmap [3][0]
bitmap[4][49] = msgbitmap [4][0]
bitmap[5][49] = msgbitmap [5][0]
bitmap[6][49] = msgbitmap [6][0]
bitmap[7][49] = msgbitmap [7][0]

//set rest to 0?

2nd Shift:
bitmap[0][49] = msgbitmap [0][1]
bitmap[1][49] = msgbitmap [1][1]
bitmap[2][49] = msgbitmap [2][1]
bitmap[3][49] = msgbitmap [3][1]
bitmap[4][49] = msgbitmap [4][1]
bitmap[5][49] = msgbitmap [5][1]
bitmap[6][49] = msgbitmap [6][1]
bitmap[7][49] = msgbitmap [7][1]

bitmap[0][48] = msgbitmap [0][0]
bitmap[1][48] = msgbitmap [1][0]
bitmap[2][48] = msgbitmap [2][0]
bitmap[3][48] = msgbitmap [3][0]
bitmap[4][48] = msgbitmap [4][0]
bitmap[5][48] = msgbitmap [5][0]
bitmap[6][48] = msgbitmap [6][0]
bitmap[7][48] = msgbitmap [7][0]

//set rest to 0?

3rd shift:

bitmap[0][49] = msgbitmap [0][2]
bitmap[1][49] = msgbitmap [1][2]
bitmap[2][49] = msgbitmap [2][2]
bitmap[3][49] = msgbitmap [3][2]
bitmap[4][49] = msgbitmap [4][2]
bitmap[5][49] = msgbitmap [5][2]
bitmap[6][49] = msgbitmap [6][2]
bitmap[7][49] = msgbitmap [7][2]

bitmap[0][48] = msgbitmap [0][1]
bitmap[1][48] = msgbitmap [1][1]
bitmap[2][48] = msgbitmap [2][1]
bitmap[3][48] = msgbitmap [3][1]
bitmap[4][48] = msgbitmap [4][1]
bitmap[5][48] = msgbitmap [5][1]
bitmap[6][48] = msgbitmap [6][1]
bitmap[7][48] = msgbitmap [7][1]

bitmap[0][47] = msgbitmap [0][0]
bitmap[1][47] = msgbitmap [1][0]
bitmap[2][47] = msgbitmap [2][0]
bitmap[3][47] = msgbitmap [3][0]
bitmap[4][47] = msgbitmap [4][0]
bitmap[5][47] = msgbitmap [5][0]
bitmap[6][47] = msgbitmap [6][0]
bitmap[7][47] = msgbitmap [7][0]

//set rest to 0?
............
I know this can be done in a forloop, but I just can't seem to figure it out.
 

Thread Starter

kurtruk

Joined Aug 26, 2012
140
This is code that I think would work, but for some reason doesn't. Note their are two msgbitmap for two colors (red and green).

Rich (BB code):
void shift(){
bool rmsgbitmap[8][50] = {
                    {0,1,0,0,0,1,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,0,1,0},
                    {0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,1,0},
                    {0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,1,0},
                    {0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,1,0},
                    {0,1,1,1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,0,1,0},
                    {0,1,0,0,0,1,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,1,0,0,0,1,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,1,0,0,0,1,0,1,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,1,0}
                   };


bool  gmsgbitmap[8][50] = {
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0,1,0,1,1,1,1,0,0,1,1,1,1,1,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,1,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,1,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,1,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,0,0,0,0,1,0,1,1,1,1,0,0,0,0,1,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,1,0,1,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,1,0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,1,1,1,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0}};
int runTimes = timesShifted;
for(int row=0; row<8; row++){
    for(int col=49; col>-1; col--){
        for(int i=-1; i < timesShifted; i++){  //heres where it would break down if the msg is greater than 50 columns
            rbitmap[row][col] = rmsgbitmap[row][runTimes];
            gbitmap[row][col] = gmsgbitmap[row][runTimes];
            runTimes--;
        }
    }
}
timesShifted++;



};
This seems like it would work as long as the msg is less than 50 columns but it does not work.

P.S. sorry for my badly named ints.
 

shteii01

Joined Feb 19, 2010
4,644
This is code that I think would work, but for some reason doesn't. Note their are two msgbitmap for two colors (red and green).

This seems like it would work as long as the msg is less than 50 columns but it does not work.

P.S. sorry for my badly named ints.
row and col don't seem to be defined.
 

Thread Starter

kurtruk

Joined Aug 26, 2012
140
After more thinking I think the above code won't work.

I just need a simple way to shift one array into another.
 

ErnieM

Joined Apr 24, 2011
8,377
After more thinking I think the above code won't work. I just need a simple way to shift one array into another.
Cart, horse, even since that damn automobile got invented no on knows which one goes first!

DO work out what needs to get done, THEN figure out how to do it.

Is there a plan to display a bitmap? Is it written down somewhere?

Next, is there a plan to shift a bitmap? Is it written down somewhere?

You can't (well, should not) start until you have both.

Until you have both no one else can help you. That is absolute.
 

Thread Starter

kurtruk

Joined Aug 26, 2012
140
Sir, If you had read my first post you would know their is a plan
I am working on a project that takes a line of characters typed on a computer and displays them on a 50x8 LED Matrix controlled by an arduino. I am having trouble with the scrolling part.

This is how I would like to do it:
Have two bitmaps a msgbitmap and a bitmap. The msgbitmap is sent to the arduino via serial (I know how to make the msgbitmap, but have not written the code for the serial communications yet). The bitmap would be what is actually displayed on the Matrix at any "point" in time. I am not sure how to shift the msgbitmap gradually into the bitmap.
The display is done.

I know what needs to be done. I just didn't know how to do it. That's why I asked for help.


I have ended up adding ten spaces to begin the msgbitmap so it is easier to do the shifting. (so that I can start at the beginning and not have it dynamically grow). This will work, but I am still wondering if it is possible to do it the other way.

And in addition with that way I won't even need a separate shift function I can just integrate into the function that actually tells the matrix what to display
 
Last edited:

Thread Starter

kurtruk

Joined Aug 26, 2012
140
So I got it work partially. It displays the green perfectly except for three pixels that are always on for some reason. I have tested the hardware nothing is wrong.

The red is another story it display random garbage.

I have tried numerous different ways. checked my code again and again and can't figure out why it is not working.

Here is the main.cpp:

Rich (BB code):
/*50 X 8 Scrolling Matrix
 Author: Kurt
Date 2/14/14
Version 2.0 */

#include "DisplayClass.h"

void setup(){
  DisplayClass o;
  o.Setup();
  /*for(int r=0;r<8;r++){
    for(int c=0;c<50;c++){
      o.rbitmap[r][c] = 0;
    }
  }
  for(int r=0;r<8;r++){
    for(int c=0;c<50;c++){
      o.gbitmap[r][c] = 0;
    }
  }*/
}

void loop (){
  DisplayClass o;
  o.Setup();
  while(1){
    for(int Speed=0;Speed<10;Speed++){
    o.refresh();
    }
    o.shift();
  }
}
DisplayClass.h:
Rich (BB code):
#ifndef DISPLAYCLASS_H
#define DISPLAYCLASS_H


class DisplayClass
{
    public:
      int row1; //binary value for row select
      int row2; //binary value for row select
      int row3; //binary value for row select
      int rowE; // row enable enable display LOW ON
      int rclk; // register clk latch
      int clk; // serial clock input
      int rdat; // red serial data
      int gdat; // green serial date
      
      int Shift;
     
      bool  rbitmap [8][50];
      bool  gbitmap [8][50];
      
      void refresh();
      void Setup();
      void shift();
};

#endif // DISPLAYCLASS_H
DisplayClass.cpp
Rich (BB code):
#include "DisplayClass.h"
#include "Arduino.h"

bool gmsgbitmap [8][126] = {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,1,0,0,0,1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1,0,0,0,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,1,1,1,0,1,1,1,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
                     
bool rmsgbitmap [8][126] = {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,1,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,1,0,0,0,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,1,1,1,1,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,1,1,0,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};


void DisplayClass::refresh(){  
  for (int row=0; row<8; row++){
    digitalWrite (rowE, HIGH);
    digitalWrite (rclk, LOW);
 
    for (int col=0; col < 50; col++){
      digitalWrite(gdat, LOW);
      digitalWrite(rdat, LOW);
      
       if ((gbitmap [row][col]) == 1) {
         digitalWrite(gdat, HIGH);
       } 
       else digitalWrite (gdat, LOW);
       
       if ((rbitmap [row][col]) == 1){
         digitalWrite(rdat, HIGH);
       }
       else digitalWrite (rdat, LOW);
      
      digitalWrite(clk, HIGH); 
      digitalWrite(clk, LOW);
    }
  
    digitalWrite(rclk, HIGH);
    if bitRead(row,0) digitalWrite (row1, HIGH); else digitalWrite(row1, LOW); 
    if bitRead(row,1) digitalWrite (row2, HIGH); else digitalWrite(row2, LOW);
    if bitRead(row,2) digitalWrite (row3, HIGH); else digitalWrite(row3, LOW);
    digitalWrite(rowE, LOW);
    delayMicroseconds(600);    
  }
}
  

void DisplayClass::Setup(){
  row1 = 1; 
  row2 = 2; 
  row3 = 3; 
  rowE = 4; 
  rclk = 5; 
  clk  = 6; 
  rdat = 7; 
  gdat = 8; 

  pinMode (row1, OUTPUT);
  pinMode (row2, OUTPUT);
  pinMode (row3, OUTPUT);
  pinMode (rowE, OUTPUT);
  pinMode (rclk, OUTPUT);
  pinMode (clk , OUTPUT);
  pinMode (rdat, OUTPUT);
  pinMode (gdat, OUTPUT);
  Shift = 0;
}


void DisplayClass::shift(){
  for(int row=0;row<8;row++){
    for(int col=0;col<50;col++){
      rbitmap[row][col] = rmsgbitmap[row][(col+Shift)];
      gbitmap[row][col] = gmsgbitmap[row][(col+Shift)];

     }
  }
  Shift++;
  if(Shift==76){
    Shift=0;
  }
}
I don't understand why the green would work but not the red. I almost immediately thought it was a hardware malfunction but I have thoroughly tested it, and it is not.
 

takao21203

Joined Apr 28, 2012
3,702
Interesting approach to use a bool array.

But you hardcode the dimensions (even if you could use defines).

What about this:


  • Bitmap memory organized as bytes or words.


  • blitting logic to copy parts of bitmap which is visible into display buffer memory


  • Display buffer memory
  • descriptor tables how the external hardware is mapped to I/O
  • code to copy parts from the display buffer to the I/O using the hardware descriptor tables
It can be simple if you connect the matrix to full ports in ascending bit order. If you need to remap all the bits, it will be much slower.

2

Scrolling Once you have the code ready as described above, you precompute the whole string as bitmap. Advantage: you can use proportional fonts.

then you treat it as bitmap, and copy a window to the display buffer.
That window is shifted step by step.

It is possible to do all the work on the Arduino, and just send the ASCII text.

All you need to do is to realize the abstract associations (the message bitmap is copied together from the font bitmaps, then a window from the message bitmap is copied into the display buffer memory. Then the display buffer is transfered to I/O as required for instance multiplexing).

I am for instance using a proportional font, where I store the width in the upper 3 bits of the first byte. Looks much much better than fixed width. If you compute it on the fly and the character width is variable, it become very hard to code that properly.
 

Thread Starter

kurtruk

Joined Aug 26, 2012
140
I am a noob.

I don't understand half of what you are saying. Especially under "What about this:"

You're suggesting I send the text via serial and have the arduino do the rest?

My goal was to have the large computing end be done by the computer in order to be less taxing on the arduino. That way all the arduino has to do is display, shift, and receive the data.

Also I think I understand what you are saying about the proportional font with the size being stored in the three bits. I have spent literally hours and hours making that font and it seems a hassel to change it just to make it look prettier.

I thought shift could be incorporated in the refresh function like thus:
Rich (BB code):
if ((gbitmap [row][col+Shift]) == 1) {  //Communicate with Sign to display gbitmap
         digitalWrite(gdat, HIGH);
       } 
       else digitalWrite (gdat, LOW);
That would get rid of the window bitmap all together.

I am still however unsure why my red is displaying random garbage.
 

takao21203

Joined Apr 28, 2012
3,702
yes making these fonts can be time consuming.

Using C language means to learn how to apply abstraction to almost anything.

Put simpler you can think like that:

Existing data or input data

Transition or transformation function

Desired output


Existing data: The font + the ASCII text

Transformation function: the scrolling algorithm

Desired output: A pattern scrolling through


There is a deviation between the existing data, and the desired output.


the idea is to transform it with as less effort as possible, and to optimize the program for some aspects such as readability, and maintainability.


After a while, I just found it handy to precompute the bitmap for the whole string (the message), and then use a sliding window into an output buffer.


1. how the output buffer (same size as actual matrix) is mapped, transfered or shown on the matrix is totally removed from the algorithm.

2. How the font is structured also is removed from the algorithm- it just scrolls a bitmap


You may get along with your approach after a while but maybe you want to change the size or build another matrix.

Also precomputing the bitmap is reducing the amount of required processing power a lot.

I have done a scrolling message for a 16F57 with 2K FLASH (12x5 matrix).

that said I am working on a better 14x5 matrix powered by a 4K FLASH PIC, the 16f884.



Maybe you want to know why the red LEDs dont work right.
Breaking it down into independent pieces can help a lot to isolate the mistake.

for instance, you can run the bitmap generator in a software simulator.

I made the experience, rewriting a bad source can be easier than keep searching for errors.

Of course, I did not say your source is bad. Just from experience, I normally dispose sources when I get stuck :)
 

Attachments

Thread Starter

kurtruk

Joined Aug 26, 2012
140
I don't quite understand what you mean by precomputing the bitmap.



I think maybe I have failed to mention everything.

I have written a console application that takes a string of characters that the user enters and writes it to a bitmap using a font that I have created.

Since I have not created the link between the computer end and the arduino end. I just copied and pasted the msgbitmap that the computer creates.



With that said I integrated my shift function into the refresh function and heavily commented my code.

Here are the results:
main.cpp:
Rich (BB code):
/*50 X 8 Scrolling Matrix
 Author: Kurt
Date 2/14/14
Version 2.0 */

#include "DisplayClass.h"

void setup(){
  DisplayClass o;
  o.Setup(); //Setup Pins and Set as OUTPUTS

}

void loop (){
  DisplayClass o;
  o.Setup();   //For Some Reason It does NOT work without this
  while(1){
    for(int Speed=0;Speed<10;Speed++){  //Speed of shifting
    o.refresh();         //Display msgbitmaps windows
    }
    o.Shift++;          //increment shift
  }
}
DisplayClass.cpp:
Code:
#include "DisplayClass.h"
#include "Arduino.h"
/*Global msgbitmaps TEMPORARY*/
bool rmsgbitmap [8][126] = {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,1,0,0,0,1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1,0,0,0,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,1,1,1,0,1,1,1,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
                     
bool gmsgbitmap [8][126] = {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,1,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,1,0,0,0,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,1,1,1,1,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                            {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,1,1,0,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};


void DisplayClass::refresh(){    //Display the bitmaps
  for (int row=0; row<8; row++){ //Cycle through each row
    digitalWrite (rowE, HIGH);   //Turn OFF display
    digitalWrite (rclk, LOW);    //Turn OFF display
 
    for (int col=0; col < 50; col++){   //Cycle through columns
      digitalWrite(gdat, LOW);       //Make sure dataPins are LOW
      digitalWrite(rdat, LOW);       //MAke sure dataPins are LOW
      
       if ((gmsgbitmap [row][(col+Shift)]) == 1) {  //Communicate with Sign to display window of gmsgbitmap
         digitalWrite(gdat, HIGH);
       } 
       else digitalWrite (gdat, LOW);
       
       if ((rmsgbitmap [row][(col+Shift)]) == 1){  //Communicate with Sign to display windwo of rmsgbitmap
         digitalWrite(rdat, HIGH);
       }
       else digitalWrite (rdat, LOW);
      
      digitalWrite(clk, HIGH); //increment clock
      digitalWrite(clk, LOW);  //increment clock
    }
  
    digitalWrite(rclk, HIGH);  //increment row clock
    if bitRead(row,0) digitalWrite (row1, HIGH); else digitalWrite(row1, LOW); //Select Row to turn on for multiplexing
    if bitRead(row,1) digitalWrite (row2, HIGH); else digitalWrite(row2, LOW);
    if bitRead(row,2) digitalWrite (row3, HIGH); else digitalWrite(row3, LOW);
    digitalWrite(rowE, LOW);  //Turn display On
    delayMicroseconds(600);    //Rause for multiplexing
  }
  if(Shift==76){  //Reset shift to loop
    Shift=0;
  }
}
  

void DisplayClass::Setup(){
  row1 = 1; //Set Arduino Pins
  row2 = 2; 
  row3 = 3; 
  rowE = 4; 
  rclk = 5; 
  clk  = 6; 
  rdat = 7; 
  gdat = 8; 

  pinMode (row1, OUTPUT); //Set Pins as OUTPUTS
  pinMode (row2, OUTPUT);
  pinMode (row3, OUTPUT);
  pinMode (rowE, OUTPUT);
  pinMode (rclk, OUTPUT);
  pinMode (clk , OUTPUT);
  pinMode (rdat, OUTPUT);
  pinMode (gdat, OUTPUT);
  Shift = 0;  
}
DisplayClass.h:
Code:
#ifndef DISPLAYCLASS_H
#define DISPLAYCLASS_H


class DisplayClass
{
    public:
      int row1; //binary value for row select
      int row2; //binary value for row select
      int row3; //binary value for row select
      int rowE; // row enable enable display LOW ON
      int rclk; // register clk latch
      int clk; // serial clock input
      int rdat; // red serial data
      int gdat; // green serial date
      
      int Shift;
     
      bool  rbitmap [8][50]; //without this doesn't work
      bool  gbitmap [8][50];
      
      void refresh();   //Display bitmaps
      void Setup();     //Set up Arduino

};

#endif // DISPLAYCLASS_H
It works for the most part displaying the message and shifting it appropriately.

However, there are two peculiar things that don't quite work.

1. Without rbitmap and gbitmap in DisplayClass.h It does not work at all. These arrays aren't even used. Why if I delete them does it refuse to function?

2. For some reason row 1 (second from top), display random garbage. (see pic).
 

Attachments

takao21203

Joined Apr 28, 2012
3,702
I understand your setup more now. You compute on the Windows PC, and then send raw data to the Arduino.

One thing that totally springs into my eye is the way you make use of instances of your display class:

Rich (BB code):
DisplayClass o;
o.Setup();
1. the name "o" is not good but that does not matter.
2. you create a local instance of "DisplayClass" in each function!
that is not correct. You need one global instance of that class, and then you always need to work with that.

3. What do you mean "does not function". i do not see these arrays refered at all. Do you get a compiler error, or it just does not work?

Who knows. maybe Visual studio is stuck, and partiallly is refering to older instances of the sourcce.

Clean the build.
Do a debug run + single step with a suitable initial breakpoint.

I am not a master for VS, but I do get along with it.

4. If you do more work on the Arduino, you only need C, and no dealing with classes.

It should become clear you need to create an instance from a class definition, and always work with the correct instance. You only create a static instance- normally with the Windows subsystem, dynamic instances of a class are created + memory is allocated (just mentioning it).

You create temporary instances inside functions, these are discarded after leaving the function. It is a riddle it can do just anything that way.

Particulary, correct the instancing issue, and tell us what happens if you comment the arrays in the class (i.e. what error message).
 

takao21203

Joined Apr 28, 2012
3,702
I was thinking you use a C++ based program on the PC but now it's clear you run it on Arduino.

But the instancing issue is the same (creating local instance of a class inside function).

Essentially you are aready precomputing the bitmap with the scrolling text.
 

Thread Starter

kurtruk

Joined Aug 26, 2012
140
First I want to say Thank You for all your help so far it is much appreciated.

2. you create a local instance of "DisplayClass" in each function!
that is not correct. You need one global instance of that class, and then you always need to work with that.
I'm not sure if I know how to create a global instance. Do you just put it outside of a function like this:
Rich (BB code):
DisplayClass Obj;
void loop(){
     obj.refresh();
....
}
If so I tried that way and when I ran it, it display random stuff on the first row.

3. What do you mean "does not function". i do not see these arrays refered at all. Do you get a compiler error, or it just does not work?
They are in DisplayClass.h:
Rich (BB code):
#ifndef DISPLAYCLASS_H
#define DISPLAYCLASS_H


class DisplayClass
{
    public:
    
     
    
      int row1; //binary value for row select
      int row2; //binary value for row select
      int row3; //binary value for row select
      int rowE; // row enable enable display LOW ON
      int rclk; // register clk latch
      int clk; // serial clock input
      int rdat; // red serial data
      int gdat; // green serial date
      
      int Shift;
     
      bool  rbitmap [8][50]; //without this doesn't work
      bool  gbitmap [8][50];
      
      void refresh();   //Display bitmaps
      void Setup();     //Set up Arduino

};
#endif // DISPLAYCLASS_H

I put them in a red. When I run it with them commented out it simply does not display anything at all.


Who knows. maybe Visual studio is stuck, and partiallly is refering to older instances of the sourcce.

Clean the build.
Do a debug run + single step with a suitable initial breakpoint.

I am not a master for VS, but I do get along with it.
I am working in Arduino's compiler.
I copied everything into a new sketch and deleted all my builds in C:\Users\Kurt\AppData\Local\Temp\ as that is where the Arduino compiler said they are stored.

The same results as before occurred
1. Garbage on the second line as shown in previous picture.

2. Will not display anything if gbitmap and rbitmap in DisplayClass.h are commented out.

P.S. I thought maybe the garbage in row 2 was from something with the bitmap so I set up a for loop to set all elements to zero. The result did not change at all

P.S.S I also tried getting rid of my classes and putting everything in one file. I did not like how it looked at all. And it did not display anything at all either.
 
Last edited:

takao21203

Joined Apr 28, 2012
3,702
you don't have to use classes, as C++ contains C language.

Did you write all the code yourself?

It is often hard to find errors in code which has multiple issues.

the schematic for the matrix also is not clear.


What about lightening up one line, and then gain control over that, so you can move the line which lights up slowly?

Then you know your software/IO interface works.


Another idea is to use whole bytes vertically. Then you'd copy from the bitmap into a display buffer, exactly as large as the matrix.

that is not too hard.

when you gained control how to light a single line, it is also not too hard to copy the display buffer to the matrix.

2

Searching bugs is OK, I found it time saving just to rewrite everything, and if possible, test out each function somehow.


Does the Arduino IDE have a debugger, or software simulator?


3

If possible really show the complete code, for instance, use a wordpress blog (altervista free hosting).


4

The question is really if you wrote all the lines from scratch, as you ask questions about them like if you weere not totally sure what the lines are doing.

I am pretty sure you need to use a global instance of the display class, and just one.

Sorry for mixing it up with Visual Studio :)
 

Thread Starter

kurtruk

Joined Aug 26, 2012
140
I have written all the code myself this is really version 2.0 the first version I made had no interface with the computer at all and no proportional font.

I like organizing my functions into classes.

I'm going do some multiplexing detective work as suggested.

I will probably scrap all my code except my font and start over. I don't like how it was turning out anyway.
 

Thread Starter

kurtruk

Joined Aug 26, 2012
140
I am having trouble once again this time on the computer end.

Here's the code:

Rich (BB code):
#ifndef DISPLAYFUNCTIONS_H
#define DISPLAYFUNCTIONS_H


class DisplayFunctions
{
    public:
        int rmsgByteMap[];
        int gmsgByteMap[];

        char msg [512];
        int numberOfCol;
        int msgLength;
        int characterArrayLength[];


        void getMsg();   //get the users message
        void createByteMap();  //Create array of msg
        void send();     //Send users message via serial
};

#endif // DISPLAYFUNCTIONS_H
Rich (BB code):
#include "DisplayFunctions.h"
#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
#include<stdio.h>
#include<conio.h>
#include "Font.h"
using namespace std;

Font fontObj;

void DisplayFunctions::getMsg(){

    int characterLength;
    cin.getline(msg, 512);

    for(msgLength = 0; msg[msgLength] != '\0'; msgLength++);  //increment msgLength until null terminal

    characterLength = 0;
    numberOfCol = 0;         

    for(int character = 0; character < msgLength; character++){          //ArrayLength for each character
        for(int i=0; i < 8; i++){

            if (fontObj.ASCII[(msg[character])] != 256){                 //if egual to 256 (which is invalid) then don't increment array length

                    characterLength++;
            }
        }
        characterArrayLength[character] = characterLength;   //Length of each Character in the Message


        numberOfCol += characterLength;                                      //number of columns

        characterLength = 0;    //Reset arrayLength
    }

}

void DisplayFunctions::createByteMap(){
    int charColIndex =0;
    int Character = 0;


    for(int col=0;col<numberOfCol;col++){
            rmsgByteMap[col] = fontObj.ASCII[msg[Character]][charColIndex];
            charColIndex++;
            if (charColIndex==characterArrayLength[Character]){
                charColIndex = 0;
                Character++;
            }




    }
    
}








It seems as if whenever I access the msg which is a char array it deletes the entire array. I tired to bypass this by passing in the msg to another array, but it makes no difference.

Let me explain further.
After I have run getMsg and createByteMaps if I do this:
Rich (BB code):
cout << msg[0] << " ";
cout << msg[1] << " ";
cout << msg[2] << " ";
cout << msg[3] << " ";
cout << msg[4] << " ";
....
It will display .
Literally nothing.
Why is this?
I have not changed the array at all I have only accessed it.


This is really perturbing.
 

Thread Starter

kurtruk

Joined Aug 26, 2012
140
Does anyone have any idea?

I've now tried numerous ways.

For example I created a function to return the char. and then used that in the loop, but it doesn't work either.

does anyone know what my problem is?
 
Top