0

Independent PWM outputs with variable frequency (Arduino MEG
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Independent PWM outputs with variable frequency (Arduino MEG

by akerblom on Tue May 07, 2019 5:14 am

Hello!

I'm currently working on a project that requires 7 independent PWM outputs with a variable frequency from approximately 0 - 4096Hz with a Arduino MEGA.

As I write this I manage to get 4 independent outputs and understand that this is the maximum amount since the MEGA has 5 different timers that are linked between the different PWM- pins on the Arduino and that timer0 "shouldn't" be used. As you understand, this is a problem since I need 7 of these bad boys.

I'm using the PWM.h library and the frequency value is controlled by a CAN interface that sends a message to the arduino with a ID and a value of 0-100 together with some Arduino code.

Code: Select all | TOGGLE FULL SIZE
#include <PWM.h>
#define FI_factor 40.96

int32_t frequency = 100;                          //Start frequency (in Hz)

int FI_1 = 3;
int FI_2 = 4;
int FI_3 = 5;
int FI_4 = 6;
int FI_5 = 7;
int FI_6 = 8;
int FI_7 = 44;

void setup() {
InitTimersSafe();                      //initialize all timers except timer0

  for (int i = 3; i <= 8; i++) {
    SetPinFrequencySafe(i, frequency);   //sets the start frequency for the specified pin
  }
  SetPinFrequencySafe(44, frequency);
}

void loop() {

if (rxId == 0x90) {                                         //rxId is the message id from CAN and checks if a message is recieved
    frequency = (rxBuf[0] * FI_factor);          //rxBuf[0] is the massage from CAN, a value between 0 - 100.
    SetPinFrequencySafe(FI_1, frequency);    //Sets the desired frequency to the chosen pin
  }
    else if (rxId == 0x91) {
    frequency = (rxBuf[0] * FI_factor);
    SetPinFrequencySafe(FI_2, frequency);
  }
      else if (rxId == 0x92) {
    frequency = (rxBuf[0] * FI_factor);
    SetPinFrequencySafe(FI_3, frequency);
  }
      else if (rxId == 0x93) {
    frequency = (rxBuf[0] * FI_factor);
    SetPinFrequencySafe(FI_4, frequency);
  }
      else if (rxId == 0x94) {
    frequency = (rxBuf[0] * FI_factor);
    SetPinFrequencySafe(FI_5, frequency);
  }
      else if (rxId == 0x95) {
    frequency = (rxBuf[0] * FI_factor);
    SetPinFrequencySafe(FI_6, frequency);
  }
      else if (rxId == 0x96) {
    frequency = (rxBuf[0] * FI_factor);
    SetPinFrequencySafe(FI_7, frequency);
  }

  for (int i = 3; i <= 8; i++) {
    pwmWrite(i, 127);                          //Sets the duty cycle for a PWMs to 50%
  }
   pwmWrite(44, 127);
}


As i said, it works... but only 4 of them is independent. (As an example, pin 6 and 7 always get the same frequency value).

Is there some component or "trick" to bypass the timers or get these independent PWM outputs?
I hope you understand what i want to achieve.
Sincerely, Philip

akerblom
 
Posts: 2
Joined: Tue May 07, 2019 4:39 am

Re: Independent PWM outputs with variable frequency (Arduino

by adafruit_support_bill on Tue May 07, 2019 6:03 am

There are some software PWM tricks you can do by setting up a fast timer with an interrupt, then dividing that down in software to control one or more GPIO pins. This is somewhat less precise than hardware PWM, and works better at lower frequencies. But it may be good enough to accomplish what you are looking for.

adafruit_support_bill
 
Posts: 74687
Joined: Sat Feb 07, 2009 10:11 am

Re: Independent PWM outputs with variable frequency (Arduino

by akerblom on Tue May 07, 2019 6:26 am

Thank you! I will look in to it..

akerblom
 
Posts: 2
Joined: Tue May 07, 2019 4:39 am

Please be positive and constructive with your questions and comments.