How to set pwm switching frequency

Hi,

I'm new to coding working on a project atm using a pi pico to control a mosfet to switch a create a switch and a dimmer with one button for my under counter lights.

I have got the code to work arduino ide and it controls an led that is attached perfectly but am struggling to find any information on setting the frequency.

i am using a Gravity: MOSFET Power Control Module that has a maximum switching frequency of 1KHz. I beleive that the pico's base pwm will be a lot higher than that.

if anyone could help me find that would be really appreciated.

const int ledPin = 3; // Led Pin
int long brightness = 255;
bool switchstate = false;



static const int buttonpin = 4;                 // button input pin
int buttonStatePrevious = LOW;                  // previous state of switch

unsigned long minButtonPressDuration = 3000;    // long press minimum time
unsigned long buttonLongPressMillis;            // time in ms when button is pressed
bool buttonStateLongPress = false;              // True if its a long press 



const int intervalButton = 50;                  // Time between two reading of button state
unsigned long previousButtonMillis;             // Time stamp for latest reading

unsigned long buttonPressDuration;              // how long the button has been pressed in ms

/// GENERAL ///

unsigned long currentMillis;                    // Variable to store number of Ms



void setup() {
  Serial.begin(9600);  //start serial monitor

  pinMode(ledPin, OUTPUT);    // set led as output
  pinMode(buttonpin, INPUT);  // set button as input
  Serial.print("press Button");




  

}

void loop() {
  
  currentMillis = millis();
  readButtonState();

}


void readButtonState(){

  // checks if the previous reading is larger than the interval button
  if (currentMillis - previousButtonMillis > intervalButton){

    // read the digital value of the button (high/low)
    int buttonState = digitalRead(buttonpin);

    // if the button has been pressed
    // and the button wast presser before
    // and if long press is not being measured at the moment this statment will run
    if (buttonState == HIGH && buttonStatePrevious == LOW && !buttonStateLongPress){
      buttonLongPressMillis = currentMillis;
      buttonStatePrevious = HIGH;
      Serial.println("button pressed");
    }
    //calculate how long the button has been pressed
    buttonPressDuration = currentMillis - buttonLongPressMillis;


    //If te button is pressed and 
    if (buttonState == HIGH && !buttonStateLongPress && buttonPressDuration >= minButtonPressDuration){
      buttonStateLongPress = true;
      Serial.println("Button Long Pressed");

      // Light brightness control 
       if (brightness == 255){
      brightness = 50;
      }

      else {
      brightness = 255;
      }

      if (switchstate == true){
      analogWrite(ledPin, brightness);
      }
    }

    if (buttonState == LOW && buttonStatePrevious == HIGH){
      buttonStatePrevious = LOW;
      buttonStateLongPress = false;
      Serial.println("Button Released");

      if (!buttonStateLongPress && buttonPressDuration < minButtonPressDuration){
        Serial.println("Button Pressed shortly");

        // Led On and Off 
        switchstate = !switchstate;


        if (switchstate == true){
        analogWrite(ledPin, brightness);
        }

        else {
          analogWrite(ledPin, 0);
        }
      }
    }

    previousButtonMillis = currentMillis;

  }
}

30 seconds of looking in wiring_analog.cpp in the core would have rectified that. The function needed to change the PWM frequency is clearly named.

You believe? Why believe when you can check? Less than 30 seconds of looking in wiring_analog.cpp would tell you that your belief is incorrect. As would trying the simple sketch below and measuring the output frequency on GPIO2.

void setup() {
   analogWrite(2,64);
}

void loop() {
}

I used these for LEDs:

They give me High or Low side switching. Each motor output is capabile of 35A without a problem. The module will give you two channels and it will operate at the default PWM frequency of the Arduino.

Nice part it comes with heatsink etc.

Nick Gammon covers PWM and setting frequencies in some detail.
https://www.gammon.com.au/

Thank you so much.

There’s so much information with this stuff I’m never sure if what I’m doing is the correct thing to do :sweat_smile:.

Gonna give this a read through then hopefully will be able to figure it out :crossed_fingers:

I’ll keep this noted for future projects

Curious which LEDs you are trying to dim.

I actually don't have the LEDs yet , might also be running on ac rather than dc so will see how that goes once I crack open the cabinet hahaha.

The lights are g4 12v 20W halogen bulbs atm but have seen replacement g4 12v 2w LEDs (should be both about 200 lumens). I am trying to find one with a data sheet so I can look at the circuit to check that its pwm-able but its not the standard when looking on standard online websites.

on a side note I was able to get me code working and works how i want for the most part, probably will make a few tweaks later on but im pleased with it for my first project that had no guide.

Have also designed my first PCB that is being made!!!!! (so thats exhiting :slight_smile:)

Gonna apologise now for my code to anyone who has any clue at all what they are doing:

int f = 200;                                  // set pwn period to 200Hz

const int fadeInterval = 40;                  // how quickly the brightness changes

// Maximum and minimum brightness values for dimming routine
const int maxBrightness = 120;
const int minBrightness = 5;

const int ledPin = 3;                          // Led Pin
const int frequency = 1000;                    // set pwm period to 1KHz
int long brightness = 255;
bool switchstate = false;
bool fadingDirection = true;


static const int buttonpin = 4;                 // button input pin
int buttonStatePrevious = LOW;                  // previous state of switch

unsigned long minButtonPressDuration = 1000;    // long press minimum time
unsigned long buttonLongPressMillis;            // time in ms when button is pressed
bool buttonStateLongPress = false;              // True if its a long press 



const int intervalButton = 50;                  // Time between two reading of button state
unsigned long previousButtonMillis;             // Time stamp for latest reading

unsigned long buttonPressDuration;              // how long the button has been pressed in ms

/// GENERAL ///

unsigned long currentMillis;                    // Variable to store number of Ms



void setup() {
  Serial.begin(9600);                           //start serial monitor

  

  pinMode(ledPin, OUTPUT);                      // set led as output
  pinMode(buttonpin, INPUT);                    // set button as input
  Serial.print("press Button");


  analogWriteFreq(f);





  

}



void loop() {
  
  currentMillis = millis();
  readButtonState();

}

void readButtonState(){

  // checks if the previous reading is larger than the interval button
  if (currentMillis - previousButtonMillis > intervalButton){

    // read the digital value of the button (high/low)
    int buttonState = digitalRead(buttonpin);

    // if the button has been pressed
    // and the button wast presser before
    // and if long press is not being measured at the moment this statment will run
    if (buttonState == HIGH && buttonStatePrevious == LOW && !buttonStateLongPress){
      buttonLongPressMillis = currentMillis;
      buttonStatePrevious = HIGH;
      Serial.println("button pressed");
      
      
    }
    //calculate how long the button has been pressed
    buttonPressDuration = currentMillis - buttonLongPressMillis;


    //If the button is pressed and its been over 1.5s
    if (buttonState == HIGH && !buttonStateLongPress && buttonPressDuration >= minButtonPressDuration){
      Serial.println("Button Long Pressed");

      buttonStateLongPress = true;
      // LED brightness control 
       if (brightness == 255){
      


        /// Dimming function start///



      do{
        Serial.println(brightness);
        if (brightness >= maxBrightness){
         fadingDirection =  false;
        }
        
        if (brightness == minBrightness){
         fadingDirection =  true;
        }
        // slowly get brighter
        if (fadingDirection){
          brightness = ++brightness ; 
          delay(fadeInterval);
          Serial.println(brightness);
        }

        // slowly get dimmer
        if (!fadingDirection){
          brightness = --brightness ; //
          delay(fadeInterval);
          Serial.println(brightness);
        }
        analogWrite(ledPin, brightness);
        buttonState = digitalRead(buttonpin); // is the button still being pressed? if so repete

      }
      while(buttonState == HIGH);
      
      

      /// Dimming function end///



      }

      else {
      brightness = 255;
      }

      if (switchstate == true){
      analogWrite(ledPin, brightness);
      }
    }

    if (buttonState == LOW && buttonStatePrevious == HIGH){
      buttonStatePrevious = LOW;
      buttonStateLongPress = false;
      Serial.println("Button Released");
      Serial.println(brightness);
      

      if (!buttonStateLongPress && buttonPressDuration < minButtonPressDuration){
        Serial.println("Button Pressed shortly");

        // Led On and Off 
        switchstate = !switchstate;


        if (switchstate == true){
        analogWrite(ledPin, brightness);
        }

        else {
          analogWrite(ledPin, 0);
        }
      }
    }

    previousButtonMillis = currentMillis;

  }
}


Then I would suggest addressable LED strips.
You don't need a driver for these, and you can add some ambient colours.
The sky is the limit if you use a WiFi board. Automatic nigh time switching, smartphone control etc.

12V LED replacements for halogen usually have a driver built-in.
If so, then external PWM dimming can be a problem. The internal constant current driver will fight this.

The internal driver can usually be modified to take a PWM signal directly.
But you must be tech-savvy to carry out that mod.
It involves removing the internal bridge rectifier and solder a wire to the PWM pin of the smd chip.