CobraV2/sender_module/L76X.cpp
2024-06-03 20:57:13 +02:00

245 lines
8.6 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "L76X.h"
char const Temp[16]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
static const double pi = 3.14159265358979324;
static const double a = 6378245.0;
static const double ee = 0.00669342162296594323;
static const double x_pi = 3.14159265358979324 * 3000.0 / 180.0;
static char buff_t[BUFFSIZE]={0};
GNRMC GPS;
/******************************************************************************
function:
Latitude conversion
******************************************************************************/
static double transformLat(double x,double y)
{
double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 *sqrt(abs(x));
ret += (20.0 * sin(6.0 * x * pi) + 20.0 * sin(2.0 * x * pi)) * 2.0 / 3.0;
ret += (20.0 * sin(y * pi) + 40.0 * sin(y / 3.0 * pi)) * 2.0 / 3.0;
ret += (160.0 * sin(y / 12.0 * pi) + 320 * sin(y * pi / 30.0)) * 2.0 / 3.0;
return ret;
}
/******************************************************************************
function:
Longitude conversion
******************************************************************************/
static double transformLon(double x,double y)
{
double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * sqrt(abs(x));
ret += (20.0 * sin(6.0 * x * pi) + 20.0 * sin(2.0 * x * pi)) * 2.0 / 3.0;
ret += (20.0 * sin(x * pi) + 40.0 * sin(x / 3.0 * pi)) * 2.0 / 3.0;
ret += (150.0 * sin(x / 12.0 * pi) + 300.0 * sin(x / 30.0 * pi)) * 2.0 / 3.0;
return ret;
}
/******************************************************************************
function:
GCJ-02 international standard converted to Baidu map BD-09 standard
******************************************************************************/
static Coordinates bd_encrypt(Coordinates gg)
{
Coordinates bd;
double x = gg.Lon, y = gg.Lat;
double z = sqrt(x * x + y * y) + 0.00002 * sin(y * x_pi);
double theta = atan2(y, x) + 0.000003 * cos(x * x_pi);
bd.Lon = z * cos(theta) + 0.0065;
bd.Lat = z * sin(theta) + 0.006;
return bd;
}
/******************************************************************************
function:
GPS's WGS-84 standard is converted into GCJ-02 international standard
******************************************************************************/
static Coordinates transform(Coordinates gps)
{
Coordinates gg;
double dLat = transformLat(gps.Lon - 105.0, gps.Lat - 35.0);
double dLon = transformLon(gps.Lon - 105.0, gps.Lat - 35.0);
double radLat = gps.Lat / 180.0 * pi;
double magic = sin(radLat);
magic = 1 - ee * magic * magic;
double sqrtMagic = sqrt(magic);
dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
dLon = (dLon * 180.0) / (a / sqrtMagic * cos(radLat) * pi);
gg.Lat = gps.Lat + dLat;
gg.Lon = gps.Lon + dLon;
return gg;
}
/******************************************************************************
function:
Send a command to the L76XAutomatic calculation of the code
parameter:
data The end of the command ends with \0 or it will go wrong,
no need to increase the validation code.
******************************************************************************/
void L76X_Send_Command(char *data)
{
char Check = data[1], Check_char[3]={0};
UBYTE i = 0;
DEV_Uart_SendByte('\r');
DEV_Uart_SendByte('\n');
//printf(" 1i = %d Check =%x \n", i, Check);
for(i=2; data[i] != '\0'; i++){
Check ^= data[i]; //Calculate the check value
}
//printf(" i = %d Check =%x \n", i, Check);
Check_char[0] = Temp[Check/16%16];
Check_char[1] = Temp[Check%16];
Check_char[2] = '\0';
DEV_Uart_SendString(data);
DEV_Uart_SendByte('*');
DEV_Uart_SendString(Check_char);
DEV_Uart_SendByte('\r');
DEV_Uart_SendByte('\n');
}
void L76X_Exit_BackupMode()
{
DEV_Set_GPIOMode(DEV_FORCE, 0);
DEV_Digital_Write(DEV_FORCE, 1);
DEV_Delay_ms(1000);
DEV_Digital_Write(DEV_FORCE, 0);
DEV_Set_GPIOMode(DEV_FORCE, 1);
}
/******************************************************************************
function:
Analyze GNRMC data in L76x, latitude and longitude, time
******************************************************************************/
GNRMC L76X_Gat_GNRMC()
{
UWORD add = 0, x = 0, z = 0, i = 0;
UDOUBLE Time = 0, latitude = 0, longitude = 0;
GPS.Status = 0;
GPS.Time_H = 0;
GPS.Time_M = 0;
GPS.Time_S = 0;
DEV_Uart_ReceiveString(buff_t, BUFFSIZE);
Serial.print(buff_t);
add = 0;
while(add < BUFFSIZE){
if(buff_t[add] == '$' && buff_t[add+1] == 'G' && (buff_t[add+2] == 'N' || buff_t[add+2] == 'P')\
&& buff_t[add+3] == 'R' && buff_t[add+4] == 'M' && buff_t[add+5] == 'C'){
x = 0;
for(z = 0; x < 12; z++){
if(buff_t[add+z]=='\0'){
break;
}
if(buff_t[add+z]==','){
x++;
if(x == 1){//The first comma is followed by time
Time = 0;
for(i = 0; buff_t[add+z+i+1] != '.'; i++){
if(buff_t[add+z+i+1]=='\0'){
break;
}
if(buff_t[add+z+i+1] == ',')
break;
Time = (buff_t[add+z+i+1]-'0') + Time*10;
}
GPS.Time_H = Time/10000+8;
GPS.Time_M = Time/100%100;
GPS.Time_S = Time%100;
if(GPS.Time_H >= 24)
GPS.Time_H = GPS.Time_H - 24;
}else if(x == 2){
//A indicates that it has been positioned
//V indicates that there is no positioning.
if(buff_t[add+z+1] == 'A'){
GPS.Status = 1;
}else{
GPS.Status = 0;
}
}else if(x == 3){
latitude = 0;
//If you need to modify, please re-edit the calculation method below.
for(i = 0; buff_t[add+z+i+1] != ','; i++){
if(buff_t[add+z+i+1] == '\0'){
break;
}
if(buff_t[add+z+i+1] == '.'){
continue;
}
latitude = (buff_t[add+z+i+1]-'0') + latitude*10;
}
GPS.Lat = latitude/10000000.0;
}else if(x == 4){
GPS.Lat_area = buff_t[add+z+1];
}
else if(x == 5){
longitude = 0;
for(i = 0; buff_t[add+z+i+1] != ','; i++){
if(buff_t[add+z+i+1] == '\0'){
break;
}
if(buff_t[add+z+i+1] == '.')
continue;
longitude = (buff_t[add+z+i+1]-'0') + longitude*10;
}
GPS.Lon = longitude/10000000.0;
}else if(x == 6){
GPS.Lon_area = buff_t[add+z+1];
}
}
}
add = 0;
break;
}
if(buff_t[add+5] == '\0'){
add = 0;
break;
}
add++;
if(add > BUFFSIZE){
add = 0;
break;
}
}
return GPS;
}
/******************************************************************************
function:
Convert GPS latitude and longitude into Baidu map coordinates
******************************************************************************/
Coordinates L76X_Baidu_Coordinates()
{
Coordinates temp;
temp.Lat =((int)(GPS.Lat)) + (GPS.Lat - ((int)(GPS.Lat)))*100 / 60;
temp.Lon =((int)(GPS.Lon)) + (GPS.Lon - ((int)(GPS.Lon)))*100 / 60;
temp = transform(temp);
temp = bd_encrypt(temp);
return temp;
}
/******************************************************************************
function:
Convert GPS latitude and longitude into Google Maps coordinates
******************************************************************************/
Coordinates L76X_Google_Coordinates()
{
Coordinates temp;
GPS.Lat =((int)(GPS.Lat)) + (GPS.Lat - ((int)(GPS.Lat)))*100 / 60;
GPS.Lon =((int)(GPS.Lon)) + (GPS.Lon - ((int)(GPS.Lon)))*100 / 60;
temp = transform(temp);
return temp;
}