Arduino UNO pin9 and pin10 not working for PWM output

I used 433mhz and two Arduino UNOs to control a small car.

The UNO's pin9 (PWMA) and pin10 (PWMB) no PWM output, if change into pin3 and pin5, that works but ~1khz, actually it was the original sketch signed.

The reason I want to use pin9 and 10 is the high PWM frequency need.

The sketch is kind of too long, attached here.

I didn't use servo library.

The sketch was down by two stages: PWM frequency set and RC control, both of them working good separately.

Thanks for help.

Receiver_m2.ino (6.56 KB)

Try initializing the VirtualWire library before you initialize Timer1. You may find that your PWM works but VirtualWire doesn't. That would indicate that VirtualWire is using Timer1.

Thank you johnwasser, it is true, the VirtualWire library using Timer1. Do you have any solution? I searched out some body try to Converting VirtualWire from Timer1 to Timer2, seems no result.
http://forum.arduino.cc/index.php?topic=309766.0
what will be then?

Could be OK if I get rid of VirtualWire library and use RadioHead?
Best

Can you use different pins for PWM? The other PWM pins use different timers.

RadioHead also uses timer1 by default.

All the good 433mhz RF libraries use a timer, almost always timer1.

My suggestion would be to use different PWM pins. If you need more than 4 PWM pins and 433MHz RF, the atmega328p is not sufficient (328pb is, as it has more extra timers, as is mega2560, and boards based on 1284p)

Thank you groundFungus and DrAzzy, maybe my understood wrong, my motor driver need 14khz, and there is only timer1 is 16 bite, which control pin9 and 10. can I used timer1 and output at other pins? or can other timer give out ~14khz PWM?

The link groundFungus given is about MEGA, I am using UNO now.

Best

You can set pins 3 and 11 to 62,6kHz, fast enough? 8-bit though but >14kHz

Also note, a lot of motor drivers like the L298 only need a single PWM signal.

Thank you septillion, I agree with you to shift to timer2 is a simplest way.
The code for set frequency of timer1 is:

// PWM output @ 14 kHz, only on pins 9 and 10.
// Output value should be between 0 and 571, inclusive.

void analogWrite14k(int pin, int value)
{
switch (pin) {
case 9:
OCR1A = value;
break;
case 10:
OCR1B = value;
break;
default:
// no other pin will work
break;
}
}

void setup()
{
// Configure Timer 1 for PWM @ 25 kHz.
TCCR1A = 0; // undo the configuration done by...
TCCR1B = 0; // ...the Arduino core library
TCNT1 = 0; // reset timer
TCCR1A = _BV(COM1A1) // non-inverted PWM on ch. A
| _BV(COM1B1) // same on ch; B
| _BV(WGM11); // mode 10: ph. correct PWM, TOP = ICR1
TCCR1B = _BV(WGM13) // ditto
| _BV(CS10); // prescaler = 1
ICR1 = 571; // TOP = 571

// Set the PWM pins as output.
pinMode( 9, OUTPUT);
pinMode(10, OUTPUT);
}

void loop()
{
// Just an example:
analogWrite14k( 9, 110);
analogWrite14k(10, 210);
for (;:wink: ; // infinite loop
}

can you kindly show me how to modify it to timer2?

Best

If you add code tags I will have a look :slight_smile:

Thank you septillion, sure:

// PWM output @ 14 kHz, only on pins 9 and 10.
// Output value should be between 0 and 571, inclusive.

void analogWrite14k(int pin, int value)
{
    switch (pin) {
        case 9:
            OCR1A = value;
            break;
        case 10:
            OCR1B = value;
            break;
        default:
            // no other pin will work
            break;
    }
}

void setup()
{
    // Configure Timer 1 for PWM @ 25 kHz.
    TCCR1A = 0;           // undo the configuration done by...
    TCCR1B = 0;           // ...the Arduino core library
    TCNT1  = 0;           // reset timer
    TCCR1A = _BV(COM1A1)  // non-inverted PWM on ch. A
           | _BV(COM1B1)  // same on ch; B
           | _BV(WGM11);  // mode 10: ph. correct PWM, TOP = ICR1
    TCCR1B = _BV(WGM13)   // ditto
           | _BV(CS10);   // prescaler = 1
    ICR1   = 571;         // TOP = 571

    // Set the PWM pins as output.
    pinMode( 9, OUTPUT);
    pinMode(10, OUTPUT);
}

void loop()
{
    // Just an example:
    analogWrite14k( 9, 110);
    analogWrite14k(10, 210);
    for (;;) ;  // infinite loop
}

See Arduino Playground - TimerPWMCheatsheet for a big part. But it only shows it in phase correct mode aka 31kHz but I assume that's fine.

TCCR2B = (TCCR2B & 0b11111000) | 0x01;

Sets pins 3 and 11 to 31kHz.

Thank you septillion.
I'll search out the link, I'm not sure if it works, my motor driver just suite for frequency of 10 khz to 20 khz.

I modified the code to use timer 2 output PWM on pin3 and pin11 succeed and got 31 KHz output, not perfect for need of 14 KHz yet, good for testing timer2 only.

That is merged into my motor driver code works well , how to make it output 14KHz?

// PWM output @ 14 kHz, only on pins 3 and 11.
// Output value should be between 0 and 320, inclusive.
void analogWrite14k(int pin, int value)
{
   switch (pin) {
       case 3:
           OCR2A = value;
           break;
       case 11:
           OCR2B = value;
           break;
       default:
           // no other pin will work
           break;
   }
}

void setup()
{
   // Configure Timer 2 for PWM @ 14 kHz.
   TCCR2A = 0;           // undo the configuration done by...
   TCCR2B = 0;           // ...the Arduino core library
   TCNT2  = 0;           // reset timer
   TCCR2A = _BV(COM2A1)  // non-inverted PWM on ch. A
          | _BV(COM2B1)  // same on ch; B
          | _BV(WGM20);  // mode 10: ph. correct PWM, TOP = ICR1
   TCCR2B = _BV(WGM00)   // ditto
          | _BV(CS10);   // prescaler = 1
   ICR1   = 320;         // TOP = 320

   // Set the PWM pins as output.
   pinMode( 3, OUTPUT);
   pinMode(11, OUTPUT);
}

void loop()
{
   // Just an example:
   analogWrite14k( 3, 110);
   analogWrite14k(11, 220);
   for (;;) ;  // infinite loop
}
/]

When I changed: TCCR2B = (TCCR2B & 0b11111000) | 0x02; //3.92116 [kHz], I got 3.9 khz, no meet need but close to. The joystick not works well, seems the data missed up, the joystick has a very little movement , if move more the speed go down instead of go up as expected.

What kind of motor you use that's so picky about the frequency? Motors rarely are...

Thank you septillion, the motor driver need frequency: 10khz - 20 khz, I random selected 14khz.

I changed TCCR2A and TCCR2B some day and got the output double, the 3.9k becomes around 7khz, should be good enough. The thing is the joystick's moving range changed very small, I doubt maybe the data storage address conflict some where?

But whih motor driver is it? Because it's starting to get a massive XYproblem.
And what is conflicting with what?

Thank you septillion, right now I'm using a TB6612FNG dual motor driver. I may use a large driver later on like this:

https://www.aliexpress.com/item/FREE-SHIPPING-motor-drive-module-DC-motor-driver-100A-ultra-high-power-48V-5V-wide-voltage/2047317967.html?spm=2114.search0104.3.1.501d4ee8SOXBQC&ws_ab_test=searchweb0_0,searchweb201602_4_10065_10068_10130_10890_10547_319_10546_10548_317_10696_453_10084_454_10083_433_10618_431_10139_10307_537_536_10059_10884_5736015_10887_100031_321_322_10103_5736115,searchweb201603_35,ppcSwitch_0&algo_expid=c791eeb3-a9ad-4111-a0d7-654ed7cb5905-0&algo_pvid=c791eeb3-a9ad-4111-a0d7-654ed7cb5905&transAbTest=ae803_3

My concern now is how to get ~14khz PWM output.

But why? Don't really see the need for a frequency that high and that specific...

Thank you septillion, the large motor driver I put link is not the one I gonna use, the real one is in Chinese and I was told that need over 10Khz PWM frequency.

I doubt it needs it... But yeah, can't tell for sure without a datasheet or type number.