.. note:: Hallo und willkommen in der SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasten-Community auf Facebook! Tauche tiefer in Raspberry Pi, Arduino und ESP32 mit anderen Enthusiasten ein. **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ühzeitigen Zugang zu neuen Produktankündigungen und Vorschauen. - **Sonderrabatte**: Genieße exklusive Rabatte auf unsere neuesten Produkte. - **Festliche Aktionen und Verlosungen**: Nimm an Verlosungen und Feiertagsaktionen teil. 👉 Bereit, mit uns zu entdecken und zu erschaffen? Klicke auf [|link_sf_facebook|] und tritt noch heute bei! .. _3.1.4_c_pi5_mcp3008: 3.1.4 Intelligenter Lüfter (MCP3008) ==================================== .. note:: .. image:: ../img/mcp3008_and_adc0834.jpg :width: 25% :align: left Je nach deiner Kit-Version überprüfe bitte, ob du **ADC0834** oder **MCP3008** hast, und fahre mit dem entsprechenden Abschnitt fort. Einführung ---------- In diesem Projekt verwenden wir Motoren, Taster und Thermistoren, um einen manuellen + automatischen intelligenten Lüfter zu bauen, dessen Windgeschwindigkeit einstellbar ist. Benötigte Komponenten --------------------- In diesem Projekt benötigen wir die folgenden Komponenten. .. image:: ../img/list2_Smart_Fan.png :align: center Schaltplan ---------- ============ ======== ======== === T-Board-Name Physical 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 GPIO5 Pin 29 21 5 GPIO6 Pin 31 22 6 GPIO13 Pin 33 23 13 ============ ======== ======== === .. image:: ../img/schematic_3.1.4_smart_fan_mcp3008.png :align: center Experimentelle Schritte ----------------------- **Schritt 1:** Baue die Schaltung auf. .. image:: ../img/july24_3.1.4_smart_fan_mcp3008.png :align: center .. note:: Das Strommodul kann mit einer 9V-Batterie über den im Kit enthaltenen 9V-Batterieclip betrieben werden. Stecke die Jumperkappe des Strommoduls in die 5V-Stromschiene des Breadboards. .. image:: ../img/image118.jpeg :align: center **Schritt 2:** Gehe in den Code-Ordner. .. raw:: html .. code-block:: cd ~/davinci-kit-for-raspberry-pi/c/3.1.4-2/ **Schritt 3:** Kompiliere. .. raw:: html .. code-block:: gcc 3.1.4_SmartFan.c -o SmartFan -lwiringPi -lm **Schritt 4:** Führe die erstellte Datei aus. .. raw:: html .. code-block:: ./SmartFan Während der Code läuft, starte den Lüfter, indem du den Taster drückst. Jedes Drücken erhöht oder verringert die Geschwindigkeit um eine Stufe. Es gibt **5** Geschwindigkeitsstufen: **0–4**. Wenn die 4. Stufe erreicht ist und du erneut drückst, stoppt der Lüfter (Stufe 0). Sobald die Temperatur um mehr als 2 °C steigt oder fällt, wird die Geschwindigkeit automatisch um eine Stufe erhöht oder verringert. .. note:: Falls es nach dem Ausführen nicht funktioniert oder die Fehlermeldung „wiringPi.h: No such file or directory“ erscheint, siehe :ref:`install_wiringpi`. Code ---- .. code-block:: c #include #include #include #include #include #define SPI_CHANNEL 0 #define SPI_SPEED 1000000 #define MotorPin1 21 #define MotorPin2 22 #define MotorEnable 23 #define BtnPin 3 int read_ADC(int channel) { if (channel < 0 || channel > 7) return -1; unsigned char buffer[3]; buffer[0] = 1; // Startbit buffer[1] = (8 + channel) << 4; // Single-Ended-Modus und Kanal buffer[2] = 0; wiringPiSPIDataRW(SPI_CHANNEL, buffer, 3); int result = ((buffer[1] & 3) << 8) | buffer[2]; return result; } int temperture() { int analogVal = read_ADC(0); double Vr = 3.3 * analogVal / 1023.0; // 3,3V als Vref double Rt = 10000.0 * Vr / (3.3 - Vr); double temp = 1 / (((log(Rt / 10000.0)) / 3950.0) + (1 / (273.15 + 25.0))); double cel = temp - 273.15; double Fah = cel * 1.8 + 32; printf("Celsius: %.2f C Fahrenheit: %.2f F\n", cel, Fah); return (int)cel; } int motor(int level) { if (level == 0) { digitalWrite(MotorEnable, LOW); return 0; } if (level >= 4) { level = 4; } digitalWrite(MotorEnable, HIGH); softPwmWrite(MotorPin1, level * 25); return level; } void setup() { if (wiringPiSetup() == -1) { printf("wiringPi-Setup fehlgeschlagen!\n"); return; } if (wiringPiSPISetup(SPI_CHANNEL, SPI_SPEED) == -1) { printf("SPI-Setup fehlgeschlagen!\n"); return; } softPwmCreate(MotorPin1, 0, 100); softPwmCreate(MotorPin2, 0, 100); pinMode(MotorEnable, OUTPUT); pinMode(BtnPin, INPUT); } int main(void) { setup(); int currentState, lastState = 0; int level = 0; int currentTemp, markTemp = 0; while (1) { currentState = digitalRead(BtnPin); currentTemp = temperture(); if (currentTemp <= 0) continue; if (currentState == 1 && lastState == 0) { level = (level + 1) % 5; markTemp = currentTemp; delay(500); } lastState = currentState; if (level != 0) { if (currentTemp - markTemp <= -2) { level = level - 1; markTemp = currentTemp; } if (currentTemp - markTemp >= 2) { level = level + 1; markTemp = currentTemp; } } level = motor(level); } return 0; } Code-Erklärung -------------- .. code-block:: c int read_ADC(int channel) { if (channel < 0 || channel > 7) return -1; unsigned char buffer[3]; buffer[0] = 1; // Startbit buffer[1] = (8 + channel) << 4; // Single-Ended-Modus und Kanal buffer[2] = 0; wiringPiSPIDataRW(SPI_CHANNEL, buffer, 3); int result = ((buffer[1] & 3) << 8) | buffer[2]; return result; } Diese Funktion liest den analogen Eingang des MCP3008 am angegebenen Kanal. Sie sendet einen 3-Byte-SPI-Befehl und gibt einen 10-Bit-Digitalwert (0–1023) zurück. .. code-block:: c int temperture() { int analogVal = read_ADC(0); double Vr = 3.3 * analogVal / 1023.0; // 3,3V als Vref double Rt = 10000.0 * Vr / (3.3 - Vr); double temp = 1 / (((log(Rt / 10000.0)) / 3950.0) + (1 / (273.15 + 25.0))); double cel = temp - 273.15; double Fah = cel * 1.8 + 32; printf("Celsius: %.2f C Fahrenheit: %.2f F\n", cel, Fah); return (int)cel; } Die Funktion ``temperture()`` liest das analoge Signal des Thermistors über den MCP3008, berechnet die Spannung und den Widerstand und wandelt diese mithilfe der Thermistorformel (Steinhart–Hart-Approximation) in °C und °F um. .. code-block:: c int motor(int level) { if (level == 0) { digitalWrite(MotorEnable, LOW); return 0; } if (level >= 4) { level = 4; } digitalWrite(MotorEnable, HIGH); softPwmWrite(MotorPin1, level * 25); return level; } Die Funktion ``motor()`` steuert die Lüftergeschwindigkeit über PWM. Die Stufen reichen von 0–4, wobei 0 den Lüfter ausschaltet und jede höhere Stufe den Tastgrad um 25 % erhöht. .. code-block:: c void setup() { if (wiringPiSetup() == -1) { printf("wiringPi-Setup fehlgeschlagen!\n"); return; } if (wiringPiSPISetup(SPI_CHANNEL, SPI_SPEED) == -1) { printf("SPI-Setup fehlgeschlagen!\n"); return; } softPwmCreate(MotorPin1, 0, 100); softPwmCreate(MotorPin2, 0, 100); pinMode(MotorEnable, OUTPUT); pinMode(BtnPin, INPUT); } Die Funktion ``setup()`` initialisiert WiringPi, richtet SPI ein, konfiguriert PWM und GPIO-Pins für Motorsteuerung und Tastereingabe. .. code-block:: c int main(void) { setup(); int currentState, lastState = 0; int level = 0; int currentTemp, markTemp = 0; while (1) { currentState = digitalRead(BtnPin); currentTemp = temperture(); if (currentTemp <= 0) continue; if (currentState == 1 && lastState == 0) { level = (level + 1) % 5; markTemp = currentTemp; delay(500); } lastState = currentState; if (level != 0) { if (currentTemp - markTemp <= -2) { level = level - 1; markTemp = currentTemp; } if (currentTemp - markTemp >= 2) { level = level + 1; markTemp = currentTemp; } } level = motor(level); } return 0; } Die ``main()``-Funktion enthält die Hauptschleife: 1. Liest kontinuierlich den Tasterzustand und die aktuelle Temperatur. 2. Bei Tastendruck wird die Lüfterstufe erhöht (0–4) und die Temperatur gespeichert. 3. Ändert sich die Temperatur um ±2 °C, wird die Lüftergeschwindigkeit automatisch angepasst. 4. Ruft ``motor(level)`` auf, um die PWM-Ausgabe entsprechend der aktuellen Stufe zu setzen.