pwm creation of analog voltage in arduino

Thread Starter

denison

Joined Oct 13, 2018
328
This programming gets an analog voltage output;
double a;
double b;
double v;
void setup() {
pinMode(11, OUTPUT);
Serial.begin(9600);
}
void loop() {

v=2.433;
a= ((v-.2955)/.107375);
b=(40-a);

digitalWrite(11, HIGH);
delayMicroseconds(a);
digitalWrite(11, LOW);
delayMicroseconds(b);
}
This shows that delay will accept a variable which one of your contributors was doubtful of as was I. However when I add more programming in the loop to determine the value of 'v', I just get a few millivolts output. Can anybody suggest how I can fix this? Could it be that the program spends too much time on the extra programming to do the pwm to analog conversion?
If I can't fix it I will use a digital to analog ic meaning more hardware.
I can include the complete sketch if desired. There must be something there stopping it working. Let me know.
 
Last edited:

JohnInTX

Joined Jun 26, 2012
4,787
I don't do Arduino but does delayMicroseconds accept a double precision float for a parameter? I don't know.
Even if it does, I calculated ~19.9uS for logic high and about 20uS PLUS however long it takes the processor to re-compute all of that double precision floating point stuff in the loop and, if the delays will accept floats at all, convert the float to the likely integer delay count. My guess is that takes a lot longer than the 19.9 uS high time which would make the resulting duty cycle correspondingly low.

Doesn't Arduino have an analog out function that uses a built in software PWM or one using one of the chip's peripheral PWMs?

That's all I got..
Good luck!
 

Ian Rogers

Joined Dec 12, 2012
1,136
Just to be clear.... The output on the Arduino pin will be a frequency not a voltage... You'll need to filter the output to see a voltage.
 

Thread Starter

denison

Joined Oct 13, 2018
328
Just to be clear.... The output on the Arduino pin will be a frequency not a voltage... You'll need to filter the output to see a voltage.
The total cycle time is only 40us. At that short period the output appears to be a analog voltage. If I had longer periods yes you would need a filter.
 

Thread Starter

denison

Joined Oct 13, 2018
328
I don't do Arduino but does delayMicroseconds accept a double precision float for a parameter? I don't know.
Even if it does, I calculated ~19.9uS for logic high and about 20uS PLUS however long it takes the processor to re-compute all of that double precision floating point stuff in the loop and, if the delays will accept floats at all, convert the float to the likely integer delay count. My guess is that takes a lot longer than the 19.9 uS high time which would make the resulting duty cycle correspondingly low.

Doesn't Arduino have an analog out function that uses a built in software PWM or one using one of the chip's peripheral PWMs?

That's all I got..
Good luck!
I think you are right. With the additional programming it is taking too much time in the calculations. I will try longer periods which will probably need a filter but that is ok. Even with the short program the measured voltage is lower than I calculate.
The atmega 328p which I am using does not have an analog out function unlike many microcontrollers now which have inbuilt digital to analog converters. I may need an external converter.
 

Thread Starter

denison

Joined Oct 13, 2018
328
That is the answer. You use the analog write feature. No more of this delay nonsense. much obliged Eric. this was starting to annoy me. I was looking up external digital to analog converters which meant more hardware. thanks very much. there often seems to be a simple solution to a problem which at first sight looks impossible to fix.
 

Ian Rogers

Joined Dec 12, 2012
1,136
The total cycle time is only 40us. At that short period the output appears to be a analog voltage. If I had longer periods yes you would need a filter.
Not really... what ever the cycle there will be a square wave at the pin.. The PWM pins are digital only period..
 

djsfantasi

Joined Apr 11, 2010
9,156
I don't do Arduino but does delayMicroseconds accept a double precision float for a parameter? I don't know.
Even if it does, I calculated ~19.9uS for logic high and about 20uS PLUS however long it takes the processor to re-compute all of that double precision floating point stuff in the loop and, if the delays will accept floats at all, convert the float to the likely integer delay count. My guess is that takes a lot longer than the 19.9 uS high time which would make the resulting duty cycle correspondingly low.

Doesn't Arduino have an analog out function that uses a built in software PWM or one using one of the chip's peripheral PWMs?

That's all I got..
Good luck!
First, analogWrite() is the proper Arduino function to use for this application.

Arduino has two functions for inserting a delay: delay() and delayMicroseconds().

delay() will only accept an unsigned long as a parameter.

delayMicroseconds will only accept an unsigned integer as a parameter.

When calculating the delay parameters, all variables used in the calculation need to be cast to the same type as the desired output. Then, the final value must be cast to the delay input type.
 

Thread Starter

denison

Joined Oct 13, 2018
328
Yes 'analogWrite' is the proper arduino function to use. The trouble with 'delay' is it stops the running of the program. I think the 'analogWrite' function will run independently of what is happening in the rest of the program. then if the variable of this function is changed by the rest of the program it will continue to run independently with the new variable.
At least I hope this is what will happen.
 

djsfantasi

Joined Apr 11, 2010
9,156
Yes 'analogWrite' is the proper arduino function to use. The trouble with 'delay' is it stops the running of the program. I think the 'analogWrite' function will run independently of what is happening in the rest of the program. then if the variable of this function is changed by the rest of the program it will continue to run independently with the new variable.
At least I hope this is what will happen.
Yes, analogWrite() will create a PWM signal that continues to run/exist in the background, letting the Arduino sketch continue running.

There is one detail that I haven’t seen thus far. Not all pins on an Arduino can be used for background PWM. Several pins are designated for PWM and they must be used for background generation with the analogWrite() command. What the pins are depends on the Arduino model you are using. More powerful models maintain compatibility by adding more pins and keeping the same pins as the previous model.
 

Ian Rogers

Joined Dec 12, 2012
1,136
I think you are right. With the additional programming it is taking too much time in the calculations. I will try longer periods which will probably need a filter but that is ok. Even with the short program the measured voltage is lower than I calculate.
The atmega 328p which I am using does not have an analog out function unlike many microcontrollers now which have inbuilt digital to analog converters. I may need an external converter.
Unfortunately for you the pin capacitance of the 328p is only 30pF but there doesn't seem to be any internal useable resitance.. even at 10k you would need a pwm in the order of megacycles..

If you just use the default PWM of the analogWrite() and a 10k + 100nF you'll get reasonable results.. This depends on the impedance of the load... If you loading is too much you'll need a voltage follower to prop it up..
 
Top