542 lines
11 KiB
C++
542 lines
11 KiB
C++
const uint32_t baudSIM808[] = {
|
|
300,
|
|
600,
|
|
1200,
|
|
2400,
|
|
4800,
|
|
9600,
|
|
19200,
|
|
38400,
|
|
57600,
|
|
74880,
|
|
115200
|
|
};
|
|
class DataGPSSimManager
|
|
{
|
|
public:
|
|
uint16_t year;
|
|
uint8_t month;
|
|
uint8_t day;
|
|
uint8_t hour;
|
|
uint8_t minute;
|
|
uint8_t second;
|
|
uint8_t centisecond;
|
|
float lat;
|
|
float lon;
|
|
float speed_kmh;
|
|
float heading;
|
|
float altitude;
|
|
uint8_t nSatelites;
|
|
bool IsValid;
|
|
//precision------------
|
|
float pdop;//precision posicion (position Dilution of precision)
|
|
float hdop;//precision horizontal
|
|
float vdop;//precision vertical
|
|
DataGPSSimManager()
|
|
{
|
|
initValues();
|
|
}
|
|
|
|
char* getPrecision(char*buf)
|
|
{
|
|
if(hdop<=0)
|
|
strcpy(buf, "NoValido");
|
|
else if(hdop<1)
|
|
strcpy(buf, "Perfecta");
|
|
else if(hdop<2)
|
|
strcpy(buf, "Excelente");
|
|
else if(hdop<5)
|
|
strcpy(buf, "Buena");
|
|
else if(hdop<10)
|
|
strcpy(buf, "Media");
|
|
else if(hdop<20)
|
|
strcpy(buf, "Mala");
|
|
else
|
|
strcpy(buf, "MuyMala");
|
|
return buf;
|
|
}
|
|
char* getFecha(char*buf)
|
|
{
|
|
sprintf(buf, "%04d-%02d-%02dT%02d:%02d:%02d", year, month, day, hour, minute, second);
|
|
return buf;
|
|
}
|
|
char* getTimeStamp(char*buf)
|
|
{
|
|
sprintf(buf, "%02d%02d%02d%02d", day, hour, minute, second);
|
|
return buf;
|
|
}
|
|
void initValues()
|
|
{
|
|
year = 0;
|
|
month = 0;
|
|
day = 0;
|
|
hour = 0;
|
|
minute = 0;
|
|
second = 0;
|
|
centisecond = 0;
|
|
speed_kmh = 0;
|
|
heading = 0;
|
|
altitude = 0;
|
|
nSatelites = 0;
|
|
IsValid = false;
|
|
}
|
|
};
|
|
|
|
class Sim808Manager
|
|
{
|
|
char buffer[256];
|
|
bool simIniciada;
|
|
bool gpsIniciada;
|
|
int pk;
|
|
DataGPSSimManager dataGPS;
|
|
HardwareSerial *pSeria;
|
|
int AjusteHora;
|
|
public:
|
|
Sim808Manager()
|
|
{
|
|
pk = -1;
|
|
simIniciada = false;
|
|
gpsIniciada = false;
|
|
AjusteHora = 1;
|
|
}
|
|
|
|
bool inicia(HardwareSerial *mySerial, int powerKey = -1)
|
|
{
|
|
pSeria = mySerial;
|
|
pk = powerKey;
|
|
if (pk >= 0)
|
|
pinMode(pk, OUTPUT);
|
|
if (!CheckAt())
|
|
enciende();
|
|
return CheckAt();
|
|
}
|
|
|
|
bool EnviaSMS(char* tlf, char *sms)
|
|
{
|
|
printCOM("env sms");
|
|
if(!checkea())
|
|
return false;
|
|
printCOM("mira si inicia");
|
|
if (!iniciaSIM())
|
|
return false;
|
|
printCOM("proce envia");
|
|
//envia numero telefono----------------------
|
|
sprintf(buffer, "AT+CMGS=\"%s\",145", tlf);
|
|
//sprintf(buffer,"AT+CMGS=\"%s\"",tlf);
|
|
int kk = strlen(buffer);
|
|
envia(buffer);
|
|
char * res = recibe();
|
|
if (!strstr(res, ">"))
|
|
{
|
|
printCOM(res);
|
|
return false;
|
|
}
|
|
//envia sms---------------------------------
|
|
kk = strlen(sms);
|
|
|
|
enviaSolo(sms, kk);
|
|
|
|
buffer[0] = (char)26; //0x1A;//(ctrl-z)
|
|
buffer[1] = 0;
|
|
enviaSolo(buffer, 1);
|
|
for (int i = 0; i < 70; i++)
|
|
{
|
|
res = recibe();
|
|
if (strstr(res, "ERROR"))
|
|
{
|
|
printCOM(res);
|
|
buffer[0] = (char)0x1B; //enviamos Esc
|
|
buffer[1] = 0;
|
|
enviaSolo(buffer, 1);
|
|
recibe();
|
|
return false;
|
|
}
|
|
if (strstr(res, "OK"))
|
|
{
|
|
printCOM(res);
|
|
return true;
|
|
}
|
|
delay(1000);
|
|
}
|
|
printCOM("fin espera env sms");
|
|
return false;
|
|
|
|
}
|
|
|
|
DataGPSSimManager* GetGPSValid()
|
|
{
|
|
GetGPS();
|
|
while (!dataGPS.IsValid)
|
|
{
|
|
|
|
delay(1000);
|
|
GetGPS();
|
|
}
|
|
return &dataGPS;
|
|
}
|
|
|
|
char* GetFecha(char *buf)
|
|
{
|
|
GetGPSValid();
|
|
return dataGPS.getFecha(buf);
|
|
}
|
|
DataGPSSimManager* GetUltGPS()
|
|
{
|
|
return &dataGPS;
|
|
}
|
|
|
|
DataGPSSimManager* GetGPS()
|
|
{
|
|
printCOM("GetGPS");
|
|
if(!checkea())
|
|
return &dataGPS;
|
|
printCOM("PassCheck");
|
|
if(!iniciaGPS())
|
|
return &dataGPS;
|
|
printCOM("PassInit");
|
|
if (!recibeGPRMC())
|
|
printCOM("GPRMC no valido");
|
|
if (!recibeCGPSINF_0())
|
|
printCOM("info 0 no valido");
|
|
if(!recibeGPGSA())
|
|
{
|
|
printCOM("GPGSA no valida");
|
|
}
|
|
return &dataGPS;
|
|
}
|
|
|
|
//funciones auxiliares
|
|
|
|
private:
|
|
bool iniciaGPS()
|
|
{
|
|
if(gpsIniciada)
|
|
return true;
|
|
envia("AT+CGPSPWR=1");
|
|
if (!reciveOK())
|
|
return false;
|
|
envia("AT+CGPSRST=1");
|
|
if (!reciveOK())
|
|
return false;
|
|
gpsIniciada=true;
|
|
return true;
|
|
}
|
|
bool iniciaSIM()
|
|
{
|
|
|
|
if (simIniciada)
|
|
return true;
|
|
printCOM("inicia sim");
|
|
//verifica que no este configurado el pin
|
|
envia("AT+CPIN?");
|
|
char* res = recibe();
|
|
if (!strstr(res, "+CPIN: READY"))
|
|
{
|
|
printCOM("Sim Necesita Pin");
|
|
return false;
|
|
}
|
|
//configura sms en modo texto
|
|
envia("AT+CMGF=1");
|
|
if (!reciveOK())
|
|
return false;
|
|
simIniciada = true;
|
|
|
|
return true;
|
|
}
|
|
|
|
char* recibe()
|
|
{
|
|
unsigned long start = millis();
|
|
char d;
|
|
char *buff = buffer;
|
|
char *buf = buffer;
|
|
while (millis() - start < 100)
|
|
{
|
|
while (pSeria->available() > 0)
|
|
{
|
|
start = millis();
|
|
d = pSeria->read();
|
|
*buf = d;
|
|
buf++;
|
|
}
|
|
}
|
|
*buf = 0;
|
|
if(*buff)
|
|
printCOM(buff);
|
|
|
|
return buff;
|
|
}
|
|
|
|
void envia(char* dat)
|
|
{
|
|
pSeria->println(dat);
|
|
//printCOM(dat);
|
|
}
|
|
|
|
void enviaSolo(char* dat, int ndata)
|
|
{
|
|
for ( int i = 0; i < ndata; i++)
|
|
{
|
|
pSeria->write(dat[i]);
|
|
}
|
|
//printCOM(dat);
|
|
}
|
|
bool CheckAt()
|
|
{
|
|
envia("AT");
|
|
return reciveOK();
|
|
}
|
|
void enciende()
|
|
{
|
|
if (pk < 0)
|
|
return;
|
|
digitalWrite(pk, HIGH);
|
|
delay (2000);
|
|
digitalWrite (pk, LOW);
|
|
delay (2000);
|
|
}
|
|
bool reciveOK()
|
|
{
|
|
char* resp = recibe();
|
|
if (strstr(resp, "OK"))
|
|
return true;
|
|
return false;
|
|
}
|
|
//traza nmea gprmc
|
|
bool recibeGPRMC()
|
|
{
|
|
dataGPS.initValues();
|
|
bool datoValido=true;
|
|
char buf[16];
|
|
envia("AT+CGPSINF=32");
|
|
char *res = recibe();
|
|
if (!strstr(res, "+CGPSINF:"))
|
|
{
|
|
printCOM("info no valido\n");
|
|
return false;
|
|
}
|
|
StringSplit sp(res, ",");
|
|
sp.get();
|
|
char* res2 = sp.get();
|
|
if (!res2 || strlen(res2) < 6)
|
|
{
|
|
printCOM("longitud hora\n");
|
|
return false;
|
|
}
|
|
int i = 0;
|
|
//HORA----------------
|
|
buf[0] = res2[i++];
|
|
buf[1] = res2[i++];
|
|
buf[2] = 0;
|
|
dataGPS.hour = atoi(buf) + AjusteHora;
|
|
//MIN---------------
|
|
buf[0] = res2[i++];
|
|
buf[1] = res2[i++];
|
|
buf[2] = 0;
|
|
dataGPS.minute = atoi(buf);
|
|
//SEG---------------
|
|
buf[0] = res2[i++];
|
|
buf[1] = res2[i++];
|
|
buf[2] = 0;
|
|
dataGPS.second = atoi(buf);
|
|
//dato valido-------
|
|
res2 = sp.get();
|
|
if (!res2 || strlen(res2) < 1)
|
|
{
|
|
printCOM("longitud valido\n");
|
|
return false;
|
|
}
|
|
if (!strstr(res2, "A"))
|
|
{
|
|
//printCOM("Dato no valido\n");
|
|
datoValido=false;
|
|
}
|
|
|
|
//latitud----------
|
|
res2 = sp.get();
|
|
i = 0;
|
|
if (!res2 ||strlen(res2) < 5)
|
|
{
|
|
return false;
|
|
}
|
|
//grados
|
|
buf[0] = res2[i++];
|
|
buf[1] = res2[i++];
|
|
buf[2] = 0;
|
|
dataGPS.lat = atof(buf) + (atof(&res2[i]) / 60.);
|
|
//hemisferio
|
|
res2 = sp.get();
|
|
i = 0;
|
|
if (!res2 || strlen(res2) < 1)
|
|
{
|
|
return false;
|
|
}
|
|
if (!strstr(res2, "N"))
|
|
dataGPS.lat = -dataGPS.lat;
|
|
|
|
//longitud----------
|
|
res2 = sp.get();
|
|
i = 0;
|
|
if (!res2 || strlen(res2) < 5)
|
|
{
|
|
return false;
|
|
}
|
|
//grados
|
|
buf[0] = res2[i++];
|
|
buf[1] = res2[i++];
|
|
buf[2] = res2[i++];
|
|
buf[3] = 0;
|
|
dataGPS.lon = atof(buf) + (atof(&res2[i]) / 60.);
|
|
//Signo
|
|
res2 = sp.get();
|
|
i = 0;
|
|
if (!res2 || strlen(res2) < 1)
|
|
return false;
|
|
if (res2[0] != 'E')
|
|
dataGPS.lon = -dataGPS.lon;
|
|
|
|
//velocidad---------
|
|
res2 = sp.get();
|
|
i = 0;
|
|
if (!res2 || strlen(res2) < 1)
|
|
return false;
|
|
dataGPS.speed_kmh = atof(res2) * 1.852;
|
|
//direccion--------
|
|
res2 = sp.get();
|
|
i = 0;
|
|
if (!res2 || strlen(res2) < 1)
|
|
return false;
|
|
dataGPS.heading = atof(res2);
|
|
//fecha------------
|
|
res2 = sp.get();
|
|
i = 0;
|
|
if (!res2 || strlen(res2) < 6)
|
|
return false;
|
|
//dia
|
|
buf[0] = res2[i++];
|
|
buf[1] = res2[i++];
|
|
buf[2] = 0;
|
|
dataGPS.day = atoi(buf);
|
|
//mes
|
|
buf[0] = res2[i++];
|
|
buf[1] = res2[i++];
|
|
buf[2] = 0;
|
|
dataGPS.month = atoi(buf);
|
|
//anio
|
|
buf[0] = res2[i++];
|
|
buf[1] = res2[i++];
|
|
buf[2] = 0;
|
|
dataGPS.year = 2000 + atoi(buf);
|
|
|
|
dataGPS.IsValid = datoValido;
|
|
return true;
|
|
|
|
}
|
|
bool recibeCGPSINF_0()
|
|
{
|
|
char buf[16];
|
|
envia("AT+CGPSINF=0");
|
|
char *res = recibe();
|
|
if (!strstr(res, "+CGPSINF:"))
|
|
{
|
|
return false;
|
|
}
|
|
int i = 0;
|
|
StringSplit sp(res, ",");
|
|
sp.get();//cabecera
|
|
sp.get();//longitud
|
|
sp.get();//latidud
|
|
//altura
|
|
char* res2 = sp.get();
|
|
i = 0;
|
|
if (!res2 || strlen(res2) < 1)
|
|
return false;
|
|
dataGPS.altitude = atof(res2);
|
|
sp.get();//tiempo
|
|
sp.get();//TTF
|
|
|
|
//numero de satelites
|
|
res2 = sp.get();
|
|
i = 0;
|
|
if (!res2 || strlen(res2) < 1)
|
|
return false;
|
|
dataGPS.nSatelites = atoi(res2);
|
|
|
|
return true;
|
|
}
|
|
bool recibeGPGSA()
|
|
{
|
|
envia("AT+CGPSINF=8");
|
|
char *res = recibe();
|
|
if (!strstr(res, "+CGPSINF:"))
|
|
{
|
|
return false;
|
|
}
|
|
int i = 0;
|
|
StringSplit sp(res, ",");
|
|
//pasa datos hasta
|
|
for (i=0;i<15; i++)
|
|
sp.get();//cabecera
|
|
//precision posicion
|
|
char* res2 = sp.get();
|
|
i = 0;
|
|
if (!res2 || strlen(res2) < 1)
|
|
return false;
|
|
dataGPS.pdop = atof(res2);
|
|
//precision horizontal
|
|
res2 = sp.get();
|
|
i = 0;
|
|
if (!res2 || strlen(res2) < 1)
|
|
return false;
|
|
dataGPS.hdop = atof(res2);
|
|
//precision vertical
|
|
res2 = sp.get();
|
|
i = 0;
|
|
if (!res2 || strlen(res2) < 1)
|
|
return false;
|
|
dataGPS.vdop = atof(res2);
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
bool checkea()
|
|
{
|
|
if (!CheckAt())
|
|
{
|
|
printCOM("Reinicia modulo Sim");
|
|
gpsIniciada=false;
|
|
simIniciada=false;
|
|
enciende();
|
|
}
|
|
else
|
|
return true;
|
|
return CheckAt();
|
|
|
|
}
|
|
|
|
bool configBaud(int baud)
|
|
{
|
|
pSeria->begin(baud);
|
|
if (checkea())
|
|
return true;
|
|
char auxbuf[16];
|
|
sprintf(auxbuf,"AT+IPR=%d", baud );
|
|
for(int i=0; i<=11; i++)
|
|
{
|
|
int baudTest=baudSIM808[i];
|
|
pSeria->begin(baudTest);
|
|
if (checkea())
|
|
{
|
|
envia(auxbuf);
|
|
if(reciveOK())
|
|
break;
|
|
}
|
|
}
|
|
pSeria->begin(baud);
|
|
return checkea();
|
|
|
|
}
|
|
};
|