Simultaneous polling of Touchscreen and GPS Receiver

Hey Everybody,

I am having great difficulty trying to figure out how to structure what appears to be a very simple algorithm.

I am using a MEGA 2560 along with an 4D Systems uLCD-70DT and an Adafruit Ultimate GPS Breakout.

I want to poll the LCD on Serial1 UART while I am also receiving a stream of GPS data on Serial2 UART.

The LCD does not "see" my button presses while receiving the GPS stream, so I have placed delays all over the place and this just makes my program work even worse.

In the getInput() function, I poll Serial1 UART for 6 bytes of data that are always sent from the slave LCD to the master MICROCONTROLLER with every "soft" button press of the 4D Systems uLCD-70DT. I look at particular bytes of data received in order to decide what to do next.

I also use the getGPS() function to receive a stream of data so that I can send the data back to the LCD to update the current GPS location.

So while I am looking for GPS data, I cannot be looking for button presses,...and vice versa.

How can I use an interrupt to provide more "simultaneous" functionality?

void loop()
{
while(1)
{
getInput();
getGPS();
}
}

TIA,
--Neal

Please post all your code.

The LCD does not "see" my button presses while receiving the GPS stream, so I have placed delays all over the place and this just makes my program work even worse.

So you are surprised that just stopping the processor at random points slows things down?

You need code in the form of a state machine, see the blink without delay example in the IDE. You need to totally eliminate the use of delays not adding them in.

Dear Grumpy_Mike,

I have very lengthy code that I really don’t want to post for not other reason that it is just verbose.

All of my serial code works for the GPS, and all of my serial code works for the uLCD.

The only issue that I am having is that while the microcontroller is spending time receiving the GPS stream on Serial1, I want to be able to poll the uLCD “soft” button presses on Serial2. I have created an int called buttonPressFlag = 0 (at initialization). As soon as there is a button press, I would like to set buttonPressFlag and then getInput().

So rather than polling the serial port with something like if(Serial2.available() > 0), which really isn’t an ISR, I would like to create an ISR to take me out of the getGPS() function when there is a button press.

TIA,
–Neal

Hi Neal,

delays all over the place and this just makes my program work even worse

Exactly correct. To make things better, you need to remove delays. Very short delays (<100ms) occasionally in your code may be acceptable, but in general you should aim to remove almost all of them. But it’s not as simple as deleting those lines. Some restructuring may be required, and use of millis() to time actions.

I don’t think there’s an opportunity to use interrupts here, but even if there was, it would not be appropriate or desirable in your project.

Your use of while(1){…} in your example code above is unnecessary, because loop() is called over and over anyway.

If your can’t post your full code, make a short version with minimal functionality, perhaps just a button which increments a count displayed on screen, plus a value from the GPS updated every second. That should be short enough to post, so we can guide you to understand the principle you can follow to fix your larger code.

You do something like:

void loop() {
  if (Serial.available()>0) readSerial();
  if (Serial2.available()>0) readSerial2();
  checkButtons();
}

The readSerial routines must only read one char at a time, if they need it they can buffer the data until they have a full message.

Hey Everybody,

So I am designing a hybrid boat/sub. I run it out to a GPS location on the surface and then submerge. I have a predetermined time coded into my sketch after which time the boat/sub will resurface. I realize that I will have NO RF communication while submerged.

This is a small sample of my code. The problem that I am seeing is that I cannot receive GPS data and poll for “soft” button presses simultaneously.

So while the GPS stream is being received by the MEGA2560 and coordinates are being transmitted/updated to the uLCD-70DT, I cannot poll the receive port for “soft” button presses.

uLCD is on Serial1
GPS is on Serial2

TIA,
–Neal

sub_12242019.ino (8 KB)

All,

Can I connect a jumper from PIN 17 (RX2 pin) to another digital I/O pin on the MEGA 2560 and then use an interrupt to monitor the digital pin for a FALLING edge? So let's say we jumper PIN 17 to PIN 3. Then have something like this:

buttonPressFlag = 0;

attachInterrupt(digitalPinToInterrupt(3), rcvInterrupt, FALLING);

void getGPS(void)
{
getInput();
if(!buttonPressFlag)
{
getGPS();
buttonPressFlag = 0;
}
}

void rcvInterrupt(void)
{
buttonPressFlag = 1;
}