GloboSondaV1/PruebaModuloSim/SIM808Manager.h

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();
}
};