Laggy GPS with dht22 sensor

hi there. I have a perfectly fine GPS speedometer, when I add the dht22 sensor GPS becomes laggy and the speed freezes sometimes. I couldn't understand the problem because both the GPS and the sensor work perfectly on their own but when I combine them this happens.
Here is my code:

[code]
#include "DHT.h"
#include <Arduino.h>
/*
 Connections:
 GPS TX -> Arduino 0 (disconnect to upload this sketch)
 GPS RX -> Arduino 1
 Screen SDA -> Arduino A4
 Screen SCL -> Arduino A5
*/

#include "U8glib.h"

U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_DEV_0|U8G_I2C_OPT_FAST);
#define GPS Serial
#define DHTPIN 10
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
unsigned long lastDHT;
int dhtReadInterval = 10000;
float hum;  //Stores humidity value
float temp;

const unsigned char UBLOX_INIT[] PROGMEM = {
  // Disable NMEA
  0xB5,0x62,0x06,0x01,0x08,0x00,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x24, // GxGGA off
  0xB5,0x62,0x06,0x01,0x08,0x00,0xF0,0x01,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x2B, // GxGLL off
  0xB5,0x62,0x06,0x01,0x08,0x00,0xF0,0x02,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x32, // GxGSA off
  0xB5,0x62,0x06,0x01,0x08,0x00,0xF0,0x03,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x39, // GxGSV off
  0xB5,0x62,0x06,0x01,0x08,0x00,0xF0,0x04,0x00,0x00,0x00,0x00,0x00,0x01,0x04,0x40, // GxRMC off
  0xB5,0x62,0x06,0x01,0x08,0x00,0xF0,0x05,0x00,0x00,0x00,0x00,0x00,0x01,0x05,0x47, // GxVTG off

  // Disable UBX
  0xB5,0x62,0x06,0x01,0x08,0x00,0x01,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x17,0xDC, //NAV-PVT off
  0xB5,0x62,0x06,0x01,0x08,0x00,0x01,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0xB9, //NAV-POSLLH off
  0xB5,0x62,0x06,0x01,0x08,0x00,0x01,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x13,0xC0, //NAV-STATUS off

  // Enable UBX
  0xB5,0x62,0x06,0x01,0x08,0x00,0x01,0x07,0x00,0x01,0x00,0x00,0x00,0x00,0x18,0xE1, //NAV-PVT on
  //0xB5,0x62,0x06,0x01,0x08,0x00,0x01,0x02,0x00,0x01,0x00,0x00,0x00,0x00,0x13,0xBE, //NAV-POSLLH on
  //0xB5,0x62,0x06,0x01,0x08,0x00,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x00,0x14,0xC5, //NAV-STATUS on

  // Rate
 0xB5,0x62,0x06,0x08,0x06,0x00,0x64,0x00,0x01,0x00,0x01,0x00,0x7A,0x12, //(10Hz)
  //0xB5,0x62,0x06,0x08,0x06,0x00,0xC8,0x00,0x01,0x00,0x01,0x00,0xDE,0x6A, //(5Hz)
  //0xB5,0x62,0x06,0x08,0x06,0x00,0xE8,0x03,0x01,0x00,0x01,0x00,0x01,0x39 //(1Hz)
};

const unsigned char UBX_HEADER[] = { 0xB5, 0x62 };

struct NAV_PVT {
  unsigned char cls;
  unsigned char id;
  unsigned short len;
  unsigned long iTOW;          // GPS time of week of the navigation epoch (ms)

  unsigned short year;         // Year (UTC) 
  unsigned char month;         // Month, range 1..12 (UTC)
  unsigned char day;           // Day of month, range 1..31 (UTC)
  unsigned char hour;          // Hour of day, range 0..23 (UTC)
  unsigned char minute;        // Minute of hour, range 0..59 (UTC)
  unsigned char second;        // Seconds of minute, range 0..60 (UTC)
  char valid;                  // Validity Flags (see graphic below)
  unsigned long tAcc;          // Time accuracy estimate (UTC) (ns)
  long nano;                   // Fraction of second, range -1e9 .. 1e9 (UTC) (ns)
  unsigned char fixType;       // GNSSfix Type, range 0..5
  char flags;                  // Fix Status Flags
  unsigned char reserved1;     // reserved
  unsigned char numSV;         // Number of satellites used in Nav Solution

  long lon;                    // Longitude (deg)
  long lat;                    // Latitude (deg)
  long height;                 // Height above Ellipsoid (mm)
  long hMSL;                   // Height above mean sea level (mm)
  unsigned long hAcc;          // Horizontal Accuracy Estimate (mm)
  unsigned long vAcc;          // Vertical Accuracy Estimate (mm)

  long velN;                   // NED north velocity (mm/s)
  long velE;                   // NED east velocity (mm/s)
  long velD;                   // NED down velocity (mm/s)
  long gSpeed;                 // Ground Speed (2-D) (mm/s)
  long heading;                // Heading of motion 2-D (deg)
  unsigned long sAcc;          // Speed Accuracy Estimate
  unsigned long headingAcc;    // Heading Accuracy Estimate
  unsigned short pDOP;         // Position dilution of precision
  short reserved2;             // Reserved
  unsigned long reserved3;     // Reserved
};

NAV_PVT pvt;

void calcChecksum(unsigned char* CK) {
  memset(CK, 0, 2);
  for (int i = 0; i < (int)sizeof(NAV_PVT); i++) {
    CK[0] += ((unsigned char*)(&pvt))[i];
    CK[1] += CK[0];
  }
}

long numGPSMessagesReceived = 0;

bool processGPS() {
  static int fpos = 0;
  static unsigned char checksum[2];
  const int payloadSize = sizeof(NAV_PVT);

  while ( GPS.available() ) {
    byte c = GPS.read();
    if ( fpos < 2 ) {
      if ( c == UBX_HEADER[fpos] )
        fpos++;
      else
        fpos = 0;
    }
    else {      
      if ( (fpos-2) < payloadSize )
        ((unsigned char*)(&pvt))[fpos-2] = c;

      fpos++;

      if ( fpos == (payloadSize+2) ) {
        calcChecksum(checksum);
      }
      else if ( fpos == (payloadSize+3) ) {
        if ( c != checksum[0] )
          fpos = 0;
      }
      else if ( fpos == (payloadSize+4) ) {
        fpos = 0;
        if ( c == checksum[1] ) {
          return true;
        }
      }
      else if ( fpos > (payloadSize+4) ) {
        fpos = 0;
      }
    }
  }
  return false;
}

void setup() 
{
  GPS.begin(9600);
  dht.begin();
  u8g.setColorIndex(1);

  // send configuration data in UBX protocol
  for(unsigned int i = 0; i < sizeof(UBLOX_INIT); i++) {                        
    GPS.write( pgm_read_byte(UBLOX_INIT+i) );
    delay(5); // simulating a 38400baud pace (or less), otherwise commands are not accepted by the device.
  }
  
}

long gSpeed = 0;
int numSV = 0;
unsigned long lastScreenUpdate = 0;
char speedBuf[16];
char satsBuf[16];
char unit[6];

char* spinner = "/-\\|";
byte screenRefreshSpinnerPos = 0;
byte gpsUpdateSpinnerPos = 0;

void loop() {
 
  if ( processGPS() ) {
    numSV = pvt.numSV;
    gSpeed = pvt.gSpeed;    
    gpsUpdateSpinnerPos = (gpsUpdateSpinnerPos + 1) % 4;
  }

  unsigned long now = millis();
  if ( now - lastScreenUpdate > 100 ) {
    updateScreen();
    lastScreenUpdate = now;
    screenRefreshSpinnerPos = (screenRefreshSpinnerPos + 1) % 4;
  }
  if (millis() - lastDHT >= (unsigned long) dhtReadInterval) //check if time has elapsed
  {
    lastDHT = millis();  //save for next time
  hum = dht.readHumidity();
  temp= dht.readTemperature();
  }
}

void draw() {
   //  // graphic commands to redraw the complete screen should be placed here
  //u8g.setScale2x2(); don't do this!
//  u8g.setFont(u8g_font_courB24);
u8g.setFont(u8g_font_ncenB24n);
//u8g.setFont(u8g_font_gdb30n);
  u8g.drawStr( 6, 60, speedBuf);
  u8g.setFont(u8g_font_helvR10r);
  u8g.drawStr( 99, 60, unit);
  //u8g.undoScale();
 // u8g.setFont(u8g_font_fur11r);
  u8g.drawStr( 2, 12, satsBuf);
 u8g.setFont(u8g_font_helvR10r);
  u8g.setPrintPos(58, 12);
  u8g.print("T: "),u8g.print(temp);
  u8g.setFont(u8g_font_helvR08);
  u8g.setPrintPos(115, 12);
  u8g.write(0xB0), u8g.print("C");
  u8g.setFont(u8g_font_helvR10r);
  u8g.setPrintPos(58, 25);
  u8g.print("H: "),u8g.print(hum) ;
  u8g.setFont(u8g_font_helvR08);
  u8g.setPrintPos(116, 25);
  u8g.print("%");
}

void updateScreen() {
  
  int kmh = gSpeed * 0.0036;
  sprintf(speedBuf, "%d", kmh);
  sprintf(unit, "%4s", "km/h");
  sprintf(satsBuf, "%c %c %d %s", spinner[screenRefreshSpinnerPos], spinner[gpsUpdateSpinnerPos], numSV, " ");
  
  u8g.firstPage();
  do {
    draw();
  } while( u8g.nextPage() );
}
[/code]

and this is my harware:
arduino nano
neo 7m GPS module
sh1106 OLED
DHT22 temp and humidity sensor
I would appreciate any help.
Thanks in advance.

I'd guess that it's the display that's causing the issue, try commenting out that piece.

1 Like

You can also switch to a non-blocking library for your sensor: https://github.com/olewolf/DHT_nonblocking

As for the screen, you are completely redrawing it every 100msec. I seriously doubt your temperature or humidity is changing that quickly. Slow that down to something like every minute.

1 Like

which part do you think is causing the issue?

I'll test the library. as for the screen I use that redrawing for the gps speedo not the sensor.

I'd suggest stopping the drawing altogether as a test. If you're convinced it's the dht, maybe write a test sketch and measure how long it actually takes to get the two readings.

2 Likes

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.