Arduino STM32 + OLED + NEO 6 GPS - very slow

Hi at all,
I need your help :slight_smile:

It is my first project with the arduino and i learnd a lot in the last two weeks :slight_smile: I know that the code can be better but …its my first project. :slight_smile:

Ok let’s talk about my problem: I use a OLED Display (SSD1327) for showing the temperature and the speed. I use a switch to change between the two pages. The temperature works great but the GPS show the speed irregularly or not at all. So I connect the GPS Sensor my PC and use u-center and change some settings (Baudrate 9600, 5hz timing, automotive mode). After a short drive i can see that the speed in u-center is showing correctly and very fast. I switch back to the arduino…but it don’t work. I got the value but irregularly (every some minutes).

I use the tinygps++ libary and the u8g2.

void loop(void) 
{
      //Switch for Mode
      buttonState = digitalRead(buttonPin);
      if (buttonState == HIGH) 
      {
        sensors.requestTemperatures();
        u8g2.clearBuffer();
        drawHeader();
        drawTemp();
        u8g2.sendBuffer();
        delay(1000);
      }
      else {
      while (Serial2.available() > 0)
        gps.encode(Serial2.read());

             
              u8g2.clearBuffer();
              drawHeader();

              //Speed
              if(6 < 5) //TESTMODE
              {
                //speedkmh[10] = "0 km/h";
                //speedmph[10] = "0 mph";
                //strcpy (speedkmh, "0 km/h");
                //strcpy (speedmph, "0 km/h");
                u8g2.setCursor((125 - u8g2.getStrWidth("0 km/h")) ,70);
                u8g2.print("0 km/h");
                u8g2.setCursor((125 - u8g2.getStrWidth("0 km/h")) ,95);
                u8g2.print("0 km/h");
              }
              else
              {
                // km/h
                u8g2.setFont(u8g2_font_fur20_tr);
                sprintf(speedkmh, "%3.1f \x6b\x6d\x2f\x68" , gps.speed.kmph()); 
                u8g2.setCursor((125 - u8g2.getStrWidth(speedkmh)) ,70); //right align
                u8g2.print(speedkmh);

                //mph
                u8g2.setFont(u8g2_font_fur11_tr);
                sprintf(speedmph, "%3.1f \x6d\x70\x68" , gps.speed.mph()); 
                u8g2.setCursor((125 - u8g2.getStrWidth(speedmph)) ,95); //right align
                u8g2.print(speedmph);
        
                //TEST for communications
                Serial.print("LAT:");
                Serial.print(gps.location.lat(), 6);
                Serial.print("  - LONG:");
                Serial.print(gps.location.lng(), 6);    
                Serial.print("  - Speed:");
                Serial.println(gps.speed.kmph());
               }

              //Datum einblenden
              u8g2.setFont(u8g2_font_fur11_tr);
              sprintf(datum, "%02d/%02d/%02d", gps.date.month(), gps.date.day(), gps.date.year()); 
              u8g2.setCursor((128 - u8g2.getStrWidth(datum)) ,128);
              u8g2.print(datum);
              u8g2.setCursor(0, 110);
              u8g2.print(gps.time.second());
              u8g2.sendBuffer();
              //Serial.println("TEST");

              // delay between each page
              delay(10);
        
      }
}

I suspect that your GPS data is overflowing the buffer and being thrown away. You need to read from it on every iteration of loop whether you're displaying it or not. Also, get rid of those delays - they'll guarantee that you drop data.

Use millis so that you only display occasionally rather than all the time. WHat's likely happening now is that you get one or two characters from the GPS and then do all that LCD and serial output for every couple of characters.

Like wildbill says, read the GPS often, display at a rate of 2 - 5 times per second.
I use a NEO-6M showing speed, direction, altitude on an I2C display without any problems.
Let the button decide what data You want to monitour but exercise the GPS every cycle in loop().

      while (Serial2.available() > 0)
        gps.encode(Serial2.read());

You are updating the screen every time you read data from the GPS. You don’t have new data unless gps.encode() returns ‘true’! Check the return value!

Also check to see if the message received resulted in valid data. Check gps.speed.isValid() before displaying a new speed.

void loop(void)
{
  //Switch for Mode
  buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH)
  {
    sensors.requestTemperatures();
    u8g2.clearBuffer();
    drawHeader();
    drawTemp();
    u8g2.sendBuffer();
    delay(1000);
  }
  else
  {
    while (Serial2.available() > 0)
      if (gps.encode(Serial2.read()))
      {
        if (gps.speed.isValids())
        {
          u8g2.clearBuffer();
          drawHeader();

          //Speed
          if (6 < 5) //TESTMODE
          {
            //speedkmh[10] = "0 km/h";
            //speedmph[10] = "0 mph";
            //strcpy (speedkmh, "0 km/h");
            //strcpy (speedmph, "0 km/h");
            u8g2.setCursor((125 - u8g2.getStrWidth("0 km/h")) , 70);
            u8g2.print("0 km/h");
            u8g2.setCursor((125 - u8g2.getStrWidth("0 km/h")) , 95);
            u8g2.print("0 km/h");
          }
          else
          {
            // km/h
            u8g2.setFont(u8g2_font_fur20_tr);
            sprintf(speedkmh, "%3.1f \x6b\x6d\x2f\x68" , gps.speed.kmph());
            u8g2.setCursor((125 - u8g2.getStrWidth(speedkmh)) , 70); //right align
            u8g2.print(speedkmh);

            //mph
            u8g2.setFont(u8g2_font_fur11_tr);
            sprintf(speedmph, "%3.1f \x6d\x70\x68" , gps.speed.mph());
            u8g2.setCursor((125 - u8g2.getStrWidth(speedmph)) , 95); //right align
            u8g2.print(speedmph);

            //TEST for communications
            Serial.print("LAT:");
            Serial.print(gps.location.lat(), 6);
            Serial.print("  - LONG:");
            Serial.print(gps.location.lng(), 6);
            Serial.print("  - Speed:");
            Serial.println(gps.speed.kmph());
          }
        } // end gps.speed.isValid()


        //Datum einblenden
        u8g2.setFont(u8g2_font_fur11_tr);
        sprintf(datum, "%02d/%02d/%02d", gps.date.month(), gps.date.day(), gps.date.year());
        u8g2.setCursor((128 - u8g2.getStrWidth(datum)) , 128);
        u8g2.print(datum);
        u8g2.setCursor(0, 110);
        u8g2.print(gps.time.second());
        u8g2.sendBuffer();
        //Serial.println("TEST");

        // delay between each page
        delay(10);
      }