Geocaching with mBed and Parallax GPS Module
Overview
Here is a game in which the user travels to predefined geographic locations, navigating with a display on an LCD screen. The GPS functionality is provided through a serial interface with a Parallax GPS module. There is also voice feedback that interacts with the user through .wav files stored on an SD card.
Additional information and documentation for the Parallax GPS Receiver can be found in the following manual:
/media/uploads/smmcneil00/gpsmanualv1.1.pdf
Necessary Items
mBed
Parallax GPS Module
uLCD Display
Class D Audio Amplifier

SD Card Breakout
Speaker
Hardware Hookup Guide
| GPS | mBed |
|---|---|
| VCC | +5V |
| Gnd | Gnd |
| SIO | p10 |
| /RAW | Gnd |
| mbed | uLCD Header | uLCD cable |
|---|---|---|
| 5V | 5V | 5V |
| Gnd | Gnd | Gnd |
| p28 | RX | TX |
| p27 | TX | RX |
| p29 | Reset | Reset |
| SD Breakout | mBed |
|---|---|
| VCC | +3.3V |
| Gnd | Gnd |
| CS | p8 |
| DI | p5 |
| SCK | p7 |
| DO | p6 |
| Amplifier | mBed | Speaker |
|---|---|---|
| PWR+ | +5V | |
| PWR- | Gnd | |
| IN+ | p18 | |
| IN- | Gnd | |
| OUT+ | Speaker + | |
| OUT- | Speaker - |
Video and Pictures
Code
geocachingGame
#include "mbed.h"
#include "SDFileSystem.h"
#include "wave_player.h"
#include "uLCD_4DGL.h"
#include "rtos.h"
#include <algorithm>
uLCD_4DGL uLCD(p28, p27, p29);
Serial gps(p9,p10);
DigitalOut led(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
DigitalOut led4(LED4);
SDFileSystem sd(p11, p12, p13, p8, "sd");
AnalogOut DACout(p18);
wave_player waver(&DACout);
char byteGPS;
char linea[300] = "";
char comandoGPR[7] = "$GPRMC";
int countB=0;
int good=0;
int countA=0;
int indices[13];
char latStr[9] = "";
float latFloat = 0.0f;
char lonStr[9] = "";
float lonFloat = 0.0f;
float lat[3]; //Can add more locations if desired
float lon[3]; //Can add more locations if desired
int locCount = 0;
float latFloatT = 8423.4753;
float lonFloatT = 3346.2227;
float diffLon = 10.0f;
float diffLat = 10.0f;
float margin = 0.0020f;
int locCircX = 0;
int locCircY = 0;
void lcd_createMap(){ //Initialize/Reset Screen
uLCD.circle(63,63,10,RED);
uLCD.line(93,63,33,63,RED);
uLCD.line(63,93,63,33,RED);
FILE *wave_file;
wave_file=fopen("/sd/Loading.wav","r");
waver.play(wave_file);
fclose(wave_file);
wait(.5);
uLCD.circle(63,63,10,BLACK);
uLCD.line(93,63,33,63,BLACK);
uLCD.line(63,93,63,33,BLACK);
uLCD.circle(63,63,4,RED);
uLCD.line(73,63,53,63,RED);
uLCD.line(63,73,63,53,RED);
uLCD.color(BLUE);
uLCD.locate(9,0);
uLCD.putc('N');
uLCD.locate(9,15);
uLCD.putc('S');
uLCD.locate(0,7);
uLCD.putc('W');
uLCD.locate(17,7);
uLCD.putc('E');
wave_file=fopen("/sd/Proceed.wav","r");
waver.play(wave_file);
fclose(wave_file);
}
void reachedPoint(){ //Called when location is reached
if(locCount<2){ //Change if using a different number of coordinates
locCount++;
}else{
locCount=0;
}
uLCD.cls();
uLCD.circle(63,63,10,RED);
uLCD.line(93,63,33,63,RED);
uLCD.line(63,93,63,33,RED);
FILE *wave_file;
wave_file=fopen("/sd/Success.wav","r");
waver.play(wave_file);
fclose(wave_file);
wait(.5);
lcd_createMap();
}
void checkPoint(){ //Checks to see if location is reached
if(abs(diffLon)<=margin && abs(diffLat)<=margin){
reachedPoint();
}else{
}
}
void lcd_thread() { //Updates navigation screen
uLCD.filled_circle(locCircX,locCircY,2,BLACK);
uLCD.line(63,12,locCircX,12,BLACK);
uLCD.line(12,63,12,locCircY,BLACK);
uLCD.circle(63,63,4,RED);
uLCD.line(73,63,53,63,RED);
uLCD.line(63,73,63,53,RED);
diffLon = lon[locCount]-lonFloat;
diffLat = lat[locCount]-latFloat;
locCircX = 63-480.0f*diffLon;
locCircY = 63-480.0f*diffLat;
if(locCircX<20){
locCircX=20;
}else if(locCircX>100){
locCircX=100;
}
if(locCircY<20){
locCircY=20;
}else if(locCircY>100){
locCircY=100;
}
uLCD.line(63,12,locCircX,12,GREEN);
uLCD.filled_circle(locCircX,locCircY,2,GREEN);
uLCD.line(12,63,12,locCircY,GREEN);
checkPoint();
}
void gps_thread(void const *args) { //Gets GPS Data
gps.baud(4800);
//pc.baud(115200);
for (int i=0;i<300;i++){ // Initialize a buffer for received data
linea[i]=' ';
}
for (int i=0;i<9;i++){ // Initialize a buffer for received data
latStr[i]=' ';
}
for (int i=0;i<9;i++){ // Initialize a buffer for received data
lonStr[i]=' ';
}
while(1){
//Get GPS Data
byteGPS = gps.getc(); // Read a byte of the serial port
linea[countA]=byteGPS; // If there is serial port data, it is put in the buffer
countA++;
if (byteGPS=='\r'){ // If the received byte is = to 13, end of transmission
// note: the actual end of transmission is <CR><LF> (i.e. 0x13 0x10)
countB=0;
good=0;
// First byte is the <LF> (0x10) from the previous transmission.
for (int i=1;i<7;i++){ // Verifies if the received command starts with $GPR
if (linea[i]==comandoGPR[i-1]){
good++;
}
}
if(good==6){ // If yes, continue and process the data
for (int i=0;i<300;i++){
if (linea[i]==','){
indices[countB]=i;
countB++;
}
if (linea[i]=='*'){ // ... and the "*"
indices[12]=i;
countB++;
}
}
//Get latitude value
int i=2;
for (int j=indices[i];j<(indices[i+1]-1);j++){
latStr[j-indices[i]] = linea[j+1];
}
latFloat = atof(latStr);
//Get longitude value
i=4;
for (int j=indices[i];j<(indices[i+1]-1);j++){
lonStr[j-indices[i]] = linea[j+1];
}
lonFloat = atof(lonStr);
lcd_thread();
}
countA=0; // Reset the buffer
for (int i=0;i<300;i++){
linea[i]=' ';
}
}
}
}
int main() {
// EDIT COORDINATES HERE
lat[0] = 3346.2283;
lon[0] = 8423.5186;
lat[1] = 3346.2340;
lon[1] = 8423.4885;
lat[2] = 3346.2173;
lon[2] = 8423.4818;
// END EDIT COORDINATES
led = 0;
led2 = 0;
led3 = 0;
led4 = 0;
uLCD.baudrate(BAUD_3000000);
lcd_createMap();
Thread tGPS(gps_thread, (void *)"Thread 1"); //GPS thread started
while(1)
{
led=!led;
Thread::wait(500);
}
}
int main() {
// EDIT COORDINATES HERE
lat[0] = 3346.2283;
lon[0] = 8423.5186;
lat[1] = 3346.2340;
lon[1] = 8423.4885;
lat[2] = 3346.2173;
lon[2] = 8423.4818;
// END EDIT COORDINATES
led = 0;
led2 = 0;
led3 = 0;
led4 = 0;
uLCD.baudrate(BAUD_3000000);
lcd_createMap();
Thread tGPS(gps_thread, (void *)"Thread 1"); //GPS thread started
while(1)
{
led=!led;
Thread::wait(500);
}
}
Import librarySDFileSystem
SDFileSystem
Import librarymbed-rtos
Official mbed Real Time Operating System based on the RTX implementation of the CMSIS-RTOS API open standard.
Import programWavePlayer_HelloWorld
A basic wave player demo using the cookbook waveplayer and SD file system examples with a low-cost speaker and transistor
Import library4DGL-uLCD-SE
Fork of 4DGL lib for uLCD-144-G2. Different command values needed. See https://mbed.org/users/4180_1/notebook/ulcd-144-g2-128-by-128-color-lcd/ for instructions and demo code.
.WAV Files for Voice Feedback
/media/uploads/smmcneil00/loading.wav
Please log in to post comments.
