天天看點

arduino 2560GPS資料的處理

最近做個小項目,需要實作導航功能,用到了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類型變量長度不夠的情況,如果你的運作環境浮點型類型長度夠長,則可以不必使用這種方法。