极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 9336|回复: 6

老外的 Arduino GPS System

[复制链接]
发表于 2015-10-11 18:50:54 | 显示全部楼层 |阅读模式
Arduino GPS System 2010-09-05
A fully functional GPS receiver with the ability to display the current location, heading, speed, average speed and maximum speed, the distance traveled, the bearing, distance and ETA to a way-point or coordinates, and the date and time.
原贴 http://www.seancarney.ca/projects/arduino-gps-receiver/arduino-gps-system#.Vho9wVKheM9


程序编译通过,界面正常,只是收不到GPS信号,哪位大仙能验证一下。

// GPS SYSTEM

/* Keys
/
/      1
/  4  3 0
/      2
/
*/

#include <SoftwareSerial.h>
#include <TinyGPS.h>
#include <LiquidCrystal.h>
#include <EEPROM.h>
#include <math.h>

union bitFloat {
      float float_num;
      char byte[4];
};

byte upArrow[8] = {
  B00100,
  B01110,
  B10101,
  B00100,
  B00100,
  B00100,
  B00100,
  B00000
};

byte downArrow[8] = {
  B00100,
  B00100,
  B00100,
  B00100,
  B10101,
  B01110,
  B00100,
  B00000
};

byte degree[8] = {
  B01100,
  B10010,
  B10010,
  B01100,
  B00000,
  B00000,
  B00000,
  B00000
};



LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

int adcKeyIn;
int NUM_KEYS = 5;
int key=-1;
int oldKey=-1;
int adcKeyVal[5] ={
  30, 150, 360, 535, 760 };

// Options

boolean useCurrentSpeed = 0;
boolean useDirections = 0;
boolean useAbsoluteHeadings = 0;
byte timeZone = 0;

TinyGPS gps;
SoftwareSerial nss(3, 2);// RX, TX

// Maximum speed and last known position
float maxSpeed = 0;
float lastFlat = 0;
float lastFlon = 0;

// Default location to navigate from
float targetFlat = 49.88622;
float targetFlon = -97.15256;

// Current waypoint selected
byte waypoint = 1;

// To track time elasped for average speed calculation
byte startHour = 0;
byte startMinute = 0;
byte startSecond = 0;

// Default menu choice
byte screen = 0;

boolean started = 1;
long distance = 0;

const int DEBOUNCE_DELAY = 50;
byte screenRefresh = 120;

void gpsdump(TinyGPS &gps);
bool feedgps();
void printFloat(double f, int digits = 2);

void setup() {
  Serial.begin(57600);
  nss.begin(4800);
  pinMode(13, OUTPUT);  //we'll use the debug LED to output a heartbeat

  lcd.createChar(0, upArrow);
  lcd.createChar(1, downArrow);
  lcd.createChar(2, degree);
  lcd.begin(16, 2);

  showSplash();

  // Load settings

  useCurrentSpeed = (boolean)EEPROM.read(0);
  useDirections = (boolean)EEPROM.read(1);
  useAbsoluteHeadings = (boolean)EEPROM.read(2);
  timeZone = EEPROM.read(3);

  showMenu();

}

void loop() {

  bool newdata = false;
  unsigned long start = millis();

  // Every 5 seconds we print an update
  while (millis() - start < 100)
  {
    if (feedgps())
      newdata = true;        
  }

  if (checkKeyDebounce() == 4)
    showNavigationMenu();

  if (newdata)
  {
    Serial.println("Acquired Data");
    Serial.println("-------------");
    gpsdump(gps);
    Serial.println("-------------");
    Serial.println();
  }
  else {
    Serial.println("No data");
  }

}

int checkKeyDebounce() {

  adcKeyIn = analogRead(0); // read the value from the

  key = getKey(adcKeyIn); // convert into key press

  if (key != oldKey) { // if keypress is detected

    delay(50); // wait for debounce time

    adcKeyIn = analogRead(0); //read the value from the sensor

    key = getKey(adcKeyIn); // convert into key press

    if (key != oldKey) {

      oldKey = key;

      if (key >=0) {

        return key;

      }

      else

        return -1;

    }

    else

        return -1;

  }

  else

      return -1;

}

int getKeyDebounce() {
  // wait for no keypress, then return keypress held for debounce period
  adcKeyIn = analogRead(0);    // read the value from the sensor  
  key = getKey(adcKeyIn);            // convert into key press
  do {
    key = getKey(analogRead(0));
  }
  while (key != -1);
  oldKey = key;
  while (oldKey == -1 || key == -1 || key != oldKey) {
    oldKey = key;
    delay(DEBOUNCE_DELAY);
    key = getKey(analogRead(0));
  }
  return key;
}

// Convert ADC value to key number
int getKey(unsigned int input)
{
  int k;
  for (k = 0; k < NUM_KEYS; k++)
  {
    if (input < adcKeyVal[k])
    {
      return k;
    }
  }
  if (k >= NUM_KEYS)
    k = -1;     // No valid key pressed
  return k;
}


void printLCDFloat(double number, int digits)
{
  // Handle negative numbers
  if (number < 0.0)
  {
    lcd.print("-");
    number = -number;
  }

  // Round correctly so that print(1.999, 2) prints as "2.00"
  double rounding = 0.5;
  for (uint8_t i=0; i<digits; ++i)
    rounding /= 10.0;

  number += rounding;

  // Extract the integer part of the number and print it
  unsigned long int_part = (unsigned long)number;
  double remainder = number - (double)int_part;
  char sTemp[10];
  ltoa(int_part, sTemp, 10);
  lcd.print(sTemp);

  // Print the decimal point, but only if there are digits beyond
  if (digits > 0)
    lcd.print(".");

  // Extract digits from the remainder one at a time
  while (digits-- > 0)
  {
    remainder *= 10.0;
    int toPrint = int(remainder);
    ltoa(toPrint, sTemp, 10);
    lcd.print(sTemp);
    remainder -= toPrint;
  }
}

void printFloat(double number, int digits)
{
  // Handle negative numbers
  if (number < 0.0)
  {
    Serial.print('-');
    number = -number;
  }

  // Round correctly so that print(1.999, 2) prints as "2.00"
  double rounding = 0.5;
  for (uint8_t i=0; i<digits; ++i)
    rounding /= 10.0;

  number += rounding;

  // Extract the integer part of the number and print it
  unsigned long int_part = (unsigned long)number;
  double remainder = number - (double)int_part;
  Serial.print(int_part);

  // Print the decimal point, but only if there are digits beyond
  if (digits > 0)
    Serial.print(".");

  // Extract digits from the remainder one at a time
  while (digits-- > 0)
  {
    remainder *= 10.0;
    int toPrint = int(remainder);
    Serial.print(toPrint);
    remainder -= toPrint;
  }
}

void gpsdump(TinyGPS &gps)
{

  if (screenRefresh == 120)
  {
    lcd.clear();
    screenRefresh = 0;
  }
  else
    screenRefresh++;

  float flat, flon;
  unsigned long age;
  int year;
  byte month, day, hour, minute, second, hundredths;

  feedgps(); // If we don't feed the gps during this long routine, we may drop characters and get checksum errors

    gps.f_get_position(&flat, &flon, &age);

  Serial.print("Lat/Long(float): ");
  printFloat(flat, 5);
  Serial.print(", ");
  printFloat(flon, 5);
  Serial.print(" Fix age: ");
  Serial.print(age);
  Serial.println("ms.");

  feedgps();

  gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
  Serial.print("Date: ");
  Serial.print(static_cast<int>(month));
  Serial.print("/");
  Serial.print(static_cast<int>(day));
  Serial.print("/");
  Serial.print(year);
  Serial.print("  Time: ");
  Serial.print(static_cast<int>(hour));
  Serial.print(":");
  Serial.print(static_cast<int>(minute));
  Serial.print(":");
  Serial.print(static_cast<int>(second));
  Serial.print(".");
  Serial.print(static_cast<int>(hundredths));
  Serial.print("  Fix age: ");  
  Serial.print(age);
  Serial.println("ms.");

  feedgps();

  Serial.print("Alt(cm): ");
  Serial.print(gps.altitude());
  Serial.print(" Course(10^-2 deg): ");
  Serial.print(gps.course());
  Serial.print(" Speed(10^-2 knots): ");
  Serial.println(gps.speed());
  Serial.print("Alt(float): ");
  printFloat(gps.f_altitude());
  Serial.print(" Course(float): ");
  printFloat(gps.f_course());
  Serial.println();
  Serial.print("Speed(knots): ");
  printFloat(gps.f_speed_knots());
  Serial.print(" (mph): ");  
  printFloat(gps.f_speed_mph());
  Serial.print(" (mps): ");
  printFloat(gps.f_speed_mps());
  Serial.print(" (kmph): ");
  printFloat(gps.f_speed_kmph());
  Serial.println();

  if (started == 1)
  {
    startHour = hour;
    startMinute = minute;
    startSecond = second;
  }

  float hours = (hour - startHour) + (((minute) - static_cast<float>(startMinute)) / 60) + (((second) - static_cast<float>(startSecond)) / 60 / 60);

  if ((gps.f_speed_kmph() > maxSpeed) && (gps.f_speed_kmph() < 1000))  // check for fastest speed and limit to 999 kmph
    maxSpeed = gps.f_speed_kmph();

  if (gps.f_speed_kmph() > 3.9)
  {
    if (started == 1)
    {
      started = 0;
      lastFlat = flat;
      lastFlon = flon;
    }
    else
    {
      distance = distance + calc_dist(flat, flon, lastFlat, lastFlon);
      lastFlat = flat;
      lastFlon = flon;
    }
  }

   if (age > 30000)
   {
   lcd.clear();
   lcd.setCursor(4, 0);
   lcd.print("WARNING!");
   lcd.setCursor(0, 1);
   lcd.print("Fix Age: ");
   printLCDFloat(age/1000, 0);
   lcd.print(" s");
   delay(3000);
   lcd.clear();
   }

  if (screen == 0)  // Latitude longitude speed and heading

  {

    lcd.setCursor(0, 0);
    printLCDFloat(flat, 5);
    lcd.print(" ");
    lcd.setCursor(0, 1);
    printLCDFloat(flon, 5);
    lcd.print(" ");

    lcd.setCursor(12, 1);
    if (useDirections == 0) {
      if (gps.f_course()<100)
        lcd.print(" ");
          if (gps.f_course()<10)
        lcd.print(" ");
      printLCDFloat(gps.f_course(), 0);
      lcd.write(2);
    }
    else {
      lcd.print(" ");
      printHeadingDirection(gps.f_course());
    }
    lcd.setCursor(10, 0);
    if (gps.f_speed_kmph()<99.5)
      lcd.print(" ");
    if (gps.f_speed_kmph()<9.5)
      lcd.print(" ");
    printLCDFloat(gps.f_speed_kmph(), 0);
    lcd.print("kmh");

  }

  if (screen == 1)  // Distance, Average speed and maximum speed

  {

    lcd.setCursor(0, 0);
    lcd.print("Dist ");

    float fDist = distance;
    fDist /= 1000;

    float avgSpeed = 0;

    if (hours != 0)
      avgSpeed = fDist / hours;

    printLCDFloat(fDist, 3);

    lcd.print("km");

    lcd.setCursor(0, 1);
    lcd.print("Av/Mx ");

    printLCDFloat(avgSpeed, 0);
    lcd.print("/");
    printLCDFloat(maxSpeed, 0);
    lcd.print("kmh");

  }

  if ((screen == 2)||(screen == 3))  // Navigate to Coordinates

  {

    lcd.setCursor(0,0);
    lcd.print("Go ");

    float fDist = (double)calc_dist(flat, flon, targetFlat, targetFlon) / 1000;

    float avgSpeed = 0;

    float fDist2 = distance;
    fDist2 /= 1000;

    if (hours != 0)
      avgSpeed = fDist2 / hours;

    printLCDFloat(fDist, 3);

    lcd.print("km");

    lcd.setCursor(0, 1);

    if (useDirections == 0) {
      if (useAbsoluteHeadings == 1) {
        if (calc_bearing(flat, flon, targetFlat, targetFlon) < 99.5)
          lcd.print(" ");
        if (calc_bearing(flat, flon, targetFlat, targetFlon) < 9.5)
          lcd.print(" ");
        printLCDFloat(calc_bearing(flat, flon, targetFlat, targetFlon), 0);
        lcd.write(2);
        lcd.print(" T");
      }
      else {
        if ((calc_bearing(flat, flon, targetFlat, targetFlon) - gps.f_course()) > 0) {
          if (calc_bearing(flat, flon, targetFlat, targetFlon)-gps.f_course() < 99.5)
            lcd.print(" ");
          if (calc_bearing(flat, flon, targetFlat, targetFlon)-gps.f_course() < 9.5)
            lcd.print(" ");
          printLCDFloat(calc_bearing(flat, flon, targetFlat, targetFlon)-gps.f_course(), 0);
          lcd.write(2);
          lcd.print(" R");
        }
        else {
          if (calc_bearing(flat, flon, targetFlat, targetFlon)-gps.f_course()+360 < 99.5)
            lcd.print(" ");
          if (calc_bearing(flat, flon, targetFlat, targetFlon)-gps.f_course()+360 < 9.5)
            lcd.print(" ");
          printLCDFloat(calc_bearing(flat, flon, targetFlat, targetFlon)-gps.f_course()+360, 0);
          lcd.write(2);
          lcd.print(" R");
        }
      }
      lcd.print("  ");
    }
    else {
      if (useAbsoluteHeadings == 1) {
        printHeadingDirection(calc_bearing(flat, flon, targetFlat, targetFlon));
        lcd.print(" T");
      }
      else {
        if ((calc_bearing(flat, flon, targetFlat, targetFlon) - gps.f_course()) > 0) {
          printHeadingDirection(calc_bearing(flat, flon, targetFlat, targetFlon)-gps.f_course());
          lcd.print(" R");
        }
        else {
          printHeadingDirection(calc_bearing(flat, flon, targetFlat, targetFlon)-gps.f_course()+360);
          lcd.print(" R");
        }
      }
    }

    lcd.setCursor(8, 1);

    long ETA = 0;

    if (useCurrentSpeed == 1)
    {
      if (gps.f_speed_kmph() != 0)
        ETA = (fDist/gps.f_speed_kmph())*60*60;
    }
    else
    {
      if (avgSpeed != 0)
        ETA = ((double)fDist/(double)avgSpeed)*60*60;
    }

    if (ETA/60/60 < 10)
      lcd.print("0");

    if (ETA/60/60 < 100)  // limit display to 99 hours
      printLCDFloat((ETA/60/60)%100, 0);

    int ETAHours = ETA/60/60;

    lcd.print(":");

    if ((ETA/60-(ETAHours*60) < 10))
      lcd.print("0");
    printLCDFloat((ETA/60-(ETAHours*60)), 0);

    int ETAMinutes = (ETA/60);

    lcd.print(":");

    if ((ETA-(ETAMinutes*60) < 10))
      lcd.print("0");
    printLCDFloat((ETA-(ETAMinutes*60)), 0);

  }

  if (screen == 5)  // Date and Time

  {

    int timeIZone;

    if (timeZone <= 12)
      timeIZone = (int)timeZone;
    else
      timeIZone = ((int)timeZone - 12) * - 1;

    int ihour = (int)hour + timeIZone;

    if (ihour > 23) {
      ihour = ihour - 24;
      day = day - 1;
    }

    if (ihour < 0) {
      ihour = ihour + 24;
      day = day - 1;
    }

    lcd.setCursor(0, 0);
    lcd.print("Date ");
    printLCDFloat(year, 0);
    lcd.print("/");
    if (month < 10)
      lcd.print("0");
    printLCDFloat(month, 0);
    lcd.print("/");
    if (day < 10)
      lcd.print("0");
    printLCDFloat(day, 0);
    lcd.setCursor(0, 1);
    lcd.print("Time ");
    if (ihour < 10)
      lcd.print("0");
    printLCDFloat(ihour, 0);
    lcd.print(":");
    if (minute < 10)
      lcd.print("0");
    printLCDFloat(minute, 0);
    lcd.print(":");
    if (second < 10)
      lcd.print("0");
    printLCDFloat(second, 0);

  }
  
  if (age > 30000)
   {
     delay(3000);
   }

}


void showNavigationMenu() {

boolean inMenu = 0;
byte lastOption = 1;
byte option = 0;

  while (inMenu == 0) {
   
     if ((option == 0)&&(lastOption != 0))
    {
      lcd.clear();
      lcd.print("  Mark as");
      lcd.setCursor(0,1);
      lcd.write(1);
      lcd.print(" waypoint");
      lastOption = 0;
    }
   
    if ((option == 1)&&(lastOption != 1))
    {
      lcd.clear();
      lcd.write(0.0);
      lcd.print(" Return to");
      lcd.setCursor(0,1);
      lcd.write(1);
      lcd.print(" main menu");
      lastOption = 1;
    }
   
    if ((option == 2)&&(lastOption != 2))
    {
      lcd.clear();
      lcd.write(0.0);
      lcd.print(" Cancel");
      lastOption = 2;
    }
   
    switch (getKeyDebounce())
    {

    case 1:
      if (option != 0)
        option--;
      break;
    case 2:
      if (option != 2)
        option++;
      break;
    case 4:
      if (option == 1) {
        showMenu(); }
      else if (screen == 0) {
        selectWaypoint();
        saveWaypoint(lastFlat, lastFlon);
        editWaypointName();
        lcd.clear(); }
      inMenu = 1;
      break;
      
    }
   
  }

}
  

void showMenu() {

  boolean inMenu = 0;

//  lcd.clear();
//  lcd.print("Please select");
//  lcd.setCursor(5, 1);
//  lcd.print("mode");

//  delay(2000);

  while (inMenu == 0)
  {
   
    // Main menu
   
    if (screen == 0) // Coordinates heading, speed
    {
      lcd.clear();
      lcd.print("  Coordinates,");
      lcd.setCursor(0,1);
      lcd.write(1);
      lcd.print(" heading, speed");
    }
    if (screen == 1) // Distance avg/max speed
    {
      lcd.clear();
      lcd.write(0.0);
      lcd.print(" Distance,");
      lcd.setCursor(0,1);
      lcd.write(1);
      lcd.print(" avg/max speed");
    }
    if (screen == 2) // Navigate to coordinates
    {
      lcd.clear();
      lcd.write(0.0);
      lcd.print(" Navigate to");
      lcd.setCursor(0,1);
      lcd.write(1);
      lcd.print(" coordinates");
    }
    if (screen == 3) // Navigate to waypoint
    {
      lcd.clear();
      lcd.write(0.0);
      lcd.print(" Navigate to");
      lcd.setCursor(0,1);
      lcd.write(1);
      lcd.print(" waypoint");
    }
    if (screen == 4) // View & edit waypoints
    {
      lcd.clear();
      lcd.write(0.0);
      lcd.print(" View & edit");
      lcd.setCursor(0,1);
      lcd.write(1);
      lcd.print(" waypoints");
    }
    if (screen == 5) // Date & time
    {
      lcd.clear();
      lcd.write(0.0);
      lcd.print(" Date & time");
      lcd.setCursor(0,1);
      lcd.write(1);
    }
    if (screen == 6) // Options
    {
      lcd.clear();
      lcd.write(0.0);
      lcd.print(" Options");
    }
   
    // Options menu
   
    if (screen == 10) // Current vs average speed to get ETA
    {
      lcd.clear();
      if (useCurrentSpeed == 1)
        lcd.print("  Current speed");
      else
        lcd.print("  Average speed");
      lcd.setCursor(0,1);
      lcd.write(1);
      lcd.print(" to get ETA");
    }
    if (screen == 11) // Show headings as number vs letters
    {
      lcd.clear();
      lcd.write(0.0);
      lcd.print(" Show headings");
      lcd.setCursor(0,1);
      lcd.write(1);
      if (useDirections == 0) {
        lcd.print(" as 353");
        lcd.write(2);
      }
      else
        lcd.print(" as NNW");
    }
    if (screen == 12) // Show headings as absolute vs relative
    {
      lcd.clear();
      lcd.write(0.0);
      lcd.print(" Show headings");
      lcd.setCursor(0,1);
      lcd.write(1);
      if (useAbsoluteHeadings == 1)
        lcd.print(" as absolute");
      else
        lcd.print(" as relative");
    }
    if (screen == 13) // Set time zone
    {
      lcd.clear();
      lcd.write(0.0);
      lcd.print(" Time zone");
      lcd.setCursor(0,1);
      lcd.write(1);
      lcd.print(" GMT ");
      int timeIZone;
      if (timeZone <= 12)
        timeIZone = (int)timeZone;
      else
        timeIZone = ((int)timeZone - 12) * - 1;
      printLCDFloat(timeIZone, 0);
    }
    if (screen == 15)
    {
      lcd.clear();
      lcd.write(0.0);
      lcd.print(" Delete all");
      lcd.setCursor(0,1);
      lcd.write(1);
      lcd.print(" waypoints");
    }
    if (screen == 14)
    {
      lcd.clear();
      lcd.write(0.0);
      lcd.print(" Backup");
      lcd.setCursor(0,1);
      lcd.write(1);
      lcd.print(" waypoints");
    }
    if (screen == 16)
    {
      lcd.clear();
      lcd.write(0.0);
      lcd.print(" Return to");
      lcd.setCursor(0,1);
      lcd.print("  main menu");
    }
   
    // Reset menu
   
    if (screen == 20)
    {
      lcd.clear();
      lcd.print("  Are you sure?");
      lcd.setCursor(0,1);
      lcd.write(1);
      lcd.print(" No!");
    }
    if (screen == 21)
    {
      lcd.clear();
      lcd.write(0.0);
      lcd.print(" Are you sure?");
      lcd.setCursor(0,1);
      lcd.print("  Yes!");
    }

    switch (getKeyDebounce())
    {

    case 1:
      if ((screen != 0)&&(screen != 10)&&(screen != 20))
        screen--;
      break;
    case 2:
      if ((screen != 6)&&(screen != 16)&&(screen != 21))
        screen++;
      break;
    case 4:
   
      // Main menu
   
      if (screen == 2) // Navigate to coordinates
      {
        setTargetCoords();
        inMenu = 1;
      }
      else if (screen == 3) // Navigate to waypoint
      {
        selectWaypoint();
        printTargetCoords();
        delay(2000);
        inMenu = 1;
      }
      else if (screen == 4) // View & edit waypoints
      {
        selectWaypoint();
        editWaypointName();
        setTargetCoords();
        saveWaypoint(targetFlat, targetFlon);
      }
      else if (screen == 6) // Options
      {
        screen = 10;
      }
      
      // Options menu
      
      else if (screen == 14) // Backup
      {
        saveEEPROM();
      }
      else if (screen == 15) // Reset menu
      {
        screen = 20;
      }
      else if (screen == 16) // Exit options menu
      {
        screen = 6;
      }
      
      // Reset menu
      
      else if (screen == 20) // Exit reset menu
      {
        screen = 15;
      }
      else if (screen == 21) // Reset device
      {
        clearEEPROM();
        screen = 15;
      }
        
      
      else if ((screen == 0)||(screen == 1)||(screen == 2)||(screen == 3)||(screen == 5)) // Enter the main loop
      {
        inMenu = 1;
      }
      
      break;
      
    case 0:
   
      // Options menu
   
      if (screen == 10) {
        if (useCurrentSpeed == 0)
          useCurrentSpeed = 1;
        else
          useCurrentSpeed = 0;
        EEPROM.write(0,(byte)useCurrentSpeed);
      }
      if (screen == 11) {
        if (useDirections == 0)
          useDirections = 1;
        else
          useDirections = 0;
        EEPROM.write(1,(byte)useDirections);
      }
      if (screen == 12) {
        if (useAbsoluteHeadings == 0)
          useAbsoluteHeadings = 1;
        else
          useAbsoluteHeadings = 0;
        EEPROM.write(2,(byte)useAbsoluteHeadings);
      }
      if (screen == 13) {
        timeZone = timeZone + 1;
        if (timeZone == 25)
          timeZone = 0;
        EEPROM.write(3,(byte)timeZone);
      }
      break;
      
    case 3:
   
      // Options menu
   
      if (screen == 10) {
        if (useCurrentSpeed == 0)
          useCurrentSpeed = 1;
        else
          useCurrentSpeed = 0;
        EEPROM.write(0,(byte)useCurrentSpeed);
      }
      if (screen == 11) {
        if (useDirections == 0)
          useDirections = 1;
        else
          useDirections = 0;
        EEPROM.write(1,(byte)useDirections);
      }
      if (screen == 12) {
        if (useAbsoluteHeadings == 0)
          useAbsoluteHeadings = 1;
        else
          useAbsoluteHeadings = 0;
        EEPROM.write(2,(byte)useAbsoluteHeadings);
      }
      if (screen == 13) {
        timeZone = timeZone - 1;
        if (timeZone == 255)  // This is a byte so negative values will wrap back to 255
            timeZone = 24;
        EEPROM.write(3,(byte)timeZone);
      }
      break;

    }

  }

  lcd.clear();
  lcd.print("Acquiring");
  lcd.setCursor(5, 1);
  lcd.print("signal...");

  screenRefresh = 120;

}


void selectWaypoint() {
  
  lcd.clear();
  lcd.print("Select a");
  lcd.setCursor(5, 1);
  lcd.print("waypoint...");
  
  delay(2000);
  
  boolean inMenu = 0;
  
  while (inMenu == 0) {
   
    lcd.clear();
    if (waypoint != 1)
      lcd.write(0.0);
    else
      lcd.print(" ");
    lcd.print(" Waypoint #");
    printLCDFloat(waypoint, 0);
    lcd.setCursor(0, 1);
    if (waypoint != 20)
      lcd.write(1);
    else
      lcd.print(" ");
    lcd.print(" ");
    for (int i = 0; i < 14; i++)
      lcd.print((char)EEPROM.read((waypoint * 22) + 8 + i));
   
    switch (getKeyDebounce())
    {
    case 1:
      if (waypoint != 1)
        waypoint--;
      break;
    case 2:
      if (waypoint != 20)
        waypoint++;
      break;
    case 4:
      inMenu = 1;
    break;
    }
      
  }
  
  bitFloat loadFloat;
  
  loadFloat.byte[0] = EEPROM.read((22 * waypoint) + 0);
  loadFloat.byte[1] = EEPROM.read((22 * waypoint) + 1);
  loadFloat.byte[2] = EEPROM.read((22 * waypoint) + 2);
  loadFloat.byte[3] = EEPROM.read((22 * waypoint) + 3);
  targetFlat = loadFloat.float_num;
  
  loadFloat.byte[0] = EEPROM.read((22 * waypoint) + 4);
  loadFloat.byte[1] = EEPROM.read((22 * waypoint) + 5);
  loadFloat.byte[2] = EEPROM.read((22 * waypoint) + 6);
  loadFloat.byte[3] = EEPROM.read((22 * waypoint) + 7);
  targetFlon = loadFloat.float_num;
  
}


void saveWaypoint(float saveLat, float saveLon) {
  
  bitFloat saveFloat;
  
  saveFloat.float_num = saveLat;
  EEPROM.write((22 * waypoint) + 0, saveFloat.byte[0]);
  EEPROM.write((22 * waypoint) + 1, saveFloat.byte[1]);
  EEPROM.write((22 * waypoint) + 2, saveFloat.byte[2]);
  EEPROM.write((22 * waypoint) + 3, saveFloat.byte[3]);
  
  saveFloat.float_num = saveLon;
  EEPROM.write((22 * waypoint) + 4, saveFloat.byte[0]);
  EEPROM.write((22 * waypoint) + 5, saveFloat.byte[1]);
  EEPROM.write((22 * waypoint) + 6, saveFloat.byte[2]);
  EEPROM.write((22 * waypoint) + 7, saveFloat.byte[3]);  
  
}


void editWaypointName() {

byte cursorPosition = 1;
lcd.blink();
boolean updated = 1;
boolean inMenu = 0;

  while (inMenu == 0)
  {

      lcd.clear();
      lcd.print("Waypoint name:");
      lcd.setCursor(0,1);
      for (int i = 0; i < 14; i++) {
        char printLetter;
        printLetter = EEPROM.read(((waypoint * 22) + 8 + i));
        lcd.print(printLetter);
      }
        
      switch (cursorPosition)
      {
      case 1:
        lcd.setCursor(0, 1);
        break;
      case 2:
        lcd.setCursor(1,1);
        break;
      case 3:
        lcd.setCursor(2,1);
        break;
      case 4:
        lcd.setCursor(3,1);
        break;
      case 5:
        lcd.setCursor(4,1);
        break;
      case 6:
        lcd.setCursor(5,1);
        break;
      case 7:
        lcd.setCursor(6,1);
        break;
      case 8:
        lcd.setCursor(7,1);
        break;
      case 9:
        lcd.setCursor(8,1);
        break;
      case 10:
        lcd.setCursor(9,1);
        break;
      case 11:
        lcd.setCursor(10,1);
        break;
      case 12:
        lcd.setCursor(11,1);
        break;
      case 13:
        lcd.setCursor(12,1);
        break;
      case 14:
        lcd.setCursor(13,1);
        break;
      }
   
  switch (getKeyDebounce())
  {

    case 1: {
      byte letter = EEPROM.read((waypoint * 22) + 7 + cursorPosition);
      letter++;
      if (letter >= 91)
        letter = 48;
      if (letter == 33)
        letter = 65;
      if (letter == 58)
        letter = 32;
      EEPROM.write((waypoint * 22) + 7 + cursorPosition, letter);  
      break; }
    case 2: {
      byte letter = EEPROM.read((waypoint * 22) + 7 + cursorPosition);
      letter--;
      if (letter == 64)
        letter = 32;
      if (letter == 47)
        letter = 90;
      if (letter <= 31)
        letter = 57;
      EEPROM.write((waypoint * 22) + 7 + cursorPosition, letter);
      break; }
    case 0: {
      cursorPosition++;
      if (cursorPosition > 14)
        cursorPosition = 1;
      break; }
    case 3: {
      cursorPosition--;
      if (cursorPosition < 0)
        cursorPosition = 14;
      break; }
    case 4: {
      inMenu = 1;
      lcd.noBlink();
      break; }
   
  }
  
  }
  
}


void printTargetCoords() {
  
   lcd.clear();
      if (targetFlat > 0)
      {
        lcd.print("(N) + ");
        if (targetFlat < 10)
          lcd.print("0");
        printLCDFloat(targetFlat, 5);
      }
      else
      {
        lcd.print("(S) - ");
        if (targetFlat > -10)
          lcd.print("0");
        printLCDFloat(targetFlat*-1, 5);
      }
      lcd.setCursor(0,1);
      if (targetFlon > 0)
      {
        lcd.print("(E) +");
        if (targetFlon < 100)
          lcd.print("0");
        if (targetFlon < 10)
          lcd.print("0");
        printLCDFloat(targetFlon, 5);
      }
      else
      {
        lcd.print("(W) -");
        if (targetFlon > -100)
          lcd.print("0");
        if (targetFlon > -10)
          lcd.print("0");
        printLCDFloat(targetFlon*-1, 5);
      }
      
}



void setTargetCoords() {

  boolean inMenu = 0;
  boolean updated = 1;
  byte cursorPosition = 1;

  lcd.clear();
  lcd.print("Please enter");
  lcd.setCursor(5, 1);
  lcd.print("coordinates");

  delay(2000);

  lcd.blink();

  while (inMenu == 0)
  {

    if (updated == 1)
    {
      
      printTargetCoords();

      switch (cursorPosition)
      {
      case 1:
        lcd.setCursor(1, 0);
        break;
      case 2:
        lcd.setCursor(4,0);
        break;
      case 3:
        lcd.setCursor(6,0);
        break;
      case 4:
        lcd.setCursor(7,0);
        break;
      case 5:
        lcd.setCursor(9,0);
        break;
      case 6:
        lcd.setCursor(10,0);
        break;
      case 7:
        lcd.setCursor(11,0);
        break;
      case 8:
        lcd.setCursor(12,0);
        break;
      case 9:
        lcd.setCursor(13,0);
        break;
      case 10:
        lcd.setCursor(1,1);
        break;
      case 11:
        lcd.setCursor(4,1);
        break;
      case 12:
        lcd.setCursor(5,1);
        break;
      case 13:
        lcd.setCursor(6,1);
        break;
      case 14:
        lcd.setCursor(7,1);
        break;
      case 15:
        lcd.setCursor(9,1);
        break;
      case 16:
        lcd.setCursor(10,1);
        break;
      case 17:
        lcd.setCursor(11,1);
        break;
      case 18:
        lcd.setCursor(12,1);
        break;
      case 19:
        lcd.setCursor(13,1);
        break;
      }

      updated = 0;
    }

    switch (getKeyDebounce())
    {
    case 0:
      cursorPosition++;
      if (cursorPosition == 20)
        cursorPosition = 1;
      updated = 1;
      break;
    case 3:
      cursorPosition--;
      if (cursorPosition == 0)
        cursorPosition = 19;
      updated = 1;
      break;
    case 1:
      switch (cursorPosition)
      {
      case 1:
        targetFlat *= -1;
        break;
      case 2:
        targetFlat *= -1;
        break;
      case 3:
        targetFlat += 10;
        break;
      case 4:
        targetFlat += 1;
        break;
      case 5:
        targetFlat += .1;
        break;
      case 6:
        targetFlat += .01;
        break;
      case 7:
        targetFlat += .001;
        break;
      case 8:
        targetFlat += .0001;
        break;
      case 9:
        targetFlat += .00001;
        break;
      case 10:
        targetFlon *= -1;
        break;
      case 11:
        targetFlon *= -1;
        break;
      case 12:
        targetFlon += 100;
        break;
      case 13:
        targetFlon += 10;
        break;
      case 14:
        targetFlon += 1;
        break;
      case 15:
        targetFlon += .1;
        break;
      case 16:
        targetFlon += .01;
        break;
      case 17:
        targetFlon += .001;
        break;
      case 18:
        targetFlon += .0001;
        break;
      case 19:
        targetFlon += .00001;
        break;
      }
      updated = 1;
      break;
    case 2:
      switch (cursorPosition)
      {
      case 1:
        targetFlat *= -1;
        break;
      case 2:
        targetFlat *= -1;
        break;
      case 3:
        targetFlat -= 10;
        break;
      case 4:
        targetFlat -= 1;
        break;
      case 5:
        targetFlat -= .1;
        break;
      case 6:
        targetFlat -= .01;
        break;
      case 7:
        targetFlat -= .001;
        break;
      case 8:
        targetFlat -= .0001;
        break;
      case 9:
        targetFlat -= .00001;
        break;
      case 10:
        targetFlon *= -1;
        break;
      case 11:
        targetFlon *= -1;
        break;
      case 12:
        targetFlon -= 100;
        break;
      case 13:
        targetFlon -= 10;
        break;
      case 14:
        targetFlon -= 1;
        break;
      case 15:
        targetFlon -= .1;
        break;
      case 16:
        targetFlon -= .01;
        break;
      case 17:
        targetFlon -= .001;
        break;
      case 18:
        targetFlon -= .0001;
        break;
      case 19:
        targetFlon -= .00001;
        break;
      }
      updated = 1;
      break;
    case 4:
      inMenu = 1;
      lcd.noBlink();
      break;
    }

  }

  printFloat(targetFlat,5);
  printFloat(targetFlon,5);

}



void showSplash() {

  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Arduino GPS");
  lcd.setCursor(5, 1);
  lcd.print("Version 2.0");

  delay(3000);



}

bool feedgps()
{
  while (nss.available())
  {
    if (gps.encode(nss.read()))
      return true;
  }
  return false;
}


void printHeadingDirection(float heading) {

  if ((heading > 348.75)||(heading < 11.25))
    lcd.print("  N");
  if ((heading >= 11.25)&&(heading < 33.75))
    lcd.print("NNE");
  if ((heading >= 33.75)&&(heading < 56.25))
    lcd.print(" NE");
  if ((heading >= 56.25)&&(heading < 78.75))
    lcd.print("ENE");
  if ((heading >= 78.75)&&(heading < 101.25))
    lcd.print("  E");
  if ((heading >= 101.25)&&(heading < 123.75))
    lcd.print("ESE");
  if ((heading >= 123.75)&&(heading < 146.25))
    lcd.print(" SE");
  if ((heading >= 146.25)&&(heading < 168.75))
    lcd.print("SSE");
  if ((heading >= 168.75)&&(heading < 191.25))
    lcd.print("  S");
  if ((heading >= 191.25)&&(heading < 213.75))
    lcd.print("SSW");
  if ((heading >= 213.75)&&(heading < 236.25))
    lcd.print(" SW");
  if ((heading >= 236.25)&&(heading < 258.75))
    lcd.print("WSW");
  if ((heading >= 258.75)&&(heading < 281.25))
    lcd.print("  W");
  if ((heading >= 281.25)&&(heading < 303.75))
    lcd.print("WNW");
  if ((heading >= 303.75)&&(heading < 326.25))
    lcd.print(" NW");
  if ((heading >= 326.25)&&(heading < 348.75))
    lcd.print("NWN");

}


int calc_bearing(float flat1, float flon1, float flat2, float flon2)
{
  float calc;
  float bear_calc;

  float x = 69.1 * (flat2 - flat1);
  float y = 69.1 * (flon2 - flon1) * cos(flat1/57.3);

  calc=atan2(y,x);

  bear_calc= degrees(calc);

  if(bear_calc<=1){
    bear_calc=360+bear_calc;
  }
  return bear_calc;
}  

unsigned long calc_dist(float flat1, float flon1, float flat2, float flon2)
{
  float dist_calc=0;
  float dist_calc2=0;
  float diflat=0;
  float diflon=0;

  //I've to spplit all the calculation in several steps. If i try to do it in a single line the arduino will explode.
  diflat=radians(flat2-flat1);
  flat1=radians(flat1);
  flat2=radians(flat2);
  diflon=radians((flon2)-(flon1));

  dist_calc = (sin(diflat/2.0)*sin(diflat/2.0));
  dist_calc2= cos(flat1);
  dist_calc2*=cos(flat2);
  dist_calc2*=sin(diflon/2.0);
  dist_calc2*=sin(diflon/2.0);
  dist_calc +=dist_calc2;

  dist_calc=(2*atan2(sqrt(dist_calc),sqrt(1.0-dist_calc)));

  dist_calc*=6371000.0; //Converting to meters, i love the metric system.. =)
  return dist_calc;
}


void clearEEPROM()
{
  lcd.clear();
  lcd.print("Formating EEPROM");
  lcd.setCursor(2,1);
  lcd.print("[");
  lcd.setCursor(13,1);
  lcd.print("]");
  
  delay(2000);
  
  bitFloat lat;
  lat.float_num = 49.88622; //Default value for waypoints
  bitFloat lon;
  lon.float_num = -97.15256; //Default value for waypoints

  for (int i = 1; i < 21; i++) {
  
    EEPROM.write((22 * i) + 0, lat.byte[0]);
    EEPROM.write((22 * i) + 1, lat.byte[1]);
    EEPROM.write((22 * i) + 2, lat.byte[2]);
    EEPROM.write((22 * i) + 3, lat.byte[3]);
  
    EEPROM.write((22 * i) + 4, lon.byte[0]);
    EEPROM.write((22 * i) + 5, lon.byte[1]);
    EEPROM.write((22 * i) + 6, lon.byte[2]);
    EEPROM.write((22 * i) + 7, lon.byte[3]);
  
    for (int x = 1; x < 15; x++)
      EEPROM.write((22 * i) + 7 + x, char(' '));
      
    lcd.setCursor(((i+1)/2)+2,1);
    lcd.print("-");
  }
  
  lcd.setCursor(6,1);
  lcd.print("DONE");
  
  delay(3000);

}


void saveEEPROM()
{
  
  lcd.clear();
  lcd.print("Start serial");
  lcd.setCursor(0, 1);
  lcd.print("monitor @ 57600");

  delay(5000);
  
  lcd.clear();
  lcd.setCursor(1,0);
  lcd.print("Dumping EEPROM");
  lcd.setCursor(2,1);
  lcd.print("[");
  lcd.setCursor(13,1);
  lcd.print("]");
  
  delay(2000);
  
  Serial.println("#include <EEPROM.h>");
  Serial.println("#include <LiquidCrystal.h>");
  Serial.println("LiquidCrystal lcd(8, 9, 4, 5, 6, 7);");
  Serial.println("void setup() {");
  
  Serial.println("lcd.begin(16, 2);");
  Serial.println("lcd.clear();");
  Serial.println("lcd.setCursor(1,0);");
  Serial.println("lcd.print(\"Loading EEPROM\");");
  Serial.println("lcd.setCursor(2,1);");
  Serial.println("lcd.print(\"[   BUSY   ]\");");
  
  for (int i = 0; i < 1024; i++)
  {  
    Serial.print("EEPROM.write(");
    Serial.print(i);
    Serial.print(",");
    Serial.print(int(EEPROM.read(i)));
    Serial.println(");");
   
    lcd.setCursor(((i)/103)+3,1);
    lcd.print("-");
  }
  
  Serial.println("lcd.setCursor(6,1);");
  Serial.println("lcd.print(\"DONE\");");
  
  Serial.println("}");
  Serial.println("void loop() {");
  Serial.println("}");
  
  lcd.setCursor(6,1);
  lcd.print("DONE");
  
  delay(3000);
  
}


回复

使用道具 举报

发表于 2015-10-11 19:10:26 | 显示全部楼层
你是什么GPS模块?可以参考《arduino一试就上手》,有GPS的例程,没有你这么多程序
回复 支持 反对

使用道具 举报

发表于 2015-10-12 08:42:18 | 显示全部楼层
出现了什么情况没有详细描述,是否没有收到GPS信号?GPS信号需要在室外才能接收到,或者将模块移到户外,或者GPS模块接天线,将天线放在户外。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-10-12 10:53:18 | 显示全部楼层
原贴 http://www.seancarney.ca/projects/arduino-gps-receiver/arduino-gps-system#.Vho9wVKheM9

验证:程序编译通过,下载正常,界面正常,几个按键的菜单也显示也对。
接上GPS, 安排这个接口SoftwareSerial nss(3, 2);// RX, TX,接数字口3,也试了2,在窗边,GPS正常,只是程序不显示GPS信号,如时间等,哪位大仙能验证一下。是不是GPS接口错了?不是数字接口?硬件都正常。

回复 支持 反对

使用道具 举报

发表于 2015-10-13 00:01:15 | 显示全部楼层
写得好长,gps没必要搞得很复杂。
回复 支持 反对

使用道具 举报

发表于 2015-10-13 10:18:42 | 显示全部楼层
你这一句:nss.begin(4800);

1、建议首先通过USB-TTL将GPS模块接到PC上位机上(网上有调试程序,很多,自搜),然后在同一地点(如阳台或者户外)看看该模块默认的波特率是多少,是不是4800,4800只是TINYGPS库例程当中的一个默认值。

2、玩GPS不要急着COPY这样大段程序,可以先试试TINYGPS库自带的例程,调试通了再试完整的功能,并没有捷径可走,即便这次侥幸通过了,一旦出现了一点问题,你就会束手无策,求助别人,别人并不见得恰好有你使用的模块或者库。

循序渐进吧,我有一个测试报告,在microduino板块,你可以参考一下,有用tinygps库的一个简单的实例,arduino+gps+oled的。希望对你有所帮助。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-10-13 15:33:11 | 显示全部楼层
本帖最后由 水镜 于 2015-10-13 15:34 编辑

感谢大师指点。只是好玩,想验证一下。
还有个GPS的TX和主板速率一致的问题。
把这二句
Serial.begin(57600);
   nss.begin(4800);
都改为9600就行了。我估计老外当时用的GPS比较老了,现在的GPS速度默认9600.
操作上是先选择一个内容,如时间,然后再按select键,时间日期就显示了。谢谢大家热心帮忙。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|联系我们|极客工坊

GMT+8, 2026-6-15 18:20 , Processed in 0.043916 second(s), 21 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表