Go Down

Topic: Voltage control with PWM-signal (Read 9563 times) previous topic - next topic

msensor

Hello,
I'm attempting to use an Arduino Uno to modulate the output voltage according to a signal supplied from a sensor. Acquiring the signal from the sensor works fine, but I'm having some problems controlling the output voltage.

I'm using a Sensair Sensor with an I2C connection which supplies Values for relative humidity, temperature and CO2 concentration. This part works fine so I have for now set that aside and am writing into the code a constant value (mV) which should be achieved as the output voltage. Once this is working, I'm planning to replace the constant value with the input from the sensor, scaled according to the appropriate voltage range.

I'm using a variable power supply as power source, and the FDS6990A logic-level MOSFET (data sheet attached) to control the output, with a signal from one of the PWM pins of the Arduino connected to the gate. I've read through much of the online information regarding these processes and have adopted code and hardware configurations from various sources, yet it's still not functioning properly. I've included relevant code below and a schematic diagram of my circuit as an attachment.

Here I tie in the necessary libraries and initialize variables
Code: [Select]

#if ARDUINO < 100
#include <WProgram.h>                          // Add other libraries on demand as requested
#else
#include <Arduino.h>                               // Needed when working with libraries
#endif
#include <stdio.h>
/***  Declare constants and variables for the adjustable voltage regulator  ***/
const byte actualValueVoltPin       =  A1;      // Measure regulated voltage
const byte controlPin                  =  11;       // 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!!!  ***/

/////////////ADJUST VOLTAGE SETPOINT AND DURATION HERE///////////////////
const unsigned int outputVoltSetPoint  =  7000;    // Adjust output voltage (Set 0000 to 5000 in mV, depending on voltage divider)
const unsigned int duration            =  180;     //duration in seconds
///////////////////////////////////////////////////////////////////////////////////////////////////

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
byte PWMValue =  0  ;                              // Initialize PWM value
unsigned long time;
long Interval                          = 1000;
int row = 0;
int duration_m = duration*1000;   


Here I turn off the internal pull-up resistor and set the output pin to high:
Code: [Select]

void setup() {                             
     
//////Turn Pull-up Resistor on/off/////////////////////
pinMode(1+14, INPUT);      //both lines, (x+14, ...) x=PinNumber
digitalWrite(1+14, LOW);  //HIGH -> Resistor on
delay(100);
//////end adjust pull-up/////////////////////////////////

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

Serial.begin(128000);
Serial.println("CLEARDATA");
Serial.println("LABEL,Time,millis,set,voltage,pwm");
}       


Ultimately I want to use the output voltage for electrolysis in water, or to produce heat by means of a resistance wire. I've tested it so far with the electrolysis (3 uA by about 8V output voltage) and also simply with an LED parallel to a capacitor as a load. I've been setting the input voltage at about 15V, but have also tried lower and higher values.

The output voltage is measured at the analog A1 pin of the Arduino after being reduced to a quarter of it's actual level by a voltage divider. Then the value is multiplied by four in the program and used to adjust the PWM-signal (see code below). This is the idea, but it isn't working. The PWM-signal adapts as it should, but the output voltage doesn't respond. I suspect that it is a hardware problem.


Code: [Select]

void loop() {                                    // Function Loop
/***  Calculate mV based on the 10-bit AD-Converter values from 0..1023  ***/

unsigned long currentMillis = millis();
actualValueVolt = ((refVolt * 1000) / 1023) * (analogRead(actualValueVoltPin)) / 1000;
actualValueVolt *= voltageDivider;               // Multiply measured analog in voltage depending on divider factor
/***  Output voltage regulation  ***/
if((actualValueVolt < outputVoltSetPoint)&&(PWMValue<255))  // Switch on MOSFET while increasing HIGH time of Digital Pin 6
  analogWrite(controlPin,PWMValue++);
if((actualValueVolt > outputVoltSetPoint)&&(PWMValue>0))
analogWrite(controlPin,PWMValue--);             // Reduce HIGH time of the PWM signal


I've tried many configurations, including other MOSFETs (not logic level, with a driver or a NPN transistor), but none have produced the correct results. 
Here are some details regarding the incorrect functioning:
  • With negative lead from power supply connected to source of MOSFET and to ground or Arduino, output voltage is measured to be about the same as input voltage
  • When connection to ground removed, measured output voltage drops, but still rises and falls proportionately with power supply voltage and not according to set-point voltage in Arduino code
  • With 1000uF, 35V capacitor in line between drain and negative pole of electrolysis, voltage drops below that of power supply but slowly rises and does not seem to be affected by PWM-signal from Arduino


I would be most appreciative of any insights or suggestions!

Robin2

PWM is intended to control the amount of energy rather than the voltage. If it is ON all the time you get the maximum amount of energy. If it only ON for 50% of the time you get 50% of the energy averaged over a period of time. However the actual voltage is either HIGH or LOW.

You can use an RC filter to smooth the voltage. However if you want to control a voltage you would be better to use Digital to Analog Converter chip.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

TomGeorge

Hi,
Do you have a DMM?
Do you have gnd of the arduino connected to Vin- of the other supply?
It doesn't look like it, so the MOSFET cannot turn ON due to no gnd reference to the arduino signal.

Tom..... :)
Everything runs on smoke, let the smoke out, it stops running....

msensor

Hello,
Thank you both for your responses!

@R: I've read a lot of descriptions on various sites of the PWM signal being used to control a voltage via a MOSFET. I had thought that although the PWM signal is always switching between high and low, that due to the rapid nature of the switching, one could assume that a voltage ranging from 0 to 5V (for the Arduino) was being emitted from the PWM output and that this could be utilized to control the gate of a MOSFET. I selected a logic level MOSFET with a low Rds on so that it could respond to the PWM output without a transistor or driver in between...but ofcourse it's not working.
I looked here   http://provideyourown.com/2011/analogwrite-convert-pwm-to-voltage/   regarding digital-analog conversion.
You mentioned an RC-Filter as a means to (merely) smooth the voltage. While this could be nice it's not crucial at this point. In this article though, it looks like this RC-circuit is used in conjunction with the MOSFET, but not with a digital-analog converter chip. I'd like to stay with the MOSFET since I've invested some time in trying to get this system to work in this way. Do you think this sort of circuit with the PWM-signal, RC-filter and MOSFET could work?

@Tom:
I do have a Digital Multimeter (DMM). That's what I'm measuring the output voltage with.
I do not have the Gnd of the Arduino connected to the Vin- of the power supply.
Various parts of the circuit are connected to the Arduino Gnd, but not to the Vin-. I have the Arduino powered by the 12V power supply, and thought that Gnd was somehow connected to that (but now that I think more about it, I realize that the 12V power supply actually have a ground pin...) I'll try connecting the Gnd from the Breadboard (where the circuit is assembled) to the Vin- of the power supply as well as to the Arduino Gnd and see if that works better.

Marcus


msensor

Hello again,
I've connected the ground from the breadboard to the Vin- from the power supply. The ground from the breadboard is also connected to the Arduino Gnd as it was previously. Now the measured output voltage changes proportionately to the input voltage, but does not seem to be affected by the voltage defined by as the setpoint in the code - the MOSFET still does not seem to be affecting the output voltage.
Marcus

MAS3

I had thought that although the PWM signal is always switching between high and low, that due to the rapid nature of the switching, one could assume that a voltage ranging from 0 to 5V (for the Arduino) was being emitted from the PWM output and that this could be utilized to control the gate of a MOSFET.
Assumptions always are quite some risk to take.
Do you know how rapid the Arduino PWM is switching ?
You'll be surprised by the actual number.

Your multimeter is a poor instrument to use to measure PWM signals, if you do not absolutely understand how this PWM (and the multimeter) works.
That multimeter has a slow update rate, in which it will show you an average of the voltage measured.
So what you see is something different from what's actually going on.

Robin2's description of PWM is very accurate and short.
Have a look at "blink without delay".
Did you connect the grounds ?
Je kunt hier ook in het Nederlands terecht: http://arduino.cc/forum/index.php/board,77.0.html

TomGeorge

#6
Apr 05, 2015, 12:11 pm Last Edit: Apr 05, 2015, 12:22 pm by TomGeorge
Hi,

Can you post your entire sketch in one piece please.
If it won't fit in the code tags, please attach it so we can see it complete.
Can you also post a complete circuit diagram, including power supplies, sensor, MOSFET and gnd connections.
R1 in your original circuit should be 10K not 220R, it may be stopping any decent signal to the gate.
What is the output voltage controlling?
Tom.... :)
Everything runs on smoke, let the smoke out, it stops running....

TomGeorge

#7
Apr 05, 2015, 12:31 pm Last Edit: Apr 05, 2015, 12:47 pm by TomGeorge
Hi,
Why is the 1000uF capacitor in series with your load or what ever you are driving.
You will not get any feedback volts unless you have tested with a load at Vout, what was the load?

Tom.... :)
Everything runs on smoke, let the smoke out, it stops running....

TomGeorge

Hi,
the attached circuit is probably what you are trying to attain, but as pointed out you are trying to measure a PWM voltage and if you have no load the nyou will have no voltage to sense at the MOSFET Drain.

Tom..... :)
Everything runs on smoke, let the smoke out, it stops running....

msensor

Hi,
Ok, here is the entire code.

Code: [Select]
/****************************************************************************************/
/* 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
#include <stdio.h>
/***  Declare constants and variables for the adjustable voltage regulator  ***/
const byte actualValueVoltPin          =  A1;      // Measure regulated voltage
const byte controlPin                  =  11;       // 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!!!  ***/

/////////////ADJUST VOLTAGE SETPOINT AND DURATION HERE////////////////////////////////////////////////////////////////////////////////////////
const unsigned int outputVoltSetPoint  =  7000;    // Adjust output voltage (Set 0000 to 5000 in mV, depending on voltage divider)
const unsigned int duration            =  180;     //duration in seconds
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

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
byte PWMValue =  0  ;                              // Initialize PWM value
unsigned long time;
long Interval                          = 1000;
int row = 0;
int duration_m = duration*1000;                        //duration in milliseconds
/****************************************************************************************/
/****************************************************************************************/
void setup() {                                   

//////Turn Pull-up Resistor on/off/////////////////////
pinMode(1+14, INPUT);      //both lines, (x+14, ...) x=PinNumber
digitalWrite(1+14, LOW);  //HIGH -> Resistor on
delay(100);
//////end adjust pull-up/////////////////////////////////
pinMode(controlPin, OUTPUT);                     // Pin to control the output voltage
digitalWrite(controlPin,HIGH);                    // Switch on MOSFET to drive current to the output RC

Serial.begin(128000);
Serial.println("CLEARDATA");
Serial.println("LABEL,Time,millis,set,voltage,pwm");
}                                                // End of void setup() loop
/****************************************************************************************/
/****************************************************************************************/
void loop() {                                    // Function Loop
/***  Calculate mV based on the 10-bit AD-Converter values from 0..1023  ***/

unsigned long currentMillis = millis();
actualValueVolt = ((refVolt * 1000) / 1023) * (analogRead(actualValueVoltPin)) / 1000;
actualValueVolt *= voltageDivider;               // Multiply measured analog in voltage depending on divider factor
/***  Output voltage regulation  ***/
if((actualValueVolt < outputVoltSetPoint)&&(PWMValue<255))  // Switch on MOSFET while increasing HIGH time of Digital Pin 6
  analogWrite(controlPin,PWMValue++);
if((actualValueVolt > outputVoltSetPoint)&&(PWMValue>0))
analogWrite(controlPin,PWMValue--);             // Reduce HIGH time of the PWM signal


/////transfer via PLX-DAQ////////////////////////////
  Serial.print("DATA,TIME,");
  Serial.print(currentMillis);
  Serial.print(",");
  Serial.print(outputVoltSetPoint);
  Serial.print(",");
  Serial.print(actualValueVolt);
  Serial.print(",");
  Serial.println(PWMValue);
  row++;
  delay(10);
}
//////to see in Arduino Monitor////////////////
/*if(outputVoltSetPoint>0){
  Serial.print("Set=");
  Serial.print(outputVoltSetPoint);
  Serial.print(" mV |  ac.V=");
  Serial.print(actualValueVolt);
  Serial.print(" mV | PWM=");
  Serial.print(PWMValue);
  Serial.println(); 

//}
//else {
//  Serial.print("something is not right...");
//}
} //end if loop////////////////////
*////////////////////////////////////////////////


I have replaced the 220R Resistor indicated as R1 on my original circuit diagram with a 10k resistor.

I currently have the Arduino plugged into the 12V power supply. Previously I had it connected to the computer and was able to read current PWM signals and the current voltage which was supposedly being output (Vout). This output voltage did not correspond with the voltage I measured with the DMM. I stopped having the Arduino connected to the computer because later I want it to function without the computer and I thought if I set it up that way now (without the connection to the computer) it would be one less variable to think about.

I currently have the V_out+ and V_out- connected to an anode and cathode in a jar of water. I can see bubbles rising, so electrolysis is taking place, and yesterday I measured 3uA current with 8V output voltage... but perhaps this isn't a proper load? I previously had an LED as a load, and then also had it in parallel with the 35V 1000uF capacitor. I had seen this configuration on another circuit diagram on which I was basing my own. I think that same capacitor is now still in my current circuit as a left-over from that previous set-up.
Should I remove that capacitor? or perhaps set up a proper load? would an LED be sufficient? and if I set up an LED as the load, should it be with the capacitor in parallel?

With the current setup (R1 as 10k and capacitor still in place) the output voltage, measured with the DMM, still increases proportionately to the input voltage and does not seem to be affected by the PWM signal... it's certainly not going towards 7V as is being requested in the code.

Thanks for all the feedback and suggestions!
Marcus

msensor

Hello,
I now have the circuit set up like in Tom's diagram pwmreg.jpg (Thank you, Tom!), which was very similar to what I had previously... In addition to what is shown in the jpg file, I have two LEDs (parallel to one another) in series with the 1000uF Capacitor, with their negative poles connected to the ground. I also have a lead going from the negative pole of the 1000uF capacitor into my container of water. Another pole is also in the water, connected to the positive output of my variable power supply (V_out +). I am measuring the voltage (with a DMM) between the negative pole by the water jar (essentially right after the capacitor) and V_out+ of the variable power supply. This measured voltage is less than that from the power supply, but changes proportionately to the voltage set at the power supply and does not seem to be being controlled by the arduino/Mosfet. If I pull the positive pole (anode) out of the water jar the LEDs dim and the measured voltage drops. After doing this several times, the LEDs both broke. Putting a new LED back in makes the measured voltage rise again. Without an LED as a load, the voltage measured voltage is closer to what I actually want, but still changes proportionately to the voltage set by the power source.

I'm thinking that the problem might have something to do with the ground. Everything that is grounded is connected to the GND on the Arduino, but nothing is connected to the ground of the variable power supply. Should the other GND pin of the Arduino be connected to the ground of the variable power supply in order to give them a common reference?

I have the arduino plugged into an outlket with a 12V transformer. When I look at this plug, it doesn't have a ground pin. What are the ground pins from the arduino actually connected to?

all the best

CrossRoads

Arduino GNDs connect to negative pin of the barrel jack.

You say transformer - to an engineer that that means you have an AC power source, which then needs diodes for rectification, caps for smoothing, and a regulator.  Arduino boards aren't set up to accept AC as the power source.

Did you mean instead DC from a regulated power supply (i.e. a wallwart)?

Quote
Should the other GND pin of the Arduino be connected to the ground of the variable power supply in order to give them a common reference?
Yes.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

msensor

Hello,
Thanks for the response!
Yes, I did mean the wallwart, that's what I have the arduino plugged into.

I've connected the other GND pin from the arduino to the ground from the variable power supply but it hasn't produced a change in behavior...

msensor

Hello,
In the hopes of finding out what's wrong with my circuit, I've taken a closer look at the datasheet (attached to one of my firsts posts in this thread) for the MOSFET I am using, and trying to better understand what's actually happening. I'm considering the possibility that my MOSFET might be broken… It's a small logic level MOSFET with SO8 architecture, so I had to solder it to an adapter panel; maybe I damaged it while soldering…

The following is what I've done in order to analyze the functionality of my MOSFET. Does it seem to make sense?

My MOSFET has a threshhold voltage V_th of 1.9V (3V max), so I need to apply a greater voltage at the source than this value in order to switch the MOSFET to the on state and allow a current Id to flow. I have been setting V_in=15V, from my variable power source… up to 30V. I have not limited the current of the power supply and the maximum output is 2A. It seems like I should have enough current flowing in order to have the MOSFET switched on and am then in the saturation region (although the current is always displayed as 0 Amps, but with just one decimal point, so perhaps the Amperage is just too low to show up on the display).

For this to be the case, the following inequality needs to be fullfilled:
V_ds > V_gs-V_th

Yet when I measure the voltages of my circuit, I get the values V_gs=41.6mV and V_ds=37.9mV (with the V_in=15V, but the measured values stay the same even when I change V_in. Regardless of whether I use Vth=1.9V or V_thmax=3V, I get a negative value for V_ds which would indicate that I am not in saturation and the MOSFET has not been turned on.

Do I understand this correctly?
Can I expect to get accurate measurements for V_ds and V_gs, or are these unreliable because
a) there are all the other components in the circuit (resistors, capacitors, etc)? or
b) the digital multimeter is not up to the task?

It seems odd that even when I completely turn off the variable power supply, V_gs and V_ds still remain the same. So these voltages are coming from the arduino, which is plugged into the 12V regulated DC power supply.

Does this mean that my MOSFET is broken?

msensor

Hi again,
I now have tested the circuit with a number of different logic level mosfets, using the circuit pictured in the pwm.jpg file. I've attached a small motor as the load. The motor runs on 4-14V and draws 0.143A current. I'm measuring the output voltage which is provided to the motor, and switching the mosfets and entering different voltage setpoints in the code and uploading it to the arduino. Yet the altered voltages in the code have no effect on the output voltage. I've also tried different capacitors between the drain pin and the V- output attached to the motor. The output voltage changes only according to the selected capacitor; when the capacitor is completely removed, the output voltage is the same as the input voltage.

Could it be  that the motor is drawing too little current, and that the mosfet is not activating for this reason?


Go Up