GPS Clock Version 3 Part 5

Nearly there. One post left? Two? Ah, but then I've got to build a new circuit board. Not so fast.

Well overnight a minor success. Version 2 was reinstated for the night because it was the changeover night for the move to daylight savings in Eastern Australia for 2012! I wish I could have stayed up all night to watch the clock shift from 01:59 to 03:00 but, alas, I'm only human. When I went to bed last night it was correctly showing the standard time. This morning it's showing daylight savings time. No buttons pushed, nothing but programming. Beautiful!


Hardware


Next I want to connect the GPS and the LED display and for this I've migrated the project over from my Duemilanove to a Mega.


The reason for this is that the Duemilanove and the Pro Mini only have one serial port (UART) each. When the Arduino is connected to the PC, the serial port is used for that. You can connect multiple devices to the serial port but you need to switch between devices or plug and unplug jumper wires; it's just a hassle. By using a Mega, Serial0 (just called Serial in code) remains connected to the computer for programming; Serial1 can communicate with the GPS and Serial2 can look after the LED display. No contention for the one serial port means faster development. Once the code is right, I'll change it to work on only one Serial port and test it that way.

For the changeover I checked where the I2C connections should be on the Mega. The SDA pin needed to go from pin 4 on the Duemilanove to pin 20 on the Mega. Likewise SCL went from 5 to 21. A check on interrupts showed pin 2 is still interrupt0 on the Mega. Now, the GPS and LED display.


I've gone right through the connection details in the post on Version 2. So no more on that now. The only difference is the connection to separate serial ports on the Mega.



It looks a bit of a dog's breakfast but it's just a prototype, so who cares. The important thing is that we have communications to each device. More on that in a minute; there's some code preparation required before we can do that.

Code


Before adding code for the GPS and LED I want to check communications with the RTC first. In the Arduino environment: Serial Port to COM6 (for me), Board Type to Arduino Mega 2560 or Mega ADK. Verify code, upload, open Serial Monitor, there's the output as expected. Great. Now the other hardware.

In the code editor I've added tabs for GPS.h, GPS.cpp, LED.h and LED.cpp. The code for these two classes I've lifted from Version 2 without alteration. The code from the completion of the last post plus the addition of these new classes is here. This is the starting point for today's post.

GPS


For testing reasons, I'm going to comment out all of the code in the main sketch and just leave it there for later. I'll jump back into history and have a look at my post EM-406A GPS From Scratch - Part 1 from back in April. I just want to be sure I've got the right serial port for the GPS before I go further.

#include "Wire.h"

void setup()
{
  Serial.begin(115200);
  Serial1.begin(4800);
}

void loop()
{
  if (Serial1.available()) Serial.write(Serial1.read());
}

Running this code fills the serial monitor with NMEA sentences. Perfect. Now to test the LED display.

LED


#include "Wire.h"
#include "GPS.h"
#include "LED.h"

LED led;
GPS gps;

void setup()
{
  Serial.begin(115200);
  Serial1.begin(4800); // for GPS
  Serial2.begin(4800); // for LED
  gps.setPort(Serial1);
  led.setPort(Serial2);
  led.write("GPS-");
}

void loop()
{
  if (Serial1.available()) Serial.write(Serial1.read());
}

OK, now it's giving me GPS data while displaying GPS- on the LED display. Everything's connected just fine. You see what the code's doing, right? The lines LED led; and GPS gps; lines are creating objects of their respective classes (that are #included above). We initialise three serial ports and, because of the way I've designed the GPS and LED classes, we give a pointer for a serial port to the object that uses it via a call to the setPort() method. If you look in GPS.h and LED.h you'll see they each store a pointer to a HardwareSerial object. This is done so each object can look after its own communications with its device, but it's still simple to configure ports for objects in the main sketch.

So what's left to do?
  1. Reinstate the interrupt.
  2. Push the RTC time onto the LED display.
  3. Check the GPS is synchronised
  4. Set the RTC time from the GPS.
  5. And a little something more for auto dimming of the display.
A rearrangement of the main sketch looks like this:

#include "Wire.h"
#include "RTC.h"
#include "GPS.h"
#include "LED.h"

RTC rtc;
GPS gps;
LED led;

boolean interruptComplete = false;

void setup()
{
  Serial.begin(115200);
  Serial1.begin(4800); // for GPS
  Serial2.begin(4800); // for LED
  gps.setPort(Serial1);
  led.setPort(Serial2);
  led.write("GPS ");
  attachInterrupt(0, interruptHandler, FALLING);
}

void loop()
{
  if (interruptComplete)
  {
    DateTime now = rtc.getDateTime();
    led.write(now, LED::HoursMinutes);
    interruptComplete = false;
  }
  else
  {
    gps.getData();
  }
}

void interruptHandler()
{
  interruptComplete = true;
}

Run it. Won it. That takes care of 1 and 2 on the above list. Synchronising the RTC and GPS will be a bit trickier. I'm going to experiment for a bit and get back when I have an answer...

... whoa. I've been all 'round the world. The correction from UTC to local time wasn't working for me. What fixed it was a change to GPS::newSentence() that alters the way the local time is assigned to the currentLocalDateTime member variable. Also, I wasn't tracking if the GPS had good date and time data, now it does. Whew. So now the time on the LED display is the right local time. Code is here.

Right now the thing that's disconcerting is I don't have a blinking colon in the middle of the clock to tell me it's working. I need that! How did Version 2 do it? Ah, next post.

That is all.

Comments