Maybe I'll use shift registers on the LEDs and see how small a microcontroller I can make it run on.
Have a look at the TPIC6B595, it should be capable of driving the LEDs directly without the mosfets.
For a smaller microcontroller, I would also eliminate the floating point math. The compiler defaults to 16-bit integers for integer calculations, so need to be careful of overflow/underflow. Compile the code with and without the floating point calculations and note the difference in code size.
// Checkpoints need to be recalculated when the fill target changes
if (recalcCheckpoints) {
checkpoint[0] = fillTarget * 2 / 10; //round(fillTarget * 0.2);
checkpoint[1] = fillTarget * 4 / 10; //round(fillTarget * 0.4);
checkpoint[2] = fillTarget * 6 / 10; //round(fillTarget * 0.6);
checkpoint[3] = fillTarget * 8 / 10; //round(fillTarget * 0.8);
}
//from the ISR
targetVolume = 2 * volumeDisplay + volumeDisplay / 2 + 5; //volumeDisplay * 2.5 + 5;
corrected stupid mistake in arithmetic