Go Down

Topic: how to setup the pwm frequency of ATmega16U2  (Read 2216 times) previous topic - next topic


Which board are you using?
This is a critical detail which you seem allergic to posting, because since PWM frequency is not exposed to the user via the Arduino abstractions, you need to use a library or adjust the registers directly. And not all libraries for this support all boards, nor is the code the same for all boards.

You originally asked about the 16u2, which is not used as the main microcontroller in any official boards and which I was unaware of any Arduino support for programming it via the IDE - the only boards that use it use it as a usb-serial adapter for another microcontroller. Which led to my earlier questions (which you never answered).

Of course, if you just want to change the brightness of an LED connected to a PWM pin, you don't need to change the frequency, just the duty cycle - for that you can just use analogWrite() - though it's unclear whether there's some other reason you also need to change the frequency.
ATTinyCore for x4/x5/x61/x7/x8/x41/1634/828/x313 megaTinyCore for the megaavr ATtinies - Board Manager:
ATtiny breakouts, mosfets, awesome prototyping board in my store http://tindie.com/stores/DrAzzy


I was unaware of any Arduino support for programming it via the IDE
I only know of one 3rd party hardware package for it:
But I agree that laoadam needs to take a minute to provide the information needed to help them. If they had used their time to do that instead of cross posting, likely this would have been resolved days ago


If the pulse duration is held constant somehow, then changing the frequency would change the duty cycle.  PWM would then be the wrong name for what is happening.


I am using Arduino UNO, I need to setup PWM frequency as 15K.

My question is if I use such as "analogWrite(ledPin, val / 4)" to control the motor speed, will the PWM frequenct keep same as set or change back the original。


If I understand from the previous thread, PWM.h is part of some library. Is that correct? If so, post a link to where you downloaded it from. Please use the chain links icon on the toolbar to make the link clickable.

Previous thread:


If all pwm.h changes is the prescaler, then analog write wont change it back - but if it is getting that frequency by also changing TOP, you need your own version of analog write to account for that.
ATTinyCore for x4/x5/x61/x7/x8/x41/1634/828/x313 megaTinyCore for the megaavr ATtinies - Board Manager:
ATtiny breakouts, mosfets, awesome prototyping board in my store http://tindie.com/stores/DrAzzy


I used a pro micro and a TB6612FNG dual motor driver to drive a small car, now I want to use another large motor driver, and which asked a higher PWM frequency of ~15KHz, how can I modify the sketch to fit the application?

The project come from this link originally: https://www.instructables.com/id/Arduino-RC-Gamepad/
and the code:
Code: [Select]

#include <VirtualWire.h>

/* ARDUINO RC GAMEPAD by TeamJaeger in Technology from https://www.instructables.com/id/Arduino-RC-Gamepad/
 *  saved to: E:\design_info\DIY\ARDUINO\01_ARDUINO RC GAMEPAD
 *  this sketch was designed to load to a PRO MICRO, will be modify to suit sth new
//motor A connected between A01 and A02
//motor B connected between B01 and B02

int STBY = 10; //standby

//Motor A
int PWMA = 3; //Speed control
int AIN1 = 9; //Direction
int AIN2 = 8; //Direction

//Motor B
int PWMB = 5; //Speed control
int BIN1 = 6; //Direction
int BIN2 = 16; //Direction

const boolean FORWARD = HIGH;
const boolean REVERSE = LOW;
float speed_Max = 255; //pwm usually goes from 0-255
float speed_Min = 0;
float analogInput_Max = 1023;
float analogInput_Min = 0;
float analogInput_Middle_X = 515;//ideally it would be analogInput_Max / 2
float analogInput_Middle_Y = 495;//ideally it would be analogInput_Max / 2
float deadBand = 0;
float middleMax = (analogInput_Max / 2) + deadBand;
float middleMin = (analogInput_Max / 2) - deadBand;
boolean pastDirection = FORWARD;

void setup(){

Serial.begin( 9600 );

pinMode(STBY, OUTPUT);

pinMode(PWMA, OUTPUT);
pinMode(AIN1, OUTPUT);
pinMode(AIN2, OUTPUT);

pinMode(PWMB, OUTPUT);
pinMode(BIN1, OUTPUT);
pinMode(BIN2, OUTPUT);

//receiver setup
vw_set_rx_pin(2);          //Sets pin 12 as the RX Pin
vw_set_ptt_inverted(true); // Required for DR3100
vw_setup(2000);            // Bits per sec
vw_rx_start();             // Start the receiver PLL running

void loop(){

uint8_t buf[VW_MAX_MESSAGE_LEN]; // This declares a variable array. instead of 7 variables buf1, buf2 etc...
uint8_t buflen = VW_MAX_MESSAGE_LEN;
if (vw_get_message(buf, &buflen)) // Non-blocking
int i;
    int column = 0;
    String message;
    int commands[30];
        // Message with a good checksum received, dump it.
        for (i = 0; i < buflen; i++)
        if(char(buf[i]) == '|'){
        commands[column] = message.toInt();
        message = "";
        message += char(buf[i]);
        //one more time to capture the last value since the message does not end with |
        commands[column] = message.toInt();
        // DEBUG
// Serial.print("X: ");
// Serial.print(commands[0]);
// Serial.print(" Y: ");
// Serial.println(commands[1]);

motorControl(commands[0], commands[1]);



void move(int motor, int speed, boolean direction){
digitalWrite(STBY, HIGH); //disable standby

if(motor == 1){
digitalWrite(AIN1, direction);
digitalWrite(AIN2, !direction);
analogWrite(PWMA, speed);
digitalWrite(BIN1, !direction);
digitalWrite(BIN2, direction);
analogWrite(PWMB, speed);

void motorControl(float x, float y) {
boolean currentDirection = y >= analogInput_Middle_Y;

//map(value, fromLow, fromHigh, toLow, toHigh);
if(currentDirection == REVERSE){
y = map(y, analogInput_Middle_Y, analogInput_Min, speed_Min, speed_Max) ; 
y = map(y, analogInput_Middle_Y, analogInput_Max, speed_Min, speed_Max);
int subtractFromLeft = map(x, analogInput_Middle_X, analogInput_Min, speed_Min, y);
int subtractFromRight = map(x, analogInput_Middle_X, analogInput_Max, speed_Min, y);

if(subtractFromRight < 0){
subtractFromRight = 0;

if(subtractFromLeft < 0){
subtractFromLeft = 0;

int Throttle_RIGHT = y - subtractFromRight;
int Throttle_LEFT = y - subtractFromLeft;

boolean currentDirection_LEFT = currentDirection;
boolean currentDirection_RIGHT = currentDirection;

if(Throttle_LEFT < 1 && Throttle_RIGHT > 1){
currentDirection_LEFT = !currentDirection;
Throttle_LEFT = Throttle_RIGHT;

if(Throttle_RIGHT < 1 && Throttle_LEFT > 1){
currentDirection_RIGHT = !currentDirection;
Throttle_RIGHT = Throttle_LEFT;

move(1, Throttle_LEFT, currentDirection_LEFT);
move(2, Throttle_RIGHT, currentDirection_RIGHT);

// Serial.print("Throttle_LEFT: ");
// Serial.print(Throttle_LEFT);
// Serial.print(" Throttle_RIGHT: ");
// Serial.print(Throttle_RIGHT);
// Serial.println("");
// if(Throttle_LEFT >= -400 && Throttle_LEFT <= 400){
// motors.setM1Speed( Throttle_LEFT );
// }
// if(Throttle_RIGHT >= -400 && Throttle_RIGHT <= 400){
// motors.setM2Speed( Throttle_RIGHT );
// }
// delay(2);


Other than switching from ATmega16U2 to ATmega32U4, it seems like the same topic as your previous thread:
You had multiple people trying to help you in both those threads but instead of providing the information they are requesting, you either crosspost or just abandon the thread. Please just stick with a single thread, monitor that thread closely, and respond quickly to any information requests. If you do that, you are likely to get an answer to your question very quickly. Otherwise, you're just wasting everyone's time.

Go Up