I just signed up for the forum because I wanted to ask how people start working out the design of their program.
Some people start with a [u]flowchart[/u]. I haven't used a flowchart for a long time, and it might not be that useful for "random action" Windows programs. It doesn't make sense to make a flowchart if the program is super-simple and you can imagine the flow in your head.
I think you've got a good start with you list of things your program needs to do. That's where I usually start. Whether you are making a flowchart or not, you need a list of features/functions.
Usually, I'll convert that "list" into program comments or comments as (informal) psudocode, and then I'll replace those comments with the actual code (small bits at a time).
Before you go too far, investigate your hardware requirements. Study datasheets, etc., and figure out what interfaces directly with the Arduino, and what hardware will need additional driver circuits, etc. Count the number of inputs/outputs required and think about assigning I/O pins.
Then (after you have the hardware) start with something simple on the input or output. Or, you might what to start with something hard... If there's something that you think may not work or something that you think is too hard, you might want to start with that before you get halfway through your project and discover your project is not feasible.
In any case, take one small step at a time.
For example, I've done a few sound-activated lighting projects. I usually start by building the analog-input circuit. I read values from the ADC, and send them out to the serial monitor. Once that is working, I'll switch to the lighting-output side. I'll start a new test-development program to make sure I can control the lights under software control before doing anything with the analog input. Then, I'll put the two together with some kind of logic, depending on what kind of effects I want. Again, I'll start with a simple effect that turns the lights on when a certain threshold is hit.
The logic that connects the input & output is the "meat" of your program, and it may be many functions and hundreds of lines of code. Just take it a few lines at a time...
You've already got your OLED working, and maybe some timers, so you've already got a good start.
I've been writing computer programs in various languages for many years, but I don't do it every day and I'm not an expert programmer. So, I usually try to write, compile, and test, one or two lines of code at a time. That's not always an easy thing to do because the program has to "make sense" to the compiler, so you can't just start at the top and work down... If you delete the bottom half of your program, it won't compile.
When I'm making a loop or a function, I'll usually start with a "do nothing" loop/function (or maybe a loop that counts) and I'll send a message out to the serial monitor to confirm I'm in the loop or function. Then, Ill start adding (and testing) "real code" a few lines at a time until the loop/function does everything it's supposed to do.
It's helpful to make use of the serial monitor. You can "print-out" variable-values, or little messages like "Now Writing EEPROM", to make sure the program is doing (or at least trying to do) what you expect.
How do you know what functions you need to write and how to setup the variables/constants (global or not) and what to put in a library.
There is sort-of a general rule to make a function whenever you are doing something more than once. That is, if you find yourself repeating code (or very similar code), you should use a function. And sometimes, it just makes your main loop easier to understand, and it can make your code easier to debug & modify because you are working with smaller chunks of code.
So far, I haven't written a library for the Arduino, but I have thought about creating separate files for my functions. With many-many functions in the same file as the main program, it can be a pain just to find the function if I want to make a change. It would be easier and more organized to open and edit the file with the one function. And if the functions are related, it might make sense to make a library.
There's also a "rule" in C/C++ to avoid global variables. But I'm not following that rule... Probably 90% of my variables are global. That rule may not be as important in "contained" microcontroller programming as with general purpose computer programming, but that's a question for the experts.
When trying to avoid Global variables, I found myself passing a bunch of pointers (or a big structure of pointers) into my functions and it was getting very complicated... So I decided to "cheat". :D
Otherwise, I haven't used pointers with the Arduino, except with arrays (where you can be using pointers without realizing it). You'll probably know if/when you need a pointer. In C++ (but not in C) you can often use a [u]reference[/u] instead of a pointer, and that's a lot easier.