Bemerkung

Hallo und willkommen in der SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasten-Community auf Facebook! Tauche tiefer in Raspberry Pi, Arduino und ESP32 ein – gemeinsam mit anderen Technik-Begeisterten.

Warum beitreten?

  • Expertenunterstützung: Löse Probleme nach dem Kauf und technische Herausforderungen mit Hilfe unserer Community und unseres Teams.

  • Lernen & Teilen: Tausche Tipps und Tutorials aus, um deine Fähigkeiten zu verbessern.

  • Exklusive Vorschauen: Erhalte frühen Zugang zu neuen Produktankündigungen und Einblicken.

  • Sonderrabatte: Genieße exklusive Rabatte auf unsere neuesten Produkte.

  • Festliche Aktionen und Gewinnspiele: Nimm an Verlosungen und Feiertagsaktionen teil.

👉 Bereit, mit uns zu entdecken und zu kreieren? Klicke [hier] und trete noch heute bei!

3.1.8 Überhitzungsmonitor (MCP3008)

Bemerkung

_images/mcp3008_and_adc0834.jpg

Abhängig von deiner Kit-Version überprüfe bitte, ob du ADC0834 oder MCP3008 hast, und fahre mit dem passenden Abschnitt fort.

Einführung

Vielleicht möchtest du ein Überhitzungs-Überwachungsgerät bauen, das in verschiedenen Situationen eingesetzt werden kann. Zum Beispiel in einer Fabrik: Wenn eine Schaltung überhitzt, soll ein Alarm ausgelöst und die Maschine automatisch abgeschaltet werden.

In diesem Projekt verwenden wir einen Thermistor, Joystick, Summer, LED und ein LCD, um ein intelligentes Temperatur-Überwachungsgerät mit einstellbarem Schwellenwert zu bauen.

Benötigte Komponenten

Für dieses Projekt benötigen wir die folgenden Komponenten:

_images/list2_Overheat_Monitor.png

Schaltplan

T-Board Name

Physikal

wiringPi

BCM

SPICE0

Pin 24

10

8

SPIMOSI

Pin 19

12

10

SPIMISO

Pin 21

13

9

SPISCLK

Pin 23

14

11

GPIO22

Pin 15

3

22

GPIO23

Pin 16

4

23

GPIO24

Pin 18

5

24

SDA1

Pin 3

SCL1

Pin 5

_images/Schematic_three_one81.png

Versuchsschritte

Schritt 1: Baue die Schaltung auf.

_images/july24_3.1.8_overheat_monitor_mcp3008.png

Für C-Sprach-Nutzer

Schritt 2: Gehe in den Code-Ordner.

cd ~/davinci-kit-for-raspberry-pi/c/3.1.8-2/

Schritt 3: Kompiliere den Code.

gcc 3.1.8_OverheatMonitor.c -lm -lwiringPi

Schritt 4: Führe die ausführbare Datei aus.

sudo ./a.out

Während der Code läuft, werden die aktuelle Temperatur und der Hochtemperatur-Schwellenwert 40 auf dem I2C LCD1602 angezeigt.

Wenn die aktuelle Temperatur größer als der Schwellenwert ist, werden Summer und LED aktiviert, um dich zu warnen.

Mit dem Joystick kannst du den Hochtemperatur-Schwellenwert einstellen. Bewegen des Joysticks entlang der X- und Y-Achse erhöht oder verringert den aktuellen Schwellenwert. Ein erneutes Drücken des Joysticks setzt den Wert auf den Anfangswert zurück.

Bemerkung

  • Falls der Fehler wiringPi.h: No such file or directory erscheint, siehe Installieren und Überprüfen von WiringPi.

  • Falls der Fehler Unable to open I2C device: No such file or directory erscheint, siehe I²C-Konfiguration, um I2C zu aktivieren und die Verdrahtung zu prüfen.

  • Falls Code und Verdrahtung stimmen, aber das LCD dennoch nichts anzeigt, drehe am Potentiometer auf der Rückseite, um den Kontrast zu erhöhen.

Code-Erklärung

int read_ADC(int channel) {
    if (channel < 0 || channel > 7) return -1;
    unsigned char buffer[3];
    buffer[0] = 1;
    buffer[1] = (8 + channel) << 4;
    buffer[2] = 0;
    wiringPiSPIDataRW(SPI_CHANNEL, buffer, 3);
    return ((buffer[1] & 0x03) << 8) | buffer[2];
}

Liest einen 10-Bit-Analogwert vom MCP3008-Kanal (CH0–CH7) über SPI und gibt einen Wert von 0 bis 1023 zurück.

int get_joystick_value() {
    int x = read_ADC(1);
    int y = read_ADC(2);

    if (x > 900)      return 1;   // Rechts
    else if (x < 100) return -1;  // Links
    else if (y > 900) return -10; // Hoch
    else if (y < 100) return 10;  // Runter
    else              return 0;
}

Liest die analogen X- und Y-Werte des Joysticks von CH1 und CH2. Gibt eine Ganzzahl zurück, die die Bewegungsrichtung anhand von Schwellenwerten angibt.

void upper_tem_setting() {
    write_lcd(0,0, "Upper Adjust:");

    int change = get_joystick_value();

    if (change != 0 && change != lastJoystickChange) {
        upperTem += change;
        lastJoystickChange = change;
    }
    else if (change == 0) {
        lastJoystickChange = 0;
    }

    char str[6];
    snprintf(str, sizeof(str), "%d", upperTem);
    write_lcd(0,1, str);
    write_lcd(strlen(str),1, "            ");

    delay(100);
}

Ermöglicht es, den oberen Temperatur-Schwellenwert mit dem Joystick einzustellen. Verhindert wiederholte Änderungen, wenn die Richtung gehalten wird.

double temperature() {
    int raw = read_ADC(0);
    double Vr = 3.3 * ((double)raw / 1023.0);
    double Rt = 10000.0 * Vr / (3.3 - Vr);
    double tempK = 1.0 / ((log(Rt/10000.0)/3950.0) + 1.0/(273.15+25.0));
    return tempK - 273.15;
}

Liest den analogen Wert von CH0, an dem der Thermistor angeschlossen ist. Berechnet die Temperatur in Grad Celsius mithilfe der Steinhart–Hart-Gleichung.

void monitoring_temp() {
    char str[6];
    double cel = temperature();
    snprintf(str, sizeof(str), "%.2f", cel);
    write_lcd(0,0, "Temp: ");
    write_lcd(6,0, str);

    snprintf(str, sizeof(str), "%d", upperTem);
    write_lcd(0,1, "Upper: ");
    write_lcd(7,1, str);
    delay(100);

    if (cel >= upperTem) {
        digitalWrite(buzzPin, HIGH);
        digitalWrite(LedPin,  HIGH);
    } else {
        digitalWrite(buzzPin, LOW);
        digitalWrite(LedPin,  LOW);
    }
}

Liest kontinuierlich die aktuelle Temperatur und zeigt sie zusammen mit dem Schwellenwert an. Überschreitet die Temperatur den Schwellenwert, werden Summer und LED aktiviert.

void setup_all() {
    fd = wiringPiI2CSetup(LCDAddr);
    lcd_init();
    if (wiringPiSetup() == -1 || wiringPiSPISetup(SPI_CHANNEL, SPI_SPEED) == -1) {
        printf("Setup failed!\n");
        return;
    }
    pinMode(Joy_BtnPin, INPUT);
    pullUpDnControl(Joy_BtnPin, PUD_UP);
    pinMode(buzzPin, OUTPUT);
    pinMode(LedPin,  OUTPUT);
}

Initialisiert LCD, SPI und GPIO-Pins für Joystick-Taste, Summer und LED. Setzt außerdem den Pull-up-Widerstand für die Joystick-Taste.

int main(void) {
    setup_all();

    int lastBtnState = HIGH;
    int stage = 0;

    while (1) {
        int curBtn = digitalRead(Joy_BtnPin);
        if (curBtn == HIGH && lastBtnState == LOW) {
            stage = (stage + 1) % 2;
            lastJoystickChange = 0;
            delay(100);
            lcd_clear();
        }
        lastBtnState = curBtn;

        if (stage == 1)
            upper_tem_setting();
        else
            monitoring_temp();
    }

    return 0;
}

Die Hauptschleife wechselt zwischen zwei Modi:

  1. Temperaturüberwachung.

  2. Einstellung des oberen Grenzwerts mit dem Joystick.

Für Python-Sprachbenutzer

Schritt 2: Richten Sie die SPI-Schnittstelle ein und installieren Sie die spidev-Bibliothek (siehe SPI-Konfiguration für detaillierte Anweisungen). Wenn Sie diese Schritte bereits abgeschlossen haben, können Sie diesen Schritt überspringen.

Schritt 3: Gehen Sie in den Ordner mit dem Code.

cd ~/davinci-kit-for-raspberry-pi/python

Schritt 4: Führen Sie die ausführbare Datei aus.

sudo python3 3.1.8-2_OverheatMonitor.py

Während der Code ausgeführt wird, werden die aktuelle Temperatur und die Hochtemperaturschwelle 40 auf dem I2C LCD1602 angezeigt. Wenn die aktuelle Temperatur größer als die Schwelle ist, werden Summer und LED aktiviert, um Sie zu warnen.

Der Joystick dient hier dazu, die Hochtemperaturschwelle durch Drücken anzupassen. Das Bewegen des Joysticks entlang der X- und Y-Achse kann die aktuelle Hochtemperaturschwelle erhöhen oder verringern. Drücken Sie den Joystick erneut, um die Schwelle auf den Anfangswert zurückzusetzen.

Bemerkung

  • Wenn der Fehler FileNotFoundError: [Errno 2] No such file or directory: '/dev/i2c-1' auftritt, müssen Sie gemäß I²C-Konfiguration den I2C aktivieren.

  • Wenn der Fehler ModuleNotFoundError: No module named 'smbus2' auftritt, führen Sie bitte sudo apt install python3-smbus2 aus.

  • Wenn der Fehler OSError: [Errno 121] Remote I/O error erscheint, ist das Modul entweder falsch verdrahtet oder defekt.

  • Wenn Code und Verdrahtung korrekt sind, das LCD jedoch weiterhin nichts anzeigt, drehen Sie das Potentiometer auf der Rückseite, um den Kontrast zu erhöhen.

Warnung

Wenn die Fehlermeldung RuntimeError: Cannot determine SOC peripheral base address erscheint, lesen Sie bitte Wenn gpiozero nicht funktioniert.

Code

Bemerkung

Sie können den folgenden Code ändern/zurücksetzen/kopieren/ausführen/stoppen. Bevor Sie dies tun, müssen Sie jedoch in das Quellcode-Verzeichnis wie davinci-kit-for-raspberry-pi/python wechseln. Nach einer Änderung können Sie den Code direkt ausführen, um die Auswirkung zu sehen.

#!/usr/bin/env python3

import RPi.GPIO as GPIO
import spidev
import time
import math
import LCD1602

# GPIO pin definitions
JOY_BTN_PIN = 22  # Button pin
BUZZER_PIN = 23   # Buzzer pin
LED_PIN = 24      # LED pin

# Initialize GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(JOY_BTN_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(BUZZER_PIN, GPIO.OUT)
GPIO.setup(LED_PIN, GPIO.OUT)

# Set initial upper temperature threshold
upperTem = 40

# Initialize SPI for MCP3008
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 1000000  # 1 MHz

# Initialize LCD1602
LCD1602.init(0x27, 1)

def read_adc(channel):
    """
    Read analog value from MCP3008 (0–7)
    """
    if channel < 0 or channel > 7:
        return -1
    adc = spi.xfer2([1, (8 + channel) << 4, 0])
    value = ((adc[1] & 0x03) << 8) | adc[2]
    return value

def get_joystick_value():
    """
    Reads the joystick values and returns a change value based on the joystick's position.
    """
    x_val = read_adc(1)
    y_val = read_adc(2)
    if x_val > 800:
        return 1
    elif x_val < 200:
        return -1
    elif y_val > 800:
        return -10
    elif y_val < 200:
        return 10
    else:
        return 0

def upper_tem_setting():
    """
    Adjusts and displays the upper temperature threshold on the LCD.
    """
    global upperTem
    LCD1602.write(0, 0, 'Upper Adjust: ')
    change = int(get_joystick_value())
    upperTem += change
    strUpperTem = str(upperTem)
    LCD1602.write(0, 1, strUpperTem)
    LCD1602.write(len(strUpperTem), 1, '              ')
    time.sleep(0.1)

def temperature():
    """
    Reads the current temperature from the sensor and returns it in Celsius.
    """
    analogVal = read_adc(0)
    Vr = 3.3 * analogVal / 1023.0
    if Vr == 0:
        return 0
    Rt = 10000.0 * (3.3 - Vr) / Vr
    tempK = 1.0 / (((math.log(Rt / 10000.0)) / 3950.0) + (1.0 / (273.15 + 25.0)))
    Cel = tempK - 273.15
    return round(Cel, 2)

def monitoring_temp():
    """
    Monitors and displays the current temperature and upper temperature threshold.
    Activates buzzer and LED if the temperature exceeds the upper limit.
    """
    global upperTem
    Cel = temperature()
    LCD1602.write(0, 0, 'Temp: ')
    LCD1602.write(0, 1, 'Upper: ')
    LCD1602.write(6, 0, str(Cel))
    LCD1602.write(7, 1, str(upperTem))
    time.sleep(0.1)
    if Cel >= upperTem:
        GPIO.output(BUZZER_PIN, GPIO.HIGH)
        GPIO.output(LED_PIN, GPIO.HIGH)
    else:
        GPIO.output(BUZZER_PIN, GPIO.LOW)
        GPIO.output(LED_PIN, GPIO.LOW)

# Main loop
try:
    lastState = GPIO.input(JOY_BTN_PIN)
    stage = 0
    while True:
        currentState = GPIO.input(JOY_BTN_PIN)
        if currentState == GPIO.HIGH and lastState == GPIO.LOW:
            stage = (stage + 1) % 2
            time.sleep(0.1)
            LCD1602.clear()
        lastState = currentState

        if stage == 1:
            upper_tem_setting()
        else:
            monitoring_temp()

except KeyboardInterrupt:
    pass

finally:
    LCD1602.clear()
    GPIO.cleanup()
    spi.close()

Code-Erklärung

  1. Bibliotheken importieren

    Dieser Abschnitt lädt die erforderlichen Bibliotheken für GPIO, SPI, LCD-Anzeige, Zeitverzögerungen und mathematische Operationen.

    #!/usr/bin/env python3
    import RPi.GPIO as GPIO
    import spidev
    import time
    import math
    import LCD1602
    
  2. GPIO- und Geräteeinrichtung

    Definiert die GPIO-Pinnummern für den Joystick-Knopf, den Summer und die LED, und konfiguriert die GPIO-Modi.

    JOY_BTN_PIN = 22  # Taster-Pin
    BUZZER_PIN = 23   # Summer-Pin
    LED_PIN = 24      # LED-Pin
    
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(JOY_BTN_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    GPIO.setup(BUZZER_PIN, GPIO.OUT)
    GPIO.setup(LED_PIN, GPIO.OUT)
    
  3. SPI- und LCD-Initialisierung

    Startet die SPI-Schnittstelle für MCP3008 und initialisiert den LCD1602-Bildschirm mit der I2C-Adresse 0x27.

    upperTem = 40
    spi = spidev.SpiDev()
    spi.open(0, 0)
    spi.max_speed_hz = 1000000
    
    LCD1602.init(0x27, 1)
    
  4. ADC-Wert lesen

    Liest analoge Daten vom MCP3008-ADC über SPI. Der Kanal sollte im Bereich 0–7 liegen.

    def read_adc(channel):
       if channel < 0 or channel > 7:
          return -1
       adc = spi.xfer2([1, (8 + channel) << 4, 0])
       value = ((adc[1] & 0x03) << 8) | adc[2]
       return value
    
  5. Joystick-Bewegungserkennung

    Überprüft die X/Y-Achsenwerte des Joysticks und gibt zurück, um wie viel der Schwellenwert geändert werden soll.

    def get_joystick_value():
       x_val = read_adc(1)
       y_val = read_adc(2)
       if x_val > 800:
          return 1
       elif x_val < 200:
          return -1
       elif y_val > 800:
          return -10
       elif y_val < 200:
          return 10
       else:
          return 0
    
  6. Obere Temperaturschwelle einstellen

    Zeigt „Upper Adjust“ auf dem LCD an und passt die Schwelle anhand der Joystick-Eingaben an.

    def upper_tem_setting():
       global upperTem
       LCD1602.write(0, 0, 'Upper Adjust: ')
       change = int(get_joystick_value())
       upperTem += change
       strUpperTem = str(upperTem)
       LCD1602.write(0, 1, strUpperTem)
       LCD1602.write(len(strUpperTem), 1, '              ')
       time.sleep(0.1)
    
  7. Temperaturberechnung

    Wandelt den analogen Sensorwert in Spannung, Widerstand und schließlich Temperatur (Celsius) unter Verwendung der Steinhart–Hart-Annäherung um.

    def temperature():
       analogVal = read_adc(0)
       Vr = 3.3 * analogVal / 1023.0
       if Vr == 0:
          return 0
       Rt = 10000.0 * (3.3 - Vr) / Vr
       tempK = 1.0 / (((math.log(Rt / 10000.0)) / 3950.0) + (1.0 / (273.15 + 25.0)))
       Cel = tempK - 273.15
       return round(Cel, 2)
    
  8. Temperaturüberwachung

    Überprüft und zeigt kontinuierlich Temperatur und obere Grenze an. Aktiviert Summer und LED, wenn die Temperatur die Schwelle überschreitet.

    def monitoring_temp():
       global upperTem
       Cel = temperature()
       LCD1602.write(0, 0, 'Temp: ')
       LCD1602.write(0, 1, 'Upper: ')
       LCD1602.write(6, 0, str(Cel))
       LCD1602.write(7, 1, str(upperTem))
       time.sleep(0.1)
       if Cel >= upperTem:
          GPIO.output(BUZZER_PIN, GPIO.HIGH)
          GPIO.output(LED_PIN, GPIO.HIGH)
       else:
          GPIO.output(BUZZER_PIN, GPIO.LOW)
          GPIO.output(LED_PIN, GPIO.LOW)
    
  9. Hauptprogrammlogik

    Wechselt zwischen Temperaturüberwachungs- und Schwellenwerteinstellungsmodus, wenn der Joystick-Knopf gedrückt wird.

    try:
       lastState = GPIO.input(JOY_BTN_PIN)
       stage = 0
       while True:
          currentState = GPIO.input(JOY_BTN_PIN)
          if currentState == GPIO.HIGH and lastState == GPIO.LOW:
                stage = (stage + 1) % 2
                time.sleep(0.1)
                LCD1602.clear()
          lastState = currentState
    
          if stage == 1:
                upper_tem_setting()
          else:
                monitoring_temp()
    
  10. Aufräumen beim Beenden

    Sorgt für die ordnungsgemäße Freigabe von GPIO- und SPI-Ressourcen, wenn Strg+C gedrückt wird.

    except KeyboardInterrupt:
       pass
    finally:
       LCD1602.clear()
       GPIO.cleanup()
       spi.close()