// Define Connections to 74HC165
int load = 7;
int clockEnablePin = 4;
int dataIn = 5;
int clockIn = 6;
// Define Connections to 74HC595
const int latchPin = 10;
const int clockPin = 11;
const int dataPin = 12;
const int inputPin = 8; // Pin für den Taster
// Maximale Anzahl an Schieberegistern
const int maxRegisters = 8; // Bis zu 8 Register = 64 Bits
unsigned long previousState = 0;
unsigned long value = 0;
int a = 0;
// NTC
const float BETA = 3950;
int analogValue = 0;
void setup() {
Serial.begin(9600);
// 74HC165 pins
pinMode(load, OUTPUT);
pinMode(clockEnablePin, OUTPUT);
pinMode(clockIn, OUTPUT);
pinMode(dataIn, INPUT);
// 74HC595 pins
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(inputPin, INPUT_PULLUP); // Eingangs-Pin für Taster
// Servo
pinMode(3, OUTPUT); // Servo-Pin
}
void loop() {
analogWrite(3, 200); // Servo auf eine Position bewegen (angepasste Werte)
delay(1000);
analogWrite(3, 64); // Servo auf andere Position bewegen
delay(1000);
int detectedRegisters;
int detectedRegisters2;
if(a!=1){
// Erkennung der Anzahl der angeschlossenen Register
detectedRegisters = detectRegisters();
detectedRegisters2 = detectRegisters2();
// Wenn keine aktiven Register erkannt wurden
if (detectedRegisters == 0) {
Serial.println("Keine aktiven Eingangs-Register erkannt.");
return;
}
// Zeige die Anzahl der erkannten Register
Serial.print("Erkannte Eingangs-Register: ");
Serial.println(detectedRegisters);
if (detectedRegisters2 == 0) {
Serial.println("Keine aktiven Ausgangs-Register erkannt.");
return;
}
// Zeige die Anzahl der erkannten Register
Serial.print("Erkannte Ausgangs-Register: ");
Serial.println(detectedRegisters2);
a = 1;
}
// Verarbeite die Daten der Schieberegister
processShiftRegisterData(detectedRegisters,detectedRegisters2);
analogValue = analogRead(A0);
float celsius = 1 / (log(1 / (1023. / analogValue - 1)) / BETA + 1.0 / 298.15) - 273.15;
Serial.println(celsius);
delay(500); // Eine kurze Pause zwischen den Messungen
}
// Funktion zur Erkennung der Anzahl der angeschlossenen Register
int detectRegisters() {
int detectedRegisters = 0;
// Write pulse to load pin
digitalWrite(load, LOW);
delayMicroseconds(5);
digitalWrite(load, HIGH);
delayMicroseconds(5);
// Get data from 74HC165
digitalWrite(clockIn, HIGH);
digitalWrite(clockEnablePin, LOW);
// Lese nacheinander die Schieberegister aus
for (int i = 0; i < maxRegisters; i++) {
byte incoming = shiftIn(dataIn, clockIn, LSBFIRST); // Lese 8 Bit (1 Register)
// Wenn das Register nicht alle 1er hat (was in der Regel am Anfang der Kette kommt),
// brechen wir die Erkennung ab.
if (incoming != 0xFF) {
detectedRegisters = i + 1; // Register erkannt
} else {
break; // Stoppe, wenn kein aktives Register mehr gefunden wird
}
}
digitalWrite(clockEnablePin, HIGH);
return detectedRegisters;
}
int detectRegisters2(){
int detectedRegisters = 0;
//Serial.println("Beginne mit der Überprüfung der Register...");
for (int i = 0; i < maxRegisters; i= i+8) { // Maximale Anzahl an Registern (8)
// Sende ein Kontrollbyte, das nur das entsprechende Bit für das aktuelle Register setzt
byte check = (1 << i); // Setze nur das i-te Bit HIGH
//Serial.print("Sende Kontrollbyte: 0b");
// Serial.println(check, BIN); // Ausgabe des gesendeten Kontrollbytes in binärer Form
//Serial.print("Finaler Wert von check (binär): ");
//for (int j = 15 - 1; j >= 0; j--) {
//Serial.print((check >> j) & 0x01);
//}
//Serial.println(); // Zeilenumbruch nach der Ausgabe
// Sende das Check-Bit an das Schieberegister
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, check);
digitalWrite(latchPin, HIGH);
// Überprüfe den Status des Q0-Pins
if (digitalRead(inputPin) == HIGH) {
detectedRegisters++; // Erhöhe den Zähler, wenn Q0 HIGH ist
/*Serial.print("Register ");
Serial.print(i);
Serial.println(" erkannt. Q0 ist HIGH.");*/
}
/*
// Zeige die aktuelle Ausgabe in binärer Form an
Serial.print("Aktuelle Ausgabe des Schieberegisters: 0b");
byte outputState = check; // Zustand des aktuell gesendeten Bytes
Serial.println(outputState, BIN); // Zeige die Bits des gesendeten Bytes*/
return detectedRegisters;
}
}
// Funktion, um die Daten der erkannten Register zu verarbeiten
void processShiftRegisterData(int numRegisters, int numRegisters2) {
unsigned long incoming = 0;
unsigned long incoming2;
byte data[numRegisters];
// Write pulse to load pin
digitalWrite(load, LOW);
delayMicroseconds(5);
digitalWrite(load, HIGH);
delayMicroseconds(5);
// Get data from 74HC165
digitalWrite(clockIn, HIGH);
digitalWrite(clockEnablePin, LOW);
for (int i = 0; i < numRegisters; i++) {
data[i] = shiftIn(dataIn, clockIn, LSBFIRST);
incoming |= ((unsigned long)data[i]) << (i * 8); // Kombiniere die Daten zu einem Long
}
digitalWrite(clockEnablePin, HIGH);
// Zeige den aktuellen Zustand aller Bits an
int totalBits = numRegisters * 8; // Bestimmen der Gesamtanzahl an Bits
int totalBits2 = numRegisters2 * 8;
Serial.print("Aktueller Zustand (");
Serial.print(totalBits);
Serial.println(" Bits): ");
for (int i = totalBits - 1; i >= 0; i--) {
int byteIndex = i / 8;
int bitIndex = i % 8;
Serial.print((data[byteIndex] >> bitIndex) & 0x01);
}
Serial.println(); // Zeilenumbruch nach der Ausgabe
// Check which bits have changed
unsigned long changedBits = incoming ^ previousState; // XOR findet die Unterschiede
// Durchlaufe jedes Bit in umgekehrter Reihenfolge (von Bit totalBits-1 bis Bit 0)
for (int i = totalBits - 1; i >= 0; i--) {
if (changedBits & ((unsigned long)1 << i)) { // Wenn sich das Bit i geändert hat
// Umkehrung der Pin-Zuordnung
int pin = totalBits - 1 - i; // Umkehrung der Pin-Nummer
if (incoming & ((unsigned long)1 << i)) {
Serial.print("Pin ");
Serial.print(pin); // Verwende die umgekehrte Pin-Nummer
Serial.println(" ist auf HIGH gewechselt.");
} else {
Serial.print("Pin ");
Serial.print(pin); // Verwende die umgekehrte Pin-Nummer
Serial.println(" ist auf LOW gewechselt.");
}
}
}
// Setze den Wert auf 0 und verschiebe incoming nach links
value = 0b00000000; // Initialisiere value und setze das erste Bit auf 0
incoming2 = incoming;
incoming2 <<=1;
// Ausgabe von incoming in binärer Form zur Debugging-Zwecken
Serial.print("incoming (binär): ");
for (int j = totalBits - 1; j >= 0; j--) {
Serial.print((incoming >> j) & 0x01);
}
Serial.println(); // Zeilenumbruch nach der Ausgabe
// Prüfen der einzelnen Bits von incoming
for (int i = 0; i < totalBits2; i++) { // Durchlaufe die Bits
int bitValue = (incoming2 >> (totalBits - 1 - i)) & 0x01;
int valuePos = (i * 3) +1;
if (bitValue != 0) {
value |= (0b100 << valuePos); // Setze 100 an die entsprechende Position
} else {
value |= (0b010 << valuePos); // Setze 010 an die entsprechende Position
}
}
// Der endgültige Wert für das Schieberegister wird hier in value gesetzt
Serial.print("Finaler Wert von value (binär): ");
for (int j = totalBits2 - 1; j >= 0; j--) {
Serial.print((value >> j) & 0x01);
}
Serial.println(); // Zeilenumbruch nach der Ausgabe
// Sende die Bits an das Schieberegister
digitalWrite(latchPin, LOW); // Vorbereiten zum Senden
shiftOut(dataPin, clockPin, MSBFIRST, value); // Sende value an das Schieberegister
digitalWrite(latchPin, HIGH); // Abschluss des Sendens
// Speichere den aktuellen Zustand für den nächsten Vergleich
previousState = incoming;
}