simple 8 digit display hangs up

I have been using a similar sketch for years now, but for some reason this one hangs up.

I am receiving 9 bytes of data from a remote control, the first is an ID that I call PIN.

the next 8 bytes are the numbers from 8 switches.

The remote is ok as I can reboot the receiver and it comes right.

I am storing the values of the 8 bytes in eeprom so that it will always come on with the same display after a power failure.
It only rewrites the eeprom when it receives a valid transmission and has the right PIN number. ( device ID )
The numbers only change once a week at most, so it shouldnt wear out the eeprom.

A LDR is connected to the analog pin with an 18k resistor to +5 ( which has always worked fine )
I smooth the reading and send a pwm output to the notG pins of the shift reg / latches ( TPIC6B595s ) to dim.

At first all works OK, but when I start testing, by putting all 8s in the remote, it randomly hangs up, with sometimes the display on full brightness.

I have tried it without the smoothing and it still hangs.

Any ideas what I have missed ?

#include <EEPROM.h>    
#include <VirtualWire.h>
#define latchPin 11  // rck
#define clockPin 10  // sck
#define dataPin 13  // ser in
int thispin = 51;  //                      ID for this unit
int val;
int analogPin = 19;  //  reads LDR,  dims display at night
int dimPin = 5;
int blank;
int PIN ;

int digA = 0;   
int digB = 0;  
int digC = 0;   
int digD = 0;
int digE = 0;   
int digF = 0;  
int digG = 0;   
int digH = 0;  
int loopcount = 0; 
int dim; 
int total = 175;  // initial starting value for dimming smoothing
const byte digitTable [10] =  //  pattern for 7seg displays  dot afcedbg
{ 
  B01111110,B00010010,B01001111,B01011011,B00110011,B01111001,B01111101,B01010010,B01111111,B01111011 };

const byte blanked = B00000000;
//********************************************************************************************

void setup()
{
  Serial.begin(9600);	// Debugging only
  blank == HIGH;
  Serial.println("setup");

  pinMode ( latchPin, OUTPUT); 
  pinMode ( clockPin, OUTPUT);
  pinMode ( dataPin, OUTPUT);
  pinMode ( dimPin, OUTPUT);

  int digA = EEPROM.read (0);   
  int digB = EEPROM.read (1);  
  int digC = EEPROM.read (2);  
  int digD = EEPROM.read (3);  
  int digE = EEPROM.read (4);   
  int digF = EEPROM.read (5);  
  int digG = EEPROM.read (6);  
  int digH = EEPROM.read (7);

  vw_set_tx_pin(12);   //  defaults to 12
  vw_set_ptt_pin(6);  // defaults to 10 which we are using
  vw_set_rx_pin(18  );     
  vw_setup(2000);	 // Bits per sec
  vw_rx_start();    

  if ( digA || digB || digC || digD || digE || digF || digG || digH ) { 
    blank =0;  //  brings display out of standbye with any button pressed
  } 
  else { 
    blank = 1 ; 
  }

  int Adisplay = (digA) ? digitTable [ digA ] : 0;  //  zero blanking
  int Bdisplay = digitTable [ digB ];
  int Cdisplay =  digitTable [ digC ];  
  int Ddisplay = digitTable [ digD ];
  int Edisplay = (digE) ? digitTable [ digE ] : 0;  //  zero blanking
  int Fdisplay = digitTable [ digF ];
  int Gdisplay =  digitTable [ digG ]; 
  int Hdisplay = digitTable [ digH ];

  if ( blank == 1 ){              //  clear all displays if blank = high
    digitalWrite(latchPin, LOW);   
    for ( int x=0; x<= 7; x ++ ){              
      shiftOut(dataPin, clockPin, LSBFIRST, blanked); 
    }
    digitalWrite(latchPin, HIGH);
  }   
  else {      
    digitalWrite(latchPin, LOW); 
    delay ( 50 );
    shiftOut(dataPin, clockPin, LSBFIRST, Adisplay);
    shiftOut(dataPin, clockPin, LSBFIRST, Bdisplay);
    shiftOut(dataPin, clockPin, LSBFIRST, Cdisplay);
    shiftOut(dataPin, clockPin, LSBFIRST, Ddisplay); 
    shiftOut(dataPin, clockPin, LSBFIRST, Edisplay);
    shiftOut(dataPin, clockPin, LSBFIRST, Fdisplay);
    shiftOut(dataPin, clockPin, LSBFIRST, Gdisplay);
    shiftOut(dataPin, clockPin, LSBFIRST, Hdisplay); 
    digitalWrite(latchPin, HIGH);
    delay ( 50 );
  }
}
//****************************************************************************************
void loop () 
{ 
  readlight (); 

  //        CHECK FOR INCOMING MESSAGE
  uint8_t buf[VW_MAX_MESSAGE_LEN];
  uint8_t buflen = VW_MAX_MESSAGE_LEN;
  if (vw_get_message(buf, &buflen)) // Non-blocking
  { 
    Serial.println("Got: ");  // Show on PC for debugging
    PIN = buf [0];
    if ( PIN == thispin ) {   //  everything below only runs if PINs match 
      Serial.println(" PINs match ") ; 
      int digA = buf [1];   
      int digB = buf [2];  
      int digC = buf [3];   
      int digD = buf [4];
      int digE = buf [5];   
      int digF = buf [6];  
      int digG = buf [7];   
      int digH = buf [8];          

      EEPROM.write (0,digA);  // store latest values in eeprom
      EEPROM.write (1,digB);
      EEPROM.write (2,digC);
      EEPROM.write (3,digD);
      EEPROM.write (4,digE); 
      EEPROM.write (5,digF);
      EEPROM.write (6,digG);
      EEPROM.write (7,digH);         
      
      if ( digA || digB || digC || digD || digE || digF || digG || digH) { 
        blank =0;  //  brings display out of standbye with any button pressed
      } 
      else { 
        blank = 1 ; 
      }
      int Adisplay = (digA) ? digitTable [ digA ] : 0;  //  zero blanking
      int Bdisplay = digitTable [ digB ];
      int Cdisplay =  digitTable [ digC ];  
      int Ddisplay = digitTable [ digD ];
      int Edisplay = (digE) ? digitTable [ digE ] : 0;  //  zero blanking
      int Fdisplay = digitTable [ digF ];
      int Gdisplay =  digitTable [ digG ]; 
      int Hdisplay = digitTable [ digH ];

      /*      Serial.print (" buf 1 = ");  Serial.println ( int (  buf [1])); 
       Serial.print (" digA in showtime= ");  Serial.println (int ( digA)); 
       Serial.print (" dispA = ");  Serial.println ( int ( Adisplay ));    
       Serial.print (" dispB = ");  Serial.println ( int ( Bdisplay )); 
       Serial.print (" dispC = ");  Serial.println ( Cdisplay);   
       */
      if ( blank == 1 ){              //  clear all displays if blank = high
        digitalWrite(latchPin, LOW);   
        for ( int x=0; x<= 7; x ++ ){                               
          shiftOut(dataPin, clockPin, LSBFIRST, blanked); 
        }
        digitalWrite(latchPin, HIGH);
      }   
      else {            
        digitalWrite(latchPin, LOW); 
        delay ( 50 );
        shiftOut(dataPin, clockPin, LSBFIRST, Adisplay);
        shiftOut(dataPin, clockPin, LSBFIRST, Bdisplay);
        shiftOut(dataPin, clockPin, LSBFIRST, Cdisplay);
        shiftOut(dataPin, clockPin, LSBFIRST, Ddisplay); 
        shiftOut(dataPin, clockPin, LSBFIRST, Edisplay);
        shiftOut(dataPin, clockPin, LSBFIRST, Fdisplay);
        shiftOut(dataPin, clockPin, LSBFIRST, Gdisplay);
        shiftOut(dataPin, clockPin, LSBFIRST, Hdisplay);
        digitalWrite(latchPin, HIGH);

        delay ( 50 );

      }
    }  //  end of if PIN = thispin
  } //  end of if message received 
}//  end of loop

void readlight ()
{  
  val = analogRead ( analogPin ); //  reads light from LDR
  int temp = val/4  ;
  if ( temp >= 220 ) {
    temp = 220 ; 
  }  // blanking pin higher number for darker
  total = total + temp;
  total = total * 10;
  total = total / 11;
  temp = (total / 10) ; 
  //Serial.print("                   temp light = ") ; Serial.println( temp );
  analogWrite ( dimPin,  temp );
}

I want to pick on the second line in void setup () blank == HIGH;

further

if ( digA || digB || digC || digD || digE || digF || digG || digH )
{ 
    blank =0;  //  brings display out of standbye with any button pressed
} 
else 
{ 
    blank = 1 ; 
}

What's the condition for the if (digA || digB || ... ) argument to satisfy?

Whoops

I dont know where that came from, but I have changed it to blank = 1 but still the whole thing is unstable,

I am going to try it minus the dimming and memory to see if it works then...

Got caps on the shift register power pins?

Yes I have my normal caps, but I have also strung some others right on the chips, and the micro.

One of the problems was overdriving the TPICs, but I have it running at less current now, but now and again it will show rubbish on the displays, and not respond to the remote control.

I have to reboot.

At first all works OK, but when I start testing, by putting all 8s in the remote, it randomly hangs up, with sometimes the display on full brightness.

Almost certainly a power problem then.

Thanks guys, its finally been collected, I have been up all night getting it finished. The customer had his guys on standby over the weekend to install it if I was finished. The problem was a mixture of the usual suspects, and lack of sleep :-)

I had 2 lots of 8 TPIC6B595s daisychained, driving a total of just over 9000 LEDs.

I had forgotten to tie the far end of the daisy chains ground back to the main board, so the Vdrop across the ground tracks starts getting near Vin low.

Also the auto-dimming feature was unstable until I stuck a 10 mFD right on pins 7 and 8 of the 386.

Off to bed now, at 14h20, the jobs out, and hopefully the client likes it and this time next year we will be millionaires !

10 milliFarad (mF), or 10microFarad (uF)?
The first would be huge and likely create a power supply surge to power up; the latter sounds more reasonable.

Why do you have ground tracks (I am thinking traces like signal and power traces) & not ground planes (any unused copped on both sides of the board providing a ground path)?

Could just be terminology …

LOL yes 10 uF. my main supplier has some very strange terminology and uses mfd because they couldnt find a micro button when they made their parts list !

These are single sided boards, with just enough room for a track at the top and bottom for supply and ground.

If possible I try and connect each pcbs supply and ground with a separate wire to the supplies' smoothing / reservoir cap rather than daisy chaining .

In this last project, I had a hash of different boards that I had designed over the years, and I just added an extra ground to the far one, It didnt cause any ground loop problems luckily, I have done it before with these particular pcbs with the TPICs daisychained.

I have to make another 3 of these units ( not in a rush this time ) and will use surface mount TPICs (four in each display ), so the control unit will be the size of a pack of cards instead of this monstrosity for the prototype that ended up with 2 plastic boxes screwed together as it grew :-(