-
As a newbie I feel very proud that I managed to make my GPS device show all the relevant data and everything pixel perfect, the part of the sketch I posted here for help is just a very simplified excerpt of it. This is the obstacle I encountered - when GPS signal is normal, the screen shows "interface" that I drew and the appropriate values from the signal. However, every now and then the signal gets lost completely. In this situation, I would like to erase the entire screen and just print "No signal" on the screen - and then as soon as the signal is picked back up again - revert back to the default screen. Sorry if this is a basic problem but I'm very new at this so hence my asking. Also, bonus question - not crucial but if anyone has the time - how would I make a hello message appear for 3 seconds only once, when I power up the Arduino? Thank you for your time :)
|
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
You need to use a state machine, see for example here: https://www.embedded.com/implementing-finite-state-machines-in-embedded-systems/ or also here: https://www.embedded.com/programming-embedded-systems-the-easy-way-with-state-machines/ State machines are the key to solve your problems. Try to draw a suitable state diagram first, then implement the diagram by using the approaches mentioned in the above web pages. Taking your above description, I assume you will have three states:
Probably you will need to number your states, like this (the number itself is not important):
Your code will look like this: int state = 5; // initial state: Intro Screen
void loop(void) {
switch(state) {
case 5: // Intro Screen
break;
case 10: // GPS available
break;
case 15: // GPS no signal
break;
default: // unknown state, reset state to inital state:
state = 5;
break;
}
} Now, you need to do some actions here, like displaying the GPS signal or the "Hello" message. void drawHello(void) {
u8g2.setFont(u8g2_font_UnnamedDOSFontIV_tr);
u8g2.firstPage();
do {
u8g2.setCursor(40, 30);
u8g2.print("Hello");
}
while ( u8g2.nextPage() );
} Then obviously you will call this function: int state = 5; // initial state: Intro Screen
void loop(void) {
switch(state) {
case 5: // Intro Screen
drawHello();
break;
case 10: // GPS available
break;
case 15: // GPS no signal
break;
default: // unknown state, reset state to inital state:
state = 5;
break;
}
} Now the question is, how to display your screen only for 3 seconds. Let me split the "Intro Screen" activity into two steps:
We will need one more state:
Here is a code example for this: int state = 5; // initial state: Intro Screen
long t = 0;
void loop(void) {
switch(state) {
case 5: // Draw Intro Screen
drawHello();
t = millis(); // remember the current time
state = 6: // jump to the Wait Intro Screen
break;
case 6: // Wait Intro Screen
if ( t + 3000 > millis() ) { // if target time is larger then the current time, then jump to the next state
if ( isGPSSignalAvailable() )
state = 10; // jump to GPS available
else
state = 15; // jump to GPS no signal
} // else: stay in state 6 and wait until target time is reached
break;
case 10: // GPS available
break;
case 15: // GPS no signal
break;
default: // unknown state, reset state to inital state:
state = 5;
break;
}
} Implementation for state 10 and 15 are missing, but I hope you got the idea here. Feel free to post your suggestion on the remaining states. |
Beta Was this translation helpful? Give feedback.
You need to use a state machine, see for example here: https://www.embedded.com/implementing-finite-state-machines-in-embedded-systems/ or also here: https://www.embedded.com/programming-embedded-systems-the-easy-way-with-state-machines/
State machines are the key to solve your problems. Try to draw a suitable state diagram first, then implement the diagram by using the approaches mentioned in the above web pages.
Taking your above description, I assume you will have three states:
Probably you will need to number your states, like this (the number itself is not important):