I would like to produce as many 10-bit PWM outputs at 500 Hz or less as possible using a single pin of a microcontroller, in this case an Arduino Uno, and a SIPO shift register.
I found this question which led me to Binary Code Manipulation / Bit Angle Modulation and while this seems to have hints of an answer, my project requires the outputs of the shift register to be PWM. I need to maintain a minimum of 10-bit resolution, but the frequency could be anywhere between 300 and 500 Hz.
I assume I will have to use the 16-bit timer and sacrifice a bit if resolution to succeed. I wasn't sure if it was as simple as 16-10 = 6 outputs, and even if it is, I need a little help getting started, especially assuming it will involve register manipulation. I'm not a strong coder so I'll have to use (probably bad) pseudo code, but I imagined something like:
make an array of n rows with 1024 binary values
interlace this to a single row of 2^16 binary values
output this to a shift register
latch every n timer cycles // (only wire up the first n outputs of the shift register)
accept inputs to any row in the array at any time, but...
only update the single row fed to the shift register every 1/500th of a second
Thanks for any assistance. If it's not too much, I'd also like to know how many pins I can use as an output for the provided method on an ATmega328p if such information isn't apparent in the answer.
Edit: Thank you for the response ElectronicsStudent. I have some AL8861 ICs which accept pwm or analogue input for dimming. I would like to drive one of these per single LED cell, (around 750 mA peak current,) and through experimentation I have found 256 dimming stages to be too abrupt for the fades I want. I only need to find a solution to drive a dozen or so AL8861s initially, but would like the project to eventually accommodate more. The esp32 seemed viable with 16 pwm outputs at 10 bits each, but I still hoped for a way to avoid buying one esp32 for every 16 AL8861 chips.