Click here to Skip to main content
15,913,836 members
Articles / Programming Languages / C#

16x16 DotMatrix

Rate me:
Please Sign up or sign in to vote.
4.50/5 (5 votes)
28 Mar 2011CPOL3 min read 53.7K   4.2K   13   10
Building a 16x16 DotMatrix and a Matrix UserControl
16x16demo.png

Introduction

Actually, I just wanted to get some practice in coding user-controls. I started playing with Rectangles and Brushes and Pens in the onPaint method until I got the idea to set up my own dot-matrix control. A dot-matrix is used to display text and signs in dot-matrix style like LC displays do. As a spin-off product of this matrix, I got an editor to build a char-set for the matrix.

Let's Get Started

The dot-matrix is built by 16 rows, each containing 16 dots. To be more precise, 16x16 rectangles. Each rectangle might be filled completely or just with circle shape. As I needed at least some properties for each of the dots (rectangles), I started with my own rectangle-class. Let's call it RectangleXT.

Using the Code

C#
class RectangleXT
    {
        public RectangleXT()
        {

        }

        private Rectangle _rect;
        public Rectangle Rect
        {
            get { return _rect; }
            set { _rect = value; }
        }

        private int _id;
        public int Id
        {
            get { return _id; }
            set { _id = value; }
        }

        private bool _enabled;
        public bool Enabled
        {
            get { return _enabled; }
            set { _enabled = value; }
        }

        private int _row;
        public int Row
        {
            get { return _row; }
            set { _row = value; }
        }

        private int _col;
        public int Column
        {
            get { return _col; }
            set { _col = value; }
        }

        private int _binVal;
        public int BinaryValue
        {
            get { return _binVal; }
            set { _binVal = value; }
        }

        private Color _color;
        public Color Color
        {
            get { return _color; }
            set { _color = value; }
        }
    }

Having this done, I could start building the matrix. The constructor of my Matrix16x16:Control is building a RectangleXT[] array first.

C#
int row = 0;
int column = 0;
for (int i = 0; i < 256; i++)
{
    dotRects[i] = new RectangleXT();
    dotRects[i].Id = i;

    if (i % 16 == 0 && i != 0)
    {
        column = 0;
        row++;
    }
    dotRects[i].Column = column++;
    dotRects[i].Row = row;
    dotRects[i].BinaryValue = 15 - dotRects[i].Column;

    dotRects[i].Rect = new Rectangle(_dotRectWidth * dotRects[i].Column,
      _dotRectHeight * dotRects[i].Row, _dotRectWidth, _dotRectHeight);
}

Now we're ready to get it painted...

C#
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Graphics gr = e.Graphics;
Rectangle rect = ClientRectangle;
Brush brushEnabeld = new SolidBrush(ColorEnabled);
Brush brushDisabled = new SolidBrush(ColorDisabled);

int rw = rect.Width;
int refw = _dotRectWidth * 16;

for (int i = 0; i < 256; i++)
{
Rectangle rtmp = dotRects[i].Rect;

if (this.ShowBorders)
{
rtmp.Inflate(-1, -1);
}

if (dotRects[i].Enabled)
{
dotRects[i].Color = ColorEnabled;
switch (DisplayStyle)
{
case Style.Dots:
gr.FillEllipse(brushEnabeld, rtmp);
break;
case Style.Rectagles:
gr.FillRectangle(brushEnabeld, rtmp);
break;
default:
break;
}
}
else
{
dotRects[i].Color = ColorDisabled;
switch (DisplayStyle)
{
case Style.Dots:
gr.FillEllipse(brushDisabled, rtmp);
break;
case Style.Rectagles:
gr.FillRectangle(brushDisabled, rtmp);
break;
default:
break;
}
}
if (_teachMode && _showNumbers)
{
gr.DrawString((dotRects[i].Column + 1).ToString(),
this.Font, new SolidBrush(Color.Black),
dotRects[i].Rect.X + 5, dotRects[i].Rect.Y + 5);
}
}

onMatrixChanged();
}

Well, there are quite some things done in the onPaint method. There are some properties of the rectangles we have to deal with.

  • Enabled - Depending on this property, the dot will be drawn either in 'ColorEnabled' or 'ColorDisabled' color which both are properties of Matrix16x16.
  • DisplayStyle - Decides whether dots or rectangles are used to draw the matrix.
  • ShowBorders - Some border around each rectangle or not
  • TeachMode && ShowNumbers - These will be explained later when we build the character set to be displayed with the matrix. And finally, the onMatrixChanged() will notify anybody who wants to know, that some change to matrix has happened. Now that we have a matrix, it would be fine to display something. (Actually, the reason we build it) To get each dot addressed, it has a binary value. Starting with the leftmost dot with a value of 15, we count down to zero to rightmost dot. Having this, we're able to calculate the value of row. Let's do some binary math first.

The leftmost dot represents a value of 2^15 = 32768 and the rightmost dot a value of 2^0 = 1. So, if we want to display a row where the first and the last dot are enabled (lighted) the row-value is 2^15 + 2^0 = 32769. With an array of 16 integer values, we're now able to define all 16 rows of the matrix. This is done with:

C#
public void setMatrix(int[] dots)
{
    for (int i = 0; i < 256; i++)  // all Dots
    {
        for (int j = 0; j < 16; j++) // 16 Rows
        {
            if (dotRects[i].Row == j)
            {
                if (dotRects[i].BinaryValue < 8) // LowByte
                {
                    byte value = (byte)(Math.Pow(2, dotRects[i].BinaryValue));

                    byte mask = (byte)dots[j];
                    byte check = (byte)(value & mask);

                    dotRects[i].Enabled = (check == value);
                }
                else  // HighByte
                {
                    int value = (int)(Math.Pow(2, dotRects[i].BinaryValue)) >> 8;
                    int mask = dots[j] >> 8;

                    byte check = (byte)(value & mask);

                    dotRects[i].Enabled = (check == value);
                }
            }
        }
    }
    this.Invalidate();
    onMatrixChanged();
}

To display the letter "A", we can just invoke setMatrix({ 0, 2016, 4080, 6168, 6168, 6168, 6168, 6168, 8184, 8184, 6168, 6168, 6168, 6168, 6168, 0 }) Quite easy, isn't it? But how about some more letters? OK, take some piece of paper and a pen and start calculating letter "B". Way too much work, you say? You're right.

I wouldn't have it done this way either. That's why I implemented the 'TeachMode'. In the demo app, you can enable TeachMode with a checkbox. In TeachMode, you can click on the dots in the Matrix to get them enabled or disabled. Keeping the left mouse button pressed, you can easily draw a line. With the right mouse button, you can disable several dots in row. The TextBox below the matrix will show the int[16] of your drawing. That's the way I set up a set of chars to display.

C#
class Chars
    {
        private Dictionary<string,> stdChars = new Dictionary<string,>();

        public Chars()
        {
            buildStdCharset();
        }

        private void buildStdCharset()
        {
            stdChars.Add(" ", new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0,
                         0, 0, 0, 0, 0, 0, 0 });
            stdChars.Add("A", new int[] { 0, 2016, 4080, 6168, 6168,
                         6168, 6168, 6168, 8184, 8184, 6168, 6168, 6168,
			6168, 6168, 0 });
            stdChars.Add("B", new int[] { 0, 8160, 8176, 6168, 6168,
                         6168, 6168, 8184, 8184, 6168, 6168, 6168, 6168,
			8176, 8160, 0 });
            stdChars.Add("C", new int[] { 0, 1984, 4064, 6160, 6144,
                         6144, 6144, 6144, 6144, 6144, 6144, 6144, 6160,
			4064, 1984, 0 });
            stdChars.Add("D", new int[] { 0, 8160, 8176, 6168, 6168,
                         6168, 6168, 6168, 6168, 6168, 6168, 6168, 6168,
			8176, 8160, 0 });
            stdChars.Add("E", new int[] { 0, 8184, 8184, 6144, 6144,
                         6144, 6144, 8160, 8160, 6144, 6144, 6144, 6144,
			8184, 8184, 0 });
            stdChars.Add("F", new int[] { 0, 8184, 8184, 6144, 6144,
                         6144, 6144, 8160, 8160, 6144, 6144, 6144, 6144,
			6144, 6144, 0 });
            [...]
        }

        public Dictionary<string,int[]> Standard
        {
            get { return stdChars; }
        }

With the setChar() method, each of these chars can be displayed.

C#
public void setChar(char character)
{
    try
    {
        setMatrix(_characters.Standard[character.ToString()]);
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

The next step I did was just putting some of these matrixes into a UserControl.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Germany Germany
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionI want to use with Arduino Pin
Member 1481865430-Apr-20 13:54
Member 1481865430-Apr-20 13:54 
QuestionI must only copy the code to arduino IDE? Pin
Eud briel5-Apr-18 15:34
Eud briel5-Apr-18 15:34 
Questionabout c code Pin
Member 1236359725-Apr-17 5:12
Member 1236359725-Apr-17 5:12 
GeneralMy vote of 5 Pin
yulingfeng29-Sep-13 21:04
yulingfeng29-Sep-13 21:04 
Excuse me,this file decompressed failed,please update once? thanks!
GeneralThanks your project, Pin
wavelet120828-Nov-12 21:49
wavelet120828-Nov-12 21:49 
QuestionWhy not 18x18? Pin
Sergey Alexandrovich Kryukov4-Apr-11 21:09
mvaSergey Alexandrovich Kryukov4-Apr-11 21:09 
AnswerRe: Why not 18x18? Pin
frankreckt4-Apr-11 21:26
frankreckt4-Apr-11 21:26 
GeneralRe: Why not 18x18? Pin
Sergey Alexandrovich Kryukov4-Apr-11 22:07
mvaSergey Alexandrovich Kryukov4-Apr-11 22:07 
AnswerRe: Why not 18x18? Pin
Michel [mjbohn]4-Apr-11 22:13
Michel [mjbohn]4-Apr-11 22:13 
GeneralRe: Why not 18x18? Pin
Sergey Alexandrovich Kryukov4-Apr-11 22:34
mvaSergey Alexandrovich Kryukov4-Apr-11 22:34 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.