Loading...
Pages: [1]   Go Down
Author Topic: How to program 16-bit pwms in the different Arduino boards ?  (Read 351 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello,

I currently have an Arduino Mega board and one of my needs is to produce PWM signal at high frequency (for example 30khz), and if possible with 12bits or 16bits resolution. I also plan to buy an Arduino Due to be able to do this and to have more power.

Concerning the PWM frequency, on Arduino Mega this is fine : when modifying TCCRxB register, I change the prescale, thus the frequency. So I can get the 30khz frequency. But concerning the 16-bits PWM, I haven't seen much information, and I don't know if it's possible to have this 16bits (or 10 or 12?) resolution. ( Well now i am pretty sure it's impossibe as I realise that 30k* 65k is about 2ghz... )

As this Mega board is too weak for my project, I thought "ok let's buy the new Arduino Due, with this powerfull Atmel 32 bits microcontroler it's probably easy to get some kind of 12bits PWM at high frequency"
But I get confused. The Atmel documentation of the SAM3X says
Up to 8-channel 16-bit PWM (PWMC) with Complementary Output, Fault Input, 12- bit Dead Time Generator Counter for Motor Control

But when I look at the analogWriteResolution() reference I can read
The Due has the following hardare capabilities:
   12 pins with 8-bit PWM (as the other AVR based boards)
    2 pins with 12-bit DAC (Digital-to-Analog Converter)


Here I talk about PWM pins, not DAC.

So, to sum up :
1) Can Arduino Mega produce PWM with 10 or 12bits resolution? at what frequency ?

2) Can Arduino Due produce PWM with 12 or 16bits resolution? at what frequency? How do we do this?
On Due if I write
Code:
analogWriteResolution(12);
analogWrite(PWMpin, 3017);
Will I really get a PWM with duty cycle 3017/4096 ?
 
Thanks for your answers
Logged

Offline Offline
Edison Member
*
Karma: 114
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The fastest way would be to read the datasheet. The pwm module is very easy to configure.
Logged

Dubai, UAE
Offline Offline
Edison Member
*
Karma: 20
Posts: 1627
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,
   You were pointing in the right direction in your first post - 65535 * 30K = faster than a Mega and also faster than a Due.

   As the resolution gets higher, you need much faster PWM Clocks that any of the Arduinos will get you.

   Out of interest, why do you need PWM as opposed to a DAC which does not suffer from the clock limitation ?

Duane B

rcarduino.blogspot.com
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello,

The fastest way would be to read the datasheet. The pwm module is very easy to configure.

Oh, is it really so easy ? Indeed I can't tell as I don't know anything about the Atmel SAM3X. But I've made some research on the forum and it seems that several people have spent some time on it, and it's not so simple to make an easy-to-use librairy. Though you are write I will try to look in more details at the datasheet...  smiley

   You were pointing in the right direction in your first post - 65535 * 30K = faster than a Mega and also faster than a Due.

   As the resolution gets higher, you need much faster PWM Clocks that any of the Arduinos will get you.

   Out of interest, why do you need PWM as opposed to a DAC which does not suffer from the clock limitation ?

Yes I understand this limitation of "frequency*resolution < clock", but first I want to be able to configure PWMs as needed. By default it's 1khz 8bit on the Due, for example I would like 4khz 12bit resolution.
I checked that analogWriteResolution() doesn't change anything concerning this, as expected.

Why PWM ? for at least 2 reasons :
- there are more PWM pins than DAC on an Arduino board... and I need probably about 10 output of this kind
- the hardware I decided to use "after" the Arduino is now designed for receiving a pwm, as it was done using Arduino Mega.
- I reserve the 2 DAC of the Due for some other use ...

Logged

Offline Offline
Edison Member
*
Karma: 114
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If you really need that high resolution of pwm, you may try analog sampling, which, in theory, has infinite bits of resolutions. It uses a  flip-flop, a few resistors + capacitors, plus a clock (which can be generated by yours arduino).
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello,

Today I ate quite a lot of ATMEL SAM3X datasheet and indeed, after focusing on this PWM subject for a couple of hours, we can do nice programming of PWMs on the Due !!

I diretly configured SAM3X registers, it may be "brutal" and sometimes unappropriate, anyway I put here some draft code, it could help someone :

Code:
    // Let's say we want to configure PWM channel 0, PWML0 which is on pin34 Due board, and corresponds to the port C.2

    // First the peripheral must be activated instead off the general GPIO
    REG_PIOC_PDR = 4;
    // Moreover it's peripheral B (not A), which means we have to change PIO_ABSR[2]
    REG_PIOC_ABSR = REG_PIOC_ABSR | 4;
   
    // Now concerning PWM settings...

    // activation of the clock dedicated to PWM peripheral (id36), which is fifth bit of PMC_PCSR1
    REG_PMC_PCER1 = REG_PMC_PCER1 | 16;
   
    // activation of PWM_ENA register with channel 0
    REG_PWM_ENA = REG_PWM_SR | 1;
   
    // setting the period (which can take any 16 bit value...)
    REG_PWM_CPRD0 = 5000;
    // note : with this 5000 setting, we have thus 1/5000 resol, with a frequency of 16khz, if we use the defaut main clock : that's good
 
    // Finally, setting the duty cycle to the value you want (between 0 and the period, of course)
    REG_PWM_CDTY0 = 1000;
   
    // And here we can check at the oscilloscope that we get a nice PWM on pin 34, with a period of 60usec... nice!
 

Now I have one question :

Why do the PWM pin are indicated on pin number 2 to 13 on arduino boards !! ?
It seems that the 8 true PWM channels are not these ones... for example here I used the channel 0, which can be found on pin 34, 35 and other pins...

And one other interesting remark :
We can actually reach very nice resolution, especially if we use low (or high) pwm commands. For example, the hardware I use with this pwm is highly non linear, and I need to be precise with low duty cycle.
As I don't really care about precise frequency (let's say anything between 8khz and 20khz is fine), I can modify the period as well as the duty cycle.
So, from the duty cycle 1/5000, I can go to 2/5000, but also I can use 1/4990, 1/4900, etc.
And it works well.

Hope this will be usefull for someone.
Logged

Pages: [1]   Go Up
Print
 
Jump to: