Digitale Spannungsregelung mit MOSFET und Arduino über PWM (Teil 3)

Nach den theoretischen Grundsatzüberlegungen im 2. Teil erfolgt nun der praktische Aufbau im 3. Teil, allerdings verbunden mit weiteren theoretischen Grundlagen. Digitale Spannungsregelung mit SpannungsteilerHier nun erst einmal die veränderte Hardware und eine wichtige Warnung gleich noch mit dazu! Die Spannung an allen Pins des Arduino darf die Versorgungsspannung keinesfalls (typ. 5V oder auch 3,3V je nach Board) überschreiten! Mir sind während des Aufbaues und der ersten Versuche nacheinander gleich 2 Analogeingänge meines Atmega 328 wegen versehentlicher Überspannung durch Unachtsamkeit abgeraucht. Aus verständlichen Gründen kann ich grundsätzlich keine Haftung übernehmen! Ich kann grundsätzlich auch nicht garantieren, dass die Hardware oder die Software einwandfrei funktioniert. Auch dieser Teil ist als Nachbauanleitung nicht geeignet und soll hauptsächlich zur Diskussion anregen und Grundlagen vermitteln. Das interessante Kopfbild zum Beitrag habe ich übrigens hier gefunden. Hier lässt sich sich recht gut erkennen, wie sich durch Veränderung der Pulsbreite der mittlere Gleichspannungsanteil ebenfalls verändern lässt.

Die Hardware

Zur Messung der Ausgangsspannung habe ich in diesem Entwurf zuallererst noch einen Spannungsteiler vorgesehen. Ich habe mich hier für 100k Metalschichtwiderstände mit 1/4 Watt und 1% Toleranz entschieden. Durch die Parallelschaltung der 3 Widerstände R7 bis R9 ergibt sich für den unteren Teiler ein Wert von 33,333k während R6 bei seinen 100k verbleibt . Dadurch ergibt sich ein Spannungsteiler der auf 1/4 herunterteilt. Bei angenommenen 10V Ausgangsspannung, die direkt am Elko C1 gemessen werden, fließen durch das Widerstandsnetzwerk (100k + 33,333k) etwa 75uA.

I = U/R = 10V / 133,333k = 75uA

Damit messen wir am unteren Spannungsteiler bestehend aus der Parallelschaltung der Widerstände R7 bis R9 bei 10V Eingangsspannung nur noch ungefährliche 2,5V.

U = R * I = 33,333k * 75uA = 2,5V

Damit die Eingangsspannung am Analogeingang A2 des Arduino Uno ungefährliche 5V jetzt nicht doch noch übersteigt, darf die Spannung am Elko C1 daher 20V keinesfalls überschreiten, bei nur 3,3V Betriebsspannung eben entsprechend weniger!

Ohne eine Mindestlast am Ausgang funktioniert die Schaltung nicht, da sich der Elko C1 nicht schnell genug entladen kann. Dafür sind erst einmal die Kontroll LED1 und der Vorwiderstand R2 mit 330Ω vorgesehen. Besonders bei höheren Ausgangsspannungen größer 5V muss R2 ggf. auf 1k oder auch noch größer erhöht werden.

Die Basis von T1 wird über einen Vorwiderstand vom Arduino Digital Pin 6 angesteuert. Ein HIGH-Signal schaltet den bipolaren NPN Transistor durch, die Kollektor-Emitterstrecke wird dadurch niederohmig. Über R4 ist der Kollektor mit dem Gate des P-Kanal MOSFETs Q1 verbunden und schaltet die Drain-Sourcestrecke damit ebenfalls niederohmig. Grundsätzlich kann das Verhalten eines P-Kanal MOSFETs mit einem PNP Transistor verglichen werden. Das Gate ist allerdings im Vergleich zur Basis extrem hochohmig. Während ein bipolarer Transistor bereits ab 0,6V Basis-Emitterspannung anfängt leitend zu werden, typisch sind hier etwa 0,7V, beginnt der hier verwendete MOSFET ab etwa 4V Spannungsdifferenz zu leiten; allerdings können damit noch keine größeren Ströme getrieben werden! Die typisch nutzbare Gate-Sourcespannung beträgt hier etwa 10V und darf laut Datenblatt 20V nicht überschreiten. Um das Ansteigen der Gate-Sourcespannung auf über 20V zu begrenzen, ist die Zenerdiode D1 vorgesehen, die hier auf ungefährliche 10V begrenzt. Es sollte aber auch jede andere 500mW Zenerdiode zwischen 10V und 20V funktionieren. R1 dient zum sicheren sperren des MOSFETS.

Der Siebelko C1 sollte möglichst eine schaltfeste Ausführung sein, wie sie auch in Schaltreglern verwendet werden.

Arduino PWM

Der hier verwendete Arduino Uno hat 6 PWM-Ausgänge, jeweils 2 werden gemeinsam über einen intenen Timer gesteuert. Ausgehend von der üblichen Taktfrequenz des Quarzes mit 16MHz ergeben sich folgende Werte:

  • Timer 0     PWM-Pins 5+6        976,5625Hz        auch genutzt für millis() und delay()
  • Timer 1     PWM-Pins 9+10     488,28125Hz     auch genutzt für die Servo Library
  • Timer 2     PWM-Pins 3+11     488,28125Hz

Da das Schalten des MOSFETs möglichst schnell erfolgen sollte, nehmen wir erst einmal einen der über Timer 0 gesteuerten PWM-Pins, hier Digital-Pin 6. PWM-Pin 5 und 6 werden mit fast 1kHz getaktet, das entspricht einer Zykluszeit von knapp 1ms. Die 4 weiteren PWM-Pins dagegen werden nur mit der Hälfte der Taktfrequenz getaktet.

PWM, was ist das eigentlich?

PWM heißt Pulse Width Modulation oder auch Pulsbreitenmodulation. Beim hier verwendeten Atmega 328 Arduino PWMwird jeder PWM-Ausgang über einen 8-bit Registerwert kontrolliert und kann damit 256 verschiedene Pulsbreitenzustände zwischen 0 und 255 bzw. 0% (LOW-Pegel)und 100% (HIGH-Pegel) annehmen. Das hat zur Folge, dass mit dem Wert 0 über den Befehl analogWrite(controlPin, 0); der Ausgang konstant auf LOW gesetzt wird, während er mit dem Wert 255 auf konstant HIGH gesetzt wird. Mit dem Wert 1 über den Befehl analogWrite(controlPin, 1); erhalten wir sehr schmale positive Impulse mit der oben erwähnten Frequenz von etwa 976,56Hz, die immer breiter werden, je weiter der Wert erhöht wird. Bei einem Wert von 64 via analogWrite(controlPin, 64); hat dieser positive Impuls bereits eine Breite von 25% der gesamten Zykluszeit von knapp 1ms, also etwa 250ns. Mit analogWrite(controlPin, 127); erhalten wir bereits eine Pulsdauer von 50% also rund 500ns. Je weiter dieser Wert nun erhöht wird, desto breiter der Impuls, bis bei dem Wert 255 ein konstantes HIGH Signal erzeugt wird.

Beginnend mit dem Wert 1 beträgt die Impulsbreite 8us und verlängert sich mit jeder weiteren Erhöhung von 1 um weitere 4us. Mit analogWrite(controlPin, 3); beträgt die Impulsbreite daher bereits 20us. Mit analogWrite(controlPin, 254); beträgt die Impulsbreite dann 253*4us=1012us +1*8us = 1020us und einer verbleibenden Pausenzeit für das LOW-Signal von nur noch 4us. Wird der Wert von 254 auf 255 erhöht, werden auch die letzten 4us zu einem HIGH-Signal und wir erhalten einen konstanten HIGH-Pegel. Berechnen wir aus dem Kehrtwert der 1024us die Frequenz, so erhalten wir übrigens wieder die bereits o. g. 976,5625Hz.

Die Regelung

Die per Spannungsteiler durch 4 heruntergeteilte Ausgangsspannung wird am Analogeingang A2 gemessen. Im Sketch mulitplizieren wir daher den gemessenen istwert actualValueVolt wieder mit dem Faktor 4. Danach vergleichen wir diesen Wert in if-Schleifen mit der Vorgabe aus der definierten Konstante, dem Sollwert outputVoltSetPoint. Ist der gemessene Istwert kleiner als der Sollwert, so erhöhen wir den PWM-Wert um 1 im Bereich von 0 bis 255. Ist der gemessene Istwert größer als der Sollwert, so halbieren wir den aktuellen PWM-Wert. Es reicht hier leider nicht den PWM-Wert einfach wieder um den Wert 1 zu reduzieren, da die Schaltung dann anfängt wild durcheinander zu regeln.

Der Sketch

Gleich zu Anfang werden die benötigten Variablen und Konstanten definiert.

/****************************************************************************************/
/* Simple Arduino regulated power supply 2V to <= 19,9V output with high voltage input >= 10V to 30V max.
*             Input/Output voltage difference should 10V not exceed for better output ripple.
*             With actual given voltage divider, output voltage may not exceed 19,9V!!!
*
* Attention:  Don’t adjust output voltage via outputVoltSetPoint higher than 5V without voltage divider, to
*             protect your Arduino analog input! Only max. 5V at all the pins are allowed!
*             Power MOSFET needs cooling while powering > 0,25A!
*
* Reference:
*
*
* Origin Author:        Olaf Meier
* Modified by:
*
* Hardware connection:  Attention! Minimum load is needed to discharge output capacitor!
*                       Connect Gate of MOSFET to Collector of NPN T1 via 10k, not bigger due to C-load   of MOSFET
*                       Connect Basis of T2 via 10k to pin 7 for voltage control
*                       Connect U_Out, Drain of Q1 to A2 for voltage measurement via divider
*
*                       Minimum load always needed!
*
* * ToDo:
*
*/
/****************************************************************************************/
/*
* Example of output:    In normal state HIGH-Level min. 8uS in steps of 4uS, LOW-Level is variable,
*
*
*/
/****************************************************************************************/
/****************************************************************************************/
/***  Declaration of global constants and initialization of variables. Add includes.  ***/
/****************************************************************************************/
/***  Software release and date  ***/
const char* author                     =  „Olaf Meier“;
const char* revision                   =  „R.1.0 „;
const char* date                          =  „2013/08/31“;
#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 adjustable voltage regulator  ***/
const byte actualValueVoltPin          =  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
/***  Don’t adjust output voltage higher 19.500mV = 19,5V with existing resistor divider  ***/
/***  Regulation does not work higher 20V!!!  ***/
const unsigned int outputVoltSetPoint  =  2500;    // Adjust output voltage (Set 0000 to 5000 in mV, depending on voltage divider)
unsigned int actualValueVolt               =  0;       // Initialize measured output voltage with 0mV to start with/***  Declare constants and variables for resistor voltage diviver at the analog input   ***/
const unsigned int voltageDivider      =  4;    // Value depending on ratio of the resistor voltage dividerbyte PWMValue                             =  0  ;     // Initialize PWM value
/****************************************************************************************/
/****************************************************************************************/
void setup() {                                     // Function Setup
}                                                               // End of void setup() loop
/****************************************************************************************/
/****************************************************************************************/
void loop() {                                      // Function Loop
/***  Calculate mV based on the 10-bit AD-Converter values from 0..1023  ***/
actualValueVolt = ((refVolt * 1000) / 1023) * (analogRead(actualValueVoltPin)) / 1000;
actualValueVolt *= voltageDivider;               // Multiply measured analog in voltage depending on divider factor
/***  Output voltage regulation  ***/
if(actualValueVolt < outputVoltSetPoint)         // Switch on MOSFET while increasing HIGH time of Digital Pin 6
analogWrite(controlPin,PWMValue++);
if(actualValueVolt > outputVoltSetPoint)
analogWrite(controlPin,PWMValue/=2);           // Reduce HIGH time of the PWM signal
}                                                  // End of void loop()
/****************************************************************************************/
/****************************************************************************************/

Ein Kommentar zu „Digitale Spannungsregelung mit MOSFET und Arduino über PWM (Teil 3)

  1. Bringst du die Regelung durch das halbieren des PWM-Outputs nicht zum atändigen Schwingen und gleichzeitig ist der Wert immer kleiner

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