- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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!
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
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!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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!