Don't worry, after 30 years programming experience, I still don't know the difference between a definition and a declaration in C; it's only a problem for me if I try to explain something and I probably get it wrong.
Your program code is stored in one or more files; in the case of the Arduino IDE, the first file that you encounter is the ino file. And each file usually contains functions. So you do understand the basics there.
And setup() and loop() are the first two functions that you encounter.
They are called from another function that the Arduino IDE hides from you. Every C / C++ program starts with a function called main(). main() calls setup() once and in an endless loop it calls loop(). It looks something like
void main()
{
// call setup once
setup();
// call loop; once it's finished call it again
while(true)
{
loop();
}
}
The appproach you are describing (from my point of view) is organizing the code in functions that perform a certain task and calling those functions in sequence; I think that those functions is what you refer to as 'modules'. This is a good approach as it keeps your code neat and tidy.
I have never considered that calling a few functions in sequence can be seen as a statemachine. In theory one can when I think about it. I think that this is where I was confused with your use of the term statemachine. In my dictionary, a statemachine is something different.
In a statemachine, one has a number of functionalities that do something; e.g switch a LED on, switch off a LED, sound a buzzer. Those are called in sequence but the sequence is determined by 'external' factors like e.g. a button press or temperature that is not within limits or by 'internal' factors like a delay or the result of a calculation.
So I did not consider this a statemachine
void loop()
{
// state 1
getTemp();
// state 2
displayTemp();
// state 3
runPump();
// and the next time loop is called it goes back to state 1
}
But I do consider this a statemachine
void loop()
{
// state 1
getTemp();
// state 2
displayTemp();
// only go to state 3 if temperature is above 75
if(temp >75)
{
// state 3
runPump();
}
// and the next time loop is called it goes back to state 1
}
So what you are describing is a statemachine that basically is not affected by anything; it just does it things without caring what is going on outside it.
Because the fact that I was confused, I rewrote your getTemp() in a way that I would implement getTemp using a statemachine. Your getTemp() function can be in one of two states (delay and read). In the 'delay' state, it checks if a time has lapsed (an 'internal' factor).
It stays in that state till the time has lapsed. Staying in that state basically means
change nothing
return (go back) to loop()
So the next time that getTemp() is called the state is still 'delay' and it checks again if the delay has lapsed.
Once the time has lapsed, the state is changed to 'read' and further nothing is done and the function returns (goes back) to loop().
Now the next time that getTemp() is called, the state is 'read' and it will read the sensors. Once all sensors are read, the state is changed to 'delay' and the function returns (goes back) to loop.
As said, all this was done because I was confused about what you considered a statemachine But at least you learned something
//Edit
I see that I forgot about the switch/case. It's nothing more than something like
if(currentState == ST_TEMP_DELAY)
{
...
...
}
else if(currentState == ST_TEMP_READ)
{
...
...
}
The only reason I use it is that I consider it tidier and slightly easier to maintain. Imagine you have 10 states; they will all have their own 'case entry' in the switch and it's immediately clear (for me) that they belong together. It only works for single values, not for a range of values. The below can not directly be done in a switch case.
if(temp > 75)
{
}
else if(temp < 0)
{
}
else if(temp < 25)
{
}