Issues generating 4 random numbers for my 4 digit display due to multiplexing

Hello. As the title says, I am having issues generating a random 4 digit number for my 4 digit display. It works via multiplexing. My code works as expected for a single digit 7 segment display, but when I want to take in account multiplexing it just doesn't work. First of all, there is my code:

/* 
    A
   ---
F |   | B
  | G | 
   ---
E |   | C
  | D |
   ---
*/

int pinA = 2;
int pinB = 3;
int pinC = 4;
int pinD = 5;
int pinE = 6;
int pinF = 7;
int pinG = 8;
int D1 = 9;
int D2 = 10;
int D3 = 11;
int D4 = 12;
int punt = 13;
int counter = 1;

void numZero(){
  digitalWrite(pinA, HIGH);
  digitalWrite(pinB, HIGH);
  digitalWrite(pinC, HIGH);
  digitalWrite(pinD, HIGH);
  digitalWrite(pinE, HIGH);
  digitalWrite(pinF, HIGH);
  digitalWrite(pinG, LOW);
  digitalWrite(punt, LOW);
}

void numOne(){
  digitalWrite(pinA, LOW);
  digitalWrite(pinB, HIGH);
  digitalWrite(pinC, HIGH);
  digitalWrite(pinD, LOW);
  digitalWrite(pinE, LOW);
  digitalWrite(pinF, LOW);
  digitalWrite(pinG, LOW);
  digitalWrite(punt, LOW);
}

void numTwo(){
  digitalWrite(pinA, HIGH);
  digitalWrite(pinB, HIGH);
  digitalWrite(pinC, LOW);
  digitalWrite(pinD, HIGH);
  digitalWrite(pinE, HIGH);
  digitalWrite(pinF, LOW);
  digitalWrite(pinG, HIGH);
  digitalWrite(punt, LOW);
}

void numThree(){
  digitalWrite(pinA, LOW);
  digitalWrite(pinB, HIGH);
  digitalWrite(pinC, HIGH);
  digitalWrite(pinD, LOW);
  digitalWrite(pinE, LOW);
  digitalWrite(pinF, HIGH);
  digitalWrite(pinG, HIGH);
  digitalWrite(punt, LOW);
}

void numFour(){
  digitalWrite(pinA, HIGH);
  digitalWrite(pinB, HIGH);
  digitalWrite(pinC, HIGH);
  digitalWrite(pinD, HIGH);
  digitalWrite(pinE, LOW);
  digitalWrite(pinF, LOW);
  digitalWrite(pinG, HIGH);
  digitalWrite(punt, LOW);
}

void numFive(){
  digitalWrite(pinA, HIGH);
  digitalWrite(pinB, LOW);
  digitalWrite(pinC, HIGH);
  digitalWrite(pinD, HIGH);
  digitalWrite(pinE, LOW);
  digitalWrite(pinF, HIGH);
  digitalWrite(pinG, HIGH);
  digitalWrite(punt, LOW);
}

void numSix(){
  digitalWrite(pinA, HIGH);
  digitalWrite(pinB, LOW);
  digitalWrite(pinC, HIGH);
  digitalWrite(pinD, HIGH);
  digitalWrite(pinE, HIGH);
  digitalWrite(pinF, HIGH);
  digitalWrite(pinG, HIGH);
  digitalWrite(punt, LOW);
}

void numSeven(){
  digitalWrite(pinA, HIGH);
  digitalWrite(pinB, HIGH);
  digitalWrite(pinC, HIGH);
  digitalWrite(pinD, LOW);
  digitalWrite(pinE, LOW);
  digitalWrite(pinF, LOW);
  digitalWrite(pinG, LOW);
  digitalWrite(punt, LOW);
}

void numEight(){
  digitalWrite(pinA, HIGH);
  digitalWrite(pinB, HIGH);
  digitalWrite(pinC, HIGH);
  digitalWrite(pinD, HIGH);
  digitalWrite(pinE, HIGH);
  digitalWrite(pinF, HIGH);
  digitalWrite(pinG, HIGH);
  digitalWrite(punt, LOW);
}

void numNine(){
  digitalWrite(pinA, HIGH);
  digitalWrite(pinB, HIGH);
  digitalWrite(pinC, HIGH);
  digitalWrite(pinD, HIGH);
  digitalWrite(pinE, LOW);
  digitalWrite(pinF, HIGH);
  digitalWrite(pinG, HIGH);
  digitalWrite(punt, LOW);
}

void digOne(){
  digitalWrite(D1, LOW);
  digitalWrite(D2, HIGH);
  digitalWrite(D3, HIGH);
  digitalWrite(D4, HIGH);
}

void digTwo(){
  digitalWrite(D1, HIGH);
  digitalWrite(D2, LOW);
  digitalWrite(D3, HIGH);
  digitalWrite(D4, HIGH);
}

void digThree(){
  digitalWrite(D1, HIGH);
  digitalWrite(D2, HIGH);
  digitalWrite(D3, LOW);
  digitalWrite(D4, HIGH);
}

void digFour(){
  digitalWrite(D1, HIGH);
  digitalWrite(D2, HIGH);
  digitalWrite(D3, HIGH);
  digitalWrite(D4, LOW);
}

void numRandom(){
  int choose = random(9);
  switch (choose){
    case 1:
      numOne();
      break;
    case 2:
      numTwo();
      break;
    case 3:
      numThree();
      break;
    case 4:
      numFour();
      break;
    case 5:
      numFive();
      break;
    case 6:
      numSix();
      break;
    case 7:
      numSeven();
      break;
    case 8:
      numEight();
      break;
    case 9:
      numNine();
      break;
  }
}

void setup() {
  // put your setup code here, to run once:
  pinMode(pinA, OUTPUT);
  pinMode(pinB, OUTPUT);
  pinMode(pinC, OUTPUT);
  pinMode(pinD, OUTPUT);
  pinMode(pinE, OUTPUT);
  pinMode(pinF, OUTPUT);
  pinMode(pinG, OUTPUT);
  pinMode(D1, OUTPUT);
  pinMode(D2, OUTPUT);
  pinMode(D3, OUTPUT);
  pinMode(D4, OUTPUT);
  pinMode(punt, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  digOne();
  numRandom();
  delay(4);
  digTwo();
  numRandom();
  delay(4);
  numRandom();
  digThree();
  delay(4);
  numRandom();
  digFour();
  delay(4);
}

Brief explanation of why I did what I did + my issue: first of all I did functions for every different number, so "numZero()", "numThree()", etc, just sets the right pins to high and low to form said number. Second, since this is a 4 digit display, I needed to make functions to specify at which slot is this number going to appear. Those are "digOne()", "digTwo()", etc.

Those do work. If you hardcode a number in the main loop like this:

  void loop() {
  // put your main code here, to run repeatedly:
  digOne();
  numFour();
  delay(4);
  digTwo();
  numSix();
  delay(4);
  digThree();
  numNine();
  delay(4);
  digFour();
  numZero();
  delay(4);
}

it shows the number "3690" as expected. The random number generator is also very simple: it just chooses a random number between 0 and 9 and based on the plain number it got, it does a "num" function to show that specific number on the display.

This works correctly with a single digit display, or if you set all four numbers in this display to act like a single one (changing D1, D2, D3 and D4 pins to low).

The issue comes when I want to generate four random numbers and print them for a second. Since I'm doing this via multiplexing, I can't just put an "sleep(1000)" there because if you did it you would see only one digit on and keeping the loop on is not an option since everytime the loops reset I get a new set of 4 random numbers. I tried a couple things:

  • Trying to assign the value of numRandom() to a new variable like randNumberOne at the setup so it would only generate a single number and store it in randNumberOne. I wanted to repeat this 4 times and voila 4 random numbers everytime you reset the board. The issue: I couldn't get a variable to save a piece of code. I kept getting errors saying that a void didn't have any value and that actually makes sense but I don't really know what to do.
  • Using a "while" loop that adds or substracts one from the variable "counter" based on its value. Didn't work either because the while loop it's still a loop and it keeps generating a new set of four numbers everytime you run it.

So, what should I try now? I gave up on it after some hours thinking lol.

EDIT: I didn't add an image to show what are pinA-G and D1-4 variables actually pointing at. This is how my display (and I think every display?) works:

The first thing I would say is that you have chosen a very inefficient way to hold the data for each digit. There are 7 LED segments in each digit of the display which conveniently fits in a byte of data so the segment data for the digits 0 to 0 can be held in 10 bytes in an array like this

const byte segmentData[] =
{
  0b11111100, //0
  0b01100000, //1
  0b11011010, //2
  0b11110010, //3
  0b01100110, //4
  0b10110110, //5
  0b10111110, //6
  0b11100000, //7
  0b11111110, //8
  0b11110110  //9
};

You output a digit, say a 7, you pass the byte at position 7 in the array to a function that reads the bits of the byte one by one and turns on the corresponding LED segment.

You do not need a separate function for each number.

Whether the number 7 is generated randomly or by some other means is of no concern to the program

UKHeliBob:
The first thing I would say is that you have chosen a very inefficient way to hold the data for each digit. There are 7 LED segments in each digit of the display which conveniently fits in a byte of data so the segment data for the digits 0 to 0 can be held in 10 bytes in an array like this

const byte segmentData[] =

{
  0b11111100, //0
  0b01100000, //1
  0b11011010, //2
  0b11110010, //3
  0b01100110, //4
  0b10110110, //5
  0b10111110, //6
  0b11100000, //7
  0b11111110, //8
  0b11110110  //9
};



You output a digit, say a 7, you pass the byte at position 7 in the array to a function that reads the bits of the byte one by one and turns on the corresponding LED segment. 

You do not need a separate function for each number.

Whether the number 7 is generated randomly or by some other means is of no concern to the program

While I understand how is the data put together in your code example, I can't figure out how to make a function that reads bits one by one. Any tutorial?

Take a look at the bitRead() function

UKHeliBob:
Take a look at the bitRead() function

I'm trying to work on two "for" that, based on the number you give to the array you wrote, sets pins to high or low. My issue now is that for some reason I'm not cycling through arrays correctly. This is what I did:

First of all I changed all the "pinA = 2" variables to a single array:

int pins[] =
{
  2,
  3,
  4,
  5,
  6,
  7,
  8,
};

As far as I know, if I write a pins[2] it should return me a "4". Based on this, I tried to make a "for" that repeats itself 8 times, going from 0 to 7. I assumed that I could pass the variable stored in the "for" to run through all values stored in the array, letting me put on HIGH all the pins from 2 to 8:

for (int x = 0; x=6; x++) {
    digitalWrite(pins[x], HIGH);
    delay(10);
  }

It didn't work. I can't figure why. This is the first step to make the code work and it already doesn't work. What can I do?

Try this instead

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

or

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

so the loop goes from 0 to 6 and all the pins are written to.

Hm you guys are right I'm a bit stupid. Thanks for the help I'll start to work on it again.

Okay new issue... Why is "random(9)" in the setup ALWAYS giving me 4?? It doesn't make sense for me?

This is what I did to generate a random number: (this is at the setup)

int randGen = 8;
    for (int y=0; y<7; y++) {
      randNumb[y] = bitRead(segmentData[randGen], y);
      if (randNumb[y] == 0) {
        randNumb[y] = LOW;
      } else {
        randNumb[y] = HIGH;
      }
    }

And this is at the loop:

for (int x = 0; x<7; x++) {
    digitalWrite(pins[x], randNumb[x]);
    delay(10);
  }

if I hardcode a value for the randGen value (like in the example I put) it works. It shows me a 8, a 2, a 3... whatever I put in there. But when I switch the "int randGen = 8;" for a "int randGen = random(9);" it stops working since it ALWAYS brings out a 4. Any idea on why it does this?