/* EPOCH PROJECT#13-B: MULTIPLEXING THE 4-DIGIT 7-SEGMENT DISPLAY with VARIABLE DELAYS IN THIS PROJECT, WE'LL CONTROL ONE DIGIT OF THE DISPLAY, AND TURN IT ON AND OFF WITHOUT THE USE OF A LIBRARY. THIS IS SO THAT YOU CAN UNDERSTAND HOW THE DISPLAY WORKS. CONNECTIONS: MAKE ALL OF THE FOLLOWING CONNECTIONS TO CHIP-A CONNECT GPIO PINS 2/3/4/5/6/7/8/9 TO QUAD 7-SEGMENT DISPLAY PINS A/B/C/D/E/F/G/DOT RESPECTIVELY CONNECT GPIO PIN 10 TO QUAD 7-SEGMENT CHANNEL 1 DISPLAY PIN 10 CONNECT GPIO PIN 10 TO QUAD 7-SEGMENT CHANNEL 2 DISPLAY PIN 11 CONNECT GPIO PIN 10 TO QUAD 7-SEGMENT CHANNEL 3 DISPLAY PIN 12 CONNECT GPIO PIN 10 TO QUAD 7-SEGMENT CHANNEL 4 DISPLAY PIN 13 CONNECT THE "POTA" PIN TO THEA3 PIN ON CHIP-A */ #define pina 2 // THESE PINS CONTROL SEGMENTS 1A-G, AND DOT #define pinb 3 #define pinc 4 #define pind 5 #define pine 6 #define pinf 7 #define pinG 8 #define pindot 9 #define control1 10 // This pin will be used to turn display 1 on and off #define control2 11 // This pin will be used to turn display 2 on and off #define control3 12 // This pin will be used to turn display 3 on and off #define control4 13 // This pin will be used to turn display 4 on and off int seg1 = 0; // THIS IS THE NUMBER THAT THE SEGMENT IS HOLDING IN THE COUNTDOWN SEQUENCE. SEGMENT 1 IS THE RIGHT MOST DIGIT, AND SEGMENT 4 IS THE LEFT MOST // IF THE TIMER IS 05:00, SEG1, SEG2, AND SEG 4 ARE 0, AND SEG5 = 5; int seg2 = 0; int seg3 = 0; int seg4 = 0; int segnum = 0; // THIS IS USED IN THE DECODER FUNCTION, AND TELLS THE PROGRAM WHICH SEGMENT TO LOOK AT int counter = 0; // THIS IS USED FOR MULTIPLEXING int hold = 0; // THIS INTEGER HOLDS DATA TEMPORARILY int trigger = 0; // THIS INTEGER IS USED TO TELL THE PROGRAM WHEN TIME HAS RUN OUT 00:00 int timehold = 0; // THIS INTEGER WILL HOLD THE ANALOG TO DIGITAL VALUE (0-1023) FROM THE VARIBALE RESISTOR (POTA) /* BELOW IS A DIAGRAM OF THE SEGMENTS AND THE DOT ON THE LOWER RIGHT SIDE. pina CONTROLS THE "A" SEGMENT. WHEN THE pina GPIO PIN IS SET LOW (0V) THE "A" SEGMENT WILL TURN ON A ---- F| |B | G | ---- E| |C | D | ---- O DOT */ void setup() { pinMode(pina,OUTPUT); // DECLARE ALL PINS AS OUTPUTS pinMode(pinb,OUTPUT); pinMode(pinc,OUTPUT); pinMode(pind,OUTPUT); pinMode(pine,OUTPUT); pinMode(pinf,OUTPUT); pinMode(pinG,OUTPUT); pinMode(pindot,OUTPUT); pinMode(control1,OUTPUT); pinMode(control2,OUTPUT); pinMode(control3,OUTPUT); pinMode(control4,OUTPUT); seg4 = 0; // LEFT MOST SEGMENT DATA (10 MINITE DIGIT DATA seg3 = 5; // SECOND FROM THE LEFT SEGMENT DATA SET TO 5 MINUTES seg2 = 0; // 10 SECOND DIGIT DATA seg1 = 0; // 1 SECOND DIGIT DATA } void loop() { counter = 250; // WE WILL PERFORM THE FOLLOWING 250 TIMES. THIS TEAMS THAT WE'LL BE TURNING ALL FOUR SEGMENTS ON AND OFF ONE AT A TIME. 250 X (1ms x 4 SEGMENTS (20ms) = 1000ms = 1 SECOND). THIS MEANS WE'LL COUNT DOWN THE TIMER ONE SECOND AT A TIME. while(counter > 0){ // PERFORM THE FOLLOWING CODE OVER AND OVER UNTIL THE VALUE IN "counter" EQUALS 250 { digitalWrite(control1,HIGH); // TURN ON THE RIGHT MOST SEGMENT segnum = 1; // THE VALUE IN signum TELLS THE PROGRAM WHICH SEGMENT TO ACTIVATE IN THE UPCOMING "decoder()" FUNCTION. 1 = RIGHT MOST SEGMENT, AND 4 IS LEFT MOST SEGMENT decoder(); // CALL THE DECODER FUNCTION. LOOK BELOW TO SEE HOW THIS FUNCTION WORKS hold = analogRead(3); // SAMPLE POTA delay(hold); // USE THAT ANALOG TO DIGITAL VALUE (0v = 0, 5V = 1023, AND ANY VALUE IN BETWEEN AS THE DELAY digitalWrite(control1,LOW); // TURN THIS SEGMENT OFF digitalWrite(control2,HIGH); // TURN THE NEXT SEGMENT ON segnum = 2; // THE BELOW CODE IS THE SAME AS ABOVE, ONLY WE'RE CONTROLLING DIFFERENT SEGMENTS decoder(); hold = analogRead(3); // SAMPLE POTA delay(hold); // USE THAT ANALOG TO DIGITAL VALUE (0v = 0, 5V = 1023, AND ANY VALUE IN BETWEEN AS THE DELAY digitalWrite(control2,LOW); digitalWrite(control3,HIGH); segnum = 3; decoder(); hold = analogRead(3); // SAMPLE POTA delay(hold); // USE THAT ANALOG TO DIGITAL VALUE (0v = 0, 5V = 1023, AND ANY VALUE IN BETWEEN AS THE DELAY digitalWrite(control3,LOW); digitalWrite(control4,HIGH); segnum = 4; decoder(); hold = analogRead(3); // SAMPLE POTA delay(hold); // USE THAT ANALOG TO DIGITAL VALUE (0v = 0, 5V = 1023, AND ANY VALUE IN BETWEEN AS THE DELAY digitalWrite(control4,LOW); counter = counter - 1; // ONCE ALL FOUR SEGMENTS HAVE BEEN TURNED ON AND OFF 25 TIMES, "counter" WILL EQUAL 0. WHEN THIS HAPPENS, WE'LL CALL THE "decrement()" FUNTION, WHICH DEGREMENTS THE COUNTDOWN TIMER } } decrement(); // CALL THE DECREMENT FUNCTION } void decoder() // IN THIS FUNCTION, WE'LL DECREMENT THE COUNTDOWN TIMER { if(segnum == 1) // IF segnum EQUALS 1, THEN MAKE CHANGES TO THE LEFT MOST SEGMENT. IF signum IS ANY NUMBER OTHER THAN 1, THEN THE FOLLOWING CODE WILL BE IGNORED. { hold = seg1; // PLACE THE CONTENTS IN THE seg1 INTEGER, AND PLACE IT IN THE hold INTEGER. number(); // CALL THE number FUNCTION. THIS FUNCTION TURNS THE RELATIVE A-G AND DOT SEGMENTS TO TURN ON } else if(segnum == 2) // IF segnum EQUALS 1, THEN MAKE CHANGES TO THE LEFT MOST SEGMENT. THE REST OF THIS FUNCTION IS THE SAME AS ABOVE, ONLY DIFFERENT SEGMENTS ARE CONTROLLED. { hold = seg2; number(); } else if(segnum == 3) { hold = seg3; number(); digitalWrite(pindot,LOW); // ADD A DECIMAL POINT TO SEPARATE MINUTES FROM SECONDS. } else { hold = seg4; number(); } } void number() // ANOTHER DECODING FUNCTION. REMEMBER WHEN WE PLACED THE seg1-4 VALUES INTO THE hold INTEGER? WE'LL USE THAT NUMBER TO CALL THE RIGHT SEGMENT DATA. { if(hold == 0) // IF hold EQUALS 0, THEN CALL THE zero() FUNCTION. THE REST OF THIS FUNCTION SHOULD BE PRETTY CLEAR. IF hold = 5, THEN WE'LL CALL "five()" { zero(); } if(hold == 1) { one(); } if(hold == 2) { two(); } if(hold == 3) { three(); } if(hold == 4) { four(); } if(hold == 5) { five(); } if(hold == 6) { six(); } if(hold == 7) { seven(); } if(hold == 8) { eight(); } if(hold == 9) { nine(); } } void decrement() // ONE LAST DECODING FUNCTION. FIRST WE'LL CALL ANOTHER FUNCTION THAT CHECKS TO SEE IF seg1 THROUGH seg4 DATA ARE ALL ZEROs. IF THEY ARE, THEN "trigger" CHANGES FROM 0 TO 1, AND THE TIMER IS RESTARTED { allzeros(); // CALL THE allzeros(); FUNCTION. IF seg1 THROUGH seg4 DATA ARE ALL ZEROS, RESTART THE TIMER AND SET IT TO 5 MINUTES. YOU CAN PLAY WITH THESE TIMES IF YOU'D LIKE. if(trigger == 1) { seg1 = 0; seg2 = 0; seg3 = 5; // Restart the 5 minute timer seg4 = 0; } else // THE FOLLOWING IS EXECUTED IF TRIGGER DID NOT EQUAL 1, IT MEANS THAT THERE'S STILL TIME LEFT ON THE TIMER. BY THIS, I MEAN THAT ANY OF THE FOLLOWING (seg1, segt2, seg3, AND seg4) HOLD A VALUE HIGHER THAN 0. { if(seg1 > 0) // THIS IS A SOMEWHAT COMPLICATED DECODER SEQUENCE. TRY TO FOLLOW ALONG. EXECUTE THE FOLLOWING IF THE seg1 INTEGER HOLDS A VALUE HIGHER THAN 0 { seg1 = seg1 - 1; // SUBTRACT (DECREMENT) A VALUE OF 1 FROM THE seg1 INTEGER. IF THIS HAPPENS, THEN THE CODE RETURNS FROMHERE. THE REST OF THE CODE IS NOT EXECUTED. } else // IF seg1 DID HOLD A VALUE OF 0, THEN WE'LL DECREMENT A VALUE OF 1 FROM seg2 (THE TENS DIGIT), AND WE'LL SET seg1 BACK TO 9 { seg1 = 9; // SEG seg1 TO 9 if(seg2 > 0) // BEFORE WE REMOVE 1 FROM seg2, WE NEED TO SEE IF IT IS ALREADY 0. IF seg2 IS HIGHER THAN 0, THEN SIMPLY SUBTRACT 1 FROM seg2, AND WE'LL BE DONE WITH THIS FUNCTION. IF seg2 IS IN FACT 0, THEN WE HAVE MORE TO DO. { seg2 = seg2 - 1; // SUBTRACT 1 FROM seg2. IF THIS HAPPENS, THEN THE CODE RETURNS FROMHERE. THE REST OF THE CODE IS NOT EXECUTED. } else // IF seg2 WAS IN FACT 0, THEN DO THE FOLLOWING { seg2 = 5; // SET seg2 TO 5. WHY? BECAUSE THE TENS DIGIT IS NEVER HIGHER THAN 5. FOR INSTANCE: 29:59. IF WE'RE COUNTING DOWN IN MINUTES, THEN THIS DIGIT NEEDS TO NEVER BE HIGHER THAN 5. (SEGMENT FROM THE RIGHT = seg2) if(seg3 > 0) // WE NOW NEED TO SEE IF seg3 IS HIGHER THAN 0. IF IT IS, SUBRTACT 1 FROM seg3, AND WE'RE DONE WITH THIS FUNCTION. { seg3 = seg3 - 1; // SUBTRACT 1 FROM seg3. IF THIS HAPPENS, THEN THE CODE RETURNS FROMHERE. THE REST OF THE CODE IS NOT EXECUTED. } else // IF seg3 WAS IN FACT 0, THEN SET seg3 TO 9, AND REMOVE 1 FROM seg4. { seg3 = 9; // SET seg3 TO 9. seg4 = seg4 - 1; // SUBTRACT 1 FROM seg4. WE DON'T NEED TO SEE IF SEG4 IS 0 BECAUSE THAT IS LOOKED AFTER DURING THE allzeros(); FUNCTION ABOVE. IF seg4 WAS JUST SUBTRACTED DOWN TO 0, THEN seg1-4 WILL BE 0000 WHEN THIS FUNCTION IS NEXT CALLED, // AND THE allzeros() FUNCTION WILL SEE THAT. } } } } } void allzeros() // THIS FUNCTION DETERMINES IF TIME HAS RUN OUT { trigger = 0; // SET trigger TO 0 if(seg1 == 0) // CHECK ALL INTEGERS (seg1 THROUGH seg4). IF THEY'RE ALL 0, SET trigger TO 1. THIS WILL INDICATE TO THE SOFTWARE THAT TIME HAS RUN OUT. { if(seg2 == 0) { if(seg3 == 0) { if(seg4 == 0) { trigger = 1; } } } } } // THE FOLLOWING FUNCTIONS ACT TO DISPLAY A NUMBER ON A DISPLAY THAT IS TURNED ON. void zero() { off(); // CALL THE "off()" FUNCTION WHICH YOU CAN FIND BELOW. IT TURNS ALL OF THE SEGMENTS OFF. digitalWrite(pina,LOW); digitalWrite(pinb,LOW); digitalWrite(pinc,LOW); digitalWrite(pind,LOW); digitalWrite(pine,LOW); digitalWrite(pinf,LOW); digitalWrite(pinG,HIGH); // BY SETTING A SEGMENT PIN LOW, YOU TURN IT ON. BY SETTING IT HIGH, YOU TURN SAID SEGMENT OFF. digitalWrite(pindot,HIGH); // dot IS THE DECIMAL SEGMENT } void one() { off(); digitalWrite(pina,HIGH); digitalWrite(pinb,LOW); digitalWrite(pinc,LOW); digitalWrite(pind,HIGH); digitalWrite(pine,HIGH); digitalWrite(pinf,HIGH); digitalWrite(pinG,HIGH); digitalWrite(pindot,HIGH); } void two() { off(); digitalWrite(pina,LOW); digitalWrite(pinb,LOW); digitalWrite(pinc,HIGH); digitalWrite(pind,LOW); digitalWrite(pine,LOW); digitalWrite(pinf,HIGH); digitalWrite(pinG,LOW); digitalWrite(pindot,HIGH); } void three() { off(); digitalWrite(pina,LOW); digitalWrite(pinb,LOW); digitalWrite(pinc,LOW); digitalWrite(pind,LOW); digitalWrite(pine,HIGH); digitalWrite(pinf,HIGH); digitalWrite(pinG,LOW); digitalWrite(pindot,HIGH); } void four() { off(); digitalWrite(pina,HIGH); digitalWrite(pinb,LOW); digitalWrite(pinc,LOW); digitalWrite(pind,HIGH); digitalWrite(pine,HIGH); digitalWrite(pinf,LOW); digitalWrite(pinG,LOW); digitalWrite(pindot,HIGH); } void five() { off(); digitalWrite(pina,LOW); digitalWrite(pinb,HIGH); digitalWrite(pinc,LOW); digitalWrite(pind,LOW); digitalWrite(pine,HIGH); digitalWrite(pinf,LOW); digitalWrite(pinG,LOW); digitalWrite(pindot,HIGH); } void six() { off(); digitalWrite(pina,LOW); digitalWrite(pinb,HIGH); digitalWrite(pinc,LOW); digitalWrite(pind,LOW); digitalWrite(pine,LOW); digitalWrite(pinf,LOW); digitalWrite(pinG,LOW); digitalWrite(pindot,HIGH); } void seven() { off(); digitalWrite(pina,LOW); digitalWrite(pinb,LOW); digitalWrite(pinc,LOW); digitalWrite(pind,HIGH); digitalWrite(pine,HIGH); digitalWrite(pinf,HIGH); digitalWrite(pinG,HIGH); digitalWrite(pindot,HIGH); } void eight () { off(); digitalWrite(pina,LOW); digitalWrite(pinb,LOW); digitalWrite(pinc,LOW); digitalWrite(pind,LOW); digitalWrite(pine,LOW); digitalWrite(pinf,LOW); digitalWrite(pinG,LOW); digitalWrite(pindot,HIGH); } void nine() { off(); digitalWrite(pina,LOW); digitalWrite(pinb,LOW); digitalWrite(pinc,LOW); digitalWrite(pind,HIGH); digitalWrite(pine,HIGH); digitalWrite(pinf,LOW); digitalWrite(pinG,LOW); digitalWrite(pindot,HIGH); } void off() // BY SETTING ALL PINS TO HIGH, ALL SEGMENTS ARE TURNED OFF { digitalWrite(pina,HIGH); digitalWrite(pinb,HIGH); digitalWrite(pinc,HIGH); digitalWrite(pind,HIGH); digitalWrite(pine,HIGH); digitalWrite(pinf,HIGH); digitalWrite(pinG,HIGH); digitalWrite(pindot,HIGH); } void on() // THIS FUNCTION TURNS ALL OF THE SEGMENTS ON. WE DON'T USE THIS FUNCTION IN THE ABOVE CODE. IT IS HERE IN CASE WE WANT IT. { off(); digitalWrite(pina,LOW); digitalWrite(pinb,LOW); digitalWrite(pinc,LOW); digitalWrite(pind,LOW); digitalWrite(pine,LOW); digitalWrite(pinf,LOW); digitalWrite(pinG,LOW); digitalWrite(pindot,LOW); } /* NOTES * THIS CODE IS THE MOST COMPLICATED YET. THJERE'S A LOT OF DECODING, AND A TON OF FUNCTIONS. PLAY AROUND IWTH THE CODE A BIT. IF IT DOESN'T CLICK RIGHT AWAY, DON'T WORRY. THIS IS A MORE COMPLICATED PROGRAM, AND LEARNING THIS STUFF TAKES TIME. * PLAY AROUND WITH THE seg1 THROUGH seg4 INTEGERS AT THE BEGINNING OF THE CODE, AND IN THE "decrement" FUNCTION * THERE ARE FOUR 5ms DELAYS IN VOID LOOP(). ONE SEGMENT IS TURNED ON, THE RELATIVE SEGMENT DATA IS DISPLAYED FOR 5ms, THEN TURNED OFF. THEN THE NEXT TURNS ON AND UPDATED FOR 5ms, ETC ETC. TRY CHANGING THESE delays TO 200ms AND SEE WHAT HAPPENS. * NEXT TRY CHANGING THE DELAY BACK TO 5ms AND CHANGE THE VALUE IN counter TO 5. NOTE YOUR FINDINGS. NEXT TRY CHANGING counter TO 100. PLAY WITH THE CODE! * READ THE COMMENTS. I'M COMMENGING SO MUCH BECAUSE THERE'S IMPORTANT THOUGHTS AND IDEAS GOING ON IN EVERY FUNCTION */