Go Down

Topic: 16x16 LED Matrix using MAX7219 for Arduino (Read 22405 times) previous topic - next topic

sgharbi11

Hi ALL!

i want to build a 16x16 LED Matrix using MAX7219 for Arduino but i have problems in programming. Can any one help me? can some one have the solution?

you can contact us to my email: sgharbi11@gmail.com

sgharbi11

to connect the max to each other i use this shematic : http://blog.carr3r.com/content/public/upload/schema-matrix_0_o.png


and i use this codee control the 16*8 matrix but ihave no idea how to control a 16*16 matrix can any one help me:
Code: [Select]



#include "MaxMatrix.h"
#include "avr/pgmspace.h"

PROGMEM prog_uchar CH[] = {
3, 8, B00000000, B00000000, B00000000, B00000000, B00000000, // space
1, 8, B01011111, B00000000, B00000000, B00000000, B00000000, // !
3, 8, B00000011, B00000000, B00000011, B00000000, B00000000, // "
5, 8, B00010100, B00111110, B00010100, B00111110, B00010100, // #
4, 8, B00100100, B01101010, B00101011, B00010010, B00000000, // $
5, 8, B01100011, B00010011, B00001000, B01100100, B01100011, // %
5, 8, B00110110, B01001001, B01010110, B00100000, B01010000, // &
1, 8, B00000011, B00000000, B00000000, B00000000, B00000000, // '
3, 8, B00011100, B00100010, B01000001, B00000000, B00000000, // (
3, 8, B01000001, B00100010, B00011100, B00000000, B00000000, // )
5, 8, B00101000, B00011000, B00001110, B00011000, B00101000, // *
5, 8, B00001000, B00001000, B00111110, B00001000, B00001000, // +
2, 8, B10110000, B01110000, B00000000, B00000000, B00000000, // ,
4, 8, B00001000, B00001000, B00001000, B00001000, B00000000, // -
2, 8, B01100000, B01100000, B00000000, B00000000, B00000000, // .
4, 8, B01100000, B00011000, B00000110, B00000001, B00000000, // /
4, 8, B00111110, B01000001, B01000001, B00111110, B00000000, // 0
3, 8, B01000010, B01111111, B01000000, B00000000, B00000000, // 1
4, 8, B01100010, B01010001, B01001001, B01000110, B00000000, // 2
4, 8, B00100010, B01000001, B01001001, B00110110, B00000000, // 3
4, 8, B00011000, B00010100, B00010010, B01111111, B00000000, // 4
4, 8, B00100111, B01000101, B01000101, B00111001, B00000000, // 5
4, 8, B00111110, B01001001, B01001001, B00110000, B00000000, // 6
4, 8, B01100001, B00010001, B00001001, B00000111, B00000000, // 7
4, 8, B00110110, B01001001, B01001001, B00110110, B00000000, // 8
4, 8, B00000110, B01001001, B01001001, B00111110, B00000000, // 9
2, 8, B01010000, B00000000, B00000000, B00000000, B00000000, // :
2, 8, B10000000, B01010000, B00000000, B00000000, B00000000, // ;
3, 8, B00010000, B00101000, B01000100, B00000000, B00000000, // <
3, 8, B00010100, B00010100, B00010100, B00000000, B00000000, // =
3, 8, B01000100, B00101000, B00010000, B00000000, B00000000, // >
4, 8, B00000010, B01011001, B00001001, B00000110, B00000000, // ?
5, 8, B00111110, B01001001, B01010101, B01011101, B00001110, // @
4, 8, B01111110, B00010001, B00010001, B01111110, B00000000, // A
4, 8, B01111111, B01001001, B01001001, B00110110, B00000000, // B
4, 8, B00111110, B01000001, B01000001, B00100010, B00000000, // C
4, 8, B01111111, B01000001, B01000001, B00111110, B00000000, // D
4, 8, B01111111, B01001001, B01001001, B01000001, B00000000, // E
4, 8, B01111111, B00001001, B00001001, B00000001, B00000000, // F
4, 8, B00111110, B01000001, B01001001, B01111010, B00000000, // G
4, 8, B01111111, B00001000, B00001000, B01111111, B00000000, // H
3, 8, B01000001, B01111111, B01000001, B00000000, B00000000, // I
4, 8, B00110000, B01000000, B01000001, B00111111, B00000000, // J
4, 8, B01111111, B00001000, B00010100, B01100011, B00000000, // K
4, 8, B01111111, B01000000, B01000000, B01000000, B00000000, // L
5, 8, B01111111, B00000010, B00001100, B00000010, B01111111, // M
5, 8, B01111111, B00000100, B00001000, B00010000, B01111111, // N
4, 8, B00111110, B01000001, B01000001, B00111110, B00000000, // O
4, 8, B01111111, B00001001, B00001001, B00000110, B00000000, // P
4, 8, B00111110, B01000001, B01000001, B10111110, B00000000, // Q
4, 8, B01111111, B00001001, B00001001, B01110110, B00000000, // R
4, 8, B01000110, B01001001, B01001001, B00110010, B00000000, // S
5, 8, B00000001, B00000001, B01111111, B00000001, B00000001, // T
4, 8, B00111111, B01000000, B01000000, B00111111, B00000000, // U
5, 8, B00001111, B00110000, B01000000, B00110000, B00001111, // V
5, 8, B00111111, B01000000, B00111000, B01000000, B00111111, // W
5, 8, B01100011, B00010100, B00001000, B00010100, B01100011, // X
5, 8, B00000111, B00001000, B01110000, B00001000, B00000111, // Y
4, 8, B01100001, B01010001, B01001001, B01000111, B00000000, // Z
2, 8, B01111111, B01000001, B00000000, B00000000, B00000000, // [
4, 8, B00000001, B00000110, B00011000, B01100000, B00000000, // \ backslash
2, 8, B01000001, B01111111, B00000000, B00000000, B00000000, // ]
3, 8, B00000010, B00000001, B00000010, B00000000, B00000000, // hat
4, 8, B01000000, B01000000, B01000000, B01000000, B00000000, // _
2, 8, B00000001, B00000010, B00000000, B00000000, B00000000, // `
4, 8, B00100000, B01010100, B01010100, B01111000, B00000000, // a
4, 8, B01111111, B01000100, B01000100, B00111000, B00000000, // b
4, 8, B00111000, B01000100, B01000100, B00101000, B00000000, // c
4, 8, B00111000, B01000100, B01000100, B01111111, B00000000, // d
4, 8, B00111000, B01010100, B01010100, B00011000, B00000000, // e
3, 8, B00000100, B01111110, B00000101, B00000000, B00000000, // f
4, 8, B10011000, B10100100, B10100100, B01111000, B00000000, // g
4, 8, B01111111, B00000100, B00000100, B01111000, B00000000, // h
3, 8, B01000100, B01111101, B01000000, B00000000, B00000000, // i
4, 8, B01000000, B10000000, B10000100, B01111101, B00000000, // j
4, 8, B01111111, B00010000, B00101000, B01000100, B00000000, // k
3, 8, B01000001, B01111111, B01000000, B00000000, B00000000, // l
5, 8, B01111100, B00000100, B01111100, B00000100, B01111000, // m
4, 8, B01111100, B00000100, B00000100, B01111000, B00000000, // n
4, 8, B00111000, B01000100, B01000100, B00111000, B00000000, // o
4, 8, B11111100, B00100100, B00100100, B00011000, B00000000, // p
4, 8, B00011000, B00100100, B00100100, B11111100, B00000000, // q
4, 8, B01111100, B00001000, B00000100, B00000100, B00000000, // r
4, 8, B01001000, B01010100, B01010100, B00100100, B00000000, // s
3, 8, B00000100, B00111111, B01000100, B00000000, B00000000, // t
4, 8, B00111100, B01000000, B01000000, B01111100, B00000000, // u
5, 8, B00011100, B00100000, B01000000, B00100000, B00011100, // v
5, 8, B00111100, B01000000, B00111100, B01000000, B00111100, // w
5, 8, B01000100, B00101000, B00010000, B00101000, B01000100, // x
4, 8, B10011100, B10100000, B10100000, B01111100, B00000000, // y
3, 8, B01100100, B01010100, B01001100, B00000000, B00000000, // z
3, 8, B00001000, B00110110, B01000001, B00000000, B00000000, // {
1, 8, B01111111, B00000000, B00000000, B00000000, B00000000, // |
3, 8, B01000001, B00110110, B00001000, B00000000, B00000000, // }
4, 8, B00001000, B00000100, B00001000, B00000100, B00000000, // ~
4, 8, B00100110, B00100011, B00110001, B00110101, B00111000, B00110111, 00111011, //?
};

int data = 7;    // DIN pin of MAX7219 module
int load = 8;    // CS pin of MAX7219 module
int clock = 10;  // CLK pin of MAX7219 module

int maxInUse = 9;    //change this variable to set how many MAX7219's you'll use

MaxMatrix m(data, load, clock, maxInUse); // define module

byte buffer[10];



void setup(){
  m.init(); // module initialize
  m.setIntensity(7); // dot matix intensity 0-15
  Serial.begin(9600); // serial communication initialize
}

void loop(){
 
  // this is the code if you want to entering a message via serial console
  while (Serial.available() > 0){
    byte c = Serial.read();
    Serial.println(c, DEC);
    printCharWithShift(c, 100);
  }
  delay(100);
  m.shiftLeft(false, true);
 
 
  // print the active sentences
  printStringWithShift(" hi all! " , 200);
  printStringWithShift(" A 8*8 MATRIX ... " , 200);
}

void printCharWithShift(char c, int shift_speed){
  if (c < 32) return;
  c -= 32;
  memcpy_P(buffer, CH + 7*c, 7);
  m.writeSprite(72, 0, buffer);
  m.setColumn(72 + buffer[0], 0);
 
  for (int i=0; i<buffer[0]+1; i++)
  {
    delay(shift_speed);
    m.shiftLeft(false, false);
  }
}

void printStringWithShift(char* s, int shift_speed){
  while (*s != 0){
    printCharWithShift(*s, shift_speed);
    s++;
  }
}

void printString(char* s)
{
  int col = 0;
  while (*s != 0)
  {
    if (*s < 32) continue;
    char c = *s - 32;
    memcpy_P(buffer, CH + 7*c, 7);
    m.writeSprite(col, 0, buffer);
    m.setColumn(col + buffer[0], 0);
    col += buffer[0] + 1;
    s++;
  }
}

Ps991

#2
Jan 18, 2015, 10:27 am Last Edit: Jan 18, 2015, 10:30 am by Ps991
Please read the first bullet point Forum Etiquette
If you can't write your program in plain english where anyone could understand it then you have no hope of writing code for it.  -Delta_G

racemaniac

Maybe rather than asking for a solution, you could describe the problem you're having?
What is the difference you perceive between controlling a 16x8 matrix and a 16x16 matrix (or a 32x8 matrix).
you just connect your second 16x8 matrix after the first one, shift some more data into it, and that's it. How you physically position it (32x8 or 16x16) doesn't really matter.

Grumpy_Mike

#4
Jan 18, 2015, 11:14 am Last Edit: Jan 18, 2015, 11:49 am by Grumpy_Mike
How you physically position it (32x8 or 16x16) doesn't really matter.
It does if you want to scroll text around.


Maybe rather than asking for a solution, you could describe the problem you're having?
I quite agree.

Also you need to post a link to those modules you are using.

Grumpy_Mike

In your code you have:-
Code: [Select]
int maxInUse = 9;    //change this variable to set how many MAX7219's you'll use
In your wiring I see only four.

Code: [Select]
#include "MaxMatrix.h"
You need to include a link to this file so we can see what it does.

It looks like the code might require the matrices to be all in a line not in a two by two grid.
The data will be sent out in the order 1,2 ,3,4 so if they are physically laid out like that schematic the scrolling will look very odd.

sgharbi11

#6
Jan 20, 2015, 01:10 pm Last Edit: Jan 20, 2015, 01:13 pm by sgharbi11
my issue is: when i connected the shift according this schematic:

and upload the code at the top i have a scrolling message like this:the "A" mirrored on the two down matrix :



but i want to have a scrolling text like this:



Can someone help me?

sgharbi11

In your code you have:-
Code: [Select]
int maxInUse = 9;    //change this variable to set how many MAX7219's you'll use
In your wiring I see only four.

Code: [Select]
#include "MaxMatrix.h"
You need to include a link to this file so we can see what it does.

It looks like the code might require the matrices to be all in a line not in a two by two grid.
The data will be sent out in the order 1,2 ,3,4 so if they are physically laid out like that schematic the scrolling will look very odd.
i change it to 4 but nothing have change and this is the libraries: MaxMatrix.h :
Code: [Select]

/*
 * MaxMatrix
 * Version 1.0 Feb 2013
 * Copyright 2013 Oscar Kin-Chung Au
 */

#ifndef _MaxMatrix_H_
#define _MaxMatrix_H_

#include "Arduino.h"

#define max7219_reg_noop        0x00
#define max7219_reg_digit0      0x01
#define max7219_reg_digit1      0x02
#define max7219_reg_digit2      0x03
#define max7219_reg_digit3      0x04
#define max7219_reg_digit4      0x05
#define max7219_reg_digit5      0x06
#define max7219_reg_digit6      0x07
#define max7219_reg_digit7      0x08
#define max7219_reg_decodeMode  0x09
#define max7219_reg_intensity   0x0a
#define max7219_reg_scanLimit   0x0b
#define max7219_reg_shutdown    0x0c
#define max7219_reg_displayTest 0x0f

class MaxMatrix
{
  private:
    byte data;
    byte load;
    byte clock;
    byte num;
    byte buffer[80];
   
    void reload();

  public:
    MaxMatrix(byte data, byte load, byte clock, byte num);
   
    void init();
    void clear();
    void setCommand(byte command, byte value);
    void setIntensity(byte intensity);
    void setColumn(byte col, byte value);
    void setColumnAll(byte col, byte value);
    void setDot(byte col, byte row, byte value);
    void writeSprite(int x, int y, const byte* sprite);
   
    void shiftLeft(bool rotate = false, bool fill_zero = true);
    void shiftRight(bool rotate = false, bool fill_zero = true);
    void shiftUp(bool rotate = false);
    void shiftDown(bool rotate = false);
};

#endif

sgharbi11

and this is the second libraries: "MaxMatrix.cpp" :

Code: [Select]
/*
 * MaxMatrix
 * Version 1.0 Feb 2013
 * Copyright 2013 Oscar Kin-Chung Au
 */


#include "Arduino.h"
#include "MaxMatrix.h"

MaxMatrix::MaxMatrix(byte _data, byte _load, byte _clock, byte _num)
{
data = _data;
load = _load;
clock = _clock;
num = _num;
for (int i=0; i<80; i++)
buffer[i] = 0;
}

void MaxMatrix::init()
{
pinMode(data,  OUTPUT);
pinMode(clock, OUTPUT);
pinMode(load,  OUTPUT);
digitalWrite(clock, HIGH);

setCommand(max7219_reg_scanLimit, 0x07);     
setCommand(max7219_reg_decodeMode, 0x00);  // using an led matrix (not digits)
setCommand(max7219_reg_shutdown, 0x01);    // not in shutdown mode
setCommand(max7219_reg_displayTest, 0x00); // no display test

// empty registers, turn all LEDs off
clear();

setIntensity(0x0f);    // the first 0x0f is the value you can set
}

void MaxMatrix::setIntensity(byte intensity)
{
setCommand(max7219_reg_intensity, intensity);
}

void MaxMatrix::clear()
{
for (int i=0; i<8; i++)
setColumnAll(i,0);

for (int i=0; i<80; i++)
buffer[i] = 0;
}

void MaxMatrix::setCommand(byte command, byte value)
{
digitalWrite(load, LOW);   
for (int i=0; i<num; i++)
{
shiftOut(data, clock, MSBFIRST, command);
shiftOut(data, clock, MSBFIRST, value);
}
digitalWrite(load, LOW);
digitalWrite(load, HIGH);
}


void MaxMatrix::setColumn(byte col, byte value)
{
int n = col / 8;
int c = col % 8;
digitalWrite(load, LOW);   
for (int i=0; i<num; i++)
{
if (i == n)
{
shiftOut(data, clock, MSBFIRST, c + 1);
shiftOut(data, clock, MSBFIRST, value);
}
else
{
shiftOut(data, clock, MSBFIRST, 0);
shiftOut(data, clock, MSBFIRST, 0);
}
}
digitalWrite(load, LOW);
digitalWrite(load, HIGH);

buffer[col] = value;
}

void MaxMatrix::setColumnAll(byte col, byte value)
{
digitalWrite(load, LOW);   
for (int i=0; i<num; i++)
{
shiftOut(data, clock, MSBFIRST, col + 1);
shiftOut(data, clock, MSBFIRST, value);
buffer[col * i] = value;
}
digitalWrite(load, LOW);
digitalWrite(load, HIGH);
}

void MaxMatrix::setDot(byte col, byte row, byte value)
{
    bitWrite(buffer[col], row, value);

int n = col / 8;
int c = col % 8;
digitalWrite(load, LOW);   
for (int i=0; i<num; i++)
{
if (i == n)
{
shiftOut(data, clock, MSBFIRST, c + 1);
shiftOut(data, clock, MSBFIRST, buffer[col]);
}
else
{
shiftOut(data, clock, MSBFIRST, 0);
shiftOut(data, clock, MSBFIRST, 0);
}
}
digitalWrite(load, LOW);
digitalWrite(load, HIGH);
}

void MaxMatrix::writeSprite(int x, int y, const byte* sprite)
{
int w = sprite[0];
int h = sprite[1];

if (h == 8 && y == 0)
for (int i=0; i<w; i++)
{
int c = x + i;
if (c>=0 && c<80)
setColumn(c, sprite[i+2]);
}
else
for (int i=0; i<w; i++)
for (int j=0; j<h; j++)
{
int c = x + i;
int r = y + j;
if (c>=0 && c<80 && r>=0 && r<8)
setDot(c, r, bitRead(sprite[i+2], j));
}
}

void MaxMatrix::reload()
{
for (int i=0; i<8; i++)
{
int col = i;
digitalWrite(load, LOW);   
for (int j=0; j<num; j++)
{
shiftOut(data, clock, MSBFIRST, i + 1);
shiftOut(data, clock, MSBFIRST, buffer[col]);
col += 8;
}
digitalWrite(load, LOW);
digitalWrite(load, HIGH);
}
}

void MaxMatrix::shiftLeft(bool rotate, bool fill_zero)
{
byte old = buffer[0];
int i;
for (i=0; i<80; i++)
buffer[i] = buffer[i+1];
if (rotate) buffer[num*8-1] = old;
else if (fill_zero) buffer[num*8-1] = 0;

reload();
}

void MaxMatrix::shiftRight(bool rotate, bool fill_zero)
{
int last = num*8-1;
byte old = buffer[last];
int i;
for (i=79; i>0; i--)
buffer[i] = buffer[i-1];
if (rotate) buffer[0] = old;
else if (fill_zero) buffer[0] = 0;

reload();
}

void MaxMatrix::shiftUp(bool rotate)
{
for (int i=0; i<num*8; i++)
{
bool b = buffer[i] & 1;
buffer[i] >>= 1;
if (rotate) bitWrite(buffer[i], 7, b);
}
reload();
}

void MaxMatrix::shiftDown(bool rotate)
{
for (int i=0; i<num*8; i++)
{
bool b = buffer[i] & 128;
buffer[i] <<= 1;
if (rotate) bitWrite(buffer[i], 0, b);
}
reload();
}


racemaniac

Is there anything in the documentation that suggest the library you use is capable of supporting your display configuration?
I think your problem is expecting your library to magically know that you've put 2 displays on top of each other, and then make the letters a lot taller, apparantly it won't.

Maybe you should learn to code this yourself. Creating your own program that controls a few max chips and scrolls text isn't that hard, you'll learn a lot, and be able to make your display any shape you like once you understand it :).

Paul__B


CrossRoads

Might want to try the parola library as well
https://parola.codeplex.com/
"Parola is a modular scrolling text display using MAX7219/21 LED matrix display controllers. The display is made up of any number of identical modules that are plugged together to create a wider/longer display. Text left, right or center justification in the display
Text scrolling, entry and exit effects
Control display parameters and animation speed
Support for hardware SPI interface
Multiple virtual displays (zones) in each string of LED modules
User defined fonts and/or individual characters substitutions"
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

Grumpy_Mike

Quote
but i want to have a scrolling text like this
Then you will have to write your own code for this along with your own font definition.
Forget the libraries, they will not do it for you.

It also looks like you have mounted the bottom two matrices up side down. While you could compensate for that in software it makes the font definitions very difficult to do.
You need to wire the matrices so they are in the correct orientation.

Is the wiring fixed and you can't change it? If so then it might be a deliberate ploy by the person setting you this assignment so that you do not use "off the shelf" code and you have to understand and write your own. 

Paul__B

It also looks like you have mounted the bottom two matrices up side down. While you could compensate for that in software it makes the font definitions very difficult to do.
Quite so, but it appears many assemblies (16 by 16) offered for sale are arranged in exactly that fashion as I noted before.

You can use the same font definitions - the software needs to compensate.

Might want to try the parola library as well
https://parola.codeplex.com/
I was going to suggest exactly that - if only I could recall what and where it was.  :smiley-lol:

sgharbi11

Quote
you have to understand and write your own
i am not good in programming, bu when i searched i fond this code wish commanded via "IR remote", I don't like to use this "IR remote" and I don't know how to change it and make it working Without "IR remote"


the code is at the link below -----> https://docs.google.com/file/d/0BzIpQjwhROrVNDlOSzVkMzhpenM/edit

Go Up