Go Down

Topic: Assistance needed converting my scoreboard code from 7 segment LED to MAX7219 Ma (Read 306 times) previous topic - next topic

jfrodgers

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

Code: [Select]

#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
  }
}

Grumpy_Mike

The setDigit function only works with seven segment display, not with a matrix.
From the header file:-
Quote
/*
         * 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.

jfrodgers


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.

jfrodgers

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

Jerry

Paul__B

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.

jfrodgers

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

jfrodgers

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.

Code: [Select]

#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

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:-
Code: [Select]
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.

Paul__B

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.  :smiley-roll:

marco_c

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
Code: [Select]
void setup(void)
{
  P.begin();
  P.print("Hello!");
}


You may find for a scoreboard this may be all that is needed.
Arduino Libraries https://github.com/MajicDesigns?tab=Repositories
Parola for Arduino https://github.com/MajicDesigns/Parola
Arduino++ blog https://arduinoplusplus.wordpress.com

jfrodgers

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:-
Code: [Select]
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

Code: [Select]

#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);
}

PaulRB

Try
Code: [Select]

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

jfrodgers

Try
Code: [Select]

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!

PaulRB

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!)

Go Up