GPS & BMP280 combo woes

`Hello all,
I have a Mega 2560 with a
BMP280 pressure/temp sensor (I2C)
GPS on hardware serial (TX/RX1)
Both of which run great, on their own. but I am trying to have them both display on the 20 x 4 LCD.
The BMP280 is only being read every 15000us as instructed but no sign of the GPS whilst the BMP results are being displayed.
I have read and re-read 'Blink without delay' and also the 'several things at the same time' examples. They have helped, as somehow I made the thing work as intended yesterday then promptly made a mess of it trying to 'tidy up' my code. Im sure its a simple error but Ive got to the point that I feel somewhat blinded by it all.
Could anyone offer a clue as to what I might have wrong here please?
But go easy on me, I am a struggling noob :grimacing:

Many thanks in advance.

MoJoZ

/*My 'basic' project to have a BMP280, GPS and DHT11 sensor to
   provide---->>
                GPS disciplined LOCAL time (UTC +10hrs here)
                Temperature from the BMP280
                Humidity from a DHT11 -- (Yet to be incorporated)
                Barometric pressure from the BMP280
                Outputs displayed on a 20 x 4 LCD Display

                MoJoZ
                
 *              */
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h> // Library for the BMP280 pressure/temp sensor.
#include <SoftwareSerial.h>   // include software serial library
#include <LiquidCrystal.h>    // include LCD library
#include <TimeLib.h>
#include <TinyGPSPlus.h>       // http://arduiniana.org/libraries/TinyGPS/

float temperature;
float pressure;

#define ALTITUDE 0 // Altitude of the BMP280 sensor at the home QTH

Adafruit_BMP280 bmp; // I2C
Adafruit_Sensor *bmp_temp = bmp.getTemperatureSensor();
Adafruit_Sensor *bmp_pressure = bmp.getPressureSensor();

LiquidCrystal lcd(42, 44, 46, 48, 50, 52); // My 20x4 LCD Pin config on a MEGA
unsigned long startMillis; // Start the counter rolling
unsigned long currentMillis = 0; // What the counter is up to right now.
unsigned long previousgpsMillis = 0;   // when the GPS was last read.
unsigned long previousbmpMillis = 0;
const int bmpPeriod = 15000; // Check the BMP280 no more than every 15 seconds.
const int gpsPeriod = 1000; // I aim to check the GPS every second.

TinyGPSPlus gps;
#define SerialGPS Serial1

#define time_offset   36000  // clock offset of 36000 seconds (10 hours Brisbane) ==> UTC + 10

// variables
char Time[]  = "TIME: 00:00:00";
char Date[]  = "DATE: 00-00-2000";
byte last_second, Second, Minute, Hour, Day, Month;
int Year;

void setup(void)
{
  SerialGPS.begin(9600);
  startMillis = millis();  //initial start time
  //time_t previousgpsMillis = 0;

  lcd.begin(20, 4);
  //lcd.print("Reading BMP280");
  bool status;
  status = bmp.begin(0x76);  //My BMP280's are all addressed as 0x76
  if (!status) {
    lcd.clear();
    lcd.setCursor(4, 1);
    lcd.print("OOps. Check");
    lcd.setCursor(3, 2);
    lcd.print("the circuit!");
    while (1);
  }
  bmp.setSampling(Adafruit_BMP280::MODE_NORMAL,     /* Operating Mode. */
                  Adafruit_BMP280::SAMPLING_X2,     /* Temp. oversampling */
                  Adafruit_BMP280::SAMPLING_X16,    /* Pressure oversampling */
                  Adafruit_BMP280::FILTER_X16,      /* Filtering. */
                  Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */

  bmp_temp->printSensorDetails();
}
//time_t previousgpsMillis = 0; // when the digital clock was displayed

void loop() {
  currentMillis = millis();
  if (currentMillis - startMillis >= bmpPeriod)
  {
    sensors_event_t temp_event, pressure_event;
    bmp_temp->getEvent(&temp_event);
    bmp_pressure->getEvent(&pressure_event);
    startMillis = currentMillis;

    getPressure();
    // getHumidity();
    getTemperature();

    //lcd.clear();
  }

  //Printing Temperature
  String temperatureString = String(temperature, 1);
  lcd.setCursor(0, 3);
  lcd.print("Temp: ");
  lcd.print(temperatureString);
  lcd.print((char)223);

  //Printing Pressure
  lcd.setCursor(0, 2);
  lcd.print("Baro: ");
  String pressureString = String(pressure, 2);
  lcd.print(pressureString);
  lcd.print(" hPa");
}

float getTemperature()
{
  temperature = bmp.readTemperature();
}

float getPressure()
{
  pressure = bmp.readPressure();
  pressure = bmp.seaLevelForAltitude(ALTITUDE, pressure);
  pressure = pressure / 100.0F;
  previousbmpMillis += bmpPeriod;
}
void loop2()
{
  //time_t previousgpsMillis = 0;
  currentMillis = millis();
  if (millis() - previousgpsMillis >= gpsPeriod) {
    while (SerialGPS.available())
      if (gps.encode(SerialGPS.read()))
      {
        if (gps.time.isValid())
        {
          Minute = gps.time.minute();
          Second = gps.time.second();
          Hour   = gps.time.hour();
        }

        // get date drom GPS module
        if (gps.date.isValid())
        {
          Day   = gps.date.day();
          Month = gps.date.month();
          Year  = gps.date.year();
        }

        if (last_second != gps.time.second()) // if time has changed
        {
          last_second = gps.time.second();

          // set current UTC time
          setTime(Hour, Minute, Second, Day, Month, Year);
          // add the offset to get local time
          adjustTime(time_offset);
        }
        // update time array
        Time[12] = second() / 10 + '0';
        Time[13] = second() % 10 + '0';
        Time[9]  = minute() / 10 + '0';
        Time[10] = minute() % 10 + '0';
        Time[6]  = hour()   / 10 + '0';
        Time[7]  = hour()   % 10 + '0';

        // update date array
        Date[14] = (year()  / 10) % 10 + '0';
        Date[15] =  year()  % 10 + '0';
        Date[9]  =  month() / 10 + '0';
        Date[10] =  month() % 10 + '0';
        Date[6]  =  day()   / 10 + '0';
        Date[7]  =  day()   % 10 + '0';
        {
          // print time & date
          /* currentMillis = millis();
            if (currentMillis - previousgpsMillis >= gpsPeriod);*/
          lcd.setCursor(0, 0);     // move cursor to column 0 row 2
          lcd.print(Time);         // print time (HH:MM:SS)
          previousgpsMillis += gpsPeriod;
        }


      }

  }
}

A good tip is to save your code , then when you modify it , save it as a different version , and if there is a problem , you can go back to an earlier version .

You can also comment out sections of your code until you find the area with the fault then correct it . Adding extra temporary print statements can further help you keep track of what is going on.

Thanks for the help Hammy,
I HAD the auto save option turned on (till today) and that helped me mess up what once worked. I SHOULD have saved it when I had it working, with a different file name.
But you know, hindsight and such :roll_eyes:

Back to the drawing board I go then.... :confounded:

1 Like

Ho hum

I take it the OP wants to run loop2()? The OP can run loop2() by putting the following line in loop() loop2();

What does not working mean?

1 Like

Hello and thanks for your advice. By 'not working' I mean

the void loop2()
Was my attempt at just keeping the code seperated somewhat for both sensors, to help me get this going again, rather than 2 individual loops per-se.
Are you saying by typing "loop2();" somewhere in the main loop "void loop()" that it refers to the 2nd loop, and without it, that 2nd loop is ignored?
Many thanks in advance for your help.

What does that mean?

I am indicating that without the words "loop2(); in loop(), loop2 will not run.

ok, I have pressure and temperature (From the BMP280) being displayed correctly on the LCD screen at the correct update interval (15 seconds).
But the GPS which will simply display time, doesn't show up on the LCD at the moment.

I tried refering to loop2(); at the end of void loop() as suggested but that didnt change the result.

1 Like

Cool, only 8 posts for me to understand the issue.

Post the code where you tried using loop2(). It is loop2's function to read the GPS data and put it into the proper places, correct?

How often do you want to read the GPS to get the time?

What part of the code in loop() is supposed to put the time onto the display?

Thanks Idahowalker for your help. And my appolgies if I hadnt explained the issue in the opening post, well enough?
I now have it working IE: Both the GPS and BMP280 now output info to the LCD at the chosen intervals.
I followed your suggestion of the "loop2();" reference at the end on the main loop and it did not work. I placed it nearer the top of the loop and it now works?
I am extremely happy it now works as intended and can progress to getting humidity on the LCD from a DHT11 sensor.
But I still want to understand WHY the changes made on your suggestiong work the way the do.
Many thanks Idahowalker for your help. I appreciate it :pray:

The GPS displays seconds, so it needs to be more frequently read than that. Currently I have it being read every 500us and It appears fine. Increasing that interval to 1 second creates uneven displayed seconds.
Here is the working code..

[code]
void loop() {
  currentMillis = millis();
  if (currentMillis - startMillis >= bmpPeriod) {
    sensors_event_t temp_event, pressure_event;
    bmp_temp->getEvent(&temp_event);
    bmp_pressure->getEvent(&pressure_event);
    startMillis = currentMillis;

    getPressure();
    // getHumidity();
    getTemperature();

    //lcd.clear();
  }
  loop2();
  //Printing Temperature
  String temperatureString = String(temperature, 1);
  lcd.setCursor(0, 3);
  lcd.print("Temp: ");
  lcd.print(temperatureString);
  lcd.print((char)223);

  //Printing Pressure
  lcd.setCursor(0, 2);
  lcd.print("Baro: ");
  String pressureString = String(pressure, 2);
  lcd.print(pressureString);
  lcd.print(" hPa");
}

float getTemperature() {
  temperature = bmp.readTemperature();
}

float getPressure() {
  pressure = bmp.readPressure();
  pressure = bmp.seaLevelForAltitude(ALTITUDE, pressure);
  pressure = pressure / 100.0F;
  previousbmpMillis += bmpPeriod;
}

void loop2() {
  //time_t previousgpsMillis = 0;
  //currentMillis = millis();
  if (millis() - previousgpsMillis >= gpsPeriod) {
    while (SerialGPS.available())
      if (gps.encode(SerialGPS.read())) {
        if (gps.time.isValid()) {
          Minute = gps.time.minute();
          Second = gps.time.second();
          Hour = gps.time.hour();
        }

        // get date drom GPS module
        if (gps.date.isValid()) {
          Day = gps.date.day();
          Month = gps.date.month();
          Year = gps.date.year();
        }

        if (last_second != gps.time.second())  // if time has changed
        {
          last_second = gps.time.second();

          // set current UTC time
          setTime(Hour, Minute, Second, Day, Month, Year);
          // add the offset to get local time
          adjustTime(time_offset);
        }
        // update time array
        Time[12] = second() / 10 + '0';
        Time[13] = second() % 10 + '0';
        Time[9] = minute() / 10 + '0';
        Time[10] = minute() % 10 + '0';
        Time[6] = hour() / 10 + '0';
        Time[7] = hour() % 10 + '0';

        // update date array
        Date[14] = (year() / 10) % 10 + '0';
        Date[15] = year() % 10 + '0';
        Date[9] = month() / 10 + '0';
        Date[10] = month() % 10 + '0';
        Date[6] = day() / 10 + '0';
        Date[7] = day() % 10 + '0';
        {
          // print time & date
          /* currentMillis = millis();*/
          if (currentMillis - previousgpsMillis >= gpsPeriod);
          lcd.setCursor(0, 0);  // move cursor to column 0 row 2
          lcd.print(Time);      // print time (HH:MM:SS)
          previousgpsMillis += gpsPeriod;
        }
      }
  }
}
[/code]

I was going to suggest that as a next move.

Ask away and I'll try to assist you with understanding.

Ok, Have I done the right thing with this loop structure here?
My intention was to compartmentalise the loop to keep the code for each individual sensor almost separate from one another (From a writing/viewing perspective) to help me write/debug/understand each sensors code.
Thats the way I interpreted the way loop is structured for different sensors in the "Several Things At The Same Time" example sketch.
Or have I over complicated things with the 2nd loop unnecessarily?

I'd rename loop2() to something more meaningful, like void DoTheGPSThing()

You, to me, have done the correct thing with loop2 and compartmentalizing the code.

1 Like

Cool, Renaming it makes sense. I'll do that.
And Im relieved to hear I haven't gone about it all the wrong way.
Finally, I think I am getting somewhere on my Arduino journey. I just added the DHT11 sensor to the circuit and wrote the code into this and it works 100% :laughing:

Again, Many thanks for your help Idahowalker.
I do appreciate it.
Best wishes to you from Australia. :wave:

1 Like

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