diff --git a/Homework 3/Question 1 Proof/DAQ_initial.ino b/Homework 3/Question 1 Proof/DAQ_initial.ino
new file mode 100644
index 0000000000000000000000000000000000000000..d7b5fb20434310676036e7a37f11012ad0122baa
--- /dev/null
+++ b/Homework 3/Question 1 Proof/DAQ_initial.ino	
@@ -0,0 +1,1012 @@
+/*
+Group 1: Jeremy, Pavan, Ayush, Sam
+Homework 3: DAQ
+9th of Feburary, 2023
+
+File Name: DAQ initial
+
+Goal/Purpose: To have a program that is able to collect and use all of the sensors and devices intended
+for our project. In this code, it will read the GPS and RTC for time, then read the BME for temperature
+and write it and the name of a picture taken to an SD Card), all while the LCD is displaying updates on
+what task is currently being underwent and how many pictures/iterations of the loop have successfully executed.
+
+We spent around 12 hours total on this project, and referenced previous homeworks, online adafruit/arduino fourms,
+and the provided test code on the 371 website. The data graph/mean/standard deviation is found in the excel file.
+*/
+#include <Wire.h>
+#include <SPI.h>
+#include <Adafruit_Sensor.h>
+#include "Adafruit_BME680.h"
+#include <LiquidCrystal.h>
+#include <TimeLib.h>
+#include <DS1307RTC.h>
+#include <Keypad.h>
+#include "SdFat.h"
+#include <Adafruit_VC0706.h>
+//#include <SD.h>
+#include <Adafruit_GPS.h>
+#include "RTClib.h"
+RTC_DS3231 rtc;
+//GPS
+#define GPSSerial Serial1
+#define GPSECHO1 false
+#define GPSECHO2 false
+#define GPSECHO3 false
+#define PMTK_SET_NMEA_UPDATE_10SEC "$PMTK220,10000*2F"
+#define PMTK_SET_NMEA_UPDATE_5SEC "$PMTK220,5000*2F"
+#define PMTK_SET_NMEA_UPDATE_1HZ  "$PMTK220,1000*1F"
+#define PMTK_SET_NMEA_UPDATE_2HZ  "$PMTK220,500*2B"
+#define PMTK_SET_NMEA_UPDATE_5HZ  "$PMTK220,200*2C"
+
+//SNAPSHOT
+#if defined(__AVR__) || defined(ESP8266)
+#include <SoftwareSerial.h>         
+SoftwareSerial cameraconnection(69, 3);
+#else
+#define cameraconnection Serial1
+
+#endif
+#define chipSelect 53
+
+//BME SD
+#define BME_SCK 13
+#define BME_MISO 12
+#define BME_MOSI 11
+#define BME_CS 10
+#define SD_CS_PIN SS
+#define SEALEVELPRESSURE_HPA (1013.25)
+Adafruit_VC0706 cam = Adafruit_VC0706(&cameraconnection);
+#define GPSMINLENGTH 55
+#define GPSMAXLENGTH 120
+Adafruit_GPS GPS(&GPSSerial);
+char* GPS_sentence;
+String GPS_sentence_string;
+const int GPRMC_hour_index1 = 8;
+const int GPRMC_hour_index2 = GPRMC_hour_index1 + 2;
+
+const int GPRMC_minutes_index1 = GPRMC_hour_index2;
+const int GPRMC_minutes_index2 = GPRMC_minutes_index1 + 2;
+      
+const int GPRMC_seconds_index1 = GPRMC_minutes_index2;
+const int GPRMC_seconds_index2 = GPRMC_seconds_index1 + 2;
+      
+const int GPRMC_milliseconds_index1 = GPRMC_seconds_index2 + 1;   // skip the decimal point
+const int GPRMC_milliseconds_index2 = GPRMC_milliseconds_index1 + 3;
+      
+const int GPRMC_AV_code_index1 = 19;
+const int GPRMC_AV_code_index2 = GPRMC_AV_code_index1 + 1;
+      
+const int GPRMC_latitude_1_index1 = 21;
+const int GPRMC_latitude_1_index2 = GPRMC_latitude_1_index1 + 4;
+      
+const int GPRMC_latitude_2_index1 = GPRMC_latitude_1_index2 + 1;   // skip the decimal point
+const int GPRMC_latitude_2_index2 = GPRMC_latitude_2_index1 + 4;
+
+const int GPRMC_latitude_NS_index1 = 31;
+const int GPRMC_latitude_NS_index2 = GPRMC_latitude_NS_index1 + 1;
+
+const int GPRMC_longitude_1_index1 = 33;
+const int GPRMC_longitude_1_index2 = GPRMC_longitude_1_index1 + 5;    // 0 - 180 so we need an extra digit
+      
+const int GPRMC_longitude_2_index1 = GPRMC_longitude_1_index2 + 1;   // skip the decimal point
+const int GPRMC_longitude_2_index2 = GPRMC_longitude_2_index1 + 4;
+      
+const int GPRMC_longitude_EW_index1 = 44;
+const int GPRMC_longitude_EW_index2 = GPRMC_longitude_EW_index1 + 1;
+
+// pointers into a GPGGA GPS data sentence:
+
+const int GPGGA_hour_index1 = 8;
+const int GPGGA_hour_index2 = GPGGA_hour_index1 + 2;
+
+const int GPGGA_minutes_index1 = GPGGA_hour_index2;
+const int GPGGA_minutes_index2 = GPGGA_minutes_index1 + 2;
+      
+const int GPGGA_seconds_index1 = GPGGA_minutes_index2;
+const int GPGGA_seconds_index2 = GPGGA_seconds_index1 + 2;
+      
+const int GPGGA_milliseconds_index1 = GPGGA_seconds_index2 + 1;   // skip the decimal point
+const int GPGGA_milliseconds_index2 = GPGGA_milliseconds_index1 + 3;
+      
+const int GPGGA_latitude_1_index1 = 19;
+const int GPGGA_latitude_1_index2 = GPGGA_latitude_1_index1 + 4;
+      
+const int GPGGA_latitude_2_index1 = GPGGA_latitude_1_index2 + 1;   // skip the decimal point
+const int GPGGA_latitude_2_index2 = GPGGA_latitude_2_index1 + 4;
+
+const int GPGGA_latitude_NS_index1 = 29;
+const int GPGGA_latitude_NS_index2 = GPGGA_latitude_NS_index1 + 1;
+
+const int GPGGA_longitude_1_index1 = 31;
+const int GPGGA_longitude_1_index2 = GPGGA_longitude_1_index1 + 5;    // 0 - 180 so we need an extra digit
+      
+const int GPGGA_longitude_2_index1 = GPGGA_longitude_1_index2 + 1;   // skip the decimal point
+const int GPGGA_longitude_2_index2 = GPGGA_longitude_2_index1 + 4;
+      
+const int GPGGA_longitude_EW_index1 = 42;
+const int GPGGA_longitude_EW_index2 = GPGGA_longitude_EW_index1 + 1;
+
+const int GPGGA_fix_quality_index1 = 44;
+const int GPGGA_fix_quality_index2 = GPGGA_fix_quality_index1 + 1;
+
+const int GPGGA_satellites_index1 = 46;
+const int GPGGA_satellites_index2 = GPGGA_satellites_index1 + 2;
+
+// keep track of how many times we've read a character from the GPS device. 
+long GPS_char_reads = 0;
+
+// bail out if we exceed the following number of attempts. when set to 1,000,000 this corresponds
+// to about 6 seconds. we need to do this to keep an unresponsive GPS device from hanging the program.
+const long GPS_char_reads_maximum = 1000000;
+
+// define some of the (self-explanatory) GPS data variables. Times/dates are UTC.
+String GPS_hour_string;
+String GPS_minutes_string;
+String GPS_seconds_string;
+String GPS_milliseconds_string;
+int GPS_hour;
+int GPS_minutes;
+int GPS_seconds;
+int GPS_milliseconds;
+
+// this one tells us about data validity: A is good, V is invalid.
+String GPS_AV_code_string;
+
+// latitude data
+String GPS_latitude_1_string;
+String GPS_latitude_2_string;
+String GPS_latitude_NS_string;
+int GPS_latitude_1;
+int GPS_latitude_2;
+
+// longitude data
+String GPS_longitude_1_string;
+String GPS_longitude_2_string;
+String GPS_longitude_EW_string;
+int GPS_longitude_1;
+int GPS_longitude_2;
+
+// velocity information; speed is in knots! 
+String GPS_speed_knots_string;
+String GPS_direction_string;
+float GPS_speed_knots;
+float GPS_direction;
+
+String GPS_date_string;
+
+String GPS_fix_quality_string;
+String GPS_satellites_string;
+int GPS_fix_quality;
+int GPS_satellites;
+
+String GPS_altitude_string;
+float GPS_altitude;
+String GPS_command;
+char daysOfTheWeek[7][4] = 
+  {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
+int RTC_hour, RTC_minute, RTC_second;
+int RTC_year, RTC_month, RTC_day_of_month;
+bool already_set_RTC_from_GPS;
+
+
+SdFat SD_thingy;
+File myFiley;
+
+char filename[ ] = "data.csv";
+
+const char *monthName[12] = {
+  "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+};
+tmElements_t tm;
+Adafruit_BME680 bme; // I2C
+const byte ROWS = 4; 
+const byte COLS = 3;
+
+char keys[ROWS][COLS] = {
+{'1','2','3'},
+{'4','5','6'},
+{'7','8','9'},
+{'*','0','#'}
+};
+bool getTime(const char *str)
+{
+  int Hour, Min, Sec;
+
+  if (sscanf(str, "%d:%d:%d", &Hour, &Min, &Sec) != 3) return false;
+  tm.Hour = Hour;
+  tm.Minute = Min;
+  tm.Second = Sec;
+  return true;
+}
+
+bool getDate(const char *str)
+{
+  char Month[12];
+  int Day, Year;
+  uint8_t monthIndex;
+
+  if (sscanf(str, "%s %d %d", Month, &Day, &Year) != 3) return false;
+  for (monthIndex = 0; monthIndex < 12; monthIndex++) {
+    if (strcmp(Month, monthName[monthIndex]) == 0) break;
+  }
+  if (monthIndex >= 12) return false;
+  tm.Day = Day;
+  tm.Month = monthIndex + 1;
+  tm.Year = CalendarYrToTm(Year);
+  return true;
+}
+byte Arduino_colPins[COLS] = {2, 3, 18}; 
+byte Arduino_rowPins[ROWS] = {31, 33, 35, 37};
+Keypad kpd = Keypad( makeKeymap(keys), Arduino_rowPins, Arduino_colPins, ROWS, COLS );
+
+const int rs = 12, en = 11, data4 = 36, data5 = 34, data6 = 32, data7 = 30;
+LiquidCrystal lcd(rs, en, data4, data5, data6, data7);
+
+
+void setup() {
+    if (!bme.begin()) {
+    Serial.println("Could not find a valid BME680 sensor, check wiring!");
+    while (1);
+  bme.setTemperatureOversampling(BME680_OS_8X);
+  bme.setHumidityOversampling(BME680_OS_2X);
+  bme.setPressureOversampling(BME680_OS_4X);
+  bme.setIIRFilterSize(BME680_FILTER_SIZE_3);
+  bme.setGasHeater(320, 150); // 320*C for 150 ms
+
+  }
+  //HW 2
+  bool parse=false;
+  bool config=false;
+
+  // get the date and time the compiler was run
+  if (getDate(__DATE__) && getTime(__TIME__)) {
+    parse = true;
+    // and configure the RTC with this info
+    if (RTC.write(tm)) {
+      config = true;
+    }
+  }
+  Serial.begin(115200);
+  while (!Serial);
+  Serial.println(F("BME680 test"));
+
+  if (!bme.begin()) {
+    Serial.println("Could not find a valid BME680 sensor, check wiring!");
+    while (1);
+  }
+
+  // Set up oversampling and filter initialization
+  bme.setTemperatureOversampling(BME680_OS_8X);
+  bme.setHumidityOversampling(BME680_OS_2X);
+  bme.setPressureOversampling(BME680_OS_4X);
+  bme.setIIRFilterSize(BME680_FILTER_SIZE_3);
+  bme.setGasHeater(320, 150); // 320*C for 150 ms
+
+    lcd.begin(16, 2);
+    Serial.println("About to write to LCD.");
+      Serial.println("LCD lines are 16 characters long.");
+       while (!Serial) ; // wait for Arduino Serial Monitor
+  delay(200);
+  if (parse && config) {
+    Serial.print("DS1307 configured Time=");
+    Serial.print(__TIME__);
+    Serial.print(", Date=");
+    Serial.println(__DATE__);
+  } else if (parse) {
+    Serial.println("DS1307 Communication Error :-{");
+    Serial.println("Please check your circuitry");
+  } else {
+    Serial.print("Could not parse info from the compiler, Time=\"");
+    Serial.print(__TIME__);
+    Serial.print("\", Date=\"");
+    Serial.print(__DATE__);
+    Serial.println("\"");
+  }
+  //HW 2 DONE
+
+  //camera begin
+  #if !defined(SOFTWARE_SPI)
+#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
+  if(chipSelect != 53) pinMode(53, OUTPUT); // SS on Mega
+#else
+  if(chipSelect != 10) pinMode(10, OUTPUT); // SS on Uno, etc.
+#endif
+#endif
+
+
+  Serial.println("VC0706 Camera snapshot test");
+  
+  // see if the card is present and can be initialized:
+  if (!SD_thingy.begin(chipSelect)) {
+    Serial.println("Card failed, or not present");
+    // don't do anything more:
+    return;
+  }  
+  
+  // Try to locate the camera
+  if (cam.begin()) {
+    Serial.println("Camera Found:");
+  } else {
+    Serial.println("No camera found?");
+    return;
+  }
+  // Print out the camera version information (optional)
+  char *reply = cam.getVersion();
+  if (reply == 0) {
+    Serial.print("Failed to get version");
+  } else {
+    Serial.println("-----------------");
+    Serial.print(reply);
+    Serial.println("-----------------");
+  }
+  //CAMERA END
+
+  //GPS BEGIN
+  GPS.begin(9600);
+  
+  // turn on RMC (recommended minimum) and GGA (fix data, including altitude)
+  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
+    GPS.sendCommand(PMTK_SET_NMEA_UPDATE_5HZ); 
+}
+void updateTime() {
+   Serial.println("Setting the RTC Date");
+       bool parse=false;
+  bool config=false;
+  if (getDate(__DATE__) && getTime(__TIME__)) {
+    parse = true;
+    if (RTC.write(tm)) {
+      config = true;
+    }
+     while (!Serial);
+  delay(200);
+  if (parse && config) {
+    Serial.print("DS1307 configured Time=");
+    Serial.print(__TIME__);
+    Serial.print(", Date=");
+    Serial.println(__DATE__);
+  } else if (parse) {
+    Serial.println("DS1307 Communication Error :-{");
+    Serial.println("Please check your circuitry");
+  } else {
+    Serial.print("Could not parse info from the compiler, Time=\"");
+    Serial.print(__TIME__);
+    Serial.print("\", Date=\"");
+    Serial.print(__DATE__);
+    Serial.println("\"");
+  }
+  }
+}
+void writeCSV(String picname, String speed_knots, String direction) {
+    Serial.println("opening the csv file");
+        while (!Serial) { }
+  Serial.print("Initializing SD card reading software... ");
+  if (!SD_thingy.begin(SD_CS_PIN)) {
+    Serial.println("SD initialization failed!");
+    delay(100);
+    exit(0);
+  }
+  /*
+  Serial.println("initialization done.");
+  if(SD_thingy.exists(filename)) { 
+    SD_thingy.remove(filename); 
+    delay(100);   
+    }
+    */
+  myFiley = SD_thingy.open(filename, FILE_WRITE);
+  if (myFiley) {
+    Serial.print("Writing to "); Serial.print(filename); Serial.println("...");    
+    } else {   
+    Serial.print("error opening "); Serial.println(filename); 
+    delay(100);
+    exit(0);
+    }
+    myFiley.print(__TIME__);myFiley.print(",");myFiley.print(__DATE__);myFiley.print(",");myFiley.print(picname);myFiley.print(",");myFiley.print(speed_knots);myFiley.print(",");myFiley.println(direction);
+  Serial.println("Finished writing to file. Now close it, open it, read it.");
+  lcd.setCursor(0,1);
+  lcd.print("Closing");
+  myFiley.close();
+}
+String picturename = "IMAGE00.JPG";
+void getphoto() {
+  cam.setImageSize(VC0706_640x480);        // biggest
+  //cam.setImageSize(VC0706_320x240);        // medium
+  //cam.setImageSize(VC0706_160x120);          // small
+
+  // You can read the size back from the camera (optional, but maybe useful?)
+  uint8_t imgsize = cam.getImageSize();
+  Serial.print("Image size: ");
+  if (imgsize == VC0706_640x480) Serial.println("640x480");
+  if (imgsize == VC0706_320x240) Serial.println("320x240");
+  if (imgsize == VC0706_160x120) Serial.println("160x120");
+
+  Serial.println("Snap in 3 secs...");
+    lcd.setCursor(0,1);
+  lcd.print("Taking pic");
+  delay(3000);
+
+  if (! cam.takePicture()) 
+    Serial.println("Failed to snap!");
+  else 
+    Serial.println("Picture taken!");
+      lcd.setCursor(0,1);
+    lcd.print("Pic taken!");
+  
+  // Create an image with the name IMAGExx.JPG
+  char picname[13];
+  strcpy(picname, "IMAGE00.JPG");
+  for (int i = 0; i < 100; i++) {
+    picname[5] = '0' + i/10;
+    picname[6] = '0' + i%10;
+    picturename[5] = '0' + i/10;
+    picturename[6] = '0' + i%10;
+
+    // create if does not exist, do not open existing, write, sync after write
+    if (! SD_thingy.exists(picname)) {
+      break;
+    }
+  }
+  
+  // Open the file for writing
+  File imgFile = SD_thingy.open(picname, FILE_WRITE);
+
+  // Get the size of the image (frame) taken  
+  uint32_t jpglen = cam.frameLength();
+  Serial.print("Storing ");
+    lcd.setCursor(0,1);
+  lcd.print("Storing");
+  Serial.print(jpglen, DEC);
+  Serial.print(" byte image.");
+
+  int32_t time = millis();
+  pinMode(8, OUTPUT);
+  // Read all the data up to # bytes!
+  byte wCount = 0; // For counting # of writes
+  while (jpglen > 0) {
+    // read 32 bytes at a time;
+    uint8_t *buffer;
+    uint8_t bytesToRead = min((uint32_t)32, jpglen); // change 32 to 64 for a speedup but may not work with all setups!
+    buffer = cam.readPicture(bytesToRead);
+    imgFile.write(buffer, bytesToRead);
+    if(++wCount >= 64) { // Every 2K, give a little feedback so it doesn't appear locked up
+      Serial.print('.');
+      wCount = 0;
+    }
+    //Serial.print("Read ");  Serial.print(bytesToRead, DEC); Serial.println(" bytes");
+    jpglen -= bytesToRead;
+  }
+  imgFile.close();
+
+  time = millis() - time;
+  Serial.println("done!");
+  lcd.setCursor(0,1);
+  lcd.print("Done!");
+  Serial.print(time); Serial.println(" ms elapsed");
+}
+
+int count = 0;
+void loop() {
+  updateTime();
+if (! bme.performReading()) {
+    Serial.println("Failed to perform reading :(");
+    return;
+  }
+
+
+
+GPS_query();
+Serial.println(GPS_minutes * 60 + GPS_seconds);
+Serial.print("TIME: ");Serial.println(__TIME__);
+
+
+lcd.setCursor(0,0);
+lcd.print("Entries: ");lcd.print(count);
+getphoto();
+Serial.println(picturename);
+float BME_temp = bme.temperature;
+Serial.println(BME_temp);
+float GPS_second = GPS_minutes * 60 + GPS_seconds; 
+writeCSV(picturename,(String)GPS_second,(String)BME_temp);
+  delay(1000);
+
+Serial.println("pic taken");
+count++;
+delay(1000);
+
+}
+int GPS_query()
+{
+
+  // return 0 if we found good GPS navigational data and -1 if not.
+  
+  // The GPS device has its own microprocessor and, once we have loaded its parameters,
+  // free-runs at a 1 Hz sampling rate. We do not trigger its registration of
+  // latitude and longitude, rather we just read from it the last data record
+  // it has stored. And we do it one character at a time!
+
+  // I will keep reading from the GPS until I have a complete sentence carrying valid
+  // navigational data, with a maximum number of reads to prevent the program from hanging. Once
+  // the GPS reports its updates latitude/longitude information, we'll push this to the 
+  // LCD display, then return to the main loop. 
+   
+  // zero out (or set to defaults) values returned by the GPS device in case we can't 
+  // get it to respond.
+  GPS_hour = GPS_minutes = GPS_seconds = GPS_milliseconds = 0;
+
+  GPS_AV_code_string = "V";
+
+  GPS_latitude_1 = GPS_latitude_2 = 0;
+  GPS_latitude_NS_string = "x";
+  
+  GPS_longitude_1 = GPS_longitude_2 = 0;
+  GPS_longitude_EW_string = "y";
+    
+  GPS_speed_knots = 0.;
+  GPS_direction = 0.;
+    
+  GPS_date_string = "000000";
+  
+  GPS_fix_quality = GPS_satellites = 0;
+  
+  GPS_altitude = 0.;
+
+  // initialize the number-of-reads counter since we might find ourselves
+  // with an unparseable data record, or an unresponsive GPS, and want to keep trying.
+  // This will let me protect against the data logger's program hanging. 
+  GPS_char_reads = 0;
+
+  // set a flag saying we want to keep trying; we'll use this to keep looking for
+  // useful navigation when the GPS is working fine, but still looking for satellites.
+  bool keep_trying = true;
+  
+  // Stay inside the following loop until we've read a complete GPS sentence with
+  // good navigational data, or else the loop times out. With GPS_char_reads_maximum 
+  // set to a million this'll take about 6 seconds to time out. 
+  
+  while (true) {
+  
+    // if we get back to this point but the keep_trying flag is false, we'll want
+    // to declare failure and quit.
+
+    if(!keep_trying) return -1;
+    
+    // this gets the last sentence read from GPS and clears a newline flag in the Adafruit 
+    // library code.
+    GPS_sentence = GPS.lastNMEA();
+    Serial.println("printing raw");
+
+  
+    while(GPS_char_reads <= GPS_char_reads_maximum) 
+      {
+  
+      // try to read a single character from the GPS device.
+      char single_GPS_char = GPS.read();
+  
+      // bump the number of times we've tried to read from the GPS.
+      GPS_char_reads++;
+  
+      // now ask if we've received a complete data sentence. If yes, break
+      // out of this loop.
+  
+      if(GPS.newNMEAreceived()) break;
+  
+      }
+  
+          
+    // if we hit the limit on the number of character reads we'e tried, print a message and bail out.
+    if (GPS_char_reads >= GPS_char_reads_maximum) 
+      {
+Serial.println(GPS_sentence);
+      keep_trying = false;
+      
+      Serial.println("GPS navigation data not yet available. Try again later.");
+    
+        
+      return -1;
+        
+      }
+
+    // get the last complete sentence read from GP; this automatically clears a newline flag inside 
+    // the Adafruit library code.
+    GPS_sentence = GPS.lastNMEA();
+    
+    // convert GPS data sentence from a character array to a string.
+    GPS_sentence_string = String(GPS_sentence);
+  
+    // now do a cursory check that the sentence we've just read is OK. Check that there is only
+    // one $, as the first character in the sentence, and that there's an asterisk (which commes 
+    // immediately before the checksum).
+     
+    // sentence starts with a $? 
+    bool data_OK = GPS_sentence_string.charAt(0) == '$';    
+  
+    // sentence contains no other $? The indexOf call will return -1 if $ is not found.
+    data_OK = data_OK && (GPS_sentence_string.indexOf('$', 2) <  0);
+    
+    // now find that asterisk...
+    data_OK = data_OK && (GPS_sentence_string.indexOf('*', 0) >  0);
+  
+    if (GPSECHO1) 
+      {
+      Serial.println("\n******************\njust received a complete sentence, so parse stuff. Sentence is");
+      Serial.println(GPS_sentence_string);
+      }
+  
+    // now parse the GPS sentence. I am only interested in sentences that begin with
+    // $GPGGA ("GPS fix data") or $GPRMC ("recommended minimum specific GPS/Transit data").
+  
+    if(GPSECHO1)
+      {
+      Serial.print("length of GPS_sentence_string just received...");
+      Serial.println(GPS_sentence_string.length());
+      }
+  
+    // now get substring holding the GPS command. Only proceed if it is $GPRMC or $GPGGA.
+    GPS_command = GPS_sentence_string.substring(0, 6);
+  
+    // also trim it to make sure we don't have hidden stuff or white space sneaking in.
+    GPS_command.trim();
+  
+    if(GPSECHO1) 
+      {
+      Serial.print("GPS command is "); Serial.println(GPS_command);
+      }   
+  
+    // if data_OK is true then we have a good sentence. but we also need the sentence
+    // to hold navigational data we can use, otherwise we'll want to keep listening.
+    // we can only work with GPRMC and GPGGA sentences. 
+  
+    bool command_OK = GPS_command.equals("$GPRMC") || GPS_command.equals("$GPGGA"); 
+    
+    // if we have a sentence that, upon cursory inspection, is well formatted AND might
+    // hold navigational data, continue to parse the sentence. If the GPS device
+    // hasn't found any satellites yet, we'll want to go back to the top of the loop
+    // to keep trying, rather than declaring defeat and returning.
+  
+    //////////////////////////////////////////////////////////////////////
+    /////////////////////////// GPRMC sentence ///////////////////////////
+    //////////////////////////////////////////////////////////////////////
+    
+     if (data_OK && GPS_command.equals("$GPRMC"))
+        {
+            
+        if(GPSECHO2) 
+          {
+          Serial.print("\nnew GPS sentence: "); Serial.println(GPS_sentence_string);
+          }
+    
+        // parse the time. these are global variables, already declared.
+
+        GPS_hour_string = GPS_sentence_string.substring(GPRMC_hour_index1, GPRMC_hour_index2);
+        GPS_minutes_string = GPS_sentence_string.substring(GPRMC_minutes_index1, GPRMC_minutes_index2);
+        GPS_seconds_string = GPS_sentence_string.substring(GPRMC_seconds_index1, GPRMC_seconds_index2);
+        GPS_milliseconds_string = GPS_sentence_string.substring(GPRMC_milliseconds_index1, 
+          GPRMC_milliseconds_index2);
+        GPS_AV_code_string = GPS_sentence_string.substring(GPRMC_AV_code_index1, GPRMC_AV_code_index2);
+    
+        GPS_hour = GPS_hour_string.toInt();
+        GPS_minutes = GPS_minutes_string.toInt();
+        GPS_seconds = GPS_seconds_string.toInt();
+        GPS_milliseconds = GPS_milliseconds_string.toInt();
+    
+        if(GPSECHO2)
+          {
+          Serial.print("Time (UTC) = "); Serial.print(GPS_hour); Serial.print(":");
+          Serial.print(GPS_minutes); Serial.print(":");
+          Serial.print(GPS_seconds); Serial.print(".");
+          Serial.println(GPS_milliseconds);
+          Serial.print("A/V code is "); Serial.println(GPS_AV_code_string);
+          }
+    
+        // now see if the data are valid: we'll expect an "A" as the AV code string.
+        // We also expect an asterisk two characters from the end. Also check that the sentence 
+        // is at least as long as the minimum length expected.
+    
+        data_OK = GPS_AV_code_string == "A";
+    
+        // now look for the asterisk after trimming any trailing whitespace in the GPS sentence.
+        // the asterisk preceeds the sentence's checksum information, which I won't bother to check.
+        int asterisk_should_be_here = GPS_sentence_string.length() - 4; 
+    
+        data_OK = data_OK && (GPS_sentence_string.charAt(asterisk_should_be_here) == '*');
+
+        if(GPSECHO2)
+          {
+          Serial.print("expected asterisk position "); Serial.print(asterisk_should_be_here); 
+          Serial.print(" at that position: "); Serial.println(GPS_sentence_string.charAt(asterisk_should_be_here));
+          }
+    
+        // now check that the sentence is not too short.      
+        data_OK = data_OK && (GPS_sentence_string.length() >= GPSMINLENGTH);
+    
+        if (!data_OK) 
+          {
+
+          keep_trying = true;
+           
+          if (GPSECHO1)
+            {
+            Serial.print("GPS sentence not good for navigation: "); Serial.println(GPS_sentence_string);
+            Serial.println("I will keep trying...");
+            }
+            
+ 
+          }
+    
+        // if data are not good, go back to the top of the loop by breaking out of this if block.
+        // we've already set keep_trying to be true.
+        
+        if (!data_OK) break;
+            
+        // so far so good, so keep going...
+        
+        // now parse latitude 
+        
+        GPS_latitude_1_string = GPS_sentence_string.substring(GPRMC_latitude_1_index1, 
+          GPRMC_latitude_1_index2);
+        GPS_latitude_2_string = GPS_sentence_string.substring(GPRMC_latitude_2_index1, 
+          GPRMC_latitude_2_index2);
+        GPS_latitude_NS_string = GPS_sentence_string.substring(GPRMC_latitude_NS_index1, 
+          GPRMC_latitude_NS_index2);
+    
+        GPS_latitude_1 = GPS_latitude_1_string.toInt();      
+        GPS_latitude_2 = GPS_latitude_2_string.toInt();      
+    
+        if(GPSECHO2)
+          {
+          Serial.print("Latitude x 100 = "); Serial.print(GPS_latitude_1); Serial.print(".");
+          Serial.print(GPS_latitude_2); Serial.println(GPS_latitude_NS_string);
+          }
+          
+        // now parse longitude 
+        
+        GPS_longitude_1_string = GPS_sentence_string.substring(GPRMC_longitude_1_index1, 
+          GPRMC_longitude_1_index2);
+        GPS_longitude_2_string = GPS_sentence_string.substring(GPRMC_longitude_2_index1, 
+          GPRMC_longitude_2_index2);
+        GPS_longitude_EW_string = GPS_sentence_string.substring(GPRMC_longitude_EW_index1, 
+          GPRMC_longitude_EW_index2);
+    
+        GPS_longitude_1 = GPS_longitude_1_string.toInt();      
+        GPS_longitude_2 = GPS_longitude_2_string.toInt();      
+          
+        if(GPSECHO2)
+          {
+          Serial.print("Longitude x 100 = "); Serial.print(GPS_longitude_1); Serial.print(".");
+          Serial.print(GPS_longitude_2); Serial.println(GPS_longitude_EW_string); 
+          }
+    
+        // now parse speed and direction. we'll need to locate the 7th and 8th commas in the
+        // data sentence to do this. so use the indexOf function to find them.
+        // it returns -1 if string wasn't found. the number of digits is not uniquely defined 
+        // so we need to find the fields based on the commas separating them from others.
+        
+        int comma_A_index = GPRMC_longitude_EW_index2;
+        int comma_B_index = GPS_sentence_string.indexOf(",", comma_A_index + 1);
+        int comma_C_index = GPS_sentence_string.indexOf(",", comma_B_index + 1);
+    
+        GPS_speed_knots_string = GPS_sentence_string.substring(comma_A_index + 1, comma_B_index); 
+        GPS_direction_string = GPS_sentence_string.substring(comma_B_index + 1, comma_C_index); 
+        
+        GPS_speed_knots = GPS_speed_knots_string.toFloat();
+        GPS_direction = GPS_direction_string.toFloat();
+    
+        if(GPSECHO2)
+          {
+          Serial.print("Speed (knots) = "); Serial.println(GPS_speed_knots);
+          Serial.print("Direction (degrees) = "); Serial.println(GPS_direction);
+          }
+          
+        // now get the (UTC) date, in format DDMMYY, e.g. 080618 for 8 June 2018.
+        GPS_date_string = GPS_sentence_string.substring(comma_C_index+ + 1, comma_C_index + 7);
+        
+        if(GPSECHO2)
+          {
+          Serial.print("date, in format ddmmyy = "); Serial.println(GPS_date_string);    
+          }
+    
+        // Write message to LCD now. It will look like this (no satellite data in this record):
+        //     Sats: 4006.9539N
+        //     N/A  08815.4431W
+
+
+        // print a summary of the data and parsed results:
+        if(GPSECHO3)
+          {
+          Serial.print("GPS sentence: "); Serial.println(GPS_sentence_string);
+
+          Serial.print("Time (UTC) = "); Serial.print(GPS_hour); Serial.print(":");
+          Serial.print(GPS_minutes); Serial.print(":");
+          Serial.print(GPS_seconds); Serial.print(".");
+          Serial.println(GPS_milliseconds);
+        
+          Serial.print("Latitude x 100 = "); Serial.print(GPS_latitude_1); Serial.print(".");
+          Serial.print(GPS_latitude_2); Serial.print(" "); Serial.print(GPS_latitude_NS_string);
+
+          Serial.print("    Longitude x 100 = "); Serial.print(GPS_longitude_1); Serial.print(".");
+          Serial.print(GPS_longitude_2); Serial.print(" "); Serial.println(GPS_longitude_EW_string); 
+
+          Serial.print("Speed (knots) = "); Serial.print(GPS_speed_knots);
+          Serial.print("     Direction (degrees) = "); Serial.println(GPS_direction);
+
+          Serial.println("There is no satellite or altitude information in a GPRMC data sentence.");
+              
+          }
+      
+        // all done with this sentence, so return.
+        return 0;
+          
+        }  // end of "if (data_OK && GPS_command.equals("$GPRMC"))" block
+
+    //////////////////////////////////////////////////////////////////////
+    /////////////////////////// GPGGA sentence ///////////////////////////
+    //////////////////////////////////////////////////////////////////////
+    
+      if (data_OK && GPS_command.equals("$GPGGA"))
+        {
+
+        if(GPSECHO2) 
+          {
+          Serial.print("\nnew GPS sentence: "); Serial.println(GPS_sentence_string);
+          }
+    
+        // parse the time
+    
+        GPS_hour_string = GPS_sentence_string.substring(GPGGA_hour_index1, GPGGA_hour_index2);
+        GPS_minutes_string = GPS_sentence_string.substring(GPGGA_minutes_index1, GPGGA_minutes_index2);
+        GPS_seconds_string = GPS_sentence_string.substring(GPGGA_seconds_index1, GPGGA_seconds_index2);
+        GPS_milliseconds_string = GPS_sentence_string.substring(GPGGA_milliseconds_index1, 
+          GPGGA_milliseconds_index2);
+    
+        GPS_hour = GPS_hour_string.toInt();
+        GPS_minutes = GPS_minutes_string.toInt();
+        GPS_seconds = GPS_seconds_string.toInt();
+        GPS_milliseconds = GPS_milliseconds_string.toInt();
+    
+        if(GPSECHO2)
+          {
+          Serial.print("Time (UTC) = "); Serial.print(GPS_hour); Serial.print(":");
+          Serial.print(GPS_minutes); Serial.print(":");
+          Serial.print(GPS_seconds); Serial.print(".");
+          Serial.println(GPS_milliseconds);
+          }
+    
+        // now get the fix quality and number of satellites.
+    
+        GPS_fix_quality_string = GPS_sentence_string.substring(GPGGA_fix_quality_index1, 
+          GPGGA_fix_quality_index2);
+        GPS_satellites_string = GPS_sentence_string.substring(GPGGA_satellites_index1, 
+          GPGGA_satellites_index2);
+    
+        int GPS_fix_quality = GPS_fix_quality_string.toInt();      
+        int GPS_satellites = GPS_satellites_string.toInt();      
+    
+        if(GPSECHO2)
+          {
+          Serial.print("fix quality (1 for GPS, 2 for DGPS) = "); Serial.println(GPS_fix_quality);
+          Serial.print("number of satellites = "); Serial.println(GPS_satellites);
+          }
+    
+        // now see if the data are valid: we'll expect a fix, and at least three satellites.
+    
+        bool data_OK = (GPS_fix_quality > 0) && (GPS_satellites >= 3); 
+    
+        // now look for the asterisk.
+        int asterisk_should_be_here = GPS_sentence_string.length() - 4; 
+    
+        data_OK = data_OK && (GPS_sentence_string.charAt(asterisk_should_be_here) == '*');
+    
+        // now check that the sentence is not too short.      
+        data_OK = data_OK && (GPS_sentence_string.length() >= GPSMINLENGTH);
+
+        if (!data_OK) 
+          {
+
+          keep_trying = true;
+           
+          if (GPSECHO1)
+            {
+            Serial.print("GPS sentence not good for navigation: "); Serial.println(GPS_sentence_string);
+            Serial.println("I will keep trying...");
+            }
+
+          }
+    
+        // if data are not good, go back to the top of the loop by breaking out of this if block.
+        
+        if (!data_OK) break;
+            
+        // so far so good, so keep going...
+        
+        // now parse latitude 
+        
+        String GPS_latitude_1_string = GPS_sentence_string.substring(GPGGA_latitude_1_index1, 
+        GPGGA_latitude_1_index2);
+        String GPS_latitude_2_string = GPS_sentence_string.substring(GPGGA_latitude_2_index1, 
+        GPGGA_latitude_2_index2);
+        String GPS_latitude_NS_string = GPS_sentence_string.substring(GPGGA_latitude_NS_index1, 
+        GPGGA_latitude_NS_index2);
+    
+        int GPS_latitude_1 = GPS_latitude_1_string.toInt();      
+        int GPS_latitude_2 = GPS_latitude_2_string.toInt();      
+    
+        if(GPSECHO2)
+          {
+          Serial.print("Latitude x 100 = "); Serial.print(GPS_latitude_1); Serial.print(".");
+          Serial.print(GPS_latitude_2); Serial.println(GPS_latitude_NS_string);
+          }
+          
+        // now parse longitude 
+        
+        String GPS_longitude_1_string = GPS_sentence_string.substring(GPGGA_longitude_1_index1, 
+        GPGGA_longitude_1_index2);
+        String GPS_longitude_2_string = GPS_sentence_string.substring(GPGGA_longitude_2_index1, 
+        GPGGA_longitude_2_index2);
+        String GPS_longitude_EW_string = GPS_sentence_string.substring(GPGGA_longitude_EW_index1, 
+        GPGGA_longitude_EW_index2);
+    
+        int GPS_longitude_1 = GPS_longitude_1_string.toInt();      
+        int GPS_longitude_2 = GPS_longitude_2_string.toInt();      
+    
+        if(GPSECHO2)
+          {         
+          Serial.print("Longitude x 100 = "); Serial.print(GPS_longitude_1); Serial.print(".");
+          Serial.print(GPS_longitude_2); Serial.println(GPS_longitude_EW_string); 
+          }
+          
+        // let's skip the "horizontal dilution" figure and go straight for the altitude now.
+        // this begins two fields to the right of the num,ber of satellites so find this
+        // by counting commas. use the indexOf function to find them.
+        int comma_A_index = GPS_sentence_string.indexOf(",", GPGGA_satellites_index2 + 1);
+        int comma_B_index = GPS_sentence_string.indexOf(",", comma_A_index + 1);
+    
+        String GPS_altitude_string = GPS_sentence_string.substring(comma_A_index + 1, comma_B_index); 
+        
+        float GPS_altitude = GPS_altitude_string.toFloat();
+    
+        if(GPSECHO2)
+          {
+          Serial.print("Altitude (meters) = "); Serial.println(GPS_altitude);
+          }
+    
+        // Write message to LCD now. It will look like this:
+        //     Sats: 4006.9539N
+        //       10 08815.4431W
+             
+
+        // print a summary of the data and parsed results:
+        if(GPSECHO3)
+          {
+          Serial.print("GPS sentence: "); Serial.println(GPS_sentence_string);
+
+          Serial.print("Time (UTC) = "); Serial.print(GPS_hour); Serial.print(":");
+          Serial.print(GPS_minutes); Serial.print(":");
+          Serial.print(GPS_seconds); Serial.print(".");
+          Serial.println(GPS_milliseconds);
+        
+          Serial.print("Latitude x 100 = "); Serial.print(GPS_latitude_1); Serial.print(".");
+          Serial.print(GPS_latitude_2); Serial.print(" "); Serial.print(GPS_latitude_NS_string);
+
+          Serial.print("    Longitude x 100 = "); Serial.print(GPS_longitude_1); Serial.print(".");
+          Serial.print(GPS_longitude_2); Serial.print(" "); Serial.println(GPS_longitude_EW_string); 
+
+          Serial.print("Speed (knots) = "); Serial.print(GPS_speed_knots);
+          Serial.print("     Direction (degrees) = "); Serial.println(GPS_direction);
+
+          Serial.print("Number of satellites: "); Serial.print(GPS_satellites);
+          Serial.print("       Altitude (meters): "); Serial.println(GPS_altitude);
+              
+          }
+       
+        // all done with this sentence, so return.
+        return 0;
+       
+      }   // end of "if (data_OK && GPS_command.equals("$GPGGA"))" block
+  
+    // we'll fall through to here (instead of returning) when we've read a complete 
+    // sentence, but it doesn't have navigational information (for example, an antenna 
+    // status record).
+    
+    } 
+
+  }