Sorry for the deleted posts above. Again, it seems there is a keyboard key (that I am unintentionally clicking on) that would fire the post when I’m in the middle of the editing…
Costas, If you accept that my alternative formulation of your pseudo code is equivalent to yours, I’d say that 99% of the action takes place on the setup() routine, while the loop() would only be used for calibration.
So now the focus to me is: is the Blynk.run() + timer.run() cycle the best way to implement a user interaction like in my calibration routines?
I made some thinking about it, I’m still not convinced, if you have some patience left, I would add some elements to better explain why.
If you look at my previous images, you will see that I have a function menu. You can choose among a number of configuration/calibration functions. All of them are implemented by using the same user interface (1 LCD + 5 buttons). Each function has its own data acquisition logic/sequence, if you think about it, each of them is a separate “state machine”.
You can even go back to the previous input or abort (exit) the current function.
The way it is working now (I admit it is far from Blynk recommended guidelines) is that each function is implemented by a separate routine, each incorporating the logics of the associated state machine, making wide usage of while()s, while the BLYNK_WRITE() routines are kept very simple.
For example (pseudo code, I left out timeout management for simplicity):
int tiltCalibration() {
.
.
prompt("Enter tilt value for calib point ", i);
confirm_selected = back_selected = exit_selected = false;
while( !confirm_selected and !back_selected and !exit_selected )
Blynk.run();
}
if (confirm_selected) {
//store value input by user
...
} else if( back_selected) {
//go back to previous step
...
} else {
//exit tilt calibration
...
}
}
BLYNK_WRITE(CONFIRM_BUTTON) {
if (param.asInt() == 1) {
confirm_selected=true;
}
}
BLYNK_WRITE(EXIT_BUTTON) {
if (param.asInt() == 1) {
exit_selected=true;
}
}
BLYNK_WRITE(BACK_BUTTON) {
if (param.asInt() == 1) {
back_selected=true;
}
}
Code like this to me is quite easy to understand and manage, because depending on the line you are executing, the tiltCalibration routine is able to take the right decision about what to do when the user click on the BACK button (for example).
The way I understand the Blynk guidelines (but correct me if I’m wrong), since there wouldn’t be anything similar to the tiltCalibration() routine (the program is continuously executing Blink.run() - timer.run() loop) you have no other way than adding ALL the logics of ALL the state machines associated to this unique interface, to the BLYNK_WRITE() routines.
So when (let’s say) BLYNK_WRITE(BACK_BUTTON) is executed, it doesn’t know whether it is there because the user wants to go back from an input given for the battery calibration OR it was a way back from the second parameter of the third tilt calibration point (for example), unless you tell it someway.
So you need to manage “context variables” to keep track of where exactly you are in the interactive procedures, and inside BLYNK_WRITE() you have to add a lot of if()s (or big CASEs) to make different things depending on the context variables values, and manage a lot of global variables (instead of local ones). While this is technically possible of course (almost anything is possible by software) it looks like unreadable and unmanageable code, to me, but maybe you can suggest a better way to do it?