Created
February 5, 2017 17:42
-
-
Save Helios-vmg/1d98f29b1979bd87ed2253c9c466ed9b to your computer and use it in GitHub Desktop.
Arduino GPS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <SPI.h> | |
| #include <SD.h> | |
| #include <SoftwareSerial.h> | |
| #include <EEPROM.h> | |
| #include <Arduino.h> // for type definitions | |
| int EEPROM_writeInt(int ee, int value){ | |
| byte *p = (byte *)(void *)&value; | |
| unsigned i; | |
| for (i = 0; i < sizeof(value); i++) | |
| EEPROM.write(ee++, *p++); | |
| return i; | |
| } | |
| int EEPROM_readInt(int ee){ | |
| int ret; | |
| byte *p = (byte *)(void *)&ret; | |
| unsigned i; | |
| for (i = 0; i < sizeof(ret); i++) | |
| *p++ = EEPROM.read(ee++); | |
| return ret; | |
| } | |
| const int cs_sd = 10; | |
| const int rx_gps = 3; | |
| const int tx_gps = 2; | |
| const int buf_size = 256; | |
| byte buf[buf_size]; | |
| int buf_pos = 0; | |
| bool ok = false; | |
| SoftwareSerial gps(rx_gps, tx_gps); | |
| File file; | |
| //#define ENABLE_SERIAL_OUTPUT | |
| const byte turn_off_GGA[] PROGMEM = { 0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x23 }; | |
| const byte turn_off_GLL[] PROGMEM = { 0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A }; | |
| const byte turn_off_GSA[] PROGMEM = { 0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x31 }; | |
| const byte turn_off_GSV[] PROGMEM = { 0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x38 }; | |
| const byte turn_off_RMC[] PROGMEM = { 0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x3F }; | |
| const byte turn_off_VTG[] PROGMEM = { 0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x46 }; | |
| const byte turn_off_GRS[] PROGMEM = { 0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x4D }; | |
| const byte turn_off_GST[] PROGMEM = { 0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x54 }; | |
| const byte turn_off_ZDA[] PROGMEM = { 0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x5B }; | |
| const byte turn_off_GBS[] PROGMEM = { 0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x62 }; | |
| const byte turn_off_DTM[] PROGMEM = { 0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x69 }; | |
| const byte turn_off_GNS[] PROGMEM = { 0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x7E }; | |
| const byte turn_off_THS[] PROGMEM = { 0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x85 }; | |
| const byte turn_off_VLW[] PROGMEM = { 0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x8C }; | |
| const byte turn_on_GGA[] PROGMEM = { 0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x04, 0x37 }; | |
| const byte turn_on_ZDA[] PROGMEM = { 0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x08, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x0C, 0x6F }; | |
| const byte set_positioning_rate_4_Hz[] PROGMEM = { 0xB5, 0x62, 0x06, 0x08, 0x06, 0x00, 0xF4, 0x01, 0x01, 0x00, 0x01, 0x00, 0x0B, 0x77 }; | |
| void send_array(const byte *begin, const byte *end){ | |
| int i = 0; | |
| for (; begin != end; begin++) | |
| gps.write(*begin); | |
| gps.println(); | |
| gps.flush(); | |
| } | |
| void calc_checksum(byte *dst, const byte *begin, const byte *end){ | |
| byte a = 0, | |
| b = 0; | |
| for (; begin != end; begin++){ | |
| a += *begin; | |
| b += a; | |
| } | |
| dst[0] = a; | |
| dst[1] = b; | |
| } | |
| int get_ack(const byte *msg_id){ | |
| unsigned long ack_start = millis(); | |
| const unsigned long ack_timeout = 3000; | |
| byte ack_packet[10] = {0xB5, 0x62, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; | |
| int i = 0; | |
| while (i < 10){ | |
| if (gps.available()){ | |
| byte incoming_char = gps.read(); | |
| if (incoming_char == ack_packet[i]){ | |
| i++; | |
| continue; | |
| }else if (i > 2){ | |
| ack_packet[i] = incoming_char; | |
| i++; | |
| continue; | |
| } | |
| } | |
| if (millis() > ack_start + ack_timeout) | |
| return 100 + i; | |
| } | |
| if (ack_packet[3] == 0x00 || msg_id[0] != ack_packet[6] || msg_id[1] != ack_packet[7]) | |
| return 2; | |
| byte checksum[2]; | |
| calc_checksum(checksum, ack_packet + 2, ack_packet + 8); | |
| if (checksum[0] == ack_packet[8] && checksum[1] == ack_packet[9]) | |
| return 0; | |
| delay(1000); | |
| return 3; | |
| } | |
| int send_array_and_confirm(const byte *begin, const byte *end){ | |
| send_array(begin, end); | |
| return get_ack(begin + 2); | |
| } | |
| void SEND_ARRAY2(const byte *begin, const byte *end){ | |
| for (byte i = 0; send_array_and_confirm(begin, end) && i < 3; i++); | |
| } | |
| #define SEND_ARRAY(x){ \ | |
| byte temp[sizeof(x)]; \ | |
| for (int i = 0; i < sizeof(x); i++) \ | |
| temp[i] = pgm_read_byte(x + i); \ | |
| SEND_ARRAY2(temp, temp + sizeof(x)); \ | |
| } | |
| void initial_configuration(){ | |
| SEND_ARRAY(turn_off_GGA); | |
| SEND_ARRAY(turn_off_GLL); | |
| SEND_ARRAY(turn_off_GSA); | |
| SEND_ARRAY(turn_off_GSV); | |
| SEND_ARRAY(turn_off_RMC); | |
| SEND_ARRAY(turn_off_VTG); | |
| SEND_ARRAY(turn_off_GRS); | |
| SEND_ARRAY(turn_off_GST); | |
| SEND_ARRAY(turn_off_GBS); | |
| SEND_ARRAY(turn_off_DTM); | |
| SEND_ARRAY(turn_off_GNS); | |
| SEND_ARRAY(turn_off_THS); | |
| SEND_ARRAY(turn_off_VLW); | |
| SEND_ARRAY(turn_on_ZDA); | |
| SEND_ARRAY(set_positioning_rate_4_Hz); | |
| } | |
| unsigned long setup_return_time; | |
| const unsigned long wait_time = 2000; | |
| bool fully_configured = 0; | |
| void final_configuration(){ | |
| if (fully_configured || millis() < setup_return_time + wait_time) | |
| return; | |
| SEND_ARRAY(turn_on_GGA); | |
| SEND_ARRAY(turn_off_ZDA); | |
| fully_configured = 1; | |
| } | |
| void setup(){ | |
| pinMode(rx_gps, INPUT); | |
| pinMode(tx_gps, OUTPUT); | |
| pinMode(10, OUTPUT); | |
| #ifdef ENABLE_SERIAL_OUTPUT | |
| Serial.begin(115200); | |
| Serial.print("Initializing SD card..."); | |
| #endif | |
| if (!SD.begin(cs_sd)){ | |
| #ifdef ENABLE_SERIAL_OUTPUT | |
| Serial.println("Card failed, or not present"); | |
| #endif | |
| return; | |
| } | |
| ok = true; | |
| gps.begin(9600); | |
| initial_configuration(); | |
| int fileIndex = EEPROM_readInt(0); | |
| EEPROM_writeInt(0, fileIndex + 1); | |
| String filename = String(fileIndex) + ".txt"; | |
| #ifdef ENABLE_SERIAL_OUTPUT | |
| Serial.println("OK!"); | |
| Serial.println("Using file " + filename); | |
| #endif | |
| file = SD.open(filename.c_str(), O_WRITE | O_CREAT); | |
| setup_return_time = millis(); | |
| } | |
| bool only_once = false; | |
| const int counter_initial = 256; | |
| int counter = counter_initial; | |
| void loop(){ | |
| final_configuration(); | |
| if (!ok || !gps.available()) | |
| return; | |
| byte b; | |
| if (gps.overflow()){ | |
| file.write("\r\n"); | |
| #ifdef ENABLE_SERIAL_OUTPUT | |
| Serial.write("\r\n"); | |
| #endif | |
| } | |
| while (gps.available()){ | |
| b = gps.read(); | |
| file.write(b); | |
| #ifdef ENABLE_SERIAL_OUTPUT | |
| Serial.write(b); | |
| #endif | |
| if (!--counter){ | |
| file.flush(); | |
| counter = counter_initial; | |
| } | |
| } | |
| if (b == '\n'){ | |
| file.flush(); | |
| counter = counter_initial; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment