// *********************************** // * >>> Dead Bell <<< * // * * // * - Tim Timsen * // * - 03.12.2024 * // * - V. 0.97 * // * - Arduino Nano V3 * // * - TLV493D Modul * // * - Tischglocke * // * - Push-Pull DC Hubmagnet, 9 V * // * - Poti mit Schaltkontakt * // * - 2N 2222 NPN Transistor * // *********************************** #include #include // Initialisiere den TLx493D-Sensor using namespace ifx::tlx493d; TLx493D_A1B6 sensor(Wire, TLx493D_IIC_ADDR_A0_e); // Hardware-Pins const int transistorPin = 9; // Pin, Transistor für Hubmagnet const int potPin = A0; // Poti zur Sensitivitätsanpassung // Variablen float baselineMagnitude = 0; // Kalibrierter Grundwert unsigned long lastAlarmTime = 0; // Letzte Alarmzeit const unsigned long coolDownTime = 1000; // Zeit bis nächster Alarm möglich ist (ms) bool calibrationDone = true; // Flag für Kalibrierung const float hysteresisFactor = 0.05; // 5% Hysterese um Alarm auszulösen // Variablen für Mittelwertbildung const int bufferSize = 15; // Anzahl der Messungen für aktuellen Mittelwert float magnitudeBuffer[bufferSize]; // Ringpuffer für Messwerte (Mittelwert) int bufferIndex = 0; // Aktuelle Position im Ringpuffer int bufferCount = 0; // Anzahl der Werte im Puffer void setup() { pinMode(transistorPin, OUTPUT); digitalWrite(transistorPin, LOW); Serial.begin(9600); Wire.begin(); // Initialisiere den TLx493D-Sensor if (!sensor.begin()) { Serial.println("TLx493D nicht gefunden! Überprüfe die Verkabelung."); while (1); } // Setze den Modus auf Short Range sensor.setSensitivity(TLx493D_SHORT_RANGE_e); //sensor.setSensitivity(TLx493D_FULL_RANGE_e); // Warte 3 Sekunden nach dem Start Serial.println("System startet, bitte warten..."); delay(3000); // Kalibrierung durchführen Serial.println("Kalibrierung startet..."); baselineMagnitude = calibrateMagnetometer(); Serial.print("Kalibrierter Grundwert: "); Serial.println(baselineMagnitude); } void loop() { // Schwellwert aus dem Poti berechnen (Alarmgrenzwert) int potValue = analogRead(potPin); float sensitivityPercentage = map(potValue, 0, 1023, 500, 200) / 1000.0; // 50% bis 20% bezogen auf Grundwert float threshold = baselineMagnitude * sensitivityPercentage; // Schwellenwerte für Alarm (mit Hysterese) > Alarm wenn zu hoch oder zu tief float upperThreshold = baselineMagnitude + threshold * (1 + hysteresisFactor); float lowerThreshold = baselineMagnitude - threshold * (1 + hysteresisFactor); // Aktuelles Magnetfeld messen und Mittelwert berechnen float currentMagnitude = measureMagnetometer(); float averagedMagnitude = updateBufferAndCalculateAverage(currentMagnitude); // Serielle Ausgabe Serial.print("Mittelwert: "); Serial.print(averagedMagnitude); Serial.print(" | Poti-Wert: "); Serial.print(sensitivityPercentage * 100, 1); // Poti-Wert in % Serial.print("% | Alarmbereich: "); Serial.print(lowerThreshold); Serial.print(" bis "); Serial.println(upperThreshold); // Verzögerte Kalibrierung nach Alarm if (!calibrationDone && millis() - lastAlarmTime > 0.95 * coolDownTime) { Serial.println("Verzögerte Neukalibrierung nach Alarm..."); baselineMagnitude = calibrateMagnetometer(); Serial.print("Neuer kalibrierter Grundwert: "); Serial.println(baselineMagnitude); calibrationDone = true; } // Prüfen, ob ein Alarm ausgelöst werden soll if (millis() - lastAlarmTime > coolDownTime && (averagedMagnitude > upperThreshold || averagedMagnitude < lowerThreshold)) { triggerAlarm(); lastAlarmTime = millis(); } } // Kalibrierung des Magnetometers float calibrateMagnetometer() { float sum = 0; int measurements = 20; for (int i = 0; i < measurements; i++) { float magnitude = measureMagnetometer(); sum += magnitude; delay(50); } return sum / measurements; } // Magnetfeld messen und Vektorbetrag berechnen float measureMagnetometer() { double x, y, z; // Lese die Werte des Magnetometers sensor.getMagneticField(&x, &y, &z); // Vektorbetrag berechnen return sqrt(x * x + y * y + z * z); } // Ringpuffer aktualisieren und Mittelwert berechnen float updateBufferAndCalculateAverage(float newValue) { magnitudeBuffer[bufferIndex] = newValue; bufferIndex = (bufferIndex + 1) % bufferSize; if (bufferCount < bufferSize) { bufferCount++; } float sum = 0; for (int i = 0; i < bufferCount; i++) { sum += magnitudeBuffer[i]; } return sum / bufferCount; } // Alarm auslösen void triggerAlarm() { Serial.println("ALARM: Magnetfeldabweichung erkannt!"); digitalWrite(transistorPin, HIGH); // Hubmagnet einschalten delay(15); // Kurzer Impuls von 15 ms digitalWrite(transistorPin, LOW); // Hubmagnet ausschalten calibrationDone = false; // Kalibrierung zurücksetzen }