Atmega328 sufficient for 60 channel mux/demux with store-and-recall?

New to Arduino and microcontrollers in general, and hoping to figure out if the Atmega328 specifically (I’ve the Uno dev board) would be sufficient for my project. I am approaching this from the electronics realm, less so as a programmer - for now. I’ve perused the forums a bit, thrown together a few small snippets of related, useful code, but I’m no where near a final product. I’d like to get some input to find out if what I want to do is even possible, before diving deeper, and if what I have done so far is even going in the right direction. I like the idea of the 328PU because it comes in PDIP, a format that my particular fingers can reliably manage.

For those of you familiar with musical instruments which can store “patches”, the wants in this project will seem familiar. The electronics (sans Arduino) mostly already exist, so the requirements are based around those existing electronics.

In a nutshell, this is what I need the Atmega328PU to do for me:

  1. Constantly read a bank of 60 analog pots. Those pots are already wired to CMOS multiplexers. Two groups, 30 + 30 channels, each group already summed down to their own “common” analog wire, along with both groups having their own set of five address pins. I assume the two common wires will likely go into Atmega’s A0 and A1 inputs. Luckily, the “reference” voltage for the tops of those banks of pots can easily be set to any CMOS-compatible voltage, including 5V, so as not to fry the 328.

  2. Filter for “minimum pot movement” - only “detect” if a pot moves past a certain small amount, to reduce analog pot noise/false movements. I was able to write a small piece of example code which seems to do that in a simple circuit. If ( val0 > saved + 5 or val0 < saved - 5 ) digitalWrite(LED_BUILTIN, HIGH) simply tells me that the pot has moved far enough from its last known position and lights an LED telling me so. I would imagine I’d use something similar in the final sketch.

  3. With each sweep of pot reads, store their current values in what I supposed would be INTs in SRAM.

  4. Read a set of pushbuttons, 32 of them. They’re multiplexed, sampled-and-held, five address pins and one common. I will guess that this common will go into Arduino’s A2 input, maybe, why not? Store which button was last pushed, into another INT in SRAM perhaps (which ever address combo “reveals” the +5v is the one we want to “recognize” for now).

  5. Wire the Digital pins D0 through D7 to a Parallel 8-Bit Digital to Analog converter (one specially chosen to work well the existing circuits). Address them as PORTD, so they all fire at the same exact time, probably good for healthy parallel D/A conversion, right? The D/A’s output will be further fed to a demultiplexing circuit, + sample and hold, which then venture out to the rest of the project. Not sure where I’d wire this demux’s addresses to… for 60 CVs we are looking at another six demux addresses.

  6. Perform some in-chip logic: When a pushbutton is pressed, recall the values of all 60 pots from one of 30 places (“patches”) stored in flash memory, akin to a database record, I suppose. Repeatedly, rapidly, send those values out to the D/A through PORTD so its downstream sample-and-hold can make use of it. Remain aware for that “minimum pot movement”, and when the minimum threshold is encountered, change the corresponding single output to the pot’s current value (one of the multiplex values), and throw a dedicated LED to show that “the patch was changed”.

  7. Be aware for a special pushbutton to be pressed, called “Store”. When this happens, store the current set of 60 INTs into EEPROM (some will be from previous memory recall, others might be from recent pot-induced changes), lastly, deactivate that “patch was changed” LED.

  8. Drive a series of 32 “status” LEDs. These LEDs will vary in brightness based on the current values of some of the INTs in SRAM. These are already hardwired to another demux with sample-and-hold, full analog. One more analog common and five more digital address pins. So we’d just address all 32 LEDs in sequence, varying an analog voltage to match what ever the corresponding INTs are. Maybe that could “share” the D/A we are already using on PORTD? It’s a matter of making room in the timing I suppose.

  9. I could change the caps in the sample and hold’s if absolutely required, if this thing ends up being substantially faster or slower than what the current caps are timed for.

  10. Ideally, the addressing would be well up into the 100’s of KHz or higher, to help reduce the potential for needing to chase audible noise around with capacitors, copious shielding, extra space, etc.

I haven’t yet come across something of this exact nature in the forums (yet) so I’d like to find out if the Atmega328 (Arduino UNO) is sufficient for such a task - memory-wise and speed-wise, and if my idea to use “PORTD” for faster and more direct DAC is sound. I realize that some of these groups of mux/demux address pins could potentially be combined if needed, since we have all separate Common lines… I think we’d have to, being that the Atmega328 would be fast running out of pins. Maybe I need to remove it from the board, build a custom board omitting the xtal, use internal osc, so I gain a couple more addressable pins? Or is that more work than it’s worth? All insight is greatly appreciated. Pointers to existing example articles I must have missed would be super appreciated as well.

By the time you need to sample 60 ports, 32 LEDs, and 30 pushbuttons, plus write to ~14 pins worth of DAC, a 28pin microcontroller certainly doesn't sound like a good match.

the addressing would be well up into the 100's of KHz or higher,

I'm not sure what that means. If you're expecting to write 60 values, each possibly changing in 10us, you're well beyond the speed of an AVR (that'd be 6 million changes per second?

and if my idea to use "PORTD" for faster and more direct DAC is sound

Yes, it should work well if you have enough pins and don't need Serial. Another nearly as good option is to use a shift register and SPI or USART - you can process the next byte while the HW is shifting the previous one. It will probably be nearly as fast as using the whole port with possibility to add more shift registers for some additional features.

I don't understand your original description well so I don't know if Arduino will be powerful enough. You speak about using ints. Since Arduino is 8-bit use byte when possible - it is faster and needs less of the precious memory.

Thank you folks for providing these very valuable insights! Also good point about using byte instead of int - this is me getting more familiar with the world of Arduino programming. It's much appreciated.