Generate analog 10VDC with arduino

I am trying to generate 0...10V DC with pwm.

I found schematic from another thread
Screenshot from 2022-01-14 20-28-56

I did solder it, I didn't have 680R resistor so I used 330R+330R=660R
I am using ESP32 and following code:

const int ledPin = 2;
const int freq = 5000;
const int ledChannel = 0;
const int resolution = 8;
void setup(){
  ledcSetup(ledChannel, freq, resolution);
  ledcAttachPin(ledPin, ledChannel);

void loop(){
    ledcWrite(ledChannel, 255);

255 gives me: 6,13V
180 gives me: 7,04V
128 gives me: 7,74V
70 gives me: 8,69V
0 gives me: 10.32V

The circuit works but I would like that the pwm 255 would give me near 0V and pwm 0 would give me 10V like it does now.
What could I change to get the circuit to work 0...10V?

I think you can run it through an inverter before the transistor.

When you write the number precede it with the tilde "~" sign ~ (bitwise not) that requires only minor software changes and no hardware fixes.

"0-10volt" and "ledChannel" in your code suggests you want to control a LED driver.
Is this a MeanWell driver?
Then just connect collector to DIM+ and emitter/ESP grouund to DIM-
NO 12volt supply, NO collector resistors, NO cap.

It's actually some random code from internet. I am trying to use it to control proportional valve that takes 0-10V DC to control valve location.

I also found Grumpy_Mike schematic.

A single transistor is usually not a very good way to convert PWM to 0-10volt.
Better to convert ESP 3.3volt PWM first to 0-3.3volt DC with an RC filter, and then amplify it with an opamp three times to 0-10volt.
Or use a PWM to 0-10volt breakout board from ebay.


Does the other thread say what PWM frequency that circuit is designed for?

The circuit is designed to operate at a specific frequency.

For what controller was it designed? A 5V or 3V3.
If 5V then 3V3 is possibly not producing the base current to saturate the transistor, the fact that 255 will no give you 0V, means that the transistor is not being turned fully ON.

Tom.... :grinning: :+1: :coffee: :australia:

Then something is wrong with your circuit - the circuit you have drawn should perform much better than that. Check the transistor pinout is correct for instance.

If you have a component tester check the BC183 is working properly too.
You should be seeing 12V for pwm=0 and perhaps 0.2 to 0.5V maximum for pwm=255

Have you got an oscilloscope? If so, put it on the output pin of the Arduino and see what the waveform looks like with various values sent to ledcWrite. By the way, the output voltage should fall as you increase the value.

You are using some mysterious functions. What it does with regular analogWrite?

What voltage do you measure at the output pin D2 of the ESP32 with 0 and 255 as duty cycles?

Thanks.. Tom.. :grinning: :+1: :coffee: :australia:

For the ESP8266, the default 'analogWrite' range is 1023, not 255 like the other Arduino. I haven't used ESP32 but you can try adding the 'analogWriteRange (255)' command in the 'void setup ()' - for ESP8266 its works.

PWM frequency: The thread doesn't say what should the frequency be.
A 5V or 3V3: I measured the pin2 with multimeter and it is giving 3V3. That might be the problem. :confused:

Have you got an oscilloscope? Waveform was nice. I used some code with while and the waveform changed as it should.

What it does with regular analogWrite? I think there isn't analogwrite by default to esp32. Fading sample code gives error.

Changed BC183 to 2N2222 and the voltage goes from 0V to 10V like it should. Is 2N2222 ok for this use or should I use something else?

I noticed that the analog voltage is spikey. Then I upped the pwm frequency to 110000 and with oscilloscope it is smooth.