我使用Sim908模块记录GPS位置和Arduino。
Sim908以ddmm.mmmm格式发送lat和lon,但在线GPS定位的主要服务(例如google earth)使用dd.dddd格式。
那么,如何修改我的代码以转换sim 908发送到dd.dddd格式的多个坐标?
Sim 908 Gsm图书馆代码
#include "gps.h"
char GPSGSM::getBattInf(char *str_perc, char *str_vol)
{
char ret_val=0;
char *p_char;
char *p_char1;
gsm.SimpleWriteln("AT+CBC");
gsm.WaitResp(5000, 100, "OK");
if(gsm.IsStringReceived("+CBC"))
ret_val=1;
//BCL
p_char = strchr((char *)(gsm.comm_buf),',');
p_char1 = p_char+1; //we are on the first char of BCS
p_char = strchr((char *)(p_char1), ',');
if (p_char != NULL) {
*p_char = 0;
}
strcpy(str_perc, (char *)(p_char1));
//Voltage
p_char++;
p_char1 = strchr((char *)(p_char), '\r');
if (p_char1 != NULL) {
*p_char1 = 0;
}
strcpy(str_vol, (char *)(p_char));
return ret_val;
}
char GPSGSM::getBattTVol(char *str_vol)
{
char *p_char;
char *p_char1;
char ret_val=0;
gsm.SimpleWriteln("AT+CBTE?");
gsm.WaitResp(5000, 100, "OK");
if(gsm.IsStringReceived("+CBTE"))
ret_val=1;
//BCL
p_char = strchr((char *)(gsm.comm_buf),':');
p_char1 = p_char+2; //we are on the first char of BCS
p_char = strchr((char *)(p_char1), '\r');
if (p_char != NULL) {
*p_char = 0;
}
strcpy(str_vol, (char *)(p_char1));
return ret_val;
}
char GPSGSM::attachGPS()
{
if(AT_RESP_ERR_DIF_RESP == gsm.SendATCmdWaitResp("AT+CGPSPWR=1", 500, 100, "OK", 5))
return 0;
if(AT_RESP_ERR_DIF_RESP == gsm.SendATCmdWaitResp("AT+CGPSRST=1", 500, 100, "OK", 5))
return 0;
return 1;
}
char GPSGSM::deattachGPS()
{
if(AT_RESP_ERR_DIF_RESP == gsm.SendATCmdWaitResp("AT+CGPSPWR=0", 500, 100, "OK", 5))
return 0;
return 1;
}
char GPSGSM::getStat()
{
char ret_val=-1;
gsm.SimpleWriteln("AT+CGPSSTATUS?");
gsm.WaitResp(5000, 100, "OK");
if(gsm.IsStringReceived("Unknown")||gsm.IsStringReceived("unknown"))
ret_val=0;
else if(gsm.IsStringReceived("Not"))
ret_val=1;
else if(gsm.IsStringReceived("2D")||gsm.IsStringReceived("2d"))
ret_val=2;
else if(gsm.IsStringReceived("3D")||gsm.IsStringReceived("3d"))
ret_val=3;
return ret_val;
}
char GPSGSM::getPar(char *str_long, char *str_lat, char *str_alt, char *str_time, char *str_speed )
{
char ret_val=0;
char *p_char;
char *p_char1;
gsm.SimpleWriteln("AT+CGPSINF=0");
gsm.WaitResp(5000, 100, "OK");
if(gsm.IsStringReceived("OK"))
ret_val=1;
//longitude
p_char = strchr((char *)(gsm.comm_buf),',');
p_char1 = p_char+1; //we are on the first char of longitude
p_char = strchr((char *)(p_char1), ',');
if (p_char != NULL) {
*p_char = 0;
}
strcpy(str_long, (char *)(p_char1));
// latitude
p_char++;
p_char1 = strchr((char *)(p_char), ',');
if (p_char1 != NULL) {
*p_char1 = 0;
}
strcpy(str_lat, (char *)(p_char));
// altitude
p_char1++;
p_char = strchr((char *)(p_char1), ',');
if (p_char != NULL) {
*p_char = 0;
}
strcpy(str_alt, (char *)(p_char1));
// UTC time
p_char++;
p_char1 = strchr((char *)(p_char), ',');
if (p_char1 != NULL) {
*p_char1 = 0;
}
strcpy(str_time, (char *)(p_char));
// TTFF
p_char1++;
p_char = strchr((char *)(p_char1), ',');
if (p_char != NULL) {
*p_char = 0;
}
// num
p_char++;
p_char1 = strchr((char *)(p_char), ',');
if (p_char1 != NULL) {
*p_char1 = 0;
}
// speed
p_char1++;
p_char = strchr((char *)(p_char1), ',');
if (p_char != NULL) {
*p_char = 0;
}
strcpy(str_speed, (char *)(p_char1));
return ret_val;
}
void parseTime(char *field, int *time)
{
////////////////Time////////////
char tmp[4];
tmp[2]=0; // Init tmp and null terminate
tmp[0] = field[8];
tmp[1] = field[9];
time[0] = atoi(tmp); // Hours
tmp[0] = field[10];
tmp[1] = field[11];
time[1] = atoi(tmp); // Minutes
tmp[0] = field[12];
tmp[1] = field[13];
time[2] = atoi(tmp); // Seconds
/////////////Date///////////////
tmp[0] = field[0];
tmp[1] = field[1];
tmp[2] = field[2];
tmp[3] = field[3];
tmp[4]=0; // Init tmp and null terminate
time[3] = atoi(tmp); // year
tmp[0] = field[4];
tmp[1] = field[5];
tmp[2]=0; // Init tmp and null terminate
time[4] = atoi(tmp); // month
tmp[0] = field[6];
tmp[1] = field[7];
tmp[2]=0; // Init tmp and null terminate
time[5] = atoi(tmp); // day
}
// Read the latitude in decimal format from a GGA string
double convertLat(char* latString)
{
double latitude = atof(latString); // convert to a double (precise)
int deg = (int) latitude / 100; // extract the number of degrees
double min = latitude - (100 * deg); // work out the number of minutes
latitude = deg + (double) min/60.0; // convert to decimal format
return latitude;
}
// Read the longitude in decimal format from a GGA string
double convertLong(char* longString)
{
double longitude = atof(longString); // convert to a double
int deg = (int) longitude / 100; // extract the number of degrees
double min = longitude - (100 * deg); // work out the number of minutes
longitude = deg + (double) min/60.00; // convert to decimal format
return longitude;
}
答案 0 :(得分:1)
Python代码可能对某人有用:
lat_conv = int(float(lat) / 100) + math.fmod(float(lat),100) / 60
lon_conv = int(float(lon) / 100) + math.fmod(float(lon),100) / 60
答案 1 :(得分:0)
最后我找到了解决方案。现在每个人都认为没事。
我的最终守则。
#include "SIM900.h"
#include <SoftwareSerial.h>
#include <Wire.h>
#include <ADXL345.h>
/*
Flame sensor Arduino
VCC 5V
GND GND
D0 D2 (Digital pin 2)
tx 2
rx 3
*/
#include "gps.h"
#include "sms.h"
ADXL345 adxl; //variable adxl is an instance of the ADXL345 library
char aux_str[30];
char aux;
char latitude[15];
char longitude[15];
int x,y,z;
int rawX, rawY, rawZ;
float X, Y, Z;
float rollrad, pitchrad;
float rolldeg, pitchdeg;
SMSGSM sms;
int D2 = 5; // digital pin 2
int numdata;
boolean started=false;
char smsbuffer[160];
char n[20]="0599122910";
GPSGSM gps;
char lon[15];
char lat[15];
char alt[15];
char time[20];
char vel[15];
char msg1[5];
char msg2[5];
char text[20];
char stat;
char inSerial[20];
int i=0;
void setup() {
Serial.begin(9600);
adxl.powerOn();
pinMode(D2,INPUT);
//Serial connection.
Serial.begin(9600);
Serial.println("GSM Shield testing.");
//Start configuration of shield with baudrate.
//For http uses is raccomanded to use 4800 or slower.
if (gsm.begin(2400)) {
Serial.println("\nstatus=READY");
started=true;
gsm.forceON();
} else Serial.println("\nstatus=IDLE");
}
void loop() {
int sensorReading = digitalRead(D2); // read the sensor on digital D2
Serial.print(sensorReading);
adxl.readAccel(&x, &y, &z); //read the accelerometer values and store them in variables x,y,z
// Output (x,y,z) on horizontal plane should be approximately (0,0,255)
// the following 3 lines is for an offset
rawX=x-7;
rawY=y-6;
rawZ=z+10;
X = rawX/256.00; // used for angle calculations
Y = rawY/256.00; // used for angle calculations
Z = rawZ/256.00; // used for angle calculations
rollrad = atan(Y/sqrt(X*X+Z*Z)); // calculated angle in radians
pitchrad = atan(X/sqrt(Y*Y+Z*Z)); // calculated angle in radians
rolldeg = 180*(atan(Y/sqrt(X*X+Z*Z)))/PI; // calculated angle in degrees
pitchdeg = 180*(atan(X/sqrt(Y*Y+Z*Z)))/PI; // calculated angle in degrees
if (sensorReading==1 ) { // No Flames Detected
Serial.println(" - No Flames Near Sensor");
Serial.print("\t Angle according to x axis (Roll(deg)) = "); Serial.print(rolldeg); // calculated angle in degrees
Serial.print("\t Angle according to y axis (Pitch(deg)) = "); Serial.println(pitchdeg); // calculated angle in degrees
}
else { // Flames detected
Serial.println(" - Flame Detected!");
if(started) {
//GPS attach
if (gps.attachGPS())
Serial.println("status=GPSREADY");
else Serial.println("status=ERROR");
delay(20000); //Time for fixing
stat=gps.getStat();
if(stat==1)
Serial.println("NOT FIXED");
else if(stat==0)
Serial.println("GPS OFF");
else if(stat==2)
Serial.println("2D FIXED");
else if(stat==3)
Serial.println("3D FIXED");
delay(5000);
//Get data from GPS
gps.getPar(lon,lat,alt,time,vel);
convert2Degrees(lat);
convert2Degrees(lon);
Serial.print(lat); Serial.print(",");Serial.print(lon);
smsbuffer[0]='\0';
strcat(smsbuffer," It was found in the fire site: ");
strcat(smsbuffer,text);
strcat(smsbuffer," latitude: ");
strcat(smsbuffer,lat);
strcat(smsbuffer,"longitude: ");
strcat(smsbuffer,lon);
strcat(smsbuffer,"time:");
strcat(smsbuffer,time);
sms.SendSMS("0599122910", smsbuffer);
}
if ( rolldeg >80&&pitchdeg >6 ){
gps.getPar(lon,lat,alt,time,vel);
convert2Degrees(lat);
convert2Degrees(lon);
Serial.print(lat); Serial.print(",");Serial.print(lon);
smsbuffer[0]='\0';
strcat(smsbuffer," It was found in the fire site: ");
strcat(smsbuffer,text);
strcat(smsbuffer," latitude: ");
strcat(smsbuffer,lat);
strcat(smsbuffer,"longitude: ");
strcat(smsbuffer,lon);
strcat(smsbuffer,"time:");
strcat(smsbuffer,time);
sms.SendSMS("0599122910", smsbuffer);
}
//and write them on NewSoftSerial.
serialhwread();
//Read for new byte on NewSoftSerial.
serialswread();
}
if(started) {
//Read if there are messages on SIM card and print them.
if(gsm.readSMS(smsbuffer, 160, n, 20)) {
Serial.println(n);
Serial.println(smsbuffer);
}
delay(1000);
}
};
void serialhwread()
{
i=0;
if (Serial.available() > 0) {
while (Serial.available() > 0) {
inSerial[i]=(Serial.read());
delay(10);
i++;
}
inSerial[i]='\0';
if(!strcmp(inSerial,"/END")) {
Serial.println("_");
inSerial[0]=0x1a;
inSerial[1]='\0';
gsm.SimpleWriteln(inSerial);
}
//Send a saved AT command using serial port.
if(!strcmp(inSerial,"TEST")) {
// Serial.println("BATTERY TEST 1");
// gps.getBattInf(msg1,msg2);
// Serial.println(msg1);
// Serial.println(msg2);
// Serial.println("BATTERY TEST 2");
// gps.getBattTVol(msg1);
// Serial.println(msg1);
stat=gps.getStat();
if(stat==1)
Serial.println("NOT FIXED");
else if(stat==0)
Serial.println("GPS OFF");
else if(stat==2)
Serial.println("2D FIXED");
else if(stat==3)
Serial.println("3D FIXED");
}
//Read last message saved.
if(!strcmp(inSerial,"MSG")) {
Serial.println(msg1);
} else {
Serial.println(inSerial);
gsm.SimpleWriteln(inSerial);
}
inSerial[0]='\0';
}
}
void serialswread()
{
gsm.SimpleRead();
}
int8_t convert2Degrees(char* input){
float deg;
float minutes;
boolean neg = false;
//auxiliar variable
char aux[10];
if (input[0] == '-')
{
neg = true;
strcpy(aux, strtok(input+1, "."));
}
else
{
strcpy(aux, strtok(input, "."));
}
// convert string to integer and add it to final float variable
deg = atof(aux);
strcpy(aux, strtok(NULL, '\0'));
minutes=atof(aux);
minutes/=1000000;
if (deg < 100)
{
minutes += deg;
deg = 0;
}
else
{
minutes += int(deg) % 100;
deg = int(deg) / 100;
}
// add minutes to degrees
deg=deg+minutes/60;
if (neg == true)
{
deg*=-1.0;
}
neg = false;
if( deg < 0 ){
neg = true;
deg*=-1;
}
float numeroFloat=deg;
int parteEntera[10];
int cifra;
long numero=(long)numeroFloat;
int size=0;
while(1){
size=size+1;
cifra=numero%10;
numero=numero/10;
parteEntera[size-1]=cifra;
if (numero==0){
break;
}
}
int indice=0;
if( neg ){
indice++;
input[0]='-';
}
for (int i=size-1; i >= 0; i--)
{
input[indice]=parteEntera[i]+'0';
indice++;
}
input[indice]='.';
indice++;
numeroFloat=(numeroFloat-(int)numeroFloat);
for (int i=1; i<=6 ; i++)
{
numeroFloat=numeroFloat*10;
cifra= (long)numeroFloat;
numeroFloat=numeroFloat-cifra;
input[indice]=char(cifra)+48;
indice++;
}
input[indice]='\0';
}
答案 2 :(得分:0)
我解决了这个问题。 您可以使用我的函数,它将gps坐标从DMS格式转换为十进制度。
void convert2Degrees(char* input){
char res[40];
float deg;
float minutes;
float seconds;
char aux[10] ="";
//latitude format: DDmm.mmmm'
// get 'degrees' from input parameter
aux[0] = input[0];
aux[1] = input[1];
aux[2] = '\0';
// convert string to integer and add it to final float variable
deg = atoi(aux);
// get 'minutes' from input parameter
for ( int i=0; i<7; i++ ){
aux[i] = input[i+2];
}
aux[7] = '\0';
// convert string to integer and add it to final float variable
minutes = atoi(aux);
// get 'seconds' from input parameter
for ( int i=0; i<2; i++ ){
aux[i] = aux[i+3];
}
aux[3] = '\0';
seconds = atoi(aux);
// add minutes to degrees
deg = deg + minutes/60 + seconds/3600;
dtostrf(deg, 2, 10, res);
strncpy(input, res,9);
}