Benutzer-Werkzeuge

Webseiten-Werkzeuge


arduino:flaschenkuehler:programmversion_0.1

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
arduino:flaschenkuehler:programmversion_0.1 [02.07.2017 14:31] – [Ein- und Ausschalten des Lüfters] Frickelpietarduino:flaschenkuehler:programmversion_0.1 [18.05.2023 12:34] (aktuell) – Externe Bearbeitung 127.0.0.1
Zeile 1: Zeile 1:
 ====== Flaschenkühler - Programmversion 0.1 ====== ====== Flaschenkühler - Programmversion 0.1 ======
-Die erste Version der Software für den Flaschenkühler wirmet sich der Regelung des PC-Lüfters. Das erscheint zunächst nur ein Nebenschauplatz zu sein, ermöglicht mir aber Erfahrungen zu sammeln +Die erste Version der Software für den Flaschenkühler widmet sich der Regelung des PC-Lüfters. Das erscheint zunächst nur ein Nebenschauplatz zu sein, ermöglicht mir aber Erfahrungen zu sammeln 
   * mit der Änderung der PWM-Frequenz   * mit der Änderung der PWM-Frequenz
 +  * mit der Auswertung des Tachosignals
   * mit dem dem Auslesen eines Thermistors   * mit dem dem Auslesen eines Thermistors
   * mit der PID-Regelung   * mit der PID-Regelung
  
-Das Ziel ist zunächst, die Drehzahl eines 4-Pin-PC-Lüfters über ein Poti zu regeln.+Das Ziel ist zunächst, die Drehzahl eines PC-Lüfters mit 3-Pin-Anschluss über ein Poti zu regeln.((Warum ein Lüfter mit 3-Pin-Anschluss, und nicht einer mit vier Anschlusspins verwendet wird, habe ich [[arduino:flaschenkuehler|hier]] dargelegt.))
  
-===== Änderung der PWM-Frequenz ===== +==== Änderung der PWM-Frequenz ====
-==== Timer ====+
 Der Arduino Nano hat drei Timer, die sich auf die PWM-Frequenz verschiedener Pins auswirken: Der Arduino Nano hat drei Timer, die sich auf die PWM-Frequenz verschiedener Pins auswirken:
   * timer 0: Pins 5 und 6   * timer 0: Pins 5 und 6
Zeile 16: Zeile 16:
 Der timer 0 wirkt sich auf die Befehle millis(); micros() und delay() aus, so dass er nicht verändert werden sollte. Der timer 0 wirkt sich auf die Befehle millis(); micros() und delay() aus, so dass er nicht verändert werden sollte.
  
-Evtl. muss die Bibliothek gepatched werden: https://forum.arduino.cc/index.php?topic=117425.135+Um den PC-Lüfter mit 25 kHz und das Peltier-Element mit einer anderen PWM-Frequenz ansteuern zu können, wird die PWM-Bibliothek eingebunden. Die Biblothek kann [[https://code.google.com/archive/p/arduino-pwm-frequency-library/downloads|hier]] geladen werden.) Da die Bibliothek fehlerhaft ist, funktionieren nicht alle Pins. 
 +  * Der PC-Lüfter wird an Pin D9 angeschlossen. 
 +  * Das Peltier-Element wird an Pin 3 angeschlossen. (Pin 11 gibt kein Signal aus.) 
 + 
 +Der [[https://forum.arduino.cc/index.php?topic=117425.135|hier]] gepostete Patch funktioniert nicht. 
 + 
 +Die PWM-Frequenz kann mit der PWM-Bibliothek nahezu beliebig festgelegt werden. 50 kHz für das Peltier-Element an Pin 3 sind kein Problem.
  
-http://arduino-info.wikispaces.com/Arduino-PWM-Frequency 
  
-http://www.netzmafia.de/skripten/hardware/Arduino/programmierung.html 
  
 ==== Tachosignal ==== ==== Tachosignal ====
-Der PC-Lüfter geibt ein Tachosignal aus, das mit einem interruptfähigen Pin erfasst werden soll.+Der PC-Lüfter gibt ein Tachosignal aus, das am Pin 2 anliegt. Das Programm bestimmt den Abstand zwischen der ansteigenden und der fallenden Flanke und berechnet daraus die Drehzahl. Es sollte auch möglich sein, die Interruptfähigkeit von Pin 2 dafür zu verwenden, aber mir ist es nicht gelungen.
  
-  * https://www.arduino.cc/en/Reference/AttachInterrupt +==== PID-Regler ==== 
-  * https://www.frag-duino.de/index.php/maker-faq/41-steuerung-eines-4-pin-cpu-luefters-mit-arduino+Der PID-Regler für den Lüfter (und später auch der für das Peltier-Element) werden mit der [[http://playground.arduino.cc/Code/PIDLibrary|Arduino PID-Bibliothek]] realisiertSchon mit den Standardwerten für das P-, Iund D-Glied funktioniert die Regelung des Lüfters gut.
  
 ==== Ein- und Ausschalten des Lüfters ==== ==== Ein- und Ausschalten des Lüfters ====
-Der verwendete PC-Lüfter von BeQueit hat eine Sicherheitsfunktionen, die dafür sorgt, dass der Lüfter voll aufdreht, wenn kein PWM-Siganl anliegt. Außerdem kann der Lüfter nicht mit dem PWM-Siganl ausgeschaltet werden: Fällt der Duty Cycle unter einen Wert, der einen sauberen Rundlauf nicht gewähren könnte, wird das Signal ignoriert. Damit der Lüfter beim Systemstart nicht unkontrolliert anläuft und im Betrieb vollständig ausgeschaltet werden kann, wird er mit einem NPN-Transistor geschaltet.+Der verwendete PC-Lüfter von BeQuiet! hat eine Sicherheitsfunktionen, die dafür sorgt, dass der Lüfter voll aufdreht, wenn kein PWM-Siganl anliegt. Außerdem kann der Lüfter nicht mit dem PWM-Signal ausgeschaltet werden: Fällt der Duty Cycle unter einen Wert, der einen sauberen Rundlauf nicht gewähren könnte, wird das Signal ignoriert. Damit der Lüfter beim Systemstart nicht unkontrolliert anläuft und im Betrieb vollständig ausgeschaltet werden kann, wird er mit einem MOSFET geschaltet. 
 + 
 +<code> 
 +// Flaschenkühler Programmversion 0.1 
 +// Diese Version steuert einen PC-Lüfter mit 4-Pin-Anschluss ... 
 +// ... liest das Tachosignal aus ... 
 +// ... berechnet die Drehzahl des Lüfters ... 
 +// ... liest einen Thermistor aus und berechnet die Temperatur ... 
 +// ... stellt über ein Poti die Zieltemperatur ein ... 
 +// ... und regelt den Lüfter mit einem PID-Modul. 
 + 
 +# include <PWM.h>                  // Bibliothek für Änderung der Frequenz der Timer 
 +# include <RunningAverage.h>       // Bibliothek für Berechnung von Mittelwerten 
 +# include <PID_v1.h>               // Bibliothek für PID-Regler 
 + 
 +// Definition der Ein- und Ausgänge 
 +int potiPin = A0;                  // Input-Pin für den Lüfter 
 +int thermistorPin = A1;            // Input-Pin für den Thermistor 
 +int fanPin = 9;                    // PWM-Pin für Lüfter 
 +int powerPin = 4;                  // Schaltet den Transistor 
 +int tachoPin = 2;                  // Pin für Tachosignal des Lüfters 
 +int peltierPin  = 3;               // PWM-Pin für Peltier-Element (hier zunächst nur als Funktionstest) 
 + 
 +// Definition der Variablen 
 +float thermistorValue = 0;         // Variable in der der Wert des Thermistors gespeichert wird 
 +int potiValue = 0;                 // variable to store the value coming from the sensor 
 + 
 +uint16_t frequencyFan = 25000;     // PWM-Frequenz für den Lüfter (in Hz) 
 +uint16_t frequencyPeltier = 50000; // PWM-Frequenz für den Lüfter (in Hz) 
 + 
 +int tachoSignal;                   // Tachosignal 
 +uint32_t pulseOn = 0;              // Ansteigende Signalflanke (Variablenformat nicht verändern!) 
 +uint32_t pulseOff = 0;             // Abfallende Signalflanke (Variablenformat nicht verändern!) 
 +uint32_t duration;                 // Zeit in Mikrosekunden zwischen ansteigender und abfallender Flanke (Variablenformat nicht verändern!) 
 +bool high = false;                 // Statevariable 
 +int rpm = 0;                       // Drehzahl des Lüfters in U/Min 
 + 
 +int temperatur = 0; 
 + 
 +// Definiert Instanzen zur Berechnung von Mittelwerten 
 +RunningAverage averageRPM(10); 
 +RunningAverage averageThermistor(10); 
 + 
 +// Definiert den PID-Regler 
 +double Setpoint, Input, Output; 
 +double Kp=2, Ki=5, Kd=1; 
 +PID fanPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, REVERSE); 
 + 
 +// Definiert die Tracking-Variablen für die IF-Abfragen 
 +unsigned long previousMillisSerialPrint = 0;          // Ausgabe an die serielle Schnittstelle 
 + 
 +// Definiert die Intervalle für die IF-Abfragen in Millisekunden 
 +const unsigned long intervalSerialPrint = 250;        // Ausgabe an die serielle Schnittstelle 
 + 
 + 
 +void setup() { 
 +  Serial.begin(115200); 
 +   
 +  // Definiert die Pins 
 +  pinMode(tachoPin, INPUT_PULLUP);                    // Tachosignal des Lüfters 
 +  pinMode(powerPin, OUTPUT);                          // Schaltet den MOSFET für den Lüfter 
 +  pinMode(fanPin, OUTPUT);                            // PWM-Signal für Lüfter 
 +  pinMode(peltierPin, OUTPUT);                        // PWM-Signal für Peltier-Element 
 +   
 +  // Initialisiert timer1 und timer2 (timer0 bleibt unberührt) 
 +  InitTimersSafe();  
 + 
 +  // Definiert die Frequenzen für die angegebenen Pins 
 +  bool successFan = SetPinFrequencySafe(fanPin, frequencyFan); 
 +  bool successPeltier = SetPinFrequencySafe(peltierPin, frequencyPeltier); 
 +   
 +  //if the pin frequency was set successfully, turn pin 13 on 
 +  if(successFan) { 
 +    pinMode(13, OUTPUT); 
 +    digitalWrite(13, HIGH); 
 +    Serial.print("PWM frequency PIN D9 and D10 is set to: "); Serial.println(frequencyFan); 
 +  } 
 +  if(successPeltier) { 
 +    Serial.print("PWM frequency PIN D3 and D11 is set to: "); Serial.println(frequencyPeltier); 
 +  } 
 + 
 +  // Initialisiert die PID-Regler 
 +  fanPID.SetMode(AUTOMATIC); 
 + 
 +  // Meldung "Klar zum Start!" 
 +  Serial.println("<Arduino is ready! Turn the potentiometer, please ...>");  
 +
 + 
 + 
 +void loop() { 
 +  // Aktuelle Zeit abfragen 
 +  unsigned long currentMillis = millis(); 
 +   
 +  // Lese die analogen Inputs aus 
 +  potiValue = analogRead(potiPin);                    // Poti 
 +  thermistorValue = analogRead(thermistorPin);        // Thermistor 
 +  averageThermistor.addValue(thermistorValue);        // Wert wird an Running Average übergeben  
 +   
 +  // Berechnung der Temperatur 
 +  thermistorValue = averageThermistor.getAverage();   // Der Mittelwert wird eingelesen 
 +  thermistorValue = 1023 / thermistorValue - 1;        
 +  thermistorValue = 10000 / thermistorValue;          // Der Wert wird in einen Widerstand umgerechnet 
 +   
 +  float temperatur; 
 +  temperatur = thermistorValue / 10000;               // (R/Ro) 
 +  temperatur = log(temperatur);                       // ln(R/Ro) 
 +  temperatur /= 3950;                                 // 1/B * ln(R/Ro) 
 +  temperatur += 1.0 / (25 + 273.15);                  // + (1/To) 
 +  temperatur = 1.0 / temperatur;                      // Invert 
 +  temperatur -= 273.15;                               // convert to C 
 + 
 +  // Regelung des Lüfters (TEST) 
 +  Input = temperatur;                                 // Input ist die Temperatur des Thermistors in *C 
 +  Setpoint = 10 + float(potiValue * 0.02);            // Setpoint ist die Temperatur zwischen 10 und 30 *C 
 +  fanPID.Compute();                                   // PID-Regler wir aufgerufen 
 +  pwmWrite(fanPin, Output);                           // Gibt den Output des PID-Reglers an den Lüfter 
 + 
 +  // Wenn der Output des PID-Reglers Null ist, wird der Lüfter ausgeschaltet. 
 +  if (Output > 0) { 
 +    digitalWrite(powerPin, HIGH); 
 +    //Serial.print("HIGH"); Serial.print("; "); 
 +  } 
 +  else { 
 +    digitalWrite(powerPin, LOW); 
 +    //Serial.print("LOW"); Serial.print("; "); 
 +  } 
 +   
 +  //use this functions instead of analogWrite on 'initialized' pins 
 +  //pwmWrite(fanPin, potiValue / 4);                    // Gibt den Potiwert an den Lüfter 
 +  pwmWrite(peltierPin, potiValue / 4);                // Nur zu Testzwecken 
 +   
 +  // Messung der Pulsweite des Tachosignals 
 +  tachoSignal = digitalRead(tachoPin); 
 +  if (tachoSignal == HIGH && high != true) {          // Zeit in micros bei ansteigender Flanke 
 +    pulseOn = micros(); 
 +    high = true; 
 +  } 
 +  else if (tachoSignal == LOW && high == true) { 
 +    pulseOff = micros();                              // Zeit in micros bei fallender Flanke  
 +    high = false; 
 +    duration = pulseOff - pulseOn;                    // Aus der Differenz wir die Dauer berechnet, die das Tachosignal HIGH ist 
 +    if (duration > 7000 && duration < 150000) {       // Liegt die Variable über bzw. unter den angegebenen Werten, liegt ein Messfehler vor 
 +      rpm = float(100000 * 2 * 60 / duration);        // Berechnung der RPM 
 +    } 
 +    else { 
 +      rpm = 0; 
 +    } 
 +    averageRPM.addValue(rpm); 
 +  } 
 + 
 +  // Wenn der Lüfter angehalten wird, soll die Drehzahl "0" angezeigt werden 
 +  if (Output == 0) { 
 +    rpm = 0; 
 +    averageRPM.addValue(rpm); 
 +  }
  
-http://de.rs-online.com/web/generalDisplay.html?id=infozone&file=automation/npn-pnp+  // Ausgabe an die serielle Schnittstelle 
 +  if ((unsigned long)(currentMillis - previousMillisSerialPrint) >= intervalSerialPrint) { 
 +     
 +    Serial.print("Setpoint");Serial.print(Setpoint); 
 +    Serial.print("; Input: ");Serial.print(Input); 
 +    Serial.print("; Output: ");Serial.print(Output); 
 +    //Serial.print("; pulseOn: ");Serial.print(pulseOn); 
 +    //Serial.print("; pulseOff: ");Serial.print(pulseOff); 
 +    //Serial.print("; Duration: "); Serial.print(duration); 
 +    Serial.print("; RPM: "); Serial.print(rpm); 
 +    Serial.print("; average RPM: "); Serial.print(averageRPM.getAverage()); 
 +    Serial.print("; Temperatur: "); Serial.println(temperatur); 
 +   
 +  //Speichere die aktuelle Zeit in die zughörige Variable 
 +  previousMillisSerialPrint currentMillis; 
 +  } 
 +
 +</code> 
 +Der Sketch verwendet 8590 Bytes (27%) des Programmspeicherplatzes. Das Maximum sind 30720 Bytes. 
 +Globale Variablen verwenden 579 Bytes (28%) des dynamischen Speichers, 1469 Bytes für lokale Variablen verbleiben. Das Maximum sind 2048 Bytes.
  
-Tags: #Arduino #Nano #PC-Lüfter+Tags: #Arduino #Flaschenkühler #Nano #PC-Lüfter
arduino/flaschenkuehler/programmversion_0.1.1498998715.txt.gz · Zuletzt geändert: 18.05.2023 12:16 (Externe Bearbeitung)