Digitale Spannungsregelung mit MOSFET und Arduino (Teil 1)

Früher oder später benötigt jeder ernsthafte Elektroniker ein einstellbares Niederspannungsnetzteil, möglichst auch mit einstellbarer Strombegrenzung. Ein damals selbstgebautes Netzteil noch aus meinen frühen Jugendjahren begleitet mich auch heute wieder.  Völlig analog aufgebaut versteht sich, also mit 2 parallel geschalteten 2N3055 Leistungstransistoren, einer Zenerdiode als Spannungsreferenz und einem per Poti einstellbaren Regelkreis für die Spannungseinstellung sowie einen 2. Regelkreis über einen niederohmigen Shuntwiderstand zur einstellbaren Strombegrenzung. Damit ist das Netzteil sogar absolut Kurzschlussfest!

Analoges einstellbares Labornetzteil Marke Eigenbau
Einstellbares Labornetzteil Marke Eigenbau

Leider existiert davon kein Schaltplan mehr, ich werde aber bei Gelegenheit versuchen etwas nachzureichen. Was ich zu der Zeit ziemlich uncool fand, nämlich Analogdrehspulinstrumente zu verwenden, hat heute schon wieder einen Touch Nostalgie, da nahezu alles digital angezeigt wird.

Was damals wie heute recht gut auf analoge Weise funktioniert, muss doch auch irgendwie digital funktionieren, oder? Zumindest habe ich es nun einmal versucht.

Also man nehme….

  • Arduino Uno oder Duemilanove oder ähnlich
  • P-Kanal MOSFET mit möglichst niedrigem Rds_On wie zum Beispiel IRF9530
  • Widerstand 100kOhm
  • Widerstand 330 Ohm
  • Elko 1.000uF/35V
  • Diverse LEDs zwecks Überprüfung der Regelung
Testaufbau mit N-Kanal MOSFET
Testaufbau mit P-Kanal MOSFET

Der 100kOhm Widerstand R3 zwischen Gate und Source dient dem sicheren Sperren des P-Kanal MOSFETs. Das extrem hochohmige Gate bekommt damit schlicht das gleiche Potential wie der von der Verorgungsspannung gespeiste Source-Anschluß. Wird das Gate nun über den Arduino Pin 6 (es funktioniert hier grundsätzlich auch jeder andere Digital Pin) auf Massepotential gelegt, wird also damit negativer als der Source-Anschluß, so leitet der MOSFET. Die testweise angelegte 5V Versorgungsspannung vom Arduino Board werden dann vom Source-  zum Drain-Anschluß durchgeschaltet. Der schaltfeste 1.000uF Elko dient zur Siebung der geschalteten Ausgangsspannung. Der Widerstand R2 mit 330 Ohm ist schlichtweg der Vorwiderstand für die LED und beide bilden zusammen die Last zum Testen der Schaltung.

Die Idee ist nun mit dem Analogeingang A2 (es geht hier auch jeder andere Analogeingang) des Arduino die über einen Elko gesiebte Ausgangsspannung am Drain-Anschluß zu messen und zu vergleichen. Ist diese größer als die im Sketch per Konstante „refVolt“ vorgegebene Spannungswert, so bekommt der „controlPin“, hier Digitalausgang 6 des Arduino  High-Pegel und der MOSFET sperrt wieder. Ist die Ausgangssspannung kleiner, so wird der MOSFET durch LOW-Pegel leitend gesteuert.

Nachfolgend der Arduino Sketch:

—————————————————————————————————

/***  Software release and date  ***/
const char* author                      =  „Olaf Meier“;
const char* revision                    =  „R.0.1 „;
const char* date                           =  „2013/08/11“;

/***  Declare constants and variables for the solar charger  ***/
const byte actualValueVoltPin =  A2;      // Measure regulated voltage
const byte controlPin                  =  6;       // Switch on/off for output voltage control

/***  Declare constants and variables for analog input measurement  ***/
const unsigned long refVolt      =  5000;    // Reference voltage default 5V (5000mV) to analog converter; change to 3300 if 3,3V

const unsigned int outputVoltSetPoint  =  3000;    // Regulated output voltage (Set 0000 to 5000 in mV)
unsigned int actualValueVolt     =  0;       // Initialize measured output voltage to 0mV to start with

/******************************************************************************/
/******************************************************************************/
void setup() {                                     // Function Setup

pinMode(controlPin, OUTPUT);                     // Pin to control the output voltage
digitalWrite(controlPin,LOW);                    // Switch on MOSFET to drive current to the output RC

}                                                  // End of void setup() loop
/******************************************************************************/
/******************************************************************************/
void loop() {                                      // Function Loop

/***  Calculate mV based on the AD-Converter values from 0..1023  ***/
actualValueVolt = ((refVolt * 1000) / 1023) * (analogRead(actualValueVoltPin)) / 1000;

/***  Output voltage adjustment  ***/
if(actualValueVolt > outputVoltSetPoint)
digitalWrite(controlPin,HIGH);
else
digitalWrite(controlPin,LOW);

}                                                  // End of void loop()

----------------------------------------------------------------------

Die minimale Schaltzeit des LOW-Pegels um den MOSFET leitend zu schalten liegt bei der jetzigen Sketchgröße bei 160uS und sollte eigentlich ausreichen, um den MOSFET präzise genug leitend zu schalten. Jedoch ohne erkennbaren Grund sinkt die Ausgangsspannung hin und wieder auf 0V ab, obwohl die Regelung grundsätzlich offensichtlich funktioniert. Ausserdem steigt die Ausgangsspannung bei einer Eingangsspannung oberhalb von knapp 9V auf die Eingangsspannung an! Die Versorgung vom Arduinoboard ist dann natürlich getrennt. Arduino und die Schaltung werden getrennt gespeist. Diese beiden Phenomene bleiben auf jeden Fall noch weiter zu untersuchen.

Eine weitere Möglichkeit einen Regelkreis aufzubauen, ist einen der PWM-Ausgänge zu verwenden. Der Hardwareaufbau bleibt identisch.

Nachfolgend der Arduino Sketch dazu:

———————————————————————————————————————

/***  Software release and date  ***/
const char* author                      =  „Olaf Meier“;
const char* revision                    =  „R.0.1 „;
const char* date                           =  „2013/08/11“;

#if ARDUINO < 100
#include <WProgram.h>                              // Add other libraries on demand as requested
#else
#include <Arduino.h>                               // Needed when working with libraries
#endif

/***  Declare constants and variables for the solar charger  ***/
const byte actualValueVoltPi   =  A2;      // Measure regulated voltage
const byte controlPin                  =  6;       // PWM for output voltage control

/***  Declare constants and variables for analog input measurement  ***/
const unsigned long refVolt     =  5000;    // Reference voltage default 5V (5000mV) to analog converter; change to 3300 if 3,3V

const unsigned int outputVoltSetPoint  =  3000;    // Regulated output voltage (Set 0000 to 5000 in mV)
unsigned int actualValueVolt      =  0;       // Initialize measured output voltage to 0mV to start with

byte PWMValue                                =  254;     // Initialize PWM value to 254 creating a short low level peak

/******************************************************************************/
/******************************************************************************/
void setup() {                                     // Function Setup

}                                                  // End of void setup() loop
/******************************************************************************/
/******************************************************************************/
void loop() {                                      // Function Loop

/***  Calculate mV based on the AD-Converter values from 0..1023  ***/
actualValueVolt = ((refVolt * 1000) / 1023) * (analogRead(actualValueVoltPin)) / 1000;

PWMValue = constrain (PWMValue, 0, 255);

/***  Output voltage adjustment  ***/
if(actualValueVolt < outputVoltSetPoint){
analogWrite(controlPin,PWMValue–);
delay(1);                                     // Delay needed to settle PWM output
}
if(actualValueVolt > outputVoltSetPoint){
analogWrite(controlPin,PWMValue=255);
delay(1);                                     // Delay needed to settle PWM output
}

}                                                  // End of void loop()

——————————————————————————————————————–

Wirklich überzeugend stabiler läuft dieser Weg zur Regelung der Ausgangsspannung allerdings bei höheren Eingangsspanunngen ab etwa 8V bis 9V wider Erwarten auch nicht. Nun hatte ich erste einmal keine weitere Idee. Zusammengefasst scheint es bei beiden Lösungen zu ähnlichen unerwünschten Effekten zu kommen. Unvermittelte Spannungseinbrüche bis runter auf etwas 0V sowie das Ansteigen der Ausgangsspannung auf den Pegel der Eingangsspannung, sofern diese etwa 8V-9V übersteigt.

An solchen Stellen erst einmal alles an die Seite zu legen, ist häufig eine gute Entscheidung. Das habe ich an dieser Stelle deshalb auch so gemacht. Jedoch bereits am nächsten Tag kam ich schon wieder etwas ins grübeln. Ein Blick ins Datenblatt des MOSFET brachte dann auch sofort etwas Licht ins Dunkel. Sobald bei Zimmertemperatur die Gatespannung um etwa 4V negativer als die Sourcespannung wird, fängt der MOSFET schon an zu leiten. Bei 5V kann er bereits grob die Hälfte des Maximalstromes und bei 10V den Maximalstrom liefern. 20V darf sie allerdings nicht überschreiten! Damit war klar, warum die Schaltung bei 5V bereits recht orderntlich funktionierte, da ich auch keine großen Ströme benötigt hatte; bei knapp 9V jedoch nicht mehr funktionierte, da bei 4V Spannungsdifferenz der MOSFET bereits anfängt zu leiten. Um auch größere Spannungen regeln zu können, muss die Schaltung daher angepasst werden. Das zweite Phänomen, das zeitweise Aussetzen der Regelung und der Einbruch der Spannung auf 0V ist damit jedoch noch nicht erklärt. Also habe ich bei nächster Gelegenheit ein Oszilloskop bemüht. Irgendwo mußte es auch hier eine Gemeinsamkeit geben, da bei beiden Sketchen das identische Fehlverhalten auftritt.

Ausfall der Regelung 1,6s
Ausfall der Regelung für etwa 1,6s

Mit etwas Geduld ist es mir gelungen genau diese Aussetzphase festzuhalten. Wie hier zu sehen ist, bricht der H-Pegel des PWM-Signales (oben links in Grün) generell von 5V auf etwa 4,4V zusammen, ein PWM-Signal gibt es dazu nicht mehr.  Nach etwa 1,6 Sekunden fängt die Regelung wieder an. Das untere Signal zeigt parallel dazu den Verlauf der Ausgangsspannung. Bei dieser Messung hier sind der Arduino und der MOSFET mit getrennter Versorgungsspannung betrieben worden. Der Arduino über USB,  der MOSFET über das regelbare Netzteil mit 4,5V! Weitere Vergleichsmessungen mit anderen Konfigurationen haben dann ergeben, dass dieser Fehler bei Betrieb des Arduino mit einem 12V Steckernetzteil  definitiv nicht mehr auftritt! Warum das so ist, werde ich demnächst noch etwas genauer untersuchen müssen. Für den Moment reicht es mir zu wissen, dass beide Softwareversionen sich zur Spannungsregelung eignen können. Mehr dazu in einem weiteren Teil zu einem späteren Zeitpunkt.

3 Kommentare zu „Digitale Spannungsregelung mit MOSFET und Arduino (Teil 1)

  1. Hallo Olaf,
    1. Zyklische Aussetzer
    Die periodischen Aussetzer der Schaltung sind durch die Windows Eigenschaft erklärbar, zyklisch USB auf angeschlossene Geräte zu prüfen, wobei Datentraffic am USB Anschluß entsteht. Dummerweise erzeugt traffic Interupts am Arduino.
    Abhilfe: Eine separate Spannungsversorgung verwenden und den USB Anschluß trennen, oder den entsprechenden Arduino Interrupt ausschalten.

    2. Ankopplung des P-Kanal Leistungs Mosfets an den Arduino
    Was Du Open Kollektorschaltung nennst, hat den Fachbegriff Emitterschaltung. Die hat den Nachteil, nicht besonders schnell schalten zu können, da Du die Emitterschaltung wenn sie leiten soll bis in die Sättigung treibst. Das gibt Schaltverluste (Wärme). Nimm besser die Basisschaltung. Die ist schnell und Du brauchst keine Zenerdiode. Also, z.B.den NPN Transistor BC547B, oder besser BC547C mit der Basis an die 5V Versorgung des Arduinos. Den Emitter schaltest Du über 3,9 kOhm an den Ausgangspin des Arduinos. Wenn der Ausgangspin auf Null schaltet, fließt ein Emitterstrom von I=U/R = (5V-0,55V)/3900Ohm = 1,14 mA. Den Kollektor schaltest Du an das Gate des Mosfets. Sobald der BC547 leitet, holt er sich diese 1,14 mA über den Kollektor. Wenn Du zwischen Gate und Source des Mosfets 4,7 kOhm schaltest, werden eben diese 1,14 mA zu 5,4 V Spannungsabfall führen.
    Im Ergebnis ist U(GS) = 0V bei U(Arduinopin) = 5V und U(GS) = -5,4V bei U(Arduinopin) = 0V.

    Genau genommen fließen über den Kollektor 1,5…4,6 µA weniger, als 1,14 mA, denn über die Basis fließt ein um die Transistorverstärkung (250…750) verringerter Betrag von den 1,14 mA ab.
    Die oben aufgeführte 0,55 Volt ist die ungefähre Basis-Emitterspannung wenn der Transistor leitet. Je nach Exemplar und Stromstärke kann sie 0,5…0,6 liegen. Die Streuungen sollten jedoch für die Funktion unerheblich sein.

    Gruß und viel Erfolg, Rainer

    1. Hallo Rainer,

      vielen Dank für Deine interessanten Ausführungen. Ich werde sie bei nächster Gelegenheit einmal austesten. Die Aussetzer sind mit Einsatz eines neueren PCs übrigens nicht mehr aufgetreten. Habe jetzt noch nicht weiter analysieren können ob das Zufall ist oder eine andere Systematik dahintersteckt.
      Ich werde wieder berichten.

      Gruß Olaf

  2. Gute Ausarbeitung und echt schön durchgerechnet Rainer – gefällt mir gut. Keine unnötigen Brücken und trotzdem schön ausgesteuert. Nette Idee mit dem BC in Gateschaltung, muss ich zugeben.
    Mehr als eine interessante Ausführung, Olaf – Rainers Ansatz müsste einwandfrei
    funktionieren.

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden /  Ändern )

Google Foto

Du kommentierst mit Deinem Google-Konto. Abmelden /  Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden /  Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden /  Ändern )

Verbinde mit %s