DUE PWM Frequency

Finally I have my DUE in hand and wow is he fast and wonderful, so is a leaf labs maple. I am building my electric vehicle around a 3 phase hex inverter an an ac induction motor. The mega 2560 ha served me well as a proof of concept, however is incapable of doing the math and operations per second that this job is going to ultimately going to require. The project can be viewed at www.evmaker.tumblr.com. One has to go back several pages to get to the video of the truck actually running with the mega pulling the strings, but it did run for 100 or so miles. The problem is that 1 I am not a great c programer. 2 the mega is a little too slow. To make this work I need to change the PWM frequency of the due to at least 4000 Hz. I want to play at least 60 samples of sine at a minimum top speed of 60 Hz This means that will be 3600 samples per second. The mega is no problem to get ~4000 Hz, just is not fast enough to do the math and analog writes for more than 19 Hz. Well it pushed the truck down the road. Until I got greedy and tried a sketch that only played 30 samples then the pulses became too long and the inductive kick of the motor blew one of my igbt transistors. The DUE should from the tests have no problem delivering That which I need in terms of speed, I just need a little help modifying the PWM frequency.

Narrowed it down I think to one bit, 0x40094000, bit #19 needs to go to 0 not 1. Tried bitWrite, bitClear, word x = xx. No effect. Like I say I am not a programer by any count. bitRead seems to work just fine for me and returns the results that I would expect. It appears that the register is not write protected at the software level. Any suggestions appreciated.

James

Howdy evmaker, very nice project you have going there.

http://arduino.cc/forum/index.php/topic,128734.0.html <This gentleman is also trying to change that same thing I believe.

Your project looks like a lot of fun, the company I am working for designs drive systems for trains, buses, boats and cars.
I see alot of IGBT’s of various sizes, and I have also seen plenty of examples of the magic smoke being released inside our drive enclosures. Its no fun to have to clean one of those rma’s =(

I seem to be able to use bitRead to read the bits in 0x400940E8 bit 0 and bit 8 are both already set to 0. This means that WPSWS0 and WPHWS0 are bot set to write protect off. It would seem that I should be able to do a simple bitWrite(0x40094000, 0x13, 0), However it seems that I have to define a long =x and use the x as the IDE thinks that it is a stinking 16 bit joe he is talking to. This becomes;

long x = 0x40094000; bitWrite(x, 0x13, 0);

and later i do

int y = bitRead(x, 0x13); Serial.print(y);

and darn if it still ain't a 1

Tried several other things like above mentioned and the compiler wont complie, guess the due was just a waste of money I will continue the project with a leaf labs maple. Already have working code for that, just wanted to make my new pcb compatible with avr and sam3. The maple pins out a little different but the IDE can call a register by name timer_suchandsuch = timer_suchandsuch & 0xshit=0 | 0xnewvalue and presto pwm is set, Real similar to the old mega2650.

Could be that I just was not supposed to be building my own inverters, but my homemade grid tie worked hard all summer long and saved me $200 or so. It only runs at the frequency of the power co. Now in the fall it is only doing 3 kwh on a good day Jul and Aug it was giving 8 to 9. Think I just need more sun and panels to catch it. Longer days would be nice too. It runs an UNO with a very short sketch.

Guess I'll just modify the pcb for maple and role on that. Just seemed that due would have been a more capable kind of guy.

Thank you all for the advice and interest, James

Impressive project! Would be sad to see you giving up the due for such a basic thing as changing the pwm frequency. The IDE does set the freq in some library, you could try to look for it and change the freq the same way the arduino guys have done. But I'm sure someone already have tried to change the freq and can show you how, it's just hope that such a person shows up :). I might give it a go tonight if I find some free time.

I'll suggest you to give a look here:

https://github.com/arduino/Arduino/blob/ide-1.5.x/hardware/arduino/sam/cores/arduino/wiring_analog.c#L252

to see an example of how to configure PWM channels, and here:

https://github.com/arduino/Arduino/blob/ide-1.5.x/hardware/arduino/sam/cores/arduino/wiring_analog.c#L252

for TC.

BTW, you should be able to change PWM_CLK register, it's weird you can't. CLK register should be accessible using:

PWM->PWM_CLK = 0x.......;

Most peripherals inside the SAM3X needs to be "clocked" through a device called PMC. You must activate PMC before any other operation with:

pmc_enable_periph_clk(PWM_INTERFACE_ID);

maybe can be this the cause of your issue?

Another thing you can try is changing the PWM_FREQUENCY constant in variant.h:

https://github.com/arduino/Arduino/blob/ide-1.5.x/hardware/arduino/sam/variants/arduino_due_x/variant.h#L180

but I don't know if this would be sufficient to fit your needs. (needless to say: if you try that check the result with a scope first!)

C

Had a quick look at it and I can confirm that changing PWM_FREQUENCY in https://github.com/arduino/Arduino/blob/ide-1.5.x/hardware/arduino/sam/variants/arduino_due_x/variant.h#L182 does change the freq. So if you just need the 4k freq it'll work fine. Still, a way to change the freq in the sketch would be preferred.

Okay. So I figured out why it dosen’t work if you set the register. It turns out that not all the pwm pins is actually pwm pin, some are timer pins. So for example doing:
‘PWM->PWM_CLK = 0b00001010111111110000101011111111;’
Works for pin 6, but not pin 2. (Tho you need to do it after every analogWrite as analogWrite insist on the 1k freq)
Another easier way to change the freq is to do:
‘PWMC_ConfigureClocks(whatever_freq_you_want * 255 , 0, VARIANT_MCK);’

From variants.cpp:

  ....
  .... 
  // 0 .. 53 - Digital pins
  // ----------------------
  // 0/1 - UART (Serial)
  { PIOA, PIO_PA8A_URXD,     ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT,  PIN_ATTR_DIGITAL,                 NO_ADC, NO_ADC, NOT_ON_PWM,  NOT_ON_TIMER }, // URXD
  { PIOA, PIO_PA9A_UTXD,     ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT,  PIN_ATTR_DIGITAL,                 NO_ADC, NO_ADC, NOT_ON_PWM,  NOT_ON_TIMER }, // UTXD

  // 2
  { PIOB, PIO_PB25B_TIOA0,   ID_PIOB, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM,  TC0_CHA0     }, // TIOA0
  { PIOC, PIO_PC28B_TIOA7,   ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM,  TC2_CHA7     }, // TIOA7
  { PIOC, PIO_PC26B_TIOB6,   ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM,  TC2_CHB6     }, // TIOB6

  // 5
  { PIOC, PIO_PC25B_TIOA6,   ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM,  TC2_CHA6     }, // TIOA6
  { PIOC, PIO_PC24B_PWML7,   ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM),   NO_ADC, NO_ADC, PWM_CH7,     NOT_ON_TIMER }, // PWML7
  { PIOC, PIO_PC23B_PWML6,   ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM),   NO_ADC, NO_ADC, PWM_CH6,     NOT_ON_TIMER }, // PWML6
  { PIOC, PIO_PC22B_PWML5,   ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM),   NO_ADC, NO_ADC, PWM_CH5,     NOT_ON_TIMER }, // PWML5
  { PIOC, PIO_PC21B_PWML4,   ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM),   NO_ADC, NO_ADC, PWM_CH4,     NOT_ON_TIMER }, // PWML4
  // 10
  { PIOC, PIO_PC29B_TIOB7,   ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM,  TC2_CHB7     }, // TIOB7
  { PIOD, PIO_PD7B_TIOA8,    ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM,  TC2_CHA8     }, // TIOA8
  { PIOD, PIO_PD8B_TIOB8,    ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM,  TC2_CHB8     }, // TIOB8

  // 13 - AMBER LED
  { PIOB, PIO_PB27B_TIOB0,   ID_PIOB, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM,  TC0_CHB0     }, // TIOB0

  // 14/15 - USART3 (Serial3)
  { PIOD, PIO_PD4B_TXD3,     ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT, PIN_ATTR_DIGITAL,                  NO_ADC, NO_ADC, NOT_ON_PWM,  NOT_ON_TIMER }, // TXD3
  { PIOD, PIO_PD5B_RXD3,     ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT, PIN_ATTR_DIGITAL,                  NO_ADC, NO_ADC, NOT_ON_PWM,  NOT_ON_TIMER }, // RXD3
   ....
   ....

As you can see only pin 6, 7, 8 and 9 is a PWM_CH pin.
You can surely change the freq on the timer pins too but I’m too tired to dig into that.

I’d say that the analogWrite need to be changed so that it allows easier change of the freq.

Edit:
If you don’t want to set the freq for every analogWrite you could use ‘PWMC_SetDutyCycle(PWM_INTERFACE, PWM_CH7, your_analog_write_value);’ instead.
So a fading led sketch with 4k pwm freq on pin 6 would be:

void setup()  { 
  pinMode(6, OUTPUT);
  analogWrite(6, 64);
  PWMC_ConfigureClocks(4000 * PWM_MAX_DUTY_CYCLE , 0, VARIANT_MCK);
} 

void loop()  { 
        for (int i = 0; i < 253; i++) {
            PWMC_SetDutyCycle(PWM_INTERFACE, PWM_CH7, i);
            delay(10);
	}
	for (int i = 255; i > 1; i--) {
            PWMC_SetDutyCycle(PWM_INTERFACE, PWM_CH7, i);
            delay(10);
	}                
}

io53, cmaglie,

Thanks so much for all the interest, and it looks like work too. I am so so sorry I simply am not that kind of programer, I am just a simple millwright who has slipped through the cracks mostly unnoticed. Most of my work involves using a 3 or 10 pound hammer or welding machine. I am what they call high functioning autistic dyslexic. But not the number genius that most are portrayed or the music virtuoso for that mater.
Mostly all that I get is just the ability to be very awkward in public, have difficulty in relationships and oh yea I am usually pretty good at fixing broken machines. At least the fixing part allows me to eat. Somehow I managed to find a good wife who is patient and tolerates all of my ticks and raise a daughter who is wonderful (wonder if she shares my dna). They are both normal and take good care of me. It wasn’t until much later than normal that I could read and write. Still very slow at both.

Here is an older sketch that actually was used to drive the truck down the road ;

/*
Copyright Sanderso-Tesier Moters

This Program is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This software is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this software; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/

// SANDERSON DYNAMIC DRIVE V1.8

// sucessful attempt at feedback loop
// Wave shaping on the fly under cube factor
// voltage Weighting proportional to pot and freq.
// THIS CODE RUNS ON MEGA 2560 ONLY

int y = 0;
float xa = (0);                                     //A phase starting point//
float xb = (2.0943951023931954923084289221863);     //B phase starting point 2pie/3//
float xc = (4.1887902047863909846168578443727);     //C phase starting point 4pie/3//
float index = (0.10471975511965977461542144610932); // 2pie/60 or 60 samples of 2pie//



//define data table arrays
int ahdat[60]; int aldat[60]; //A phase data
int bhdat[60]; int bldat[60]; //B phase data
int chdat[60]; int cldat[60]; //C phase data

//define use data table array
int ahdatu[60]; int aldatu[60]; //A phase data for use
int bhdatu[60]; int bldatu[60]; //B phase data for use
int chdatu[60]; int cldatu[60]; //C phase data for use

//output pin definition digital output pwm
int ahigh = 2;   //Naming IGBT drive pins for hex inverter
int alow = 3;
int bhigh = 5;
int blow = 6;
int chigh = 7;
int clow = 8;

//output to drive pump motor shield pins
int drivepump1 = 12; //Naming drivepump output pins
int drivepump2 = 11; //             "
int drivelev1 = 10;  //             "
int drivelev2 = 9;   //             "

//define input and assoc variables for pot box
int pot = A15;
int potvali = 0;
int hexdrive = 1000;
float potval = 0;
float hexpass = 1000;

//define input and assoc variables for feed back loop
int feed = A13;
int feedv = 0;
float feedc =0;
int decel =0;

//define variables assoc with voltage calculation
float v = .795;
float vc = .795;
float vcf = 0;
int hexv = 0;


void setup() {
  
  // Serial is for testing only rem out for use
  /*
  Serial.begin(9600);
  Serial.write(17);
  Serial.write(12); 
  */
  
 // change carrier value of pwm timers so that they are the same
 // HEXINVERTER
 TCCR3B=(TCCR3B & 0xF8) | 0x02; //CHANGE OUTPUT PWM TO ~4000 HZ TIMER 3 PINS 2, 3, 5 MEGA ONLY LINE
 TCCR4B=(TCCR4B & 0xF8) | 0x02; //CHANGE OUTPUT PWM TO ~4000 HZ TIMER 3 PINS 6, 7, 8 MEGA ONLY LINE
 
 //change carrier value of pwm for drive pump
 TCCR2B=(TCCR2B & 0xF8) | 0x02; //CHANGE OUTPUT PVM PINS 9, 10 4000 HZ TIMER MEGA LINE ONLY
 TCCR1B=(TCCR1B & 0xF8) | 0x03; //CHANGE PWM TO ~500 HZ PINS 11, 12, FOR DRIVE PUMP MEGA ONLY LINE
 
 //pin asssignment hexinvewrter
 pinMode(ahigh, OUTPUT);  // assigns output pins for hex inverter as output
 pinMode(alow, OUTPUT);   //                     "
 pinMode(bhigh, OUTPUT);  //                     "
 pinMode(blow, OUTPUT);   //                     "
 pinMode(chigh, OUTPUT);  //                     "
 pinMode(clow, OUTPUT);   //                     "
 
 //pin assignment drivepump
 pinMode(drivepump1, OUTPUT);  // assigns pins as output for drive pump
 pinMode(drivepump2, OUTPUT);
 pinMode(drivelev1, OUTPUT);
 pinMode(drivelev2, OUTPUT);
 
 //initialize drive pump
 analogWrite(drivepump1, 127);  // Starts drive pump running
 analogWrite(drivepump2, 127);
 digitalWrite(drivelev1, HIGH);
 digitalWrite(drivelev2, HIGH);
 
 //populate array tables
 
 for (int x = 1; x < 61; x = (x + 1)) {
 
  //A PHASE HIGH DATA  
  ahdat[x] = ((sin (xa)) * (255));
  aldat[x] = (ahdat[x]);
  if ((ahdat[x]) <= (30)) { ahdat[x] = (0); }
  
  if (ahdat[x] > 250) { ahdat[x] = 255 ; }
  
  //A PHASE LOW DATA
  if ((aldat[x]) >= (-30)) { 
     aldat[x] = (0); 
     }
  else {
    aldat[x] = ((aldat[x]) - ((aldat[x]) + (aldat[x])));
  }
  if (aldat[x] > 250) { aldat[x] = 255 ; }
  
  //B PHASE HIGH DATA
  bhdat[x] = ((sin (xb)) * (255));
  bldat[x] = (bhdat[x]);
  if ((bhdat[x]) <= (30)) { bhdat[x] = (0); }
  
  if (bhdat[x] > 250) { bhdat[x] = 255 ; }
 
  //B PHASE LOW DATA 
  if ((bldat[x]) >= (-30)) {
    bldat[x] = (0);
  }
  else {
    bldat[x] = ((bldat[x]) - ((bldat[x]) + (bldat[x])));
  }
  if (bldat[x] > 250) { bldat[x] = 255 ; }
  
  //C PHASE HIGH DATA  
  chdat[x] = ((sin (xc)) * (255));
  cldat[x] = (chdat[x]);
  if ((chdat[x]) <= (30)) { chdat[x] = (0); }
  
  if (chdat[x] > 250) { chdat[x] = 255 ; }
  
  //C PHASE LOW DATA
  if ((cldat[x]) >= (-30)) {
    cldat[x] = (0);
  }
  else {
    cldat[x] = ((cldat[x]) - ((cldat[x]) + (cldat[x])));
  }
  if (cldat[x] > 250) { cldat[x] = 255 ; }
// Serial is for testing only rem out for use
/*
Serial.print (ahdat[x]);
Serial.print ("  ");
Serial.print (aldat[x]);
Serial.print ("  ");
Serial.print ("/");
Serial.print ("  ");
Serial.print (bhdat[x]);
Serial.print ("  ");
Serial.print (bldat[x]);
Serial.print ("  ");
Serial.print ("/");
Serial.print ("  ");
Serial.print (chdat[x]);
Serial.print ("  ");
Serial.print (cldat[x]);
Serial.print ("  ");
Serial.print ("/");
Serial.print ("  ");
Serial.println (); */


//delay (1500);
 xa = xa + index;
 xb = xb + index;
 xc = xc + index;
 }
}

 void loop() {
   
     y = ((y) + 1);//index y value for reading sine table
   
   //Feedback loop reading based on motor amps
   feedv = (analogRead(feed));
   feedc = feedc + feedv;
   feedv = feedc / 15;
   feedc = feedc - feedv;
   feedv = (feedv * sqrt(v));
   if (decel == 0) {
   if ((feedv) > (200)) { hexpass = (hexpass + ((sqrt(hexpass)) / (7))); }
   }
   decel = 0;
   //POT READING throttle position
   potval = (sq((analogRead(pot) * .0250829) + 6.32455));
   
   // PROCESS POT DATA
   potvali = potval;
   
   if ((potvali) > (hexdrive)) { hexpass = (hexpass + (sqrt(hexpass) / 400)); decel = 1;}  //LINEAR DECELERATION
   if (feedv < 195) {
   if ((potvali) < (hexdrive - 5)) { hexpass = (hexpass - (sqrt(hexpass) / 65)); } //LINEAR ACCELERATION
   }  
   
   hexdrive = hexpass;
   
   //DRIVE VOLTAGE ADJUSTMENT V1.7 Production
   
   //AJUST APPLIED VIRTUAL VOLTAGE TO COMPENSATE FOR FREQUENCY
   // .78 SINE TO 1.7 SINE
   
   if ((hexdrive) > (1007)) {
    v = (.76);
    hexdrive = 1024;
   }
  else {
   hexv = (1014 - ((potvali + hexpass) / 2));
   // vc = (((hexv) * (.0139475)) * ((hexv) * (.0139475)) * ((hexv) * (.0139475)));
   vc = (sq (sq((hexv) * (.006912))));
   vc = (vc / 1000); 
   vc = vc + .74;
   if (vc > v) { v = vc ; }
   else { if (decel = 1) { v = vc; }
  // vcf = v - vc;
   //if (vcf > .45) { v = (v - .005); }
   }
   
  }
  
     ahdatu[y] = (ahdat[y] * v);
     if ((ahdatu[y]) >= (250)) { ahdatu[y] = 255 ; }
     aldatu[y] = (aldat[y] * v);
     if ((aldatu[y]) >= (250)) { aldatu[y] = 255 ; }
     bhdatu[y] = (bhdat[y] * v);
     if ((bhdatu[y]) >= (250)) { bhdatu[y] = 255 ; }
     bldatu[y] = (bldat[y] * v);
     if ((bldatu[y]) >= (250)) { bldatu[y] = 255 ; }
     chdatu[y] = (chdat[y] * v);
     if ((chdatu[y]) >= (250)) { chdatu[y] = 255 ; }
     cldatu[y] = (cldat[y] * v);
     if ((cldatu[y]) >= (250)) { cldatu[y] = 255 ; }
    
  
  
   hexinverter();
   }
   
  void hexinverter() {

  analogWrite(ahigh, (ahdatu[y]));
  analogWrite(alow, (aldatu[y]));
  analogWrite(bhigh, (bhdatu[y]));
  analogWrite(blow, (bldatu[y]));
  analogWrite(chigh, (chdatu[y]));
  analogWrite(clow, (cldatu[y]));
  delayMicroseconds(hexdrive);
  if (y >= 60) { y = (0); }
}

As you can see I am not a real slick programer. It seemed to me that those example codes had to do with software serial and playing music. I just want to make all the PWM the same except a pair of them to drive the inverter that runs the drive pump. Leaf Labs Maple will do this line for line just have to rename the timers and swap a pin or two. So it looks like there will no open source arduino electric car it will be a Leaf Labs car. Provably I am trying to do something that should not be done, and am not the one who should be doing it anyway. My Grandfather said that anything worth doing will involve sweat. So far all due has yeald is a head ache. I did however win the bet with my friend and made a truck move with electricity, it will be a maple that takes it out on the town.

Thank you all,
James

Several people have also been asking for this feature on Teensy 3.0.

I'm considering adding an API to set the PWM frequency, and a bit of extra code in analogWrite to automatically scale the resolution to the available range. That will add a bit of extra overhead in analogWrite, but perhaps that's ok? Normally analogWrite doesn't take effect until the next PWM cycle anyway.

Christian, Massimo... if you guys are reading this, would you be interested in adding an API for this too? If so, I'd really like to chat about what the function name and params would be, so we both do something that's compatible.

Paul, sure, would you like to make a proposal on the dev list?

Using that mail list drains my enthusiasm for Arduino contributions.

That Would be really really cool to have that added, I would call it pwmWrite as the leaf labs bunch dose. In fact the leaf labs pwmWrite already has this functionality.
This week I have been modifying my pcb and sketches to run with a maple. Would have preferred to use DUE, as I it is my belief that it will eventually become the standard but right now it is shall we say green and not ready. Once the DUE grows up and matures it will provably overwhelm the little maple and press it out of existence.

Maple's pwmWrite appears to be only a 16 bit version of analogWrite

http://leaflabs.com/docs/lang/api/pwmwrite.html

How does it let you also control the frequency?

It seems that you must use HardwareTimer methods:

http://leaflabs.com/docs/lang/api/hardwaretimer.html#lang-hardwaretimer-setperiod

this API is not final, since they put a disclaimer that says:

"Warning: The timer interface is still taking shape, and is expected to change significantly between releases. Because of that, the functionality described in this page shouldn’t be considered stable."

I am finalizing my code for the maple, wow the documentation on maple is wonderful.

In the maple world they have a library timer.h which allows the easy modification of the timer properties. I am not sure how it all works as I am not the sharpest guy in the world, but I assure you it works quite well.

This is the first code I was playing with the pwm freq with on maple

#include <timer.h>

//HardwareTimerb timer(1);
int d = 100;
int b = 177;
int pin2 = 5;
int pin3 = 6;
HardwareTimer timer1(1);
HardwareTimer timer4(4);


void setup() {
    // Set up the built-in LED pin as an output:
    timer1.pause();
    timer4.pause();
    timer1.setPrescaleFactor(3);
    timer4.setPrescaleFactor(3);
    timer1.setOverflow(4000);
    timer4.setOverflow(4000);
    timer1.refresh();
    timer4.refresh();
    timer1.resume();
    timer4.resume();
    pinMode(24, OUTPUT);
    digitalWrite(24, HIGH);

   // pinMode(23, OUTPUT);
    //digitalWrite(23, HIGH);
    pinMode(20, INPUT);
    pinMode(19, INPUT);
    pinMode(pin2, PWM);
    pinMode(pin3, PWM);

}

void loop() {
d = (analogRead(20) + 1);//  pot on20
b = (analogRead(19)); //read other  pot on19
if(b > 4000) { b = 4000; }
//SerialUSB.println(b);
analogWrite (pin2, 0);
analogWrite (pin3, b);
    delay(100);          // Wait for d milis
    analogWrite (pin3, 0);
    analogWrite(pin2, b);
    delay (100);
}

It alternately blinks two leds back to back in parallel across pins 5 and 6.
Renders 6000 Hz pwm exactly the way I want it to.

It would be really nice to do this the same way with due

There was actually a recent discussion on the Arduino developers mail list about this feature. I believe the final consensus was on analogWriteFrequency(pin, frequency), though there's some lingering controversy over using the pin number vs some way of specifying which timer resource is being programmed. It's not easy to agree on an API that is easy to understand and flexible and general enough to work across different boards with different chips, yet can be implemented efficiently and doesn't abstract the hardware so much that the user is completely unaware of possible compatibility issues.

Maple's API gives you low-level access to the timers, but it's very hardware specific. You can't reasonably expect that code, using raw overflow and prescaler constants for ST's chip, to work the same way across different boards. It might not even work when/if Leaflabs makes another board based on a newer ST chip. That API also produces very unreable code. How can anyone reading the code know the output is 6 kHz? Somehow a prescale factor of 3 and an overflow of 4000 make 6 kHz? Will that be true on every Maple board to come in the future? Certainly AVR and SAM3X and Freescale MK20 need different parameters, because they have dramatically different timer hardware. Maple's API just isn't practical for non-ST chips, and long term I suspect it won't even work well for whatever boards appear in the future with new ST parts.

I've implemented analogWriteFrequency() on Teensy 3.0, so far only as a code drop in a forum topic, but soon to be released as a beta test.

I don't know when or if Christian is planning to implement it on Arduino Due.

Paul,

Yes all those things are true. The scetch is only going to work on the maple with that exact chip.

My original code would only run on the 2560, However it was reasonably well documented how to do it. I would expect that the same would be true of due. That in calling a timer one would have to know the pin map in relation to the timer and how the modification will affect the timer. I am also reasonably sure that it is possible to time up the due in a similar way. Basically the original code I used on the 2560 did the same thing prescaling the timer. Just did not have the ability to set the number of counts. That is provably also possible I just have not discovered it.

All is well, the maple is doing my bidding The due is communicating with the maple i2c or serial, much testing to do. Getting the due to run the interface the lcd touchscreen monitoring the battery, running the 12 v charging system many things for due to do. I am sure that as due matures pwm modification will mainstream in one form or an other. My pcb is ready for maple my first beta code for maple is meeting my expectation. My project is moving forward and soon I will drive down the road under ~duino control hopefully before Christmas.

Any idea when the "analogWriteFrequency(pin, frequency)" function to be released for the Due?

In the meantime, I verified that the default PWM frequency (1000hz) can be changed in the variant.h file (see PWM_FREQUENCY variable).

Is there an easy way of setting frequency in the sketch directly? I tried the following code, but no success. Any verified suggestions for the community? Thank you.

\\ This approach not working:
void setup()  { 
  pinMode(6, OUTPUT);
  analogWrite(6, 64);
  PWMC_ConfigureClocks(4000 * PWM_MAX_DUTY_CYCLE , 0, VARIANT_MCK);
}

Has anyone found a solid way (preferably in sketch) to modify the output PWM frequency? Also changing variant.h from 1k to what ever you want isnt working for me. Changing it and saving doesn't change the output frequency.

Daniel