using arduino with gps modules - mercury www...

15
Using Arduino with GPS Modules Dr. Padraig Houlahan Dept. of Physics, Embry-Riddle Aeronautical University, Prescott, AZ. 1-15-2015

Upload: dinhtram

Post on 30-Aug-2018

215 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Using Arduino with GPS Modules - Mercury WWW ...mercury.pr.erau.edu/~houlahap/Arduino/arduino_and_GPS.docx · Web viewIn addition, for this project we use Adafruit’s 32x128 LCD/OLED

Using Arduino with GPS Modules

Dr. Padraig Houlahan

Dept. of Physics, Embry-Riddle Aeronautical University, Prescott, AZ.

1-15-2015

Page 2: Using Arduino with GPS Modules - Mercury WWW ...mercury.pr.erau.edu/~houlahap/Arduino/arduino_and_GPS.docx · Web viewIn addition, for this project we use Adafruit’s 32x128 LCD/OLED

Table of ContentsUsing Arduino with GPS Modules................................................................................................................1

Working with GPS and OLED Displays......................................................................................................3

Software..................................................................................................................................................4

Wiring the project...................................................................................................................................5

Operational considerations.....................................................................................................................6

Web Sources............................................................................................................................................7

Software Listing.......................................................................................................................................8

Page 3: Using Arduino with GPS Modules - Mercury WWW ...mercury.pr.erau.edu/~houlahap/Arduino/arduino_and_GPS.docx · Web viewIn addition, for this project we use Adafruit’s 32x128 LCD/OLED

Working with GPS and OLED Displays

GPS modules are now relatively inexpensive and can be purchased for about $40. Here we use the Adafruit ‘Ultimate GPS Breakout’ shown in Fig. 1. A set of header pins is provided for the user to solder before use.

Fig. 1 The Adafruit GPS module retails for about $40.

In addition, for this project we use Adafruit’s 32x128 LCD/OLED display (see figure 2) so we can display data in real time from the GPS module.

Fig. 2 A 32x128 OLED display – about $17.

Page 4: Using Arduino with GPS Modules - Mercury WWW ...mercury.pr.erau.edu/~houlahap/Arduino/arduino_and_GPS.docx · Web viewIn addition, for this project we use Adafruit’s 32x128 LCD/OLED

SoftwareTo work with these devices we used knowledge and expertise encapsulated in the form of libraries contributed to the community in the form of software libraries, example software, and related documentation. Some sources are vendors; others are hobbyists and enthusiasts. We used the tinyGPS++ libraries and examples as the basis of our GPS code segments, and Adafruit’s SSD1306 libraries and samples for the OLED display.

The software is included as an appendix to this document, and while not trivial, it does contain the typical elements one would expect for this kind of project.

An quirk that we encountered was that the tinyGPS++ libraries and headers in the sample codes we modified for our purposes, actually referred to ‘tinyGPSplus,’ and this meant both the files that comprised the library had to be renamed – and the tinyGPSplus.cpp file modified so it included tinyGPSplus.h (not tinyGPS++.h.)

The only issue encountered with the OLED libraries was that they were written to support general formats and needed to be configured to explicitly support the 32x128 pixel version used here, by adding the statement: #define SSD1306_128_32 to the header file.

Since this particular display is small, in order to allow more information to be shown a simple counter was incremented every time through the main loop, and by using a modulus 3 calculation, three different pages could be displayed in turn,

Page 5: Using Arduino with GPS Modules - Mercury WWW ...mercury.pr.erau.edu/~houlahap/Arduino/arduino_and_GPS.docx · Web viewIn addition, for this project we use Adafruit’s 32x128 LCD/OLED

Wiring the projectWiring up the GPS and OLED modules to an Arduino UNO is straightforward, and shown in Fig. 3.

Fig. 3. Wiring the GPS and OLED display modules to the Arduino UNO

The wiring is as following:

TX (yellow) and RX (orange) from the GPS are connected to digital ports 3 and 4

GPS Vin voltage (red) comes from the Arduino 3.3v port

GPS ground (black) connects to an Arduino GND port

OLED RST (blue) connects to Arduino digital port 5.

OLED voltage (red) is sourced from the Arduino 5v port

OLED Ground (black) connects to the remaining GND port

OLED SDA and SCL (orange and white) connects to Arduino analog ports A4 and A5

Page 6: Using Arduino with GPS Modules - Mercury WWW ...mercury.pr.erau.edu/~houlahap/Arduino/arduino_and_GPS.docx · Web viewIn addition, for this project we use Adafruit’s 32x128 LCD/OLED

Operational considerationsThis project was able to easily detect up to 10 GPS satellites from inside a typical wood-frame home and seemed to work well. The Arduino power sources seem to be adequate, and a 9v battery was sufficient to allow the system to operate independent of the USB cable.

Sample OLED display screens are shown in figure 4, but the possibilities of further customizations makes for ideal student projects.

Fig. 4. Different screen display produced by the included code. Customized displays include (left to right): text and character drawing, date, time, and satellite count; coordinate, altitude, and speed (km/h.)

Page 7: Using Arduino with GPS Modules - Mercury WWW ...mercury.pr.erau.edu/~houlahap/Arduino/arduino_and_GPS.docx · Web viewIn addition, for this project we use Adafruit’s 32x128 LCD/OLED

Web Sources

GPS Support:

https://github.com/mikalhart/TinyGPSPlus

OLED Support:

https://github.com/adafruit/Adafruit_SSD1306

Page 8: Using Arduino with GPS Modules - Mercury WWW ...mercury.pr.erau.edu/~houlahap/Arduino/arduino_and_GPS.docx · Web viewIn addition, for this project we use Adafruit’s 32x128 LCD/OLED

Software Listing

#include <TinyGPSPlus.h>#include <SoftwareSerial.h>#include <Adafruit_GFX.h>#include <SPI.h>#include <Wire.h>#include <Adafruit_SSD1306.h>#include <stdlib.h>

#define OLED_RESET 5Adafruit_SSD1306 display(OLED_RESET);

#define LOGO16_GLCD_HEIGHT 16 #define LOGO16_GLCD_WIDTH 16 static const unsigned char PROGMEM logo16_glcd_bmp[] ={ B00000000, B11000000, B00000001, B11000000, B00000001, B11000000, B00000011, B11100000, B11110011, B11100000, B11111110, B11111000, B01111110, B11111111, B00110011, B10011111, B00011111, B11111100, B00001101, B01110000, B00011011, B10100000, B00111111, B11100000, B00111111, B11110000, B01111100, B11110000, B01110000, B01110000, B00000000, B00110000 };

#if (SSD1306_LCDHEIGHT != 32)#error("Height incorrect, please fix Adafruit_SSD1306.h!");#endif

int count;

/*This sample code demonstrates the normal use of a TinyGPS++ (TinyGPSPlus) object.It requires the use of SoftwareSerial, and assumes that you have a 4800-baud serial GPS device hooked up on pins 4(rx) and 3(tx).*/static const int RXPin = 4, TXPin = 3;static const uint32_t GPSBaud = 9600;

Page 9: Using Arduino with GPS Modules - Mercury WWW ...mercury.pr.erau.edu/~houlahap/Arduino/arduino_and_GPS.docx · Web viewIn addition, for this project we use Adafruit’s 32x128 LCD/OLED

// The TinyGPS++ objectTinyGPSPlus gps;

// The serial connection to the GPS deviceSoftwareSerial ss(RXPin, TXPin);

void setup(){ count = 0; oled_init(); Serial.begin(115200); ss.begin(GPSBaud);}

void oled_init(void){display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3C (for the 128x32)

display.display(); delay(1000); // Clear the buffer. display.clearDisplay(); // draw scrolling text testscrolltext(); delay(1000); display.clearDisplay();}

void loop() // MAIN LOOP{ static const double LONDON_LAT = 51.508131, LONDON_LON = -

0.128002; //obsolete int res; count = count+1; // use this to select between output displays res = count % 3; if (res == 1){ page1(); } else if (res == 2){ page2(); } else { page0(); } Serial.println(); smartDelay(5000); if (millis() > 5000 && gps.charsProcessed() < 10) Serial.println(F("No GPS data received: check wiring"));} // END MAIN LOOP

Page 10: Using Arduino with GPS Modules - Mercury WWW ...mercury.pr.erau.edu/~houlahap/Arduino/arduino_and_GPS.docx · Web viewIn addition, for this project we use Adafruit’s 32x128 LCD/OLED

void page2(void){ // mostly character drawing stuff from here char satb[9]; display.clearDisplay(); display.setCursor(0,0); display.setTextSize(1); display.setTextColor(WHITE); displayDateTime(gps.date, gps.time); display.print("Satellites: "); display.println(gps.satellites.value()); display.display();}

void page1(void){ char latb[15],lonb[15],altb[15],velb[15]; String t_str, b_str;

dtostrf(gps.location.lat(),9,4,latb); dtostrf(gps.location.lng(),9,4,lonb); dtostrf(gps.altitude.meters(),9,4,altb); dtostrf(gps.speed.kmph(),9,4,velb); display.clearDisplay(); display.setCursor(0,0); display.setTextSize(1); display.setTextColor(WHITE); display.print("Lat: "); display.println(latb); display.print("Lon: "); display.println(lonb); display.print("Alt: "); display.println(altb); display.print("kph: "); display.println(velb); display.display();}

void page0(void){ display.clearDisplay();

// text display tests display.setTextColor(BLACK,WHITE); display.setTextSize(2); display.setTextColor(WHITE); display.setCursor(0,0); display.println("ERAU"); display.setTextSize(1); display.println("Aviation Sciences"); display.display();}

Page 11: Using Arduino with GPS Modules - Mercury WWW ...mercury.pr.erau.edu/~houlahap/Arduino/arduino_and_GPS.docx · Web viewIn addition, for this project we use Adafruit’s 32x128 LCD/OLED

// This custom version of delay() ensures that the gps object// is being "fed".static void smartDelay(unsigned long ms){ unsigned long start = millis(); do { while (ss.available()) gps.encode(ss.read()); } while (millis() - start < ms);}

static void printFloat(float val, bool valid, int len, int prec){ if (!valid) { while (len-- > 1) Serial.print('*'); Serial.print(' '); } else { Serial.print(val, prec); int vi = abs((int)val); int flen = prec + (val < 0.0 ? 2 : 1); // . and - flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1; for (int i=flen; i<len; ++i) Serial.print(' '); } smartDelay(0);}

static void printInt(unsigned long val, bool valid, int len){ char sz[32] = "*****************"; if (valid) sprintf(sz, "%ld", val); sz[len] = 0; for (int i=strlen(sz); i<len; ++i) sz[i] = ' '; if (len > 0) sz[len-1] = ' '; Serial.print(sz); smartDelay(0);}

static void displayDateTime(TinyGPSDate &d, TinyGPSTime &t){ if (!d.isValid())

Page 12: Using Arduino with GPS Modules - Mercury WWW ...mercury.pr.erau.edu/~houlahap/Arduino/arduino_and_GPS.docx · Web viewIn addition, for this project we use Adafruit’s 32x128 LCD/OLED

{ display.print(F("********** ")); } else { char sz[32]; sprintf(sz, "%02d/%02d/%02d ", d.month(), d.day(), d.year()); display.print(sz); } if (!t.isValid()) { display.print(F("******** ")); } else { char sz[32]; sprintf(sz, "%02d:%02d:%02d ", t.hour(), t.minute(),

t.second()); display.print(sz); }

display.println(""); smartDelay(0);}

static void printStr(const char *str, int len){ int slen = strlen(str); for (int i=0; i<len; ++i) Serial.print(i<slen ? str[i] : ' '); smartDelay(0);}

void testdrawchar(void) { display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0,0);

for (uint8_t i=0; i < 168; i++) { if (i == '\n') continue; display.write(i); if ((i > 0) && (i % 21 == 0)) display.println(); } display.display();}

Page 13: Using Arduino with GPS Modules - Mercury WWW ...mercury.pr.erau.edu/~houlahap/Arduino/arduino_and_GPS.docx · Web viewIn addition, for this project we use Adafruit’s 32x128 LCD/OLED

void testscrolltext(void) { display.setTextSize(2); display.setTextColor(WHITE); display.setCursor(10,0); display.clearDisplay(); display.println("ERAU"); display.display(); display.startscrollright(0x00, 0x0F); delay(2000); display.stopscroll(); delay(1000); display.startscrollleft(0x00, 0x0F); delay(2000); display.stopscroll(); delay(1000); display.startscrolldiagright(0x00, 0x07); delay(2000); display.startscrolldiagleft(0x00, 0x07); delay(2000); display.stopscroll();}