const int NUM_BYTES = 5;
// 74HC165 - PRZYCISKI (BUTTONS)
const int BTN_SL = 3; // sr16:PL
const int BTN_CK = 15; // sr16:CP
const int BTN_DI = 23; // sr16:Q7
// 74HC165 - POTWIERDZENIE (FEEDBACK)
const int FEED_SL = 12; // sr11:PL
const int FEED_CK = 13; // sr11:CP
const int FEED_DI = 1; // sr11:Q7
// 74HC595 - PRZEKAŹNIKI (RELAY)
const int RELAY_CLOCK = 19; // sr10:SHCP (shift clock)
const int RELAY_LATCH = 18; // sr10:STCP (latch clock)
const int RELAY_DATA = 20; // sr10:DS
// 74HC595 - DIODY LED
const int LED_CLOCK = 4; // sr1:SHCP
const int LED_LATCH = 5; // sr1:S
const int LED_DATA = 0; // sr5:
const int BUZZER_PIN = 22;
/*
0, 1, 3, 4, 5, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23
*/
// Tablice danych (40 bitów każda)
byte buttonData[NUM_BYTES]; // Surowy odczyt z przycisków
byte lastButtonState[NUM_BYTES]; // Do detekcji kliknięcia
byte relayState[NUM_BYTES]; // Stan bistabilny przekaźników
byte feedbackData[NUM_BYTES]; // Odczyt feedbacku z A2
// Mikrosekundy dla ESP32-C6
const int pulseDelay = 5;
void setup() {
Serial.begin(115200);
while (!Serial) {
delay(10);
}
Serial.println("START");
pinMode(BTN_SL, OUTPUT);
pinMode(BTN_CK, OUTPUT);
pinMode(BTN_DI, INPUT);
pinMode(LED_LATCH, OUTPUT);
pinMode(LED_CLOCK, OUTPUT);
pinMode(LED_DATA, OUTPUT);
pinMode(FEED_SL, OUTPUT);
pinMode(FEED_CK, OUTPUT);
pinMode(FEED_DI, INPUT);
pinMode(RELAY_LATCH, OUTPUT);
pinMode(RELAY_CLOCK, OUTPUT);
pinMode(RELAY_DATA, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
digitalWrite(BUZZER_PIN, LOW);
digitalWrite(BTN_SL, HIGH);
digitalWrite(FEED_SL, HIGH);
Serial.println("System ESP32-C6");
}
void loop() {
// 1. ODCZYT PRZYCISKÓW
digitalWrite(BTN_SL, LOW);
delayMicroseconds(pulseDelay);
digitalWrite(BTN_SL, HIGH);
delayMicroseconds(pulseDelay);
for (int i = NUM_BYTES - 1; i >= 0; i--) {
for (int j = 0; j < 8; j++) {
int bit = digitalRead(BTN_DI);
bitWrite(buttonData[i], j, bit);
digitalWrite(BTN_CK, HIGH);
delayMicroseconds(pulseDelay);
digitalWrite(BTN_CK, LOW);
delayMicroseconds(pulseDelay);
}
}
// 2. LOGIKA BISTABILNA
for (int i = 0; i < NUM_BYTES; i++) {
for (int j = 0; j < 8; j++) {
bool isPressed = bitRead(buttonData[i], j);
bool wasPressed = bitRead(lastButtonState[i], j);
// Jeśli wciśnięto (zbocze narastające)
if (isPressed && !wasPressed) {
// 1. Zmiana stanu
bool newState = !bitRead(relayState[i], j);
bitWrite(relayState[i], j, newState);
if (newState == true) {
tone(BUZZER_PIN, 2500, 15);
} else {
tone(BUZZER_PIN, 2000, 15);
}
int buttonNumber = (i * 8) + j;
Serial.print("Kanal ");
Serial.print(buttonNumber);
Serial.println(newState ? " -> ON" : " -> OFF");
}
}
// Zapamiętaj stan
lastButtonState[i] = buttonData[i];
}
// 3. WYSYŁANIE DO PRZEKAŹNIKÓW
digitalWrite(RELAY_LATCH, LOW);
for (int i = 0; i < NUM_BYTES; i++) {
shiftOut(RELAY_DATA, RELAY_CLOCK, LSBFIRST, relayState[i]);
}
digitalWrite(RELAY_LATCH, HIGH);
// 4. ODCZYT FEEDBACKU
digitalWrite(FEED_SL, LOW);
delayMicroseconds(pulseDelay);
digitalWrite(FEED_SL, HIGH);
for (int i = NUM_BYTES - 1; i >= 0; i--) {
feedbackData[i] = shiftIn(FEED_DI, FEED_CK, LSBFIRST);
}
// 5. WYSYŁANIE NA LED
digitalWrite(LED_LATCH, LOW);
for (int i = 0; i < NUM_BYTES; i++) {
// LEDy pokazują to, co fizycznie odczytał feedback w A2
shiftOut(LED_DATA, LED_CLOCK, LSBFIRST, feedbackData[i]);
}
digitalWrite(LED_LATCH, HIGH);
// Odświeżanie ~100Hz wystarczy
delay(10);
}DS: dataPin (cyan)
CP / SHCP: clockPin (yellow)
PL / STCP: latchPin (magenta)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
1 ... 2 ... 3 ... 4 ... 5 ... 6 ... 7 ... 8 ... 9 ... 10
11 . 12 .13 . 14 . 15 .16 . 17 . 18 .19 . 20
21 . 22 .23 . 24 . 25 .26 . 27 . 28 .29 . 30
31 . 32 .33 . 34 . 35 .36 . 37 . 38 .39 . 40
RELAY 1
RELAY 40