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