0

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);
}
  • You kind of already know the answer. To turn on a specific segment you manually connected it to ground. But in your code you are setting the segment you want to HIGH, and al the segments you don’t want to LOW (I.e. ground). Change HIGH to LOW, and LOW to HIGH in your chooseCommon function. – Gerben Jul 6 '18 at 17:27
  • I'm having trouble specifying the specific common, I think that's the trouble. I have tried the following code, but its just turning the entire display off, and not just comPin[0] as i thought it should. I can't post it all here cause of length so ill stick it in another comment. – Ashley Reid Jul 6 '18 at 20:06
  • if (Mode == 0) { byte bit[4]; bit[0] = LightClocksec % 10; bit[1] = LightClocksec / 10 % 10; bit[2] = LightClockmin % 10; bit[3] = LightClockmin / 10 % 10; chooseCommonblink(0); writeData(num[bit[0]]); writeData(0xff); } and then after my void loop(): void chooseCommonblink(byte com) { digitalWrite(comPin[com], LOW); delay(50); digitalWrite(comPin[com], HIGH); delay(50); digitalWrite(comPin[com], LOW); delay(50); digitalWrite(comPin[com], HIGH); } – Ashley Reid Jul 6 '18 at 20:11
  • It seems you have a common cathode, but the code is for a common anode. Or do you have some transistors on those pins? – Gerben Jul 6 '18 at 20:11
  • 1
    ok, well, I just looked up the code off my display and your right, I have a common cathode I bought as an undefined replacement for an old one that was included in a kit that is now living in another project, that one had a common anode. Well, the displaying is working as i think it should, lighting up correctly etc. now I'm not sure how that is possible? – Ashley Reid Jul 6 '18 at 20:23
0

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.

  • I have used 'millis()' / 'BlinkWithoutDelay' in other projects so understand that process. What I am looking at is just creating an interrupt with 5 flashes as the mode changes so normal delays are not an issue for me. The trouble I'm having is "comparing the current digit number" as you say or allocating the correct comPin for a digitalWrite LOW/HIGH sequence. Sorry, if my terminology is a bit off, i hope you inderstand what im getting at. – Ashley Reid Jul 6 '18 at 14:26
  • This line: writeData(num[bit[3 - i]]); - compare i with your selected digit, and if it matches then either run that line or don't depending on a "blink" variable controlled by millis(). – Majenko Jul 6 '18 at 14:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.