RobiSydney icon

Arduino Uno GPS + Dimming + LCD.ino

RobiSydney | PRO | 05/25/17 12:54:51 AM UTC | 0 ⭐ | 293 👁️ | Never ⏰ | []
C++ |

11.36 KB

|

None

|

0 👍

/

0 👎

 
/**
   Code to display the time & date from a GPS receiver on a LCD.
 
   This code was inspired by http://arduino.cc/en/Tutorial/LiquidCrystal and
   http://playground.arduino.cc/Tutorials/GPS
 
   For more information, see http://quaxio.com/arduino_gps/
 
Edit: 4 June 2017 : Fixed the direction logic..  North is OR less than 22.5 OR greater than 3sumptin || everything else is AND &&
Cleaned it up a bit.
 
*/
#include <SoftwareSerial.h>
#include <LiquidCrystal.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#define DEBUG 0
SoftwareSerial mySerial(19, 18); // RX, TX
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
int VOID = 1;
int rxPin = 19; // RX pin
int txPin = 18; // TX pin
int DayLight = -8;
int byteGPS = -1;
int counter1 = 0; // counts how many bytes were received (max 300)
int counter2 = 0; // counts how many commas were seen
int offsets[13];
char buf[310] = "";
int first = 1;
byte North[8] = {
  B00000,
  B00100,
  B01110,
  B10101,
  B00100,
  B00100,
  B00100,
  B00000
  
};
 
byte NorthEast[8] = {
  B00000,
  B00000,
  B01111,
  B00011,
  B00101,
  B01001,
  B10000,
  B00000
  
};
byte East[8] = {
  B00000,
  B00100,
  B00010,
  B11111,
  B00010,
  B00100,
  B00000,
  B00000
  
};
byte SouthEast[8] = {
  B00000,
  B10000,
  B01001,
  B00101,
  B00011,
  B01111,
  B00000,
  B00000
  
};
byte South[8] = {
  B00000,
  B00100,
  B00100,
  B00100,
  B10101,
  B01110,
  B00100,
  B00000
  
};
byte SouthWest[8] = {
  B00000,
  B00001,
  B10010,
  B10100,
  B11000,
  B11110,
  B00000,
  B00000
  
};
byte West[8] = {
  B00000,
  B00100,
  B01000,
  B11111,
  B01000,
  B00100,
  B00000,
  B00000
  
};
byte NorthWest[8] = {
  B00000,
  B00000,
  B11110,
  B11000,
  B10100,
  B10010,
  B00001,
  B00000
  
};
// Keys AnalogRead(0);
const int Keyselect = 650;
const int KeyLeft = 409;
const int KeyRight = 49;
const int KeyUp = 100;
const int KeyDown = 255;
// select 600-650
// left 350-500
// right 0
// up 50-200
// down 201-349
 
int Key, KeyCount, LastKey;
int backLight=125;
int BackLightPin = 10;
char CRLF[3] = {13,10,0};
 
char chksum(char checksumsource[300], char header[1], char footer[1]) {
  int CRC=0;
  int i,h,f = 0;
  if(checksumsource[i] == header[0]) h++;
 
#if DEBUG == 5
Serial.println("\n -=-=-=-=-=-=-=-=-= CHK SUM SOURCE =-=-=-=-=-=-=-=-");  
Serial.print(checksumsource);
Serial.println("\n -=-=-=-=-=-=-=-=-= chksum =-=-=-=-=-=-=-=-");  
Serial.print(checksumsource[0]);
#endif  
  for(i=h; checksumsource[i] != '*'; i++ ) {
#if DEBUG == 1
  Serial.print(checksumsource[i]);
#endif
    CRC = (CRC ^ checksumsource[i]) && 255;     
  }
  f=i;
#if DEBUG == 5
  Serial.print(checksumsource[f]);
  Serial.print(CRC,HEX);
  Serial.print("\n -=-=-=-=-=-=-=-= end chksum =-=-=-=-=-=-=-\n\n");  
#endif
  return CRC;
}
 
/**
   Setup display and gps
*/
void setup() {
  char buf2(300);
  pinMode(rxPin, INPUT);
  pinMode(txPin, OUTPUT);
  pinMode(10,OUTPUT);
  Serial.begin(9600);
  lcd.createChar(0,North);
  lcd.createChar(1,NorthEast);
  lcd.createChar(2,East);
  lcd.createChar(3,SouthEast);
  lcd.createChar(4,South);
  lcd.createChar(5,SouthWest);
  lcd.createChar(6,West);
  lcd.createChar(7,NorthWest);
  
  lcd.begin(16, 2);
  lcd.clear();
  //Serial.println("Wait for gps");
  lcd.print("    Wait for gps");
 
  offsets[0] = 0;
  reset();
  mySerial.begin(9600);
  //mySerial.println(cmd);
#if DEBUG == 1  
  char buf4[]="$PSRF103,00,00,01,01*11";
  delay(1000);
  //Serial.print("\n");
  //Serial.print(buf4);
  //Serial.print("-");
  //Serial.print(chksum(buf4,'$','*'),HEX);
  //Serial.print(CRLF);
#endif
}
 
 
void reset() {
  counter1 = 0;
  counter2 = 0;
  offsets[0] = 0;
  //  offset=0;
}
 
int get_size(int offset) {
  return offsets[offset + 1] - offsets[offset] - 1;
}
 
int DoGPRMC(void ) {
  int b,j,h = 0;
  float f;
  char cmd[7] = "$GPRMC";
  char buf2[11];
  char buf3[11];
  if (counter2 == 0) return 0;
  if ((counter2 == 12 ) && (get_size(0) == 6)) {
    // Check that we received $GPRMC
    for (j = 0; j < 6; j++) {
      if (buf[j] != cmd[j]) {
        return 0;
      }
    }
  //Serial.println("\n ---------- GPRMC checksum --------------- ");
  for (j = 1; buf[ j-1] != '*'; ++j) {
    buf2[j] = buf[ j];
  }
  buf2[0] = '$';
  buf2[j]=0;
    
    if (get_size(1) != 10) {
      return 0;
    }
 
    // Check that date is well formed
    if (get_size(9) != 6) {
      return 0;
    }
    if (first == 1 ) {
      first = 0;
      lcd.clear();
    }
 
    // TODO: compute and validate checksum
 
    // TODO: handle timezone offset
// 0      1          2 3         4 5          6 7    8     9      10 11 12
// $GPRMC,185726.000,A,3327.8968,N,11707.0896,W,0.00,44.99,060517,  ,  ,A*4B
 
    // print time
    lcd.setCursor(11, 0);
    for (j = 0; j < 2; j++) {
      buf2[j] = buf[offsets[1] + j];
    }
    buf2[j] = 0;
    
    DayLight = -8;
    if(buf[offsets[9]]='0' && ( buf[offsets[9]+1]='5' && buf[offsets[9]+2]> '2')) DayLight = -7;
    if(buf[offsets[9]]='1' && (buf[offsets[9]+1]='1' && buf[offsets[9]+2]<'1')) DayLight = -7;
    if(buf[offsets[9]]='0' && buf[offsets[9]+1]>'5') DayLight = -7;
    if(buf[offsets[9]]='1' && buf[offsets[9]+1]<'1') DayLight = -7;
 
    if ((atoi(buf2) + DayLight) < 0)
      j = atoi(buf2) + (24+ DayLight);
    else
      j=atoi(buf2) + DayLight;
#if DEBUG == 1
 
 //Serial.print(atoi(buf2));
 //Serial.print(" <- buf2   j-> ");
 //Serial.println(j);
#endif
    j=sprintf(buf3,"%2.0d:%c%c",j,buf[offsets[1] + 2],buf[offsets[1] + 3]);
    lcd.print(buf3);
    ////Serial.print(buf3);
    ////Serial.println(" <- buf3");
    lcd.setCursor(13, 1);
    j=sprintf(buf3," %c%c",buf[offsets[1] + 4],buf[offsets[1] + 5]);
    j=atoi(buf3);
    lcd.print(buf3);
    //lcd.print(buf[offsets[1] + 5]);
/*    
 *     if (buf[offsets[2]] == 'V') {
      lcd.setCursor(0, 1);
      lcd.blink();
      //lcd.print("    DATA VOID   ");
      //Serial.println("    DATA VOID   ");
      VOID = 1;
      return 0;
    } else {
      if (VOID == 1) lcd.clear();
      VOID = 0;
      lcd.noBlink();
      lcd.print(":");
    }
*/
 
    // print Speed
    for (j = 0; buf[offsets[7] + j] != ','; j++) {
      buf2[j] = buf[offsets[7] + j];
    }
    buf2[j] = 0;
    lcd.setCursor(0, 0);
    f = atoi(buf2);
//    if (f > 0) {
      dtostrf(f*1.151,4,1,buf2);
      if (atof(buf2)*1.151 > 75) {
        lcd.blink();
        //Serial.println("OVER SPEED BLINK ");
      } else lcd.noBlink();
      lcd.print(buf2);
      lcd.print(" M ");
      lcd.setCursor(0, 1);
      dtostrf(f*1.852,4,1,buf2);
      lcd.print(buf2);
      lcd.print(" k");
#if DEBUG == 1
      //Serial.print(" SPEEEEDDDDD                          ");
      //Serial.println(buf2);
#endif
/*    } else {
      lcd.print("Stopped ");
      lcd.setCursor(0, 1);
      lcd.print("       ");
    }
*/
    // print heading
    if (get_size(8) > 0) {
      for (j = 0; buf[offsets[8] + j] != ','; j++) {
        buf2[j] = buf[offsets[8] + j];
      }
      buf2[j] = 0;
      lcd.setCursor(9, 1);
      float f;
      #if DEBUG == 0
      Serial.print(buf2);
      #endif
      f = atof(buf2);
      #if DEBUG == 0
      Serial.print(" heading ");
      Serial.println(f);
      #endif
      if(f >= 337.5 || f < 22.5) {
        j=sprintf(buf2, "N  ");
        h=0;
      } else if(f >=    22.5 && f < 67.5) {
        j=sprintf(buf2, "NE ");
        h=1;
      } else if (f >= 67.5 && f < 112.5) {
        j=sprintf(buf2, "E  ");
        h=2;
      } else if (f >= 112.5 && f < 157.5) {
        j=sprintf(buf2, "SE ");
        h=3;
      } else if (f >= 157.5 && f < 202.5) {
        j=sprintf(buf2, "S");
        h=4;
      } else if (f >= 202.5 && f < 247.5) {
        j=sprintf(buf2, "SW   ");
        h=5;
      } else if (f >= 247.5 && f < 292.5) {
        j=sprintf(buf2, "W  ");
        h=6;
      } else if (f >= 292.5 && f < 337.5) {
        j=sprintf(buf2, "NW   ");
        h=7;
      } 
      #if DEBUG == 0
      Serial.print(" Buf2 ");
      Serial.println(buf2);
      #endif
      lcd.print(buf2);
      lcd.setCursor(12,1);
      lcd.write(byte(h));
      //Serial.print(buf2);
    //  lcd.print("D");
 
    }
    buf2[0] = 0;
    counter2 = 0;
    counter1 = 0;
    //    offset=0;
    offsets[0] = 0;
    buf[0] = '*';
    return 0;
  } else {
    return 0;
  }
}
 
int DoGPVTG(void ) {
  char cmd[7]="$GPVTG";
  int j,h=0;
  char buf2[11];
  char buf3[11];
  for (j = 0; j < 6; j++) {
    if (buf[j] != cmd[j]) {
      return 0;
    }
  }
  return 0;
}
 
int DoGPGGA(void ) {
  char cmd[7]="$GPGGA";
  int j,h=0;
  char buf2[11];
  char buf3[11];
    for (j = 0; j < 6; j++) {
      if (buf[j] != cmd[j]) {
        return 0;
      }
    }
  return 0;
}
 
int DoGPGSV(void ) {
  char cmd[7]="$GPGSV";
  int j,h=0;
  char buf2[11];
  char buf3[11];
    for (j = 0; j < 6; j++) {
      if (buf[j] != cmd[j]) {
        return 0;
      }
    }
  for (j = 1; buf[ j-1] != '*'; ++j) {
    buf2[j] = buf[ j];
  }
  buf2[0] = '$';
  buf2[j]=0;
#if DEBUG > 0
  Serial.println(buf2);
  Serial.print(cmd);
  Serial.print(" Satellites in view");
#endif
  lcd.setCursor(7,0);
  for (j = 0; buf[offsets[3]+j]!=','; j++) {
    lcd.print(buf[offsets[3]+j]);
  }
  lcd.print("S ");
  return 0;
}
 
int handle_byte(int byteGPS) {
  if (byteGPS == '$') {
    //offsets[12] = counter1;
    counter1 = 0;
    counter2 = 0;
    offsets[0] = 0;
    buf[1] = 0;
  }
  buf[counter1] = byteGPS;
  buf[counter1 + 1] = 0;
  buf[counter1 + 2] = 0;
  counter1++;
  if (counter1 == 300) {
    buf[0] = 0;
    buf[40] = 0;
    buf[80] = 0;
    return 0;
  }
  if (byteGPS == ',') {
    counter2++;
    offsets[counter2] = counter1;
  }
 
  if (byteGPS == '*') {
    if (buf[counter1 - 2] == 'V') {
      VOID = 1;
    }
    buf[counter1 + 1] = 0;
    buf[counter1 + 2] = 0;
    buf[counter1 + 3] = 0;
    buf[counter1 + 4] = 0;
  }
 
  // Check if we got a <LF>, which indicates the end of line
  if (byteGPS == 10) {
    int h = 0;
    buf[counter1 - 1] = 0;
    buf[counter1] = 0;
    buf[counter1 + 1] = 0;
    buf[counter1 + 2] = 0;
  
    DoGPRMC();
    DoGPVTG();
    DoGPGSV();
    DoGPGGA();
    #if DEBUG == 2
    Serial.println(buf);
    #endif
  }
  return 1;
}
 
 
/**
   Main loop
*/
void loop() {
  if (mySerial.available() > 0) {
    byteGPS = mySerial.read();
#if DEBUG > 5
      Serial.print(byteGPS);
    // Read a byte of the serial port
#endif
    //delay(50);
    if (!handle_byte(byteGPS)) {
      reset();
    }
  }
Key = analogRead(0);
if(abs(LastKey-Key)<20) {
  if(++KeyCount>3) {
    if(abs(Key-KeyUp)<30 ) { 
      if(backLight<251) backLight += 5; 
      KeyCount=0; 
      //Serial.println(backLight);
    } else if(abs(Key-KeyDown)<30 ) { 
      if(backLight>4) backLight -= 5;
      KeyCount=0;   
      //Serial.println(backLight);
    }
  } // else KeyCount++;
}else {
  KeyCount=0;
  if(Key<800) {
    //Serial.print("LastKey " );
    //Serial.print(LastKey);
    //Serial.print(" Key ");
    //Serial.println(Key);
  }
}
LastKey=Key;
  analogWrite(BackLightPin,backLight);
  #if DEBUG > 3
  Serial.print("BackLight  : ");
  Serial.println(backLight);
  #endif
// int backLight=128;
//int BackLightPin = 10;
 
  
 
}

Comments