Multiplexed 6 digit 7-seg flashing (4 x 74HC595)

One suggestion would be to replace that 4th 74hc595 with a tpic6b595. These chips work identically to a 74hc595, but their outputs can sink up to 150mA each, which would be more than enough and no transistors would be needed. (Note: the tpic chip's outputs can only sink current, they cannot source any current.) But unless you happen to have tpic6b595 on hand, you would need to order some, and in that case you should order max7219 or ht16k33.

And I recommend ordering the modules as they are fairly inexpensive, generally reliable and you have them nicely mounted.

Oh! Ok, I guess that full schematic would have been useful after all. I was assuming that the 2nd and 3rd '595s were sourcing current to the segments of the other 6 x 2- digit displays, but now I realise they are sinking current from the digit pins of the other 6 displays.

In that case, I think I may understand the flickering/flashing problem. It's partly because of the fact that only 1 of 18 digits is lit at a time, so data has to be sent to the chips at quite a fast speed. That's absolutely possible with Arduino, but the combination of your code and that library you are using is probably so slow and inefficient that the data transfer can't be done fast enough to avoid flickering/flashing.

Cheers for the help, I'll be ordering some of both those modules when I can to try again. There'll probably be another post in the next month with more badly written code :laughing:

In the mean time I think I'm going to try writing it all again and shifting the bits out instead of using that library. I may also add more shift registers to try dealing with the refresh rate. At least this way I can keep learning while waiting for the correct parts.

I'll also be uploading the full diagram next time I need help on something, my laziness caused confusion there. It was my first time using eagle and after getting that far, the thought of drawing the wires again twice over and also not being able to find a pro micro in the part libraries had me thinking to myself "yeahhh that'll be enough.."

Yes. I would recommend using the SPI library. This is the fastest way of shifting the data out because it uses dedicated hardware inside the Arduino Pro Micro chip. It does however mean you have to use specific pins, namely those marked "MOSI", "SCK" and "SS". As long as those are free, or can be freed-up, and you add a couple of lines to setup() to configure the SPI hardware, it's really no different to using shiftOut() but way faster.

I think the flicker you have mentioned is because you are using a delay in the wrong place. You should hold at the time the current digit is fully displayed. You appear to be holding only when nothing is being displayed.

To set up the next digit in a multiplexed display you normally:

  1. cut power to the common pins, in this case the cathodes of the displays.
  2. set each segment to the desired value for the current digit position.
  3. power the cathode for the current digit position
    4 hold for say 2 or 3 milliseconds (you are currently using delay) for long enough for persistence of vision to work but not so long that there is a visible flickering of the digits.

This construct is rather unusual. For one thing, you are changing the for loop control variable in the for loop:

uint64_t value = 123456;
. . . 
. . .

loop {

  char valueArray[7];
  dtostrf(value, 6, 0, valueArray);

  int digit1 = valueArray[0];
  int digit2 = valueArray[1];
  int digit3 = valueArray[2];
  int digit4 = valueArray[3];
  int digit5 = valueArray[4];
  int digit6 = valueArray[5];

  int digit[6] = {digit1, digit2, digit3, digit4, digit5, digit6};

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

    digTable(digVal = i);
    segTable(segVal = digit[i]);
    sdOff();

    i++;
    segTable(segVal = digit[i]);
    digTable(digVal = i);
    sdOff();

    i++;
    segTable(segVal = digit[i]);
    digTable(digVal = i);
    sdOff();

    i++;
    segTable(segVal = digit[i]);
    digTable(digVal = i);
    sdOff();

    i++;
    segTable(segVal = digit[i]);
    digTable(digVal = i);
    sdOff();

    i++;
    digTable(digVal = i);
    segTable(segVal = digit[i]);
    sdOff();
  }

}

This may be clearer and hopefully achieves the same thing:

uint8_t value[ 6 ] = { 1, 2, 3, 4, 5, 6} ;  // test number to be displayed
. . .
. . .

loop {
    static uint8_t i = 0 ;

    digTable( i );
    segTable( value[i] );
    delay( 2 ) ; // hold here for 2 to 3 ms
    sdOff();  // remove delay() from here

    if ( ++i >= 6 ) i = 0 ;  // cycle i:  0 to 5

}

Unfortunately with @birchop 's current arrangement, that will result in around 27 refreshes per second, so will still flicker. But 1 millisecond should be much less flickery.

Are you sure? I can't see how you have calculated that. From the OP's test program, it looks like he is currently using only 3 double displays and is switching all the segments for a digit simultaneously and that cycle simply goes through each of the 6 digit positions constantly. He has currently only one delay() which is active once per displayed digit. Or, at least, that is how it seems to me. The delay(2) that I added is per digit, not per segment.

From what I can tell, and it's absolutely possible I'm mistaken, @birchop 's plan is to have a total of 9 double digit displays, of which only 3 are shown in the schematic. I mistook the partial schematic to mean that 3 digits would be lit simultaneously, 1 digit in each group of 3 displays (6 digits). That would have meant each digit would be lit 1/6th of the time. 2ms x 6 = 12ms per refresh = 83 refreshes per second. But it turns out I was wrong, and only 1 digit will be lit at any time out of all 18 digits, ie 1/18th of the time. 2ms x 18 = 36ms per refresh = 27 refreshes per second.

Yes I see. That does look right for the final system where 18 digits will be displayed. From his test program, however, it looks like he is trying with only 6 digits (if I have understood that correctly).
Shorter refresh rates can be used but then switching losses start becoming apparent, resulting in a dimmer display, especially if there is a "de-ghosting" phase built into the refresh cycle.