// Definice konstant pro tři sedmisegmentové displeje
const int bcdPins[] = {5, 4, 3, 2}; // Piny pro BCD vstupy (společné pro všechny čipy)
const int latchPin1 = 6; // Latch pin pro první CD4511 (jednotky odpočtu)
const int latchPin2 = 7; // Latch pin pro druhý CD4511 (desítky odpočtu)
const int latchPin3 = 8; // Latch pin pro třetí CD4511 (počet nízkých hodnot)
// Definice konstant pro čtení a vyhodnocení vstupů
const int analogPins[] = {A0, A1, A2, A3, A4}; // Analogové vstupy
const int modePin = A5; // Pin pro výběr režimu
const int digitalPins[] = {9, 10, 11, 12, 13}; // Digitální výstupy
const float threshold = 1.45; // Prahová hodnota ve voltech
const float modeThreshold = 2.5; // Prahová hodnota pro volbu režimu
// Proměnné pro BIATHLON režim
bool digitalOutputStates[5] = {false, false, false, false, false}; // Stav digitálních výstupů
int biathlonCount = 0; // Počet výstupů ve stavu HIGH
// Proměnné pro PETIBOJ režim
int petibojCount = 0; // Počet změn pod threshold na A2
int secondsElapsed = 0; // Čas od 0 do 50 sekund
// Proměnné pro časovač
unsigned long previousMillis = 0;
const unsigned long interval = 1000; // Interval 1 sekundy
// Proměnná pro aktuální režim
bool isPetibojMode = true; // Výchozí režim (PETIBOJ)
bool displayedModeInfo = false; // Indikátor, zda byla zobrazena informace o režimu
void setup() {
// Nastavení pinů pro BCD vstupy CD4511 jako výstupy
for (int i = 0; i < 4; i++) {
pinMode(bcdPins[i], OUTPUT);
}
// Nastavení pinů pro LATCH vstupy všech CD4511 jako výstupy
pinMode(latchPin1, OUTPUT);
pinMode(latchPin2, OUTPUT);
pinMode(latchPin3, OUTPUT);
// Inicializace LATCH pinů do hodnoty HIGH
digitalWrite(latchPin1, HIGH);
digitalWrite(latchPin2, HIGH);
digitalWrite(latchPin3, HIGH);
// Nastavení digitálních výstupů jako výstupy
for (int i = 0; i < 5; i++) {
pinMode(digitalPins[i], OUTPUT);
digitalWrite(digitalPins[i], LOW);
}
Serial.begin(9600); // Pro ladění
}
void loop() {
float modeVoltage = analogRead(modePin) * (5.0 / 1023.0); // Čtení napětí na pinu A5
// Rozlišení režimů na základě prahového napětí
bool currentModeIsPetiboj = (modeVoltage < modeThreshold);
// Pokud došlo ke změně režimu, zobrazit informaci o režimu
if (currentModeIsPetiboj != isPetibojMode || !displayedModeInfo) {
isPetibojMode = currentModeIsPetiboj;
displayModeInfo(isPetibojMode); // Zobrazení informace o zvoleném režimu
displayedModeInfo = true; // Nastavení indikátoru, že již byla informace zobrazena
}
// Spuštění příslušného režimu
if (isPetibojMode) {
petibojMode();
} else {
biathlonMode();
}
}
// Funkce pro zobrazení informace o zvoleném režimu
void displayModeInfo(bool isPetibojMode) {
unsigned long startMillis = millis();
bool displayOn = false;
while (millis() - startMillis < 10000) { // Po dobu 10 sekund
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= 500) { // Střídání stavu každých 0,5 s
previousMillis = currentMillis;
displayOn = !displayOn;
if (displayOn) {
if (isPetibojMode) {
// PETIBOJ: 5 na třetím displeji, 80 na displejích času
displayNumber(5, latchPin3);
displayNumber(0, latchPin1); // Jednotky času
displayNumber(8, latchPin2); // Desítky času
} else {
// BIATHLON: 8 na třetím displeji, 10 na displejích času
displayNumber(8, latchPin3);
displayNumber(0, latchPin1); // Jednotky času
displayNumber(1, latchPin2); // Desítky času
}
} else {
// Zhasnutí displejů
displayNumber(15, latchPin1);
displayNumber(15, latchPin2);
displayNumber(15, latchPin3);
}
}
}
}
// Funkce pro režim PETIBOJ
void petibojMode() {
static bool belowThreshold = false;
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval && secondsElapsed < 50 && petibojCount < 5) {
previousMillis = currentMillis;
secondsElapsed++;
int analogValue = analogRead(A2);
float voltage = analogValue * (5.0 / 1023.0);
if (voltage < threshold) {
belowThreshold = true;
} else if (belowThreshold) {
belowThreshold = false;
petibojCount++;
}
int tens = secondsElapsed / 10;
int ones = secondsElapsed % 10;
// Aktualizace displejů pro čas
displayNumber(ones, latchPin1);
displayNumber(tens, latchPin2);
}
if (secondsElapsed >= 50 || petibojCount >= 5) {
// Zachování posledního času a ukončení počítání
int tens = secondsElapsed / 10;
int ones = secondsElapsed % 10;
displayNumber(ones, latchPin1);
displayNumber(tens, latchPin2);
}
// Zobrazení počtu změn na třetím displeji
displayNumber(petibojCount, latchPin3);
}
// Funkce pro režim BIATHLON
void biathlonMode() {
int highCount = 0;
for (int i = 0; i < 5; i++) {
static bool belowThreshold[5] = {false, false, false, false, false};
int analogValue = analogRead(analogPins[i]);
float voltage = analogValue * (5.0 / 1023.0);
if (voltage < threshold) {
belowThreshold[i] = true;
} else if (belowThreshold[i]) {
belowThreshold[i] = false;
digitalOutputStates[i] = true;
digitalWrite(digitalPins[i], HIGH);
}
if (digitalOutputStates[i]) {
highCount++;
}
}
// Vypnutí displejů pro čas
displayNumber(15, latchPin1);
displayNumber(15, latchPin2);
// Zobrazení počtu aktivních výstupů na třetím displeji
displayNumber(highCount, latchPin3);
}
// Funkce pro zobrazení čísla na daném displeji
void displayNumber(int number, int latchPin) {
// Nastavení BCD hodnot na vstupy
for (int i = 0; i < 4; i++) {
digitalWrite(bcdPins[i], (number >> i) & 0x01);
}
// Aktivace latch pinu pro aktualizaci displeje
digitalWrite(latchPin, LOW);
delayMicroseconds(1); // Krátký impuls
digitalWrite(latchPin, HIGH);
}