/*
GPS Fake using custom chip
by Anderson Costa
GPS NMEA 0183 Messaging Protocol 101
https://docs.arduino.cc/learn/communication/gps-nmea-data-101
NMEA Generator
https://www.nmeagen.org/
*/
#include <SoftwareSerial.h>
#include "NMEA.h"
#define MODULO_CENTRAL 0xFF // Define o ID do modulo central
#define TIPO_MODULOS 0x00 // Define tipo como todos os modulos
#define TIPO_MODULO_GPS 0x03 // Define como modulo GPS
#define ID_MODULO_ADDR 0x01 // Endereço do modulo na EEPROM
#define ID_CENTRAL_ADDR 0x02 // Endereço da central na EEPROM
#define COMANDO_ID_MODULO 0x05 // Define o ID do modulo ADUBO
#define COMANDO_SETA_ID_MODULO 0x06 // Define comando para mudar o ID do módulo
#define COMANDO_RESET 0x07 // Comando de reset do módulo
#define COMANDO_DESLIGA 0x08 // Comando para desativar o modo plantio
#define COMANDO_LIGA 0x09 // Comando para ativar o modo plantio
#define COMANDO_VELOCIDADE_GPS 0x0A // Comando velocidade do GPS
#define CAN_MODULO_ORIGEM 0 // Define a posição do módulo origem da rede
#define CAN_DESTINO 1 // Define a posição do módulo destino da rede
#define CAN_COMANDO 2 // Define a posição do comando da rede
#define CAN_DADOS_1 3 // Define a posição 1 dos dados da CAN
#define CAN_DADOS_2 4 // Define a posição 2 dos dados da CAN
#define CAN_DADOS_3 5 // Define a posição 3 dos dados da CAN
#define CAN_DADOS_4 6 // Define a posição 4 dos dados da CAN
#define CAN_DADOS_5 7 // Define a posição 5 dos dados da CAN
#define CAN_DADOS_6 8 // Define a posição 6 dos dados da CAN
#define LEN(arr) ((int)(sizeof(arr) / sizeof(arr)[0]))
// // Defina os pinos para o Software Serial (RX e TX)
const int gpsRxPin = 2; // Pino RX do GPS, conecte ao TX do GPS
const int gpsTxPin = 3; // Pino TX do GPS, não é usado neste exemplo
// Cria o objeto SoftwareSerial
SoftwareSerial gpsSerial(gpsRxPin, gpsTxPin);
union {
char bytes[4];
float valor;
} velocidadeGPS;
float latitude;
float longitude;
char serialData;
NMEA gps(ALL); // Cria uma conexão de dados GPS com o tipo de sentença GPRMC
uint8_t data[8]; // Data field
void setup() {
Serial.begin(115200); // Inicializa o Serial padrão
gpsSerial.begin(9600); // Inicializa o Software Serial para leitura de dados GPS
Serial.println("Dados recebidos do NMEA:");
}
void loop() {
// Aguarda dados na porta serial do GPS (Software Serial)
while (gpsSerial.available()) {
// Recebe dados do GPS do Software Serial
serialData = static_cast<char>(gpsSerial.read());
// Verifica se a sentença do GPS é válida
Serial.print(serialData);
if (gps.decode(serialData)) {
// Checks if GPS status is 'A'
if ((gps.gprmc_status() == 'A')) {
// Receives GPS speed in km/h
velocidadeGPS.valor = gps.gprmc_speed(KMPH);
data[CAN_MODULO_ORIGEM] = TIPO_MODULO_GPS;
data[CAN_DESTINO] = MODULO_CENTRAL; // Envia para o modulo central
data[CAN_COMANDO] = COMANDO_VELOCIDADE_GPS;
memcpy(data + CAN_DADOS_1, &velocidadeGPS.valor, sizeof(velocidadeGPS.valor));
latitude = gps.gprmc_latitude();
longitude = gps.gprmc_longitude();
// Show Latitude
Serial.print(" Latitude: ");
Serial.println(latitude, 8);
// Show Longitude
Serial.print("Longitude: ");
Serial.println(longitude, 8);
// Show Speed in km/h
Serial.print(" Speed: ");
Serial.print(velocidadeGPS.valor);
Serial.print(" Km/h");
Serial.print(" CAN Send:");
for (uint8_t i = 0; i < 8; i++) {
Serial.print(" ");
Serial.print(data[i], DEC);
}
Serial.println();
} else {
velocidadeGPS.valor = 0;
}
// if (gps.type() == GPGGA) {
Serial.println();
Serial.print("Número de satélites: ");
Serial.print(gps.gpgga_satellites());
// }
}
}
}
void convertCoordinatesToCartesian(float latitude, float longitude) {
// Converte Coordenadas Geográficas para Plano Cartesiano
float latRadius = latitude * (PI) / 180; // Convert from Degrees to Radians
float lonRadius = longitude * (PI) / 180;
int earthRadius = 6371; // Radius in km
float posX = earthRadius * cos(latRadius) * cos(lonRadius);
float posY = earthRadius * cos(latRadius) * sin(lonRadius);
Serial.print(" X: "); Serial.println(posX);
Serial.print(" Y: "); Serial.println(posY);
}