最近做个小项目,需要实现导航功能,用到了GPS模块,需要对GPS数据进行处理,但是arduino2560的float和double都只是4个字节,无法用一个变量存储经纬度数据,于是想用一个float数组分开存储,具体实现如下!
我的GPS模块返回的经纬度使用一个字符数组存储的,长度是11,下面是GPS模块返回数据的结构体:
struct
{
char GPS_Buffer[80];
bool isGetData; //是否获取到GPS数据
bool isParseData; //是否解析完成
char UTCTime[11]; //UTC时间
char latitude[11]; //纬度
char N_S[2]; //N/S
char longitude[12]; //经度
char E_W[2]; //E/W
char vec[11];
char yaw[11];
bool isUsefull; //定位信息是否有效
}
我直接贴出代码:
/*****************************************************************************
将字符串表示的字符串转换为两个浮点型数据,保存在一个浮点型数组内
*****************************************************************************/
void la_lo(char *str1, char *str2)
{
int si, i;
char **ret = explode('.', str1, &si);
for (i = 0; i < si; i++)
{
x[i] = atof(ret[i]);
free(ret[i]);
}
free (ret);
while (x[1] / 10000 < 1)
{
x[1] = x[1] * 10;
}
int i1 = search(str1, '.');
//Serial.print("weizhi: ");
//Serial.print(i1);
if ((str1[i1 + 1] == '0') && (str1[i1 + 2] != '0'))
{
x[1] = x[1] / 10;
}
else if (((str1[i1 + 1] == '0') && (str1[i1 + 2] == '0')) && (str1[i1 + 3] != '0'))
{
x[1] = x[1] / 100;
}
else if (((str1[i1 + 1] == '0') && (str1[i1 + 2] == '0') && (str1[i1 + 3] == '0')) && (str1[i1 + 4] != '0'))
{
x[1] = x[1] / 1000;
}
else if (((str1[i1 + 1] == '0') && (str1[i1 + 2] == '0') && (str1[i1 + 3] == '0') && (str1[i1 + 4] == '0')) && (str1[i1 + 5] != '0'))
{
x[1] = x[1] / 10000;
}
else if ((str1[i1 + 1] == '0') && (str1[i1 + 2] == '0') && (str1[i1 + 3] == '0') && (str1[i1 + 4] == '0') && (str1[i1 + 5] == '0'))
{
x[1] = 0;
}
//分离整数部分,小数部分
int tem1 = int(x[0]) % 10;
int tem2 = tem1 + (int(x[0]) - tem1) % 100;
x[0] = x[0] / 100.0;
x[1] = tem2 / 100.0 + x[1] / 10000000.0;
x[0] = int(x[0]);
**ret = explode('.', str2, &si);
for (i = 0; i < si; i++)
{
x[i + 2] = atof(ret[i]);
free(ret[i]);
}
free (ret);
while (x[3] / 10000 < 1)
{
x[3] = x[3] * 10;
}
int i2 = search(str2, '.');
//Serial.print("weizhi: ");
//Serial.print(i1);
if ((str2[i2 + 1] == '0') && (str2[i2 + 2] != '0'))
{
x[3] = x[3] / 10;
}
else if ((str2[i2 + 1] == '0') && (str2[i2 + 2] == '0') && (str2[i2 + 3] != '0'))
{
x[3] = x[3] / 100;
}
else if ((str2[i2 + 1] == '0') && (str2[i2 + 2] == '0') && (str2[i2 + 3] == '0') && (str2[i2 + 4] != '0'))
{
x[3] = x[3] / 1000;
}
else if ((str2[i2 + 1] == '0') && (str2[i2 + 2] == '0') && (str2[i2 + 3] == '0') && (str2[i2 + 4] == '0') && (str2[i2 + 5] != '0'))
{
x[3] = x[3] / 10000;
}
else if ((str2[i2 + 1] == '0') && (str2[i2 + 2] == '0') && (str2[i2 + 3] == '0') && (str2[i2 + 4] == '0') && (str2[i2 + 5] == '0'))
{
x[3] = 0;
}
//分离整数部分,小数部分
tem1 = int(x[2]) % 10;
tem2 = tem1 + (int(x[2]) - tem1) % 100;
x[2] = x[2] / 100.0;
x[3] = tem2 / 100.0 + x[3] / 10000000.0;
x[2] = int(x[2]);
}
/*****************************************************************************************
以特定字符分离字符数组,此处特定字符是‘.’,字符数组是经纬度
*****************************************************************************************/
char **explode(char sep, const char *str, int *size)
{
int count = 0, i;
for (i = 0; i < strlen(str); i++)
{
if (str[i] == sep)
{
count ++;
}
}
char **ret = calloc(++count, sizeof(char *));
int lastindex = -1;
int j = 0;
for (i = 0; i < strlen(str); i++)
{
if (str[i] == sep)
{
ret[j] = calloc(i - lastindex, sizeof(char)); //分配子串长度+1的内存空间
memcpy(ret[j], str + lastindex + 1, i - lastindex - 1);
j++;
lastindex = i;
}
}
//处理最后一个子串
if (lastindex <= strlen(str) - 1)
{
ret[j] = calloc(strlen(str) - lastindex, sizeof(char));
memcpy(ret[j], str + lastindex + 1, strlen(str) - 1 - lastindex);
j++;
}
*size = j;
return ret;
}
/**************************************************************************************
找到目标字符的位置
**************************************************************************************/
int search(const char *a, const char b)
{
int i;
for (i = 0; a[i]; i++)
if (a[i] == b)
return i;
}
核心就是这三个函数,可以实现经纬度的字符数组形式,转换为浮点型数据,进而可以直接用到你需要的地方。当然,这个方法适用于float类型变量长度不够的情况,如果你的运行环境浮点型类型长度够长,则可以不必使用这种方法。