Soft PWM library doesn't support all MEGA digital pins?

Alright so the underlying usage might be a bit backwards here. I have a MEGA that controls about 45 lights using 45 mosfets. The lights can be dimmed so I need to use a PWM signal to drive em with a brightness values. The reason I went with a MEGA is because the amount of pins it has on board pretty much provides enough output pins and then some to do the job. Only problem is that not all of them are PWM pins. So naturally I went with the SoftPWM library (which doesn't work on DUE's which I own about 9 of and had to use the MEGA of which I own 2, 1 already engaged in a project) Anyways. I've discovered that the soft PWM refuses to engage pins after a certain pin number (haven't tested which one yet.) In the set up, I've created a For loop which set all the pins to outputs and set all the PWM pins using the softPWM pin setup command.

So is this some sort of hardware limitation on the Mega? or is the library just not programmed to set-up about 45 PWM pins. I know all the engineering veterans are angrily slamming on the keyboards right about now, telling me that I can't use all digital pins as PWM pins. I know, sort of. I only really need to use about 7 PWM pins at once at a time. But I do need to have about 45 of them present. I'm aware of actual LED driver ICs out there, I just don't own any of them in the shop atm and the Mega has so many pins that I figured I'd try to see if that would be enough.

For the sake of testing, if I swap the PWM driving functions with a simple digitalWrite function, the pins light up, it works fine. It's just the softPWM that refuses to drive anything above pin 20 or 18 (or something along those lines, again, haven't done a definitive test). Someone said that you can code your own code in exchange for processing cycles. Something to do with tracking delta time.

Now should I not be able to do this using just the MEGA, I'll either have to settle for simple ON - OFF states or wait a couple of weeks to order some LED drivers like the TLC5940 or LM3915. And realistically speaking, if I go with these ICs, I can just use an UNO instead of a MEGA for this too.

Can I still get away with just using the Megas on-board pins? It has more than enough for me to work with.

Getting curious I wanted to have a look at the library source - a quick Google search turned up at least two SoftPWM libraries for Arduino. If max 20 pins supported that would suggest the author was focussed on the Uno.

Which exact library are you using?

You should have used three hardware PWM PCA9685 breakout boards (Adafruit, ebay), and an Uno or Nano. Then you also would have had better (12-bit) dimming. Leo..

wvmarle: Getting curious I wanted to have a look at the library source - a quick Google search turned up at least two SoftPWM libraries for Arduino. If max 20 pins supported that would suggest the author was focussed on the Uno.

Which exact library are you using?

I used the one that was available from the Arduino IDE built in library downloader.

Wawa: You should have used three hardware PWM PCA9685 breakout boards (Adafruit, ebay), and an Uno or Nano. Then you also would have had better (12-bit) dimming. Leo..

Well if it doesn't work out I'll just get some of the LED driver ICs mentioned above and just use an UNO. I don't have any led drivers on site and it would take a good month to get a shipment. For now I was looking to use what is already available at hand.

wvmarle: Getting curious I wanted to have a look at the library source - a quick Google search turned up at least two SoftPWM libraries for Arduino. If max 20 pins supported that would suggest the author was focussed on the Uno.

You know what, I've found the github of the library by pressing on the link in the library description in the Arduino IDE library manager, and you can actually see this:

https://github.com/bhagman/SoftPWM/blob/master/SoftPWM.h

define SOFTPWM_MAXCHANNELS 20

so that's pretty much it right there. I'm gonna check tomorrow to see if editing this value will allow me to use more pins.

You could try to change this

define SOFTPWM_MAXCHANNELS 20

to

define SOFTPWM_MAXCHANNELS 45

But your not going to beable to use 45 the timer can't handle but 20 at one time but if you wasn't using 20 at time it maybe work.

be80be:
You could try to change this
#define SOFTPWM_MAXCHANNELS 20
to
#define SOFTPWM_MAXCHANNELS 45

But your not going to beable to use 45 the timer can’t handle but 20 at one time but if you wasn’t using 20 at time it maybe work.

Will be trying that tomorrow.

Adafruit seems to have this:

which is also serial link-able so two of these pretty much do the job I need.

be80be: You could try to change this

define SOFTPWM_MAXCHANNELS 20

to

define SOFTPWM_MAXCHANNELS 45

But your not going to beable to use 45 the timer can't handle but 20 at one time but if you wasn't using 20 at time it maybe work.

That would require a study of the rest of the code - it would totally depend on how it works, and how the timers are set up.

I guess the timers will be linked to specific pins, and to use them spread out over 45 pins you would have to reassign them all the time.

Maybe easier to assign pins to PWM outputs as needed, without modifying the library itself?

I've used that bhagman library but I ended up switching to using this one instead: https://github.com/Palatis/arduino-softpwm I added support for using Arduino pin numbers without any loss in efficiency in my fork: https://github.com/per1234/PalatisSoftPWM But yeah, 45 channels of software PWM on a Mega is tough. You should be able to do it with that library but you'll have to set a low frequency, which will cause a visual flicker, especially if the LEDs are moving relative to your eye. So in the end you'll probably be better off with a hardware solution but it's kind of fun to see how far you can go just using software PWM. I'm using the library with 15 channels on an ATmega328P running at 8 MHz and it's not so bad. If I remember correctly, I'm able to get a PWM frequency of about 100 Hz .

wvmarle: That would require a study of the rest of the code - it would totally depend on how it works, and how the timers are set up.

I guess the timers will be linked to specific pins, and to use them spread out over 45 pins you would have to reassign them all the time.

Maybe easier to assign pins to PWM outputs as needed, without modifying the library itself?

Well when I looked through the code on the githup, anything that has to do with SOFTPWM_MAXCHANNELS was inside of a for loop. This was just me skimming over the code but I'd think that if it's a for loop, whatever was inside would have been automated. By anyways, only a test will tell. Gonna do that tomorrow.

what about writing your own PWM - like handling in code, the controller doesn't do much of anything else besides reading the serial data which determines what PINS and the Value of the PWM to set.

Sure, you can write your own software PWM but if you try to use digitalWrite() then you'll have terrible performance because it's very inefficient. I remember there's a digitalWrite() based software PWM demonstration on the Arduino Playground if you want to check it out. You can definitely just look at the bhagman and palatis libraries to see how they did it. bhagman's has a bunch of unnecessary code for the fade function so you need to disregard that to see how the PWM alone is done.

The fade function seemed useful at first, which was why I originally wanted to use that library, but in the end I found they were useless for my application because I like the option of nice slow color transitions and the code in the library limits you to 4000 ms maximum fade time, which is way to fast for most of the effects I want. I preferred a library that solely focused on efficient software PWM and then I can just implement the fade code in my sketch.

pert: Sure, you can write your own software PWM but if you try to use digitalWrite() then you'll have terrible performance because it's very inefficient. I remember there's a digitalWrite() based software PWM demonstration on the Arduino Playground if you want to check it out. You can definitely just look at the bhagman and palatis libraries to see how they did it. bhagman's has a bunch of unnecessary code for the fade function so you need to disregard that to see how the PWM alone is done.

The fade function seemed useful at first, which was why I originally wanted to use that library, but in the end I found they were useless for my application because I like the option of nice slow color transitions and the code in the library limits you to 4000 ms maximum fade time, which is way to fast for most of the effects I want. I preferred a library that solely focused on efficient software PWM and then I can just implement the fade code in my sketch.

Well alright. I'll try to see if setting the SOFTPWM_MAXCHANNELS yields any useful results. If no then I'll just work with On - Off and get a few of those adafruit boards linked above and upgrade to those once they arrive some time later down the line.

I'm sorry to revive such an old thread. Were you able to use more than 20 pins with Mega?

I haven’t used the ‘canned ’soft PWM libraries, but have used my own code to run 72 channels of soft PWM on 3 pins - across a chain of TPIC595 shift registers. With that many channels on an 8MHz PIC, the steps were just noticeable.

It was no problem running all of them at once with cross fades and RGB colour mixing as needed. 16MHz Arduino should be ‘easy’. https://youtu.be/eewAOwAOzpw