GPS module + NeoGPS library causes 7seg to flicker on 1 sec intervals

Hey all,

I’m currently using a NEO-6M-0-001 gps module alongside the NEOGPS library, and a few CC 7 segment displays with an arduino mega. My 7segs are driven by 595 shift registers and npn transistors. The gps module is connected to the Serial1 TX,RX pins (18,19) of the mega. Everything works as intended, but the 7segs flicker on a 1 second interval when the gps fix is being read from Serial1. As a side note, the flickers happen when I Serial.print as well.

The only solution I can come up with was to make the gps only update once every 5 seconds, which is okay for my purposes, but it doesn’t inherently solve the problem. Using a 7 seg module connected to serial did resolve the issue, but I need the option of using different size segments, which aren’t available as modules.

Do I basically need to recreate the 7 seg modules with the sizes I want, or is there possibly a way to resolve it with coding?

I’ve omitted the bulk of my code as it’s quite long, but below are the core codes of the relevant issue.

Thanks in advance!

My GPS code

#include <NMEAGPS.h>
#include <GPSport.h>
NMEAGPS  gps; // This parses the GPS characters
gps_fix  fix; // This holds on to the latest values

void findGps()
{
  if (gps.available(gpsPort) && !gpsConfirmed && (millis() - gpsPreviousTime >= 5000)) 
  {
    gpsPreviousTime = millis();
    fix = gps.read();
    
      if (fix.valid.location)
      {               
        int distanceA = haversine(fix.latitude(), fix.longitude(), A_LAT, A_LON);
        int distanceB = haversine(fix.latitude(), fix.longitude(), B_LAT, B_LON);
        int distanceC = haversine(fix.latitude(), fix.longitude(), C_LAT, C_LON);
        int distanceD = haversine(fix.latitude(), fix.longitude(), D_LAT, D_LON);
        int distanceE = haversine(fix.latitude(), fix.longitude(), E_LAT, E_LON);
        
        if(distanceA < 20) {
          lcd.clear();
          lcd.setCursor(0,0);
          lcd.print("A");
          gpsConfirmed = true;
        }  else if(distanceB < 20) {
          lcd.clear();
          lcd.setCursor(0,0);
          lcd.print("B");
          gpsConfirmed = true;
        } else if(distanceC <20) {
          lcd.clear();
          lcd.setCursor(0,0);
          lcd.print("C");
          gpsConfirmed = true;
        } else if(distanceD <20) {
          lcd.clear();
          lcd.setCursor(0,0);
          lcd.print("D");
          gpsConfirmed = true;
        } else if(distanceE <20) {
          lcd.clear();
          lcd.setCursor(0,0);
          lcd.print("E");
          gpsConfirmed = true;
        } 
        
      }
      else
      {
       lcd.setCursor(0,0);
        lcd.print("INVALIDs");
      }
    }
}

One of my 7 segment codes as reference. The other segments are driven the same way.

void coreTimer()
{
  if ((timercurrentTime - timerpreviousTime >= timerInterval) && (time > 0) && (previousTimeLogged)) {
    //if (!correctCut)
    //{
      time = time - (timercurrentTime - timerpreviousTime); //update countdown timer by subtracting elapsed time
    //}
    timerpreviousTime = timercurrentTime; //update previous time to current time

    timerDigit[0] = ((time / 1000) / 60) / 10; //calculating each digit of MM:SS individually and storing the values into array
    timerDigit[1] = ((time / 1000) / 60) % 10;
    timerDigit[2] = ((time / 1000) % 60) / 10;
    timerDigit[3] = ((time / 1000) % 60) % 10;

    for (int i = 0; i < sizeof(timerDigitPins); i++) { //turning off all digit pins
      digitalWrite(timerDigitPins[i], LOW);
    }
    
    timerData = pickNumber[timerDigit[timerCounter]]; //select digit that needs to be displayed
    digitalWrite(timerLatchPin, 0);
    shiftOut(timerDataPin, timerClockPin, timerData);
    digitalWrite(timerLatchPin, 1);

    digitalWrite(timerDigitPins[timerCounter], HIGH); //select digit to turn on

    if (time <= 0) { //changing all digits to display 0 when time = 0

      timerData = pickNumber[0];
      digitalWrite(timerLatchPin, 0);
      shiftOut(timerDataPin, timerClockPin, timerData);
      digitalWrite(timerLatchPin, 1);

      for (int i = 0; i < sizeof(timerDigitPins); i++) { //turning on all digits
        digitalWrite(timerDigitPins[i], HIGH);
      }

    }
    timerCounter = (++timerCounter) % 4;
  }
}

This question was asked a very dhort time ago. Search for similiar titles.

So you are using software multiplexing of the 7-segment displays. Well, you must expect this sort of problem.

Yes, you could use some very intricate state machine coding to interleave the GPS processing with the multiplexing, but I suspect you don't really want to.

The most practical thing in your case is to do the 7-segment display properly with a MAX7219. I have frequently explained the benefit of using one of the readily available modules custom wired to whatever displays you use, so I will not repeat it here. :roll_eyes:

Paul__B:
So you are using software multiplexing of the 7-segment displays. Well, you must expect this sort of problem.

Yes, you could use some very intricate state machine coding to interleave the GPS processing with the multiplexing, but I suspect you don't really want to.

The most practical thing in your case is to do the 7-segment display properly with a MAX7219. I have frequently explained the benefit of using one of the readily available modules custom wired to whatever displays you use, so I will not repeat it here. :roll_eyes:

Cool! I wasn't aware that a chip like that existed. Seems pretty straight forward to setup plus the added benefit of saving some space compared to using shift registers. You're always very helpful =) Thank you!