PSoc 4: How to generate varying PWM with analog input?

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

Hello everyone,

I am new to this field. I want to convert an analog input (from a potentiometer) to PWM output. Which mean,

if 0 V analog input --> 0% duty for PWM

if 3.3 V (max) analog input --> 100% duty for PWM

PWM output connected  to LED

By searching online and in the community, I am able to do the project attached below.


The problem I am facing is if I change a potentiometer nothing happens on the LED. Please help me!

0 Likes
1 Solution

You should not update the PWM's compare value more than once within a cycle. Because the ADC is free-running there is no clean connection between ADC and PWM.

I would suggest to configure ADC as one shot and using the PWM as the timer by using the ov output. You may connect ov to soc of the ADC. When conversion is done, eoc will be raised which you could connect to an isr component. In the interrupt handler you can read the conversion value and set the PWM compare.

Bob

View solution in original post

13 Replies
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Your timing is wrong:

The PWM input frequency is 1kHz, prescaler is 8 and period is 65536. This results in a period of 500 seconds. Quite a long time.

At first: Do you want to control the brightness of the LED (needs a period of max 10ms) or do you want to control the visible on-time of the LED (needs a period of ~1 second)

You need to re-calculate the compare value of the PWM so that your ADC max value (4096) reflects the PWM period value. Thus

Compare = ((uint32)ADC * Period) / ADCMaxValue

The parentheses ensure no precision loss.

And at last: Move the ADC_StartConvert() out of the loop into the initialization part, your adc is free running.

Bob

0 Likes
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

Thank you for the help. @user_1377889

1st: Changed the PWM prescale to 1x and period to 255. So that with the clock of 1khz, I can make 2.55 sec signal

Included the Compare equation.

I don't want to control brightness or visible time of LED. My objective is to see varying waveform on Oscilloscope but I connected LED so that I can roughly see if it's working or not.

In the attached project - Replaced LED with Oscilloscope as I have decided to connect it.

Things that are working,

- I can see PWM varying the duty as I change POT

Problem I am having is,

- below 0v it is going to 100% duty but ideally, it should give 0% duty

- from 0v to 3.3v duty is increasing

- ideally at 3.3v duty should be 100% but it is not. It is around 60%

- Duty still increases if I go above 3.3v

What I can think of this problem is ADC is not reflecting the correct value for PWM compare register. I am not sure how to solve it.

Please find the attached project. Let me know what do you think or what should I change. Also, feel free to edit my project if you want.

Thank you so much for your help. Really helped.

0 Likes
Anonymous
Not applicable

@user_1377889 Please reply!

0 Likes

In system view set VDDD and VDDA to 5V

Set ADCMaxValue to 2047, resolution is only 11Bit in this configuration, see ADC datasheet.

Change

PWMCompare = ((uint32)val*PWMPeriod/ADCMaxValue)

To

PWMCompare = ((uint32)val * PWMPeriod) / ADCMaxValue

No clue for behave at low voltage, you should check with debugger.

Bob

Anonymous
Not applicable

user_1377889 That worked! Thank you so much.

The next step I am going to do is applying sine wave instead of constant dc and generate sine PWM.

But, sine wave values go negative. What should I do to convert it to PWM? Please help!

Thank you for your time.

0 Likes

You need to do a level shift using an R-ladder. Keep in mind that the input of a pin must be GND < pin < VDDD.

Have a look into this thread and the answer Dana gave.

0 Likes
Anonymous
Not applicable

user_1377889 Thank you!

Understood. I gave DC offset from the function generator and applied sine wave (0 to 5v). But PWM does not sync with sine. What I can understand is PWM or ADC is very slow compared to changes in sine.

I also tried matching Sine and PWM freq. Doesn't work out.

What should I do now?! Please let me know.

0 Likes

I also tried matching Sine and PWM freq. Doesn't work out.

Your PWM frequency needs to be at least 10 times your input frequency to reflect the waveform.

You might get into troubles with glitches due to switching to different duty cycles. Could only be resolved using interrupts. Needs a bit of experience in design.

Is there a concrete project goal you want to perform? Which??

Bob

0 Likes
Anonymous
Not applicable

user_1377889

The end goal is to generate Sine Wave PWM for an inverter. I tried with 10x PWM freq and also 100x. But PWM cannot catch up with the change in sine and to catch up with sine it is working weirdly at a different frequency.

Do you have any material where I can refer to?

0 Likes

The PWM output is pure digital. How do you think to convert it into a sine wave?

I solved a similar project (3 phase sine generator) by using PSoC5, a sine loookup table and a DMA triggered by a timer. The DMA transfered the table to a DAC. Runs completely without CPU intervention except for changing the frequency.

Can you please submit your actual project so that we can have a look at?

Bob

0 Likes
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

user_1377889

I don't want to convert PWM to the sine wave. I just want to generate PWM like in the attached image. You can see the bottom waveform in the image. It changes duty according to the sine wave. And this PWM will go to external gate drivers for MOSFETs.

http://www.powerguru.org/wordpress/wp-content/uploads/2012/08/Sine-wave-PWM-modulation1.jpg

Also, find the attached project. In this project, I am applying sine wave of 0-5V for POT input with respect to ground. I am getting the PWM shown in above image but at very low sine frequency of about 5 HZ. Also, PWM cannot maintain its frequency.

I am not sure what should I do now. I am thinking to generate the sine wave and triangular wave and compare it to generate PWM. But that thing will also have frequency limitations. Please let me know your thoughts.  Thank you!

0 Likes

You should not update the PWM's compare value more than once within a cycle. Because the ADC is free-running there is no clean connection between ADC and PWM.

I would suggest to configure ADC as one shot and using the PWM as the timer by using the ov output. You may connect ov to soc of the ADC. When conversion is done, eoc will be raised which you could connect to an isr component. In the interrupt handler you can read the conversion value and set the PWM compare.

Bob

lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

user_1377889 Hey Buddy. Thank you for your help. I was able to get the results. I successfully converted a 0-5 V sine wave into PWM. Find the attached project for those who are interested. Also, can you please check my project once? I think it is working fine but if you feel anything that can be changed. Suggestions are welcomed.

Let me know!

0 Likes