user47885: I have a project that is simply a relay timer. The code is not complete so you will see 'in progress' sections not related to my question in my code.
However, my question is...
I am creating a timer with 4 x 7 segment display using a rotary encoder to set the time. I have 3 'Modes' that allow me to increment the time by 1 second, 10 seconds and minutes. All this is working correctly however when I switch modes I would like to flash the corresponding digit to give a kind of visual feedback showing what mode you are in (the first digit for seconds, the second for 10 seconds etc..). I can manually ground the corresponding common pin to create that effect manually, however, I am having trouble with the code.
I have tried creating for loops that digitalwrite() to the specific comPin, however, this is just turning the entire display off and on. The section of code that I am looking at is roughly halfway down.
The Bonus Question: I would like the Dp to illuminate between the second and third digits to show "min:sec". I assume this must be to do with my byte table, however, this is all new to me and I am not sure of what direction to go regarding changes.
#include <MD_REncoder.h>

int LightClocksec = 0;
int LightClockmin = 0;

int LightClockAdd = 1;
int Mode = 0;
boolean LightSW = 5;

int EncoderSW = 4;
boolean EncoderSWstate = 0;
MD_REncoder R1 = MD_REncoder(2, 3);

int FocusSW = 13;
boolean FocusSWstate = 0;
boolean FocusSWstatePRE = 0;
int FocusSWCounter = 0;

int MainSW = 14;
boolean MainSWstate = 0;
boolean MainSWstatePRE = 0;

int RelayPIN = 15;
boolean Relaystate = LOW;

unsigned long millispre = 0;

int buttonPushCounter = 0;   // counter for the number of button presses
int lastButtonState = 0;     // previous state of the button

int latchPin = 7;          // Pin connected to ST_CP of 74HC595（Pin12）
int clockPin = 8;          // Pin connected to SH_CP of 74HC595（Pin11）
int dataPin = 6;           // Pin connected to DS of 74HC595（Pin14）
int comPin[] = {12, 11, 10, 9};// Common pin (anode) of 4 digit 7-segment 
display


byte num[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 
0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e};


void setup() {
  //  Serial.begin(9600);
  R1.begin();
  pinMode (LightSW, OUTPUT);
  pinMode (RelayPIN, OUTPUT);

  pinMode (EncoderSW, INPUT);
  pinMode (FocusSW, INPUT);

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

for (int i = 0; i < 4; i++) {
  pinMode(comPin[i], OUTPUT);
  }

}

void loop() {

  ///set time, encoder..

  EncoderSWstate = digitalRead(EncoderSW);

  uint8_t z = R1.read();
  if (z) {
    if (EncoderSWstate == 0) {
      if ((Mode == 2) )
      {
        z == DIR_CW ? LightClockmin ++  : LightClockmin --;
      }
      else if (Mode == 1) {
        z == DIR_CW ? LightClocksec = LightClocksec + 10  : LightClocksec = LightClocksec - 10 ;
        if (LightClocksec >= 60) {
          LightClocksec = (LightClocksec - 60);
          LightClockmin ++;
        }
        if ((LightClocksec < 0) && (LightClockmin >= 1 )) {
          LightClocksec = (60 - LightClockAdd) ;
          LightClockmin --;
        }
      }
      else if (Mode == 0) {
        z == DIR_CW ? LightClocksec ++  :  LightClocksec --;
        if (LightClocksec >= 60) {
          LightClocksec = (LightClocksec - 60);
          LightClockmin ++;
        }
        if ((LightClocksec < 0) && (LightClockmin >= 1 )) {
      LightClocksec = (60 - LightClockAdd) ;
      LightClockmin --;
    }
  }
  LightClocksec = constrain(LightClocksec, 0, 59);
  LightClockmin = constrain(LightClockmin, 0, 59);
}

if (EncoderSWstate == 1) {
  z == DIR_CW ? Mode -- : Mode ++ ;
  Mode = constrain(Mode, 0, 3);
  if (Mode == 0) {
    ////////STACK EXCHANGE?//// FLASH first digit on and off 5 times
  }

  if (Mode == 1) {
    ////////STACK EXCHANGE?//// FLASH second digit on and off 5 times
  }
  if (Mode == 2) {
   ////////STACK EXCHANGE?////  FLASH 3rd Digit On and of 5 times
  }
   }
 }

  ////switching

  FocusSWstate = digitalRead(FocusSW);
  MainSWstate = digitalRead(MainSW);

  if (FocusSWstate != FocusSWstatePRE ) {
    if (FocusSWstate == HIGH) {
      FocusSWCounter++;
    } else {}
  }

  FocusSWstatePRE  = FocusSWstate;
  if (FocusSWCounter % 2 == 0) {
    digitalWrite(RelayPIN, LOW);
  } else {
    digitalWrite(RelayPIN, HIGH);
  }


  if (MainSWstate != MainSWstatePRE ) {
    if (MainSWstate == HIGH) {
      digitalWrite(RelayPIN, HIGH);
      delay(((LightClockmin * 60) + (LightClocksec)) * 1000);
      digitalWrite(RelayPIN, LOW);
    }
    else {}
  }
  MainSWstatePRE  = MainSWstatePRE;

  //display

  byte bit[4];
  bit[0] = LightClocksec % 10;
  bit[1] = LightClocksec / 10 % 10;
  bit[2] = LightClockmin % 10;
  bit[3] = LightClockmin / 10 % 10;

  for (int i = 0; i < 4; i++) {
    chooseCommon(i);
    writeData(num[bit[3 - i]]);
    writeData(0xff);
  }
 }

void chooseCommon(byte com) {
  // Close all single 7-segment display
  for (int i = 0; i < 4; i++) {
    digitalWrite(comPin[i], LOW);
  }
  // Open the selected single 7-segment display
  digitalWrite(comPin[com], HIGH);
}

void writeData(int evalue) {
  // Make latchPin output low level
  digitalWrite(latchPin, LOW);
  // Send serial data to 74HC595
  shiftOut(dataPin, clockPin, LSBFIRST, evalue);
  // Make latchPin output high level, then 74HC595 will update the data to parallel output
  digitalWrite(latchPin, HIGH);
}


user4143: When displaying the digits you need to compare the current digit number (i) with the digit number you want to flash. If it's a match then either display the number, or don't display the number. How you make that decision is to examine millis().
Take a look at the BlinkWithoutDelay example in the IDE to see how to make something flash without using delay(), and apply that knowledge to blinking a digit.

47885: <p>I have a project that is simply a relay timer. The code is not complete so you will see 'in progress' sections not related to my question in my code.</p>

<p>However, my question is...</p>

<p>I am creating a timer with 4 x 7 segment display using a rotary encoder to set the time. I have 3 'Modes' that allow me to increment the time by 1 second, 10 seconds and minutes. All this is working correctly however when I switch modes I would like to flash the corresponding digit to give a kind of visual feedback showing what mode you are in (the first digit for seconds, the second for 10 seconds etc..). I can manually ground the corresponding common pin to create that effect manually, however, I am having trouble with the code.</p>

<p>I have tried creating for loops that <code>digitalwrite()</code> to the specific comPin, however, this is just turning the entire display off and on. The section of code that I am looking at is roughly halfway down.</p>

<p>The Bonus Question: I would like the Dp to illuminate between the second and third digits to show "min:sec". I assume this must be to do with my byte table, however, this is all new to me and I am not sure of what direction to go regarding changes.</p>

<pre><code>#include &lt;MD_REncoder.h&gt;

int LightClocksec = 0;
int LightClockmin = 0;

int LightClockAdd = 1;
int Mode = 0;
boolean LightSW = 5;

int EncoderSW = 4;
boolean EncoderSWstate = 0;
MD_REncoder R1 = MD_REncoder(2, 3);

int FocusSW = 13;
boolean FocusSWstate = 0;
boolean FocusSWstatePRE = 0;
int FocusSWCounter = 0;

int MainSW = 14;
boolean MainSWstate = 0;
boolean MainSWstatePRE = 0;

int RelayPIN = 15;
boolean Relaystate = LOW;

unsigned long millispre = 0;

int buttonPushCounter = 0;   // counter for the number of button presses
int lastButtonState = 0;     // previous state of the button

int latchPin = 7;          // Pin connected to ST_CP of 74HC595（Pin12）
int clockPin = 8;          // Pin connected to SH_CP of 74HC595（Pin11）
int dataPin = 6;           // Pin connected to DS of 74HC595（Pin14）
int comPin[] = {12, 11, 10, 9};// Common pin (anode) of 4 digit 7-segment 
display


byte num[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 
0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e};


void setup() {
  //  Serial.begin(9600);
  R1.begin();
  pinMode (LightSW, OUTPUT);
  pinMode (RelayPIN, OUTPUT);

  pinMode (EncoderSW, INPUT);
  pinMode (FocusSW, INPUT);

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

for (int i = 0; i &lt; 4; i++) {
  pinMode(comPin[i], OUTPUT);
  }

}

void loop() {

  ///set time, encoder..

  EncoderSWstate = digitalRead(EncoderSW);

  uint8_t z = R1.read();
  if (z) {
    if (EncoderSWstate == 0) {
      if ((Mode == 2) )
      {
        z == DIR_CW ? LightClockmin ++  : LightClockmin --;
      }
      else if (Mode == 1) {
        z == DIR_CW ? LightClocksec = LightClocksec + 10  : LightClocksec = LightClocksec - 10 ;
        if (LightClocksec &gt;= 60) {
          LightClocksec = (LightClocksec - 60);
          LightClockmin ++;
        }
        if ((LightClocksec &lt; 0) &amp;&amp; (LightClockmin &gt;= 1 )) {
          LightClocksec = (60 - LightClockAdd) ;
          LightClockmin --;
        }
      }
      else if (Mode == 0) {
        z == DIR_CW ? LightClocksec ++  :  LightClocksec --;
        if (LightClocksec &gt;= 60) {
          LightClocksec = (LightClocksec - 60);
          LightClockmin ++;
        }
        if ((LightClocksec &lt; 0) &amp;&amp; (LightClockmin &gt;= 1 )) {
      LightClocksec = (60 - LightClockAdd) ;
      LightClockmin --;
    }
  }
  LightClocksec = constrain(LightClocksec, 0, 59);
  LightClockmin = constrain(LightClockmin, 0, 59);
}

if (EncoderSWstate == 1) {
  z == DIR_CW ? Mode -- : Mode ++ ;
  Mode = constrain(Mode, 0, 3);
  if (Mode == 0) {
    ////////STACK EXCHANGE?//// FLASH first digit on and off 5 times
  }

  if (Mode == 1) {
    ////////STACK EXCHANGE?//// FLASH second digit on and off 5 times
  }
  if (Mode == 2) {
   ////////STACK EXCHANGE?////  FLASH 3rd Digit On and of 5 times
  }
   }
 }

  ////switching

  FocusSWstate = digitalRead(FocusSW);
  MainSWstate = digitalRead(MainSW);

  if (FocusSWstate != FocusSWstatePRE ) {
    if (FocusSWstate == HIGH) {
      FocusSWCounter++;
    } else {}
  }

  FocusSWstatePRE  = FocusSWstate;
  if (FocusSWCounter % 2 == 0) {
    digitalWrite(RelayPIN, LOW);
  } else {
    digitalWrite(RelayPIN, HIGH);
  }


  if (MainSWstate != MainSWstatePRE ) {
    if (MainSWstate == HIGH) {
      digitalWrite(RelayPIN, HIGH);
      delay(((LightClockmin * 60) + (LightClocksec)) * 1000);
      digitalWrite(RelayPIN, LOW);
    }
    else {}
  }
  MainSWstatePRE  = MainSWstatePRE;

  //display

  byte bit[4];
  bit[0] = LightClocksec % 10;
  bit[1] = LightClocksec / 10 % 10;
  bit[2] = LightClockmin % 10;
  bit[3] = LightClockmin / 10 % 10;

  for (int i = 0; i &lt; 4; i++) {
    chooseCommon(i);
    writeData(num[bit[3 - i]]);
    writeData(0xff);
  }
 }

void chooseCommon(byte com) {
  // Close all single 7-segment display
  for (int i = 0; i &lt; 4; i++) {
    digitalWrite(comPin[i], LOW);
  }
  // Open the selected single 7-segment display
  digitalWrite(comPin[com], HIGH);
}

void writeData(int evalue) {
  // Make latchPin output low level
  digitalWrite(latchPin, LOW);
  // Send serial data to 74HC595
  shiftOut(dataPin, clockPin, LSBFIRST, evalue);
  // Make latchPin output high level, then 74HC595 will update the data to parallel output
  digitalWrite(latchPin, HIGH);
}
</code></pre>
 4143: <p>When displaying the digits you need to compare the current digit number (<code>i</code>) with the digit number you want to flash. If it's a match then either display the number, or don't display the number. How you make that decision is to examine <code>millis()</code>.</p>

<p>Take a look at the <code>BlinkWithoutDelay</code> example in the IDE to see how to make something flash without using <code>delay()</code>, and apply that knowledge to blinking a digit.</p>
