Novice Programmer & combining Nick Gammon sketches

I am attempting to build an Tachometer for a lathe. I have found a sketch to read the RPM and another to display the number on a 4 digit 7 segment display. Both are from Nick's website. Using the sketch labeled "Another frequency counter" in a thread titled "Timers and counters" I can get a stable RPM reading. Using the sketch from "4-digit display made from minimal parts" which would be a great solution to the actual build, I get a no flicker display. I just don't have the brains to combine these to sketches. I have combined a simpler display sketch with Nick's counter but the way it displays the segments, the more on the dimmer it gets.

I just don't have the brains to combine these to sketches.

Or even post them?

Display

#include <SPI.h>

const byte LATCH = 10;  // pin for latch (slave select)

const byte MAX_DIGITS = 4;
const byte TIME_BETWEEN_DIGITS = 8;  // blanking period between digits in loop iterations

// which bit to turn on to make a particular pin of the LED go high

const unsigned int DIG1  = 0x0200;  // Q1 of second IC
const unsigned int DIG2  = 0x1000;  // Q4 of second IC
const unsigned int DIG3  = 0x2000;  // Q5 of second IC
const unsigned int DIG4  = 0x0002;  // Q1 of first IC

const unsigned int SEGA  = 0x0400;  // Q2 of second IC
const unsigned int SEGB  = 0x4000;  // Q6 of second IC
const unsigned int SEGC  = 0x0008;  // Q3 of first IC
const unsigned int SEGD  = 0x0020;  // Q5 of first IC
const unsigned int SEGE  = 0x0040;  // Q6 of first IC
const unsigned int SEGF  = 0x0800;  // Q3 of second IC
const unsigned int SEGG  = 0x0004;  // Q2 of first IC
const unsigned int SEGDP = 0x0010;  // Q4 of first IC
         
// which segments to light for each digit                    
const unsigned int digitPatterns [15] = {
 SEGA | SEGB | SEGC | SEGD | SEGE | SEGF,  // 0
 SEGB | SEGC,  // 1
 SEGA | SEGB | SEGD | SEGE | SEGG,  // 2
 SEGA | SEGB | SEGC | SEGD | SEGG,  // 3
 SEGB | SEGC | SEGF | SEGG,  // 4
 SEGA | SEGC | SEGD | SEGF | SEGG,  // 5
 SEGA | SEGC | SEGD | SEGE | SEGF | SEGG,  // 6
 SEGA | SEGB | SEGC,  // 7
 SEGA | SEGB | SEGC | SEGD | SEGE | SEGF | SEGG,  // 8
 SEGA | SEGB | SEGC | SEGD | SEGF | SEGG,  // 9
 0,  // space
 SEGG,  // hyphen
 SEGA | SEGB | SEGC| SEGE | SEGF | SEGG,  // A
 SEGA | SEGE | SEGF | SEGG,  // F
 SEGD | SEGE | SEGF,  // L
};
// how long to leave the digit on for
const byte digitOnTimes [15] = { 3, 1, 3, 3, 2, 3, 3, 2, 3, 3, 0, 0, 3, 3, 2 };
// index into digits
const unsigned int digits [4] = { DIG1, DIG2, DIG3, DIG4 };

// 0 to 9 are themselves in the patterns array
//  there are the other entries:
#define PAT_SPACE 10
#define PAT_HYPHEN 11
#define PAT_A 12
#define PAT_F 13
#define PAT_L 14

// what to display (0 to 15, plus 0x10 to light the decimal point)
// see above (eg. 1 displays 1)
volatile byte ledOutput [MAX_DIGITS];

// global variables used by the ISR
unsigned int countdown;
byte digit;

//******************************************************************
//  Timer2 Interrupt Service is invoked by hardware Timer 2 every 1ms = 1000 Hz
//  16Mhz / 128 / 125 = 1000 Hz

ISR (TIMER2_COMPA_vect) 
{
   
  // keep doing what we were doing before?
  if (countdown-- > 0)
    return;
    
  if (digit >= MAX_DIGITS)
    {
    digit = 0;
    countdown = TIME_BETWEEN_DIGITS;
    // blanking period to allow output chip and LEDs to cool down
    digitalWrite (LATCH, LOW);
    SPI.transfer (0);
    SPI.transfer (0);
    digitalWrite (LATCH, HIGH);
    return;
    } // end of done all digits
  
  // make all digits high  
  unsigned int output = DIG1 | DIG2 | DIG3 | DIG4;

  // bring low the wanted digit (this will sink)
  output &= ~digits [digit];

  // turn on wanted segments (this will source)
  output |=  digitPatterns [ledOutput [digit] & 0xF];
   
  // add decimal place if required
  if (ledOutput [digit] & 0x10)
    output |= SEGDP;
     
  // send to shift registers
  digitalWrite (LATCH, LOW);
  SPI.transfer (highByte (output));
  SPI.transfer (lowByte (output));
  digitalWrite (LATCH, HIGH);
     
  // adjust time to allow for different numbers of segments
  countdown = digitOnTimes [ledOutput [digit] & 0xF] ;
  
  // onto next digit next time
  digit++;
  
}  // end of TIMER2_COMPA_vect


void setup () 
  {
  
  SPI.begin ();
  
  // set up Timer 2
  // Timer 2 - gives us our 1 mS counting interval
  // 16 MHz clock (62.5 nS per tick) - prescaled by 128
  //  counter increments every 8 uS. 
  // So we count 125 of them, giving exactly 1000 uS (1 mS)
  TCCR2A = 0;              // stop timer 2
  TCCR2B = 0;
  TCCR2A = _BV (WGM21) ;   // CTC mode
  OCR2A  = 124;            // count up to 125  (zero relative!!!!)
  TIMSK2 = _BV (OCIE2A);   // enable Timer2 Interrupt (ie. every 1 mS)
  TCNT2 = 0;               // reset counter
  TCCR2B =  _BV (CS20) | _BV (CS22) ;  // start Timer with a prescaler of 128

} // end of setup


void loop () 
{

  unsigned long now = millis () / 100;
 
  noInterrupts ();
  for (int i = 0; i < 4; i++)
    {
    ledOutput [3 - i] = now % 10;
    now /= 10;   
    }

  // turn leading zeroes into spaces    
  for (int i = 0; i < 4; i++)
    {
    if (ledOutput [i] == 0)
      ledOutput [i] = PAT_SPACE;
    else
      break;
    }
  
  // decimal point before 10ths of a second
  ledOutput [2] |= 0x10;
  interrupts ();
  
  delay (10);
}   // end of loop

Frequency counter

// Frequency timer
// Author: Nick Gammon
// Date: 10th February 2012

// Input: Pin D2

volatile boolean first;
volatile boolean triggered;
volatile unsigned long overflowCount;
volatile unsigned long startTime;
volatile unsigned long finishTime;

// here on rising edge
void isr () 
{
  unsigned int counter = TCNT1;  // quickly save it
  
  // wait until we noticed last one
  if (triggered)
    return;

  if (first)
    {
    startTime = (overflowCount << 16) + counter;
    first = false;
    return;  
    }
    
  finishTime = (overflowCount << 16) + counter;
  triggered = true;
  detachInterrupt(0);   
}  // end of isr

// timer overflows (every 65536 counts)
ISR (TIMER1_OVF_vect) 
{
  overflowCount++;
}  // end of TIMER1_OVF_vect


void prepareForInterrupts ()
  {
  // get ready for next time
  EIFR = bit (INTF0);  // clear flag for interrupt 0
  first = true;
  triggered = false;  // re-arm for next time
  attachInterrupt(0, isr, RISING);     
  }  // end of prepareForInterrupts
  

void setup () 
  {
  Serial.begin(115200);       
  Serial.println("Frequency Counter");
  
  // reset Timer 1
  TCCR1A = 0;
  TCCR1B = 0;
  // Timer 1 - interrupt on overflow
  TIMSK1 = bit (TOIE1);   // enable Timer1 Interrupt
  // zero it
  TCNT1 = 0;  
  overflowCount = 0;  
  // start Timer 1
  TCCR1B =  bit (CS10);  //  no prescaling

  // set up for interrupts
  prepareForInterrupts ();   
  
  } // end of setup

void loop () 
  {

  if (!triggered)
    return;
 
  unsigned long elapsedTime = finishTime - startTime;
  float freq = F_CPU / float (elapsedTime);  // each tick is 62.5 ns at 16 MHz
  
  Serial.print ("Took: ");
  Serial.print (elapsedTime);
  Serial.print (" counts. ");

  Serial.print ("Frequency: ");
  Serial.print (freq);
  Serial.println (" Hz. ");

  // so we can read it  
  delay (500);

  prepareForInterrupts ();   
}   // end of loop

What do you want to see on the display?

The display code turns off interrupts while it displays data. That is going to cause you to miss interrupts from the RPM sensor. Probably not a good thing.

I took the "freq" variable (cycles per second) and multiplied it by 60 to get cycles per minute(RPM). That is what I want to display but the programs I have found that I can understand enough to change, all flicker and have uneven segment brightness due to the way they multiplex the segments. I currently have an ATTINY85 to send a PMW signal to a treadmill motor controller and another to run a "Start/Stop" system and will put the 4 digit 7 segment display in between the switches and rheostat.