#include <WiFi.h>
#include <PubSubClient.h>
#define load 25 // 74HC165 PL
#define clock 26 // Ortak clock pini
#define dataIn 27 // 74HC165 Q7
#define latch 32 // 74HC595 ST_CP
#define dataOut 33 // 74HC595 DS
const char* ssid = "Wokwi-GUEST";
const char* password = "";
const char* mqtt_server = "test.mosquitto.org";
const int mqtt_port = 1883;
WiFiClient espClient;
PubSubClient client(espClient);
uint32_t lastSwitchPress = 0;
uint32_t outputsUpdate = 0;
void setup() {
Serial.begin(115200);
pinMode(load, OUTPUT);
pinMode(clock, OUTPUT);
pinMode(dataIn, INPUT);
pinMode(latch, OUTPUT);
pinMode(dataOut, OUTPUT);
WiFi.begin(ssid, password);
Serial.print("WiFi bağlanıyor");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi Bağlandı");
client.setServer(mqtt_server, mqtt_port);
client.setCallback(callback); // 📩 Gelen MQTT mesajlarını işle
reconnectMQTT();
}
void loop() {
if (!client.connected()) {
reconnectMQTT();
}
client.loop(); // MQTT mesajlarını dinle
SN74165Control(); // Butonları oku ve MQTT'ye gönder
}
void reconnectMQTT() {
while (!client.connected()) {
Serial.print("MQTT tekrar bağlanıyor...");
if (client.connect("ESP32Client_165to595")) {
Serial.println("MQTT Bağlantısı Kuruldu.");
client.subscribe("relay/outputs"); // 🟢 Giriş olarak kullanılacak MQTT başlığı
} else {
Serial.print("Bağlantı hatası, kod: ");
Serial.println(client.state());
delay(2000);
}
}
}
// 📩 MQTT'den gelen mesajı işle
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("MQTT mesajı alındı [");
Serial.print(topic);
Serial.print("] : ");
char msg[30] = {0};
for (unsigned int i = 0; i < length && i < 29; i++) {
msg[i] = (char)payload[i];
}
msg[length] = '\0';
Serial.println(msg);
if (strcmp(topic, "relay/outputs") == 0) {
uint32_t outputVal = strtoul(msg, NULL, 10); // Sayıya çevir
outputsUpdate = outputVal; // Local değişkeni güncelle
digitalWrite(latch, LOW);
shift24Out(dataOut, clock, MSBFIRST, outputsUpdate);
digitalWrite(latch, HIGH);
Serial.print("74HC595 Güncellendi: ");
Serial.println(outputVal, BIN);
// 🔁 Röle durumu feedback olarak geri gönderiliyor
char feedback[50];
sprintf(feedback, "%lu", outputsUpdate);
client.publish("relay/status", feedback); // <-- Geri bildirim
}
}
void SN74165Control() {
static uint32_t previousButtons = 0;
if (millis() - lastSwitchPress > 100) {
digitalWrite(load, LOW);
delayMicroseconds(5);
digitalWrite(load, HIGH);
uint32_t currentButtons = shift24In(dataIn, clock, MSBFIRST);
uint32_t changed = currentButtons ^ previousButtons; // Değişen bitleri bul
uint32_t pressed = changed & currentButtons; // YENİ basılanlar
if (pressed) {
outputsUpdate ^= pressed; // Toggle et
digitalWrite(latch, LOW);
shift24Out(dataOut, clock, MSBFIRST, outputsUpdate);
digitalWrite(latch, HIGH);
Serial.print("Yeni çıkış durumu: ");
Serial.println(outputsUpdate, BIN);
char msg[50];
sprintf(msg, "%lu", outputsUpdate);
client.publish("relay/inputs", msg);
// 🔁 Röle durumu ayrıca "relay/status" başlığına da gönderiliyor
client.publish("relay/status", msg);
}
previousButtons = currentButtons;
lastSwitchPress = millis();
}
}
uint32_t shift24In(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder) {
uint32_t value = 0;
for (int i = 0; i < 24; i++) {
if (bitOrder == LSBFIRST)
value |= ((uint32_t)digitalRead(dataPin) << i);
else
value |= ((uint32_t)digitalRead(dataPin) << (23 - i));
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW);
}
return value;
}
void shift24Out(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint32_t val) {
for (int i = 0; i < 24; i++) {
if (bitOrder == LSBFIRST)
digitalWrite(dataPin, !!(val & (1 << i)));
else
digitalWrite(dataPin, !!(val & (1 << (23 - i))));
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW);
}
}