Assistance needed converting my scoreboard code from 7 segment LED to MAX7219 Ma

The size and scope of my scoreboard project has changed and I will now be using 4 MAX7219 8x8 LED matrices for the display. Two units for each scores digits. Chips 3 & 2 for the Red (left) digits and chips 1 & 0 for the Blue (right) digits. I've been trying to modify the code from the 7 segment to Matrix but I'm not having much luck as it is currently beyond my limited Arduino coding experience. I've added the digits 1 thru 0 into an array but do not know how to get them to show up on the display. When the buttons are pressed the displays are changing but not displaying the numbers. I'm not sure how to get it to display "byte zero" from the array for the digit zero etc.

I've also put frames into an array for a simple coin flip animation and arrows to point left or right at random for the winner but haven't finished. My main concern is getting the scoreboard digits to work first and the coin toss and possible scrolling text on startup for later.

Any help would be very much appreciated.

Thanks,
Jerry

#include "LedControl.h"  // Library used for communcation with LED matrices

int DIN=12;  //initialize data (load) to pin 12
int CLK=11;  //initialize clock to pin 11
int CS=10;  //initialize chip select to pin 10
int MAX=4;  //number of displays connected
int bright=1; // LED Brightness 1-15
int delayTime1=5; // Short delay to debounce button push
int delayTime2=75;  // Delay between coin frame animation (order 1,2,3,4,1,2,3,4 for each revolution ending on frame 1)
int delayTime3=1000;  // Delay on beginning and end of animation
int delaytime4-3000; //Delay after arrow is displayed

LedControl lc=LedControl(DIN,CLK,CS,MAX);  // Pins: DIN,CLK,CS, # of Display connected

// Variable to hold current scores
int scoreRed=0;
int scoreBlue=0;

// Variables to split whole number into single digits
int rightdigit;
int leftdigit;

// Switches pin connection to Arduino UNO
#define redUp 2
#define redDown 3
#define redReset 4
#define blueUp 5
#define blueDown 6
#define blueReset 7
#define flipButton 8

// Digits 0-9 rotated to the right 90 degrees
byte one[]={B00000000,B00000000,B10000010,B11111111,B10000000,B00000000,B00000000,B00000000};
byte two[]={B00000000,B10000010,B11000001,B10100001,B10010001,B10001110,B00000000,B00000000};
byte three[]={B00000000,B01000010,B10000001,B10001001,B10001001,B01110110,B00000000,B00000000};
byte four[]={B00000000,B00110000,B00101000,B00100100,B00100010,B11111111,B00000000,B00000000};
byte five[]={B00000000,B01001111,B10001001,B10001001,B10001001,B01110001,B00000000,B00000000};
byte six[]={B00000000,B01111110,B10001001,B10001001,B10001001,B01110010,B00000000,B00000000};
byte seven[]={B00000000,B00000001,B11100001,B00010001,B00001001,B00000111,B00000000,B00000000};
byte eight[]={B00000000,B01110110,B10001001,B10001001,B10001001,B01110110,B00000000,B00000000};
byte nine[]={B00000000,B01001110,B10010001,B10010001,B10010001,B01111110,B00000000,B00000000};
byte zero[]={B00000000,B01111110,B10000001,B10000001,B10000001,B01111110,B00000000,B00000000};

// Coin Frames 1-4 & Left/Right Arrows
byte Coin1[] = {B00011000,B00011000,B00011000,B00011000,B00011000,B00011000,B00011000,B00011000};
byte Coin2[] = {B00000010,B00000111,B00001110,B00011100,B00111000,B01110000,B11100000,B01000000};
byte Coin3[] = {B00000000,B00000000,B00000000,B11111111,B11111111,B00000000,B00000000,B00000000};
byte Coin4[] = {B01000000,B11100000,B01110000,B00111000,B00011100,B00001110,B00000111,B00000010};
byte LTARW[] = {B00111000,B00111000,B00111000,B00111000,B11111110,B01111100,B00111000,B00010000};  //Left Arrow Rotated
byte RTARW[] = {B00010000,B00111000,B01111100,B11111110,B00111000,B00111000,B00111000,B00111000};  //Right Arrow Rotated

void setup() {
  pinMode(redUp,INPUT_PULLUP);
  pinMode(redDown,INPUT_PULLUP);
  pinMode(redReset,INPUT_PULLUP);
  pinMode(blueUp,INPUT_PULLUP);
  pinMode(blueDown,INPUT_PULLUP);
  pinMode(blueReset,INPUT_PULLUP);
  pinMode(flipButton,INPUT_PULLUP);
  
  lc.shutdown(0,false);  // Wake up displays
  lc.shutdown(1,false);
  lc.shutdown(2,false);
  lc.shutdown(3,false);

  lc.setIntensity(0,bright);  // Set intensity levels
  lc.setIntensity(1,bright);
  lc.setIntensity(2,bright);
  lc.setIntensity(3,bright);

  lc.clearDisplay(0);  // Clear Displays
  lc.clearDisplay(1);
  lc.clearDisplay(2);
  lc.clearDisplay(3);
  
// Put zeros on both displays at startup
  lc.setDigit(3,3,0,false);  // (Max7219 chip #, Digit, value, DP on or off) Red Score
  lc.setDigit(2,2,0,false);
  
  lc.setDigit(1,1,0,false);  // (Max7219 chip #, Digit, value, DP on or off) Blue Score
  lc.setDigit(0,0,0,false);

}

void loop() { 

  // If switch redUp is clicked
  if (!digitalRead(redUp)) {
    
    scoreRed++;  // Increase scoreRed by 1
  
    // convert whole number to single digits
    rightdigit=scoreRed%10;
    leftdigit=scoreRed%100/10;

    // Display extracted digits on the display
    lc.setDigit(3,3,leftdigit,false);
    lc.setDigit(2,2,rightdigit,false);

    // Wait until switch is released to continue
    while (!digitalRead(redUp)) { 
    }
    delay(delayTime1);  // Small delay to debounce the switch
  }

  // If switch redDown is clicked
  if (!digitalRead(redDown)) {
    
    scoreRed--;  // Decrease scoreRed by 1
  
    // convert whole number to single digits
    rightdigit=scoreRed%10;
    leftdigit=scoreRed%100/10;

    // Display extracted digits on the display
    lc.setDigit(3,3,leftdigit,false);
    lc.setDigit(2,2,rightdigit,false);

    // Wait until switch is released to continue
    while (!digitalRead(redDown)) { 
    }
    delay(delayTime1);  // Small delay to debounce the switch
  }

    // If switch redReset is clicked
    if (!digitalRead(redReset)) {
    
    scoreRed=00;  // Reset scoreRed to 0
  
    lc.setDigit(3,3,0,false);
    lc.setDigit(2,2,0,false);

    // Wait until switch is released to continue
    while (!digitalRead(redReset)) { 
    }
    delay(delayTime1);  // Small delay to debounce the switch
  }

    // If switch blueUp is clicked
    if (!digitalRead(blueUp)) {
      
    scoreBlue++;  // Increase scoreBlue by 1

    // convert whole number to single digits
    rightdigit=scoreBlue%10;
    leftdigit=scoreBlue%100/10;

    // Display extracted digits on the display
    lc.setDigit(1,1,leftdigit,false);
    lc.setDigit(0,0,rightdigit,false);

    // Wait until switch is released to continue
    while (!digitalRead(blueUp)) { 
    }    
    delay(delayTime1); // Small delay to debounce the switch
  }

  // If switch blueDown is clicked
  if (!digitalRead(blueDown)) {
    
    scoreBlue--;  // Decrease scoreBlue by 1
  
    // convert whole number to single digits
    rightdigit=scoreBlue%10;
    leftdigit=scoreBlue%100/10;

    // Display extracted digits on the display
    lc.setDigit(1,1,leftdigit,false);
    lc.setDigit(0,0,rightdigit,false);
    
    // Wait until switch is released to continue
    while (!digitalRead(blueDown)) { 
    }
    delay(delayTime1);  // Small delay to debounce the switch
  }

    // If switch blueReset is clicked
    if (!digitalRead(blueReset)) {
    
    scoreBlue=00;  // Reset scoreBlue to 0
  
    lc.setDigit(1,1,0,false);
    lc.setDigit(0,0,0,false);

    // Wait until switch is released to continue
    while (!digitalRead(blueReset)) { 
    }
    delay(delayTime1);  // Small delay to debounce the switch
  }
}

The setDigit function only works with seven segment display, not with a matrix.
From the header file:-

/*

  • Display a hexadecimal digit on a 7-Segment Display
  • Params:
  • addr address of the display
  • digit the position of the digit on the display (0..7)
  • value the value to be displayed. (0x00..0x0F)
  • dp sets the decimal point.
    */
    void setDigit(int addr, int digit, byte value, boolean dp);

You want to be writing your bit patterns to the LED matrix, with decoding turned off.

How are you wiring your MAX7219 up?
There are two ways, chained or parallel.

They are chained together left to right 3, 2, 1, 0.

OK you have a very lot going on with that code. What you need to do is to start off simply and then build things up.

Start off by getting the data sheet for the MAX7219 and try and just displaying one number on one matrix. To do this you will need either a libiary to handle the matrix or, as the coed is so simple you can do it without.

So first write a function to output one byte to MAX7219, using the shift out function. Then to write to a register you need to send the register address followed by the value you want to send.

Then you set it up to work with a matrix by setting
register 0x9 to value 0 # no decode
register 0xB to value 7 # scan all digits
register 0xA to value 0x15 # maximum intensity
register 0xC to value 1 # take out of shutdown mode
Then write your bit patterns to the matrix registers
so that is the top row to register 1, next to register 2 and so on.
at the moment don't worry if the other LEDs go on and off just concentrate on the first one.

Get that working and post the code for the next step.

Thanks Mike. I will get the date sheet and take a look this evening when I get home from work.

Jerry

If you are using MAX7219 matrices, you probably had best accustom yourself to Marco_C's "parola" library which you will install from the IDE library manager as the "MD_max" series. Once you go through a few examples you should find it very easy, but it will be quite different to your original code.

I've downloaded the MD_Parola & MD_Max72xx libraries and looked at and edited a few sketches and it looks great. I was hoping however to use my current library (LedControl) just for the reason that I wouldn't need to rewrite the whole code. I need to get the displays working asap as the scoreboard will be a Christmas gift and the clock is ticking.

After I get it running and the pressure is off I will then go back and rewrite the code (probably with MD_Parola) and add a coin flip animation and scrolling text. Both of which seem far easier with MD_Parola. I can always upload a new sketch to the scoreboard after I get it working. I've only been using the arduino for a few weeks and have never coded before so this is a bit daunting especially teaching myself. I'm just glad that this forum and youtube exist or I would be doomed.

Jerry

Grumpy_Mike:
OK you have a very lot going on with that code. What you need to do is to start off simply and then build things up.

Start off by getting the data sheet for the MAX7219 and try and just displaying one number on one matrix. To do this you will need either a libiary to handle the matrix or, as the coed is so simple you can do it without.

So first write a function to output one byte to MAX7219, using the shift out function. Then to write to a register you need to send the register address followed by the value you want to send.

Then you set it up to work with a matrix by setting
register 0x9 to value 0 # no decode
register 0xB to value 7 # scan all digits
register 0xA to value 0x15 # maximum intensity
register 0xC to value 1 # take out of shutdown mode
Then write your bit patterns to the matrix registers
so that is the top row to register 1, next to register 2 and so on.
at the moment don't worry if the other LEDs go on and off just concentrate on the first one.

Get that working and post the code for the next step.

I set up the code to print a zero using the ledControl.h library as it is what I'm most familiar with. I looked at the MAX7219 data sheet as I already had it printed out and could not figure out the syntax. Hopefully this is what you were asking.

#include "LedControl.h"
LedControl lc=LedControl(12,11,10,4);

byte zero[] = {B00000000,B01111110,B10000001,B10000001,B10000001,B01111110,B00000000,B00000000};

void setup() {
  lc.shutdown(0,false);
  lc.setIntensity(0,15);
  lc.clearDisplay(0);
}

void szero()
{
  for (int i = 0; i < 8; i++)  
  {
    lc.setRow(0,i,zero[i]);
  }
}
void loop() {
  szero();
}

It displays byte zero at intensity 15 on Matrix 0

Jerry

Excellent.
So the next step is to call that function something like setNumber and pass to it a variable that contains the number you want to display on the first digit. It will be very similar to what you have written already but this time you have to have the bit patterns not in separately named arrays with one for each digit like you had before, but in one two dimensional array. These have two indexes, one you will use for the row like before but the other will be used for the number. So you have to change how you define these arrays. When you do the function will look like this:-

void setNumber(byte number)
{
  for (int i = 0; i < 8; i++)  
  {
    lc.setRow(0,i,patterns[number][i]);
  }
}

where patterns is your two dimensional array.

Grumpy_Mike:
So the next step is to call that function something like setNumber and pass to it a variable that contains the number you want to display on the first digit.

Or just use the Parola library where it is built-in. :roll_eyes:

If you are in a hurry, then a really quick way to get this running is to use the print() method in the Parola library.

See the Parola_Print_Minimal example. Basically, after declaring the object the code to print something to the matrices is

void setup(void)
{
  P.begin();
  P.print("Hello!");
}

You may find for a scoreboard this may be all that is needed.

Grumpy_Mike:
Excellent.
So the next step is to call that function something like setNumber and pass to it a variable that contains the number you want to display on the first digit. It will be very similar to what you have written already but this time you have to have the bit patterns not in separately named arrays with one for each digit like you had before, but in one two dimensional array. These have two indexes, one you will use for the row like before but the other will be used for the number. So you have to change how you define these arrays. When you do the function will look like this:-

void setNumber(byte number)

{
for (int i = 0; i < 8; i++)
{
lc.setRow(0,i,patterns[number][i]);
}
}



where patterns is your two dimensional array.

I set up all of the digits into one array. I think this is what you meant. However the display is showing this for zero.

It does change when I change setNumber(x) to another digit but isn't the correct image. I've either screwed up the syntax or have done the array incorrectly.

Jerry

#include "LedControl.h"
LedControl lc=LedControl(12,11,10,4);

byte DIGITS[][8] = {
{
  B00000000,
  B01111110,
  B10000001,
  B10000001,
  B10000001,
  B01111110,
  B00000000,
  B00000000
},{
  B00000000,
  B00000000,
  B10000010,
  B11111111,
  B10000000,
  B00000000,
  B00000000,
  B00000000
},{
  B00000000,
  B10000010,
  B11000001,
  B10100001,
  B10010001,
  B10001110,
  B00000000,
  B00000000
},{
  B00000000,
  B01000010,
  B10000001,
  B10001001,
  B10001001,
  B01110110,
  B00000000,
  B00000000
},{
  B00000000,
  B00110000,
  B00101000,
  B00100100,
  B00100010,
  B11111111,
  B00000000,
  B00000000
},{
  B00000000,
  B01001111,
  B10001001,
  B10001001,
  B10001001,
  B01110001,
  B00000000,
  B00000000
},{
  B00000000,
  B01111110,
  B10001001,
  B10001001,
  B10001001,
  B01110010,
  B00000000,
  B00000000
},{
  B00000000,
  B00000001,
  B11100001,
  B00010001,
  B00001001,
  B00000111,
  B00000000,
  B00000000
},{
  B00000000,
  B01110110,
  B10001001,
  B10001001,
  B10001001,
  B01110110,
  B00000000,
  B00000000
},{
  B00000000,
  B01001110,
  B10010001,
  B10010001,
  B10010001,
  B01111110,
  B00000000,
  B00000000
}};

void setup() {
  lc.shutdown(0,false);
  lc.setIntensity(0,1);
  lc.clearDisplay(0);
}

void setNumber(byte DIGITS[])
{
  for (int i = 0; i < 8; i++)  
  {
    lc.setRow(0,i,DIGITS[i]);
  }
}
void loop() {
  setNumber(0);
}

Try

void setNumber(byte d)
{
  for (int i = 0; i < 8; i++)  
  {
    lc.setRow(0,i,DIGITS[d][i]);
  }
}

PaulRB:
Try

void setNumber(byte d)

{
  for (int i = 0; i < 8; i++) 
  {
    lc.setRow(0,i,DIGITS[d][i]);
  }
}

That did it. It is now displaying the number.

Thank you Paul!

jfrodgers:
That did it.

Are you interested in understanding why? (I may regret asking that. Explaining why it works now is easy enough, but explaining what was going wrong before could get pretty complicated!)

PaulRB:
Are you interested in understanding why? (I may regret asking that. Explaining why it works now is easy enough, but explaining what was going wrong before could get pretty complicated!)

Very much so yes. I'm believe that simply put "d" in your explanation was the key.

I'm trying to figure out how to put it in scoreboard code to make the scores update now. It will have to wait until I get home from work to test.

Thanks again,
Jerry

void setNumber(byte DIGITS[])
{
  for (int i = 0; i < 8; i++)  
  {
    lc.setRow(0,i,DIGITS[i]);
  }
}

You passed the wrong thing to the function. You sent it a number but you told the function that this number was actually the start of an array that did not exist. Yes it had the same name as your array of bit patterns but a function has it's own scope, that is the values passed to it are valid only within the function you passed it to. Therefore when you passed the function a number and told the function that the number you passed represented an array, it took you at your word. Because this corresponded to no such number, it still assumed it did and so the upshot was when you used it it essentially dragged junk numbers from stuff that happened to be in that memory location.

By telling the function that the number passed to it represented an index in your array of bit patterns corresponding to how we see numbers represented, which is what we intended, it got the correct bit patterns.
You also note that in using:-

lc.setRow(0,i,DIGITS[d][i]);

You accessed row i of the bit patterns that corresponded to the value of the variable d and thus displayed the number you passed to the function.

Put down like this it looks very complex, but basically you screwed up and made the compiler think the number you were passing to the function was something that it wasn't.