Κώδικας:
/*
7-Segment Display Multiplexing Countdown timer
Common cathode displays
max. countdown time 99:59 [min:sec]
Arduino Software (IDE) 1.8.1
Date: 22/02/2018
# kernel panik #
*/
/*
7-Segment Display map
AAA
F B
F B
GGG
E C
E C
DDD
*/
/*------------------------------------------------------------
Includes
------------------------------------------------------------*/
#include <EEPROM.h>
/*------------------------------------------------------------
Defines
------------------------------------------------------------*/
#define pinUP 11 // Button UP Countdown
#define pinDown 12 // Button Down Countdown
#define pinStart 13 // Button Start or STOP
#define PinPause A0 // Button Pause
#define btnUP 0 // For Buttons array
#define btnDown 1 // For Buttons array
#define btnStart 2 // For Buttons array
#define btnPause 3 // For Buttons array
#define UV_Leds 10 // output
#define Buzzer A1 // Buzzer pin out
#define BlinkDot 6 // Blink led COL. every second
#define SpeedSlow 250 // milliseconds
#define SpeedFast 1500 // milliseconds
#define SpeedDwnSec 1 //
#define BeepSec 6 // Beep for the last seconds
#define Debounce 20 // milliseconds
#define EEPRminute 0 // address of the EEPROM
#define EEPRsecond 1 // address of the EEPROM
// arduino pins for segments
#define A 4 // arduino pin out
#define B 2
#define C 5
#define D 8
#define E 9
#define F 7
#define G 3
#define DP 6
// arduino pins for digits
#define Dig1 A2 // arduino pin out
#define Dig2 A3
#define Dig3 A4
#define Dig4 A5
// Button debouncing globals
const byte Buttons[] = {pinUP, pinDown, pinStart, PinPause}; // create an array of pins for switch
const byte NumOFbtns = sizeof(Buttons);
boolean oldButtonLevels[18]; // 18
boolean stableButtonLevels[18]; //18
unsigned long ButtonTime, SpeedTime;
int Minute, Second, SpeedCount; //
//=== 7 segments leds =============================
// bits representing segments A through G (and decimal point) for numerals 0-9
const int Numera[21] = {
//ABCDEFG dp
B11111100, // 0
B01100000, // 1
B11011010, // 2
B11110010, // 3
B01100110, // 4
B10110110, // 5
B00111110, // 6
B11100000, // 7
B11111110, // 8
B11100110, // 9
B10110110, // S / 10
B10011110, // E / 11
B00011110, // t / 12
B01101110, // H / 13
B00001000, // i / 14
B11001110, // P / 15
B00000010, // - / 16
B00000000, // 17 - shows nothing
B00101010, // n / 18
B01111010, // d / 19
B00111010, // o / 20
};
const int segmentPins[] = {DP, G, F, E, D, C, B, A};
const int nbrDigits = 4; // the number of digits in the LED display
const int digitPins[nbrDigits] = { Dig1, Dig2, Dig3, Dig4};
/* notes in the melody
http://www.arduino.cc/en/Tutorial/Tone */
// int melody[] = {262, 196, 196, 220, 196, 0, 247, 262};
int melody[] = {4186, 3136, 3136, 3520, 3136, 0, 3951, 4186};
//note durations. 4=quarter note / 8=eighth note
int noteDurations[] = {4, 8, 8, 4, 4, 4, 4, 4};
boolean ON = HIGH;
boolean OFF = LOW;
boolean LastBeep;
/***********************
Timer interrupt
https://www.electronicsblog.net/examples-of-using-arduinoatmega-16-bit-hardware-timer-for-digital-clock/
************************/
ISR(TIMER1_OVF_vect) {
Second --;
LastBeep = true;
digitalWrite(BlinkDot, !digitalRead(BlinkDot));
TCNT1 = 0x0BDC; // 0x0BDC set initial value to remove time error (16bit counter register)
}
//=== setup =============================================================
void setup() {
/* make buttons as input */
for (byte index_BTN = 0; index_BTN < NumOFbtns; index_BTN++) {
pinMode(Buttons[index_BTN], INPUT_PULLUP);
}
for (int i = 0; i < 8; i++) {
pinMode (segmentPins[i], OUTPUT); // set segment and BlinkDot pins to output
for (int i = 0; i < nbrDigits; i++)
pinMode (digitPins[i], OUTPUT);
}
pinMode (Buzzer, OUTPUT);
pinMode (UV_Leds, OUTPUT);
digitalWrite (Buzzer, OFF);
digitalWrite (UV_Leds, OFF);
for (int i = 0; i < 50; i++) { // Hi
showDigit (13, 1); // H
showDigit (14, 2); // i
}
TIMSK1 = 0x01; // enabled global and timer overflow interrupt;
TCCR1A = 0x00; // normal operation (mode0);
TCNT1 = 0x0BDC; // 0x0BDC set initial value to remove time error (16bit counter register)
TCCR1B = 0x00; // set clock / start timer = 0x04; / stop 0x00;
Minute = EEPROM.read(EEPRminute); // read minute from address of the EEPROM
Second = EEPROM.read(EEPRsecond); // read second from address of the EEPROM
digitalWrite (BlinkDot, ON);
Beep_();
}//==Close setup =====
//==== loop ================================================================
void loop() {
//-- pinUP ---
if (getButtonStableEdge(Buttons[btnUP]) == true && getButtonStableLevel(Buttons[btnUP]) == LOW) {
Second ++;
ButtonTime = millis();
SpeedTime = millis();
while (digitalRead(pinUP) == LOW) {
if (Second > 59) {
Second = 00;
Minute ++;
}
if (Minute >= 100) {
Minute = 00;
}
if (millis() - ButtonTime > SpeedSlow) {
Second ++;
ButtonTime = millis();
if (millis() - SpeedTime > SpeedFast) {
Second += 29;
}
}
UpdateDisplay();
}//--Close while ----
}//==Close pinUP ====
//--- Down ----
if (getButtonStableEdge(Buttons[btnDown]) == true && getButtonStableLevel(Buttons[btnDown]) == LOW) {
if ((Minute == 0) && (Second == 0)) {
Second = 59;
Minute = 99;
}
else {
Second --;
}
if ((Second == -1) || (Second > 60)) {
Second = 59;
Minute --;
}
SpeedCount = SpeedSlow;
ButtonTime = millis();
SpeedTime = millis();
while (digitalRead(pinDown) == LOW) { //-- while --
if (millis() - SpeedTime > SpeedFast) {
SpeedCount = SpeedDwnSec;
}
if (millis() - ButtonTime > SpeedCount) {
if ((Second == 0) && (Minute == 0)) {
Minute = 99;
Second = 59;
}
else {
Second --;
}
if ((Second == -1) || (Second > 60)) {
Second = 59;
Minute --;
}
ButtonTime = millis();
}
UpdateDisplay();
}//--Close while ---
} //==Close Down ===
//--- Start | EEPROM | Pause | STOP ----
//--- Pause ----
if ((digitalRead(PinPause) == HIGH) && (getButtonStableEdge(Buttons[btnStart]) == true) && (getButtonStableLevel(Buttons[btnStart]) == LOW)) {
digitalWrite (UV_Leds, OFF);
TCCR1B = 0x00; // set clock -> start = 0x04; | stop = 0x00;
Pause();
delay(10);
}
//--- Start ---
if ((digitalRead(PinPause) == LOW) && (getButtonStableEdge(Buttons[btnStart]) == true) && (getButtonStableLevel(Buttons[btnStart]) == LOW)) {
boolean CountDwn = true;
//--- Store EEPROM only if different ---
if (EEPROM.read (EEPRminute) != Minute || EEPROM.read (EEPRsecond) != Second) {
digitalWrite (BlinkDot, OFF);
EEPROM.update (EEPRminute, Minute);
EEPROM.update (EEPRsecond, Second);
for (int i = 0; i < 50; i++) { // Display SEt
showDigit (10, 0); // S
showDigit (11, 1); // E
showDigit (12, 2); // t
}
} //--Close Store EEPROM -----
TCCR1B = 0x04; // set clock -> start = 0x04; | stop = 0x00;
digitalWrite (UV_Leds, ON);
Beep_();
//--- Countdown ----
while (CountDwn) {// wait
if (Minute == 0 && Second == 0) {
CountDwn = false;
}
if (Minute == 0 && Second < BeepSec && LastBeep == true) {
Beep_();
LastBeep = false;
}
if (Second < 0) {
Minute --;
Second = 59;
}
//--- Pause ----
if (getButtonStableEdge(Buttons[btnPause]) == true && getButtonStableLevel(Buttons[btnPause]) == HIGH) {
digitalWrite (UV_Leds, OFF);
TCCR1B = 0x00; // set clock -> start = 0x04; | stop = 0x00;
Pause();
TCCR1B = 0x04; // set clock -> start = 0x04; | stop = 0x00;
digitalWrite (UV_Leds, ON);
}//--Close Pause ----
//-- STOP ----
if (getButtonStableEdge(Buttons[btnStart]) == true && getButtonStableLevel(Buttons[btnStart]) == LOW) {
digitalWrite (UV_Leds, OFF);
TCCR1B = 0x00;
digitalWrite (BlinkDot, OFF);
for (int i = 0; i < 100; i++) {
showDigit (10, 0); // S
showDigit (12, 1); // t
showDigit (20, 2); // 0
showDigit (15, 3); // P
}
Minute = 0;
Second = 0;
}//--Close STOP ----
UpdateDisplay();
}//--Close while Countdown ----
digitalWrite (UV_Leds, OFF);
TCCR1B = 0x00;
digitalWrite (BlinkDot, OFF);
BuzMelody();
// End
boolean _end = true;
do {
showDigit (11, 0); // E
showDigit (18, 1); // n
showDigit (19, 2); // d
if (getButtonStableEdge(Buttons[btnStart]) == true && getButtonStableLevel(Buttons[btnStart]) == LOW) {
Minute = EEPROM.read(EEPRminute);
Second = EEPROM.read(EEPRsecond);
_end = false;
}
}
while (_end) ; // End
digitalWrite (BlinkDot, ON);
}//--Close Start | EEPROM | Pause | STOP ----
UpdateDisplay();
}//==Close loop =====
//=== Pause ==========================================
void Pause() {
digitalWrite (BlinkDot, OFF);
//-- Animation P --
while (digitalRead(PinPause) == HIGH) { //-- while --
for (int digit = nbrDigits - 1; digit >= 0; digit--) {
for (int i = 0; i < 40; i++) {
showDigit (15, digit); // P
}
}
for (int Dig = 1; Dig <= 2; Dig++) {
for (int i = 0; i < 40; i++) {
showDigit (15, Dig); // P
}
}
}//--Close while Animation P ---
}//==Close Pause =====
//=== UpdateDisplay ===================================
void UpdateDisplay() { // mmss
showDigit (Minute / 10, 0);
showDigit (Minute % 10, 1);
showDigit (Second / 10, 2);
showDigit (Second % 10, 3);
}//==Close UpdateDisplay ====
//=== showDigit ========================================
// Displays given number on a 7-segment display at the given digit position
void showDigit (byte number, byte digit) {
digitalWrite (digitPins[digit], HIGH );
for (int segment = 1; segment < 8; segment++) {
boolean isBitSet = bitRead(Numera[number], segment);
// isBitSet will be true if given bit is 1
// isBitSet = ! isBitSet; // if common anode display remove comment line
digitalWrite (segmentPins[segment], isBitSet);
}
delay(3);
digitalWrite (digitPins[digit], LOW );
}//==Close showDigit ====
//--- Buttons -----
//=== getButtonStableEdge ====================================
boolean getButtonStableEdge(byte Button_Pin) {
// Detects debounced edges (presses and releases) of a button
boolean previousLevel = stableButtonLevels[Button_Pin];
boolean newLevel = getButtonStableLevel(Button_Pin);
return previousLevel != newLevel;
}//==Close getButtonStableEdge ====
//=== getButtonStableLevel ====================================
byte getButtonStableLevel(byte Button_Pin) {
// Reads a digital pin and filters it, returning the stable button position
byte pinLevel = digitalRead(Button_Pin);
unsigned long lastStableButtonTime;
unsigned long currentTime = millis();
// If the button is rapidly changing (bouncing) during a press, keep
// resetting the last stable time count
if (pinLevel != oldButtonLevels[Button_Pin]) {
lastStableButtonTime = currentTime;
oldButtonLevels[Button_Pin] = pinLevel;
}
// Once the button has been stable for
if ((currentTime - lastStableButtonTime) > Debounce) {
stableButtonLevels[Button_Pin] = pinLevel;
}
return stableButtonLevels[Button_Pin];
}//==Close getButtonStableLevel ======
//--End Buttons ----
/* --- Buzzer Melody ----
http://www.arduino.cc/en/Tutorial/Tone */
//=== BuzMelody ====================================
void BuzMelody() {
//iterate over the notes of the melody
for (int thisNote = 0; thisNote < 8; thisNote++) {
//to calculate the note duration, take one second. Divided by the note type
int noteDuration = 1000 / noteDurations [thisNote];
tone(Buzzer, melody [thisNote], noteDuration);
//to distinguish the notes, set a minimum time between them
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
//stop the tone playing
noTone(Buzzer);
}
}//==Close BuzMelody ====
//=== Buzzer Beep ====================================
void Beep_() {
tone(Buzzer, 2489, 30);
delay(40);
noTone(Buzzer);
}//==Close Beep_ ======
/*********( THE END )***********/
έρχεται και ένα σχεδιάκι...