To achieve a high PWM frequency, how do I do that?

Hi folks,

i have a not to fancy code but i have problems to compile it.
I need a high PWM frequency and i just heard the problem is the processor of the Arduino Nano Every that the librarys are not suitable right?

Is there a solution to it? i didnt find anything yet.

Thats the compilation error:
Compilation error: 'analogWriteFrequency' was not declared in this scope

Thats the code:

#include <wiring_private.h>

const int pwmPin = A0;
const int startStopPin = A1;
const int brakePin = A2;
const int directionPin = A3;

void setup() {
  pinMode(pwmPin, OUTPUT);
  pinMode(startStopPin, OUTPUT);
  pinMode(brakePin, OUTPUT);
  pinMode(directionPin, OUTPUT);

  
  digitalWrite(directionPin, HIGH);
  digitalWrite(brakePin, HIGH);
  digitalWrite(startStopPin, HIGH);

  
  analogWriteFrequency(pwmPin, 25000); 
}

void loop() {
  
  analogWrite(pwmPin, 128); 

  
}

How much this "high" freq should be?

I need a range between 20khz -30khz.

Where from did you find this function? There is no such method in the Nano Every Arduino core

I could find Z-Uno and teensy :wink:

In that case, you'll have to practice your google skills :wink:

https://www.google.com/search?q=arduino+Nano+Evevry+pwm+frequency

One of the first hits seems useful:

Note: it's not said that it will be easy. I don't have a Nano Every so can play around with it to help you further.

There is a very good book from Tom Almy called "Far Inside The Arduino: Nano Every Supplement" He covers comprehensibly all the things you can do with it.

You can get the code from his examples here
https://almy.us/arduinoeverybook.html

He covers examples of increasing the PWM frequency for all the timers in the processor.

Better still buy the book.

Pew, i thought there is an easy solution to this :sweat_smile:

I will take a look at it later if i can handle it, the follow up questions are coming for sure :joy:

Down load the code, it is stupidly simple what you have to do.

MegaCoreX is an alternative core for the Nano Every, and it contains a function
analogWriteFrequency( ) which will work for 8, 16, or 32 KHz.

https://github.com/MCUdude/MegaCoreX/blob/master/megaavr/cores/coreX-corefiles/wiring_analog.c

1 Like

Be aware that "PWM" is not what a lot of people think it is. PWM is a fixed frequency and the duty cycle is varied. Usually the PWM frequency is not varied. Certain devices can handle set PWM frequencies, for example a servo might handle 50Hz PWM, or some actuators might handle up to 500Hz it depends what they are designed for. Typically an Arduino does 490Hz PWM.
analogWrite sets the duty cycle of a PWM-capable pin.

In Arduino terms Tone is more like what people expect, where the frequency is varied with a 50% duty cycle - so a classic square wave.
Depending on your Arduino model Tone can do from 31Hz to quite some high frequency, higher than you need.
Look up Tone in the Arduino reference, and here's some extra info:

Hi,

The MegaCoreX is always advantageous, no longer occupies TCA for millis. TCA is thus freely usable.

A simple example which can be further refined into separate frequency and duty setting. For the prescaler you can choose 1 or 2 or set it to from TCA. Then you have all prescalers of TCA available.

/*
  Example 1
  MSB 0 und LSB 1 ..... 0% Duty Cycle
  MSB 1 und LSB 1 .... 50% Duty Cycle
  MSB 2 und LSB 1 ... 100% Duty Cycle

  Example 2  
  MSB 0 und LSB 5 ..... 0% Duty Cycle
  MSB 1 und LSB 5 .... 17% Duty Cycle
  MSB 2 und LSB 5 .... 33% Duty Cycle
  MSB 3 und LSB 5 .... 50% Duty Cycle
  MSB 4 und LSB 5 .... 67% Duty Cycle
  MSB 5 und LSB 5 .... 83% Duty Cycle
  MSB 6 und LSB 5 ... 100% Duty Cycle
*/

const uint8_t pinTCB1 {3};

void setup (void)
{
  initPins();
  initTCB1();
  updateTCB1(127,254);
}

void loop (void)
{
  
}

void initPins (void)
{
  pinMode(pinTCB1, OUTPUT);
}

void initTCB1 (void)
{
  TCB1.CTRLA = 0;
  TCB1.CTRLB = 0;
  TCB1.INTCTRL = 0;
  TCB1.CTRLA |= TCB_CLKSEL_CLKDIV2_gc;
  TCB1.CTRLB |= TCB_CNTMODE_PWM8_gc;
  TCB1.CTRLB |= TCB_CCMPEN_bm;
}


void updateTCB1 (uint8_t duty, const uint8_t periode)
{
  static uint8_t lastMSB {0};
  static uint8_t lastLSB {0};

  if ( (lastMSB != duty) || (lastLSB != periode) )
  {
    // safety check
    if ( (periode < 255) && (duty > periode+1) ) duty = periode+1;
        
    TCB1.CTRLA &= ~TCB_ENABLE_bm;     // stop
    TCB1.CNT = 0;                     // reset 
    const uint16_t tempDuty {(uint16_t)duty << 8};
    TCB1.CCMP = tempDuty | periode;   // set new value, MSB Duty Cycle / LSB Periode
    TCB1.CTRLA |= TCB_ENABLE_bm;      // start

    lastMSB = duty;
    lastLSB = periode;
  }
}    

Hi, I am doing a project that need that, can you tell me how to use this repo to include the AnalogWriteFrequency function on my project code? as I am totally beginner ? thanks a lot

What you need to know can be found at
https://github.com/MCUdude/MegaCoreX

Instructions on how to load the core through the board manager is here
https://github.com/MCUdude/MegaCoreX?tab=readme-ov-file#how-to-install

The discussion of analogWriteFrequency( ) is here
https://github.com/MCUdude/MegaCoreX?tab=readme-ov-file#pwm-output

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.