5641AS 4 Digit 7 Segment Scoreboard

Hello all!

I have developed a basic Snake Game using the Arduino Mega and using a Joystick Module and an 8 by 8 Matrix (these were all from the Most Complete Starter Kit Mega 2560). The Snake game works perfectly fine, but I wanted to implement a scoreboard into it instead of scrolling the text after the game is over. I have attached the code, and there are two problems. One is that the module only will display the fourth digit (Rightmost) at a time, which I think is a problem with multiplexing. The other which is probably in my code somewhere, is that the score looks to only be increasing by 1 every time I eat the apple 10 times. I think I need another set of eyes or a person with more experience with the module I am using.

Thanks to all that can help

SnakeGameMega.ino (10.1 KB)

Hi. Please read the forum guide in the sticky post, that will tell you what you need to include in your question in order for us to have any chance to help you.

Most forum members read the forum on smartphones and tablets and cannot open .ino files.

Sorry about that! Here is the code! I have to break it apart because it has a character limit...

#include "LedControl.h"
#include <time.h>
LedControl lc1= LedControl (23,24,22,1);

// 4 digit board pins. They go from A-G; then C1-C4
  int pin2 = 40; 
  int pin3 = 32;
  int pin4 = 37;
  int pin5 = 41;
  int pin6 = 43;
  int pin7 = 38;
  int pin8 = 35;
  int pin9 = 42;
  int pin10 = 36;
  int pin11 = 34;
  int pin12 = 33;

 // Joystick pins

 int analogJoysPinX = 1;
 int analogJoysPinY = 2;
 int joystickButton = 10;
 

 // 8 x 8 LED screen pins

 int ledPin1 = 23;
 int ledPin2 = 22;
 int ledPin3 = 24;

/*
top right is (0,0)
top left is (7,0)
bottom left is (7,7)
bottom right is (0,7)

code for light is lc1.setLed(0, x, y, boolean);
                          true=on,  false=off
 */
int tailX[63];
int tailY[63];

int snakeHeadX = 7;
int snakeHeadY = 3;
int snakeTailLength = 1;
int score = 0;
int appleX;
int appleY;

int numberPosition = 1;



bool snakeGotApple = false;



int directionVar = 1; // 0 is up, 1 is right, 2 is down, 3 is left
bool gameOverVar = false; //when false, game is in progress, when true, game is over



void clearScreen() {

    for (int x = 0; x < 8; x++) {

        for (int y = 0; y < 8; y++) {

            lc1.setLed(0, x, y, false);
          
        }
      
    }
    
}



void clearSnakeTail () {

    for (int x = 0; x < 63; x++) {

        tailX[x] = -1;
        tailY[x] = -1;
      
    }
  
}


void snakeRight() {

  if (snakeHeadX == 0) {
    snakeHeadX = 7;
  }
  else{
    snakeHeadX = snakeHeadX - 1;
  }
    directionVar = 1;
    
}

void snakeLeft() {

  if (snakeHeadX == 7) {
    snakeHeadX = 0;
  }
  else {
    snakeHeadX = snakeHeadX + 1;
  }
  
    directionVar = 3;
    
}

void snakeUp() {
  if (snakeHeadY == 0) {
    snakeHeadY = 7;
  }

  else { 
    snakeHeadY = snakeHeadY - 1;
  }
  
    directionVar = 0;
    
  
}

void snakeDown() {
  if (snakeHeadY == 7) {
    snakeHeadY = 0;
  }
  else{
    snakeHeadY = snakeHeadY + 1;
  }
  
    directionVar = 2;
    
  
}

void writeScore() {

    int firstDigit = score / 1000;
    int secondDigit = (score / 100) - ((score / 1000)*10);
    int thirdDigit = (score / 10) - ((score / 100)*10);
    int fourthDigit = score - ((firstDigit*1000) + (secondDigit*100) + (thirdDigit*10));
  
    digitalWrite(pin9, HIGH);
    digitalWrite(pin10, HIGH);
    digitalWrite(pin11, HIGH);
    digitalWrite(pin12, HIGH);
    Serial.begin(19200);
    Serial.print(firstDigit);
    Serial.print(secondDigit);
    Serial.print(thirdDigit);
    Serial.print(fourthDigit);
    Serial.print('\n');

  digitalWrite(pin9, LOW);
  displayNumberScore(5);
  digitalWrite(pin10, LOW);
  displayNumberScore(6);
  digitalWrite(pin11, LOW);
  displayNumberScore(9);
  digitalWrite(pin12, LOW);
  displayNumberScore(8); 

  
 

}

void displayNumberScore(int x) {

  if (x == 0) {
    digitalWrite(pin2, HIGH);
    digitalWrite(pin3, HIGH);
    digitalWrite(pin4, HIGH);
    digitalWrite(pin5, HIGH);
    digitalWrite(pin6, HIGH);
    digitalWrite(pin7, HIGH);
    digitalWrite(pin8, LOW);
  }

  else if (x == 1) {
    digitalWrite(pin2, LOW);
    digitalWrite(pin3, HIGH);
    digitalWrite(pin4, HIGH);
    digitalWrite(pin5, LOW);
    digitalWrite(pin6, LOW);
    digitalWrite(pin7, LOW);
    digitalWrite(pin8, LOW);
  }

  else if (x == 2) {
    digitalWrite(pin2, HIGH);
    digitalWrite(pin3, HIGH);
    digitalWrite(pin4, LOW);
    digitalWrite(pin5, HIGH);
    digitalWrite(pin6, HIGH);
    digitalWrite(pin7, LOW);
    digitalWrite(pin8, HIGH);
  }

  else if (x == 3) {
    digitalWrite(pin2, HIGH);
    digitalWrite(pin3, HIGH);
    digitalWrite(pin4, HIGH);
    digitalWrite(pin5, HIGH);
    digitalWrite(pin6, LOW);
    digitalWrite(pin7, LOW);
    digitalWrite(pin8, HIGH);
  }

  else if (x == 4) {
    digitalWrite(pin2, LOW);
    digitalWrite(pin3, HIGH);
    digitalWrite(pin4, HIGH);
    digitalWrite(pin5, LOW);
    digitalWrite(pin6, LOW);
    digitalWrite(pin7, HIGH);
    digitalWrite(pin8, HIGH);
  }

  else if (x == 5) {
    digitalWrite(pin2, HIGH);
    digitalWrite(pin3, LOW);
    digitalWrite(pin4, HIGH);
    digitalWrite(pin5, HIGH);
    digitalWrite(pin6, LOW);
    digitalWrite(pin7, HIGH);
    digitalWrite(pin8, HIGH);
  }
  
  else if (x == 6) {
    digitalWrite(pin2, HIGH);
    digitalWrite(pin3, LOW);
    digitalWrite(pin4, HIGH);
    digitalWrite(pin5, HIGH);
    digitalWrite(pin6, HIGH);
    digitalWrite(pin7, HIGH);
    digitalWrite(pin8, HIGH);
  }

  else if (x == 7) {
    digitalWrite(pin2, HIGH);
    digitalWrite(pin3, HIGH);
    digitalWrite(pin4, HIGH);
    digitalWrite(pin5, LOW);
    digitalWrite(pin6, LOW);
    digitalWrite(pin7, LOW);
    digitalWrite(pin8, LOW);
  }
  
  else if (x == 8) {
    digitalWrite(pin2, HIGH);
    digitalWrite(pin3, HIGH);
    digitalWrite(pin4, HIGH);
    digitalWrite(pin5, HIGH);
    digitalWrite(pin6, HIGH);
    digitalWrite(pin7, HIGH);
    digitalWrite(pin8, HIGH);
  }

  else if (x == 9) {
    digitalWrite(pin2, HIGH);
    digitalWrite(pin3, HIGH);
    digitalWrite(pin4, HIGH);
    digitalWrite(pin5, HIGH);
    digitalWrite(pin6, LOW);
    digitalWrite(pin7, HIGH);
    digitalWrite(pin8, HIGH);
  }
 
}

Here is part 2...

void draw() {

    clearScreen();


  
    lc1.setLed(0, snakeHeadX, snakeHeadY, true);
  
    int prevX = tailX [0];
    int prevY = tailY [0];
    int prev2X, prev2Y;

    
    
    tailX[0] = snakeHeadX;
    tailY[0] = snakeHeadY;
    
    
    
    for (int i = 1; i < (snakeTailLength + 1); i++) {
      prev2X = tailX[i];
      prev2Y = tailY[i];
      tailX[i] = prevX; 
      tailY[i] = prevY;
      prevX = prev2X;
      prevY = prev2Y;

      

    }



    for (int i = 0; i < snakeTailLength; i++) {

        lc1.setLed(0, tailX[i], tailY[i], true);
      
    }
    
  if (snakeGotApple == false) {
    
    for (int x = 0; x < 5; x++) {
      
      lc1.setLed(0, appleX, appleY, true);
      delay(5);
      lc1.setLed(0, appleX, appleY, false);
      delay(5);
    
      }
    
    
  }
  else {
    randomSeed(analogRead(0));
    appleX = random(8);
    appleY = random(8);
    snakeGotApple = false;
  }

  for (int x = 0; x < snakeTailLength; x++) {

    lc1.setLed(0, tailX[x], tailY[x], true);
    
  }


}



void input() {

  int joystickYMove = analogRead(1);
  int joystickXMove = analogRead(2);
  
  if (joystickXMove >= 800) {
    snakeRight();
    
  }

  else if (joystickYMove >= 700) {
    snakeUp();
    
  }

  else if (joystickXMove <= 100) {
    snakeLeft();
    
  }

  else if (joystickYMove <= 200) {
    snakeDown();
    
  }

  else {
    if (directionVar == 1) {
      snakeRight();
      
    }
    else if (directionVar == 3) {
      snakeLeft();
      
    }
    else if (directionVar == 0) {
      snakeUp();
      
    }
    else if (directionVar == 2) {
      snakeDown();
      
    }
  } 
}


void logic () {

   for (int i = 0; i < snakeTailLength; i++) {
   
      if (snakeHeadX == tailX[i] && snakeHeadY == tailY[i]) {
        gameOverVar = true;
      }
      
   }
   
   if (snakeHeadX == appleX && snakeHeadY == appleY) {

      
      score += 1;
      snakeTailLength = snakeTailLength + 1;
      writeScore();
      snakeGotApple = true;
      
   }
   else {
      for (int x = 0; x < snakeTailLength; x++) {
          if (tailX[x] == appleX && tailY[x] == appleY) {
            snakeGotApple = true;
          }
      }
   } 
}



void setup() {
  // put your setup code here, to run once:
  pinMode(pin2, OUTPUT);
  pinMode(pin3, OUTPUT);
  pinMode(pin4, OUTPUT);
  pinMode(pin5, OUTPUT);
  pinMode(pin6, OUTPUT);
  pinMode(pin7, OUTPUT);
  pinMode(pin8, OUTPUT);
  pinMode(pin9, OUTPUT);
  pinMode(pin10, OUTPUT);
  pinMode(pin11, OUTPUT);
  pinMode(pin12, OUTPUT);
  pinMode(analogJoysPinX, INPUT);
  pinMode(analogJoysPinY, INPUT);
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  pinMode(ledPin3, OUTPUT);
  randomSeed(analogRead(0));
  appleX = random(8);
  appleY = random(8);

  clearSnakeTail();

  for(int index=0;index<lc1.getDeviceCount();index++) {
      lc1.shutdown(index,false);
  }

}


void unrollSnake() {
  
  

  delay(250);
  for (int x = 0; x < snakeTailLength + 1; x++) {

     lc1.setLed(0, tailX[x], tailY[x], false);
     delay(100);
    
  }

  delay (1000);
  
}


void resetGame() {

  clearSnakeTail();
  randomSeed(analogRead(0));
  appleX = random(8);
  appleY = random(8);
  snakeHeadX = 7;
  snakeHeadY = 3;
  snakeTailLength = 1;
  score = 0;
  snakeGotApple = false;
  directionVar = 1;
  gameOverVar = false;


  bool waitVar = false;
  writeScore();
  int joystickYMove = analogRead(1);
  int joystickXMove = analogRead(2);
  while (waitVar == false) {
    joystickYMove = analogRead(1);
    joystickXMove = analogRead(2);
    if (!(joystickXMove <= 800 && joystickXMove >= 100 && joystickYMove <= 700 && joystickYMove >= 200)) {
        waitVar = true;
    } 
  }
  
  
}



void loop() {
  // put your main code here, to run repeatedly:

  resetGame();


  while (gameOverVar == false) {
    if (snakeTailLength == 64) {
      score = score + 200;
      resetGame();
      
    }
    draw();
    input();
    logic();
    Serial.begin(19200);
    delay(100);
  }


  
  unrollSnake();


    
    
    for (int i = 0; i < 5; i++) {

      for (int x = 0; x < 8; x++) {

        for (int y = 0; y < 8; y++) {

            lc1.setLed(0, x, y, true);
          
        }
      }
      delay(100);
      clearScreen();
      delay(100);
    }


    
  gameOverVar = false;
}

Here is the code!

That's great, +1 karma. Now what we need next is the other stuff mentioned in the forum guide, like a schematic, links to components used, that kind of thing. Without that is hard to make sense of the code. I think I can guess why your score display is not working, but I don't want to waste my time or yours explaining my theory until I can confirm it from the other things you will hopefully/helpfully include in your next post. But I will say this: I guess your 8x8 matrix has a max7219 chip? It would be so much easier if your 7-seg display also had one... Your code relies on the max chip to continuously refresh the 8x8 matrix, rather than requiring the Arduino to do that, which is fine. But it also seems to be relying on something else to continuously refresh the 7-seg display instead of the Arduino, but I don't think that "something else" is there, is it?

Sorry again. I thought that was all that I needed. My application I use for schematics wouldn't work today for whatever reason. But, I have all of the pins in the code for all of the modules. The hookup for the 8 by 8 though is not as detailed as it should be. DIN pin is hooked into D23, CS into D22 and CLK into 24. I an going to attach a picture of the setup as I have it now and see if that works for you, if not I am not sure what to do about that. Also, the 8 by 8 is a MAX7219. The 4 Digit module however, the only thing I can find on that is that it is a 5641AS, as the subject says.

I am really sorry, as I am pretty much new to the Arduino community and while I have coded in the past before, this involves a lot more. Again, I am a beginner so I probably made a mistake on this post again and my code somewhere is probably obvious but any explanation with a solution will help a lot. Thanks!

snakeGameMega1.jpg

snakeGameMega2.jpg

snakeGameMega1.jpg

snakeGameMega2.jpg

Poor resolution on those pictures.

Multiplexing is going to drive you mad and deliver a poor performance anyway. The matrix uses a MAX7219 driver, you should get a proper display module (8 digit) with a MAX7219 - presumably from the same source as the matrix module. And that is the crummy version of the matrix module too - the later version which is stackable is now actually cheaper!

I could be wrong, but a Mega looks like serious overkill. Perhaps get a Nano while you are chasing the display module. :grinning:

Were there some tutorials that you followed with that "Most Complete Starter Kit"? If so, is that how the tutorial indicated you should wire up the 7-seg display? Because that circuit in your pictures is going to damage your Arduino, or the display, or both. There is nothing to limit the current, so too much will flow and damage will probably result.

Yes and yes, I see what you mean now. I am adding 200 ohm resistors to it right now. Now, what is it in the code I need to change?

DereKoder:
I am adding 200 ohm resistors to it right now

Not enough. You would still be asking the Arduino pins attached to the digit commons to source or sink in excess of 100mA. The absolute limit on an Arduino pin is 40mA, for a descent life span, stay below 30mA, so you need more like 800 Ohms.

DereKoder:
what is it in the code I need to change?

You need to refresh all 4 digits of the display over and over, continuously, often enough so that they don't appear to flicker. Right now they get refreshed once each, and only when the score changes. The last digit gets left displaying it's value, so that's the only one you see.

So in short, get a proper MAX7219 module.

Cheap! US $3.17 at this moment (but may take a fair while to arrive). Can actually chain to the same 3 pins as the matrix module.