Wow your code is a bit long and as you have found it is error prone.
If you dive a little deeper into the Arduino hardware you will find that digital I/O pins 2 through 7 are connected to the output port named D and digital I/O pins 8 through 13 are connected to output port named B.
It would make the code much simpler if you could connect the 6 minute LEDs to port D and the 4 hour, PM and sec LEDs to port B. That is you can set all of the LEDs at once for a particular port by assigning the appropriate value into either the PORTB or PORTD registers on the mega328 or mega168 chip.
Your setup() routine to set ports B and D as outputs (replacing all of the pinMode functions) would look something like this:
int hrc;
int mnc;
int secc;
int PM;
void setup() {
DDRB = 0xFF;
DDRD = 0xFF;
PORTB = 0;
PORTD = 0;
Serial.begin(9600);
// set time
secc = 0;
mnc = 0;
hrc = 0;
PM = 0;
}
and core part of the routine to set the minutes and hours might look something like this:
void loop() {
secc = secc + 1;
if (secc == 60)
{
secc = 0;
mnc = mnc + 1;
if (mnc == 60)
{
mnc = 0;
hrc = hrc + 1;
if (hrc == 12)
{
PM = 16; // bit value for PM indicator
}
if (hrc == 13)
{
hrc = 1;
}
// need to handle case for PM going to AM
// PM = 0;
}
}
// Using these test lines affects accuracy
//Serial.print("Mins: ");
//Serial.print(mnc * 4, HEX);
//Serial.print(" Hrs: ");
//Serial.println(hrc + PM, HEX);
// display minutes - need to shift 2 bits to the left
PORTD = mnc << 2;
// display hours, PM, and secs
PORTB = hrc + PM + 32;
// turn off seconds LED
delay(500);
PORTB = hrc + PM;
// now need to wait remainder of a second
// there is a small inaccuracy here because of the time
// taken to update the LEDS
delay(500);
}
I didn't deal with the PM indicator properly but as I didn't find that in your posted code either, I will leave it to you to resolve.
If you cannot move the LEDs on the digitial I/O pins to match what I am suggesting, it will still work. You just need to set the appropriate bit patterns into each of the PORTB and PORTD registers.