#include "Sim808Manager.h" //-------------------------------------------------------------------------------------------------------- DataGPSSimManager::DataGPSSimManager() { initValues(); } char* DataGPSSimManager::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* DataGPSSimManager::getFecha(char*buf) { sprintf(buf, "%04d-%02d-%02dT%02d:%02d:%02d", year, month, day, hour, minute, second); return buf; } char* DataGPSSimManager::getTimeStamp(char*buf) { sprintf(buf, "%02d%02d%02d%02d", day, hour, minute, second); return buf; } void DataGPSSimManager::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; } //-------------------------------------------------------------------------------------------------------------------- Sim808Manager::Sim808Manager() { pk = -1; simIniciada = false; gpsIniciada = false; AjusteHora = 1; } bool Sim808Manager::inicia(HardwareSerial *mySerial, int powerKey = -1, int baud=0) { pSeria = mySerial; pk = powerKey; if (pk >= 0) pinMode(pk, OUTPUT); if(baud) return checkeaConfig(baud); return checkea(); /* if (!CheckAt()) enciende(); return CheckAt();*/ } bool Sim808Manager::EnviaSMS(char* tlf, char *sms) { Utiles::printCOM("env sms"); if (!checkea()) return false; if (!iniciaSIM()) return false; //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, ">")) { Utiles::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")) { Utiles::printCOM(res); buffer[0] = (char)0x1B; //enviamos Esc buffer[1] = 0; enviaSolo(buffer, 1); recibe(); return false; } if (strstr(res, "OK")) return true; delay(1000); } Utiles::printCOM("fin espera env sms"); return false; } DataGPSSimManager* Sim808Manager::GetGPSValid() { GetGPS(); while (!dataGPS.IsValid) { delay(1000); GetGPS(); } return &dataGPS; } char* Sim808Manager::GetFecha(char *buf) { GetGPSValid(); return dataGPS.getFecha(buf); } DataGPSSimManager* Sim808Manager::GetUltGPS() { return &dataGPS; } DataGPSSimManager* Sim808Manager::GetGPS() { dataGPS.initValues(); if (!checkea()) return &dataGPS; if (!iniciaGPS()) return &dataGPS; if (!recibeGPRMC()) Utiles::printCOM("GPRMC no valido"); if (!recibeCGPSINF_0()) Utiles::printCOM("info 0 no valido"); if (!recibeGPGSA()) { Utiles::printCOM("GPGSA no valida"); } return &dataGPS; } //funciones auxiliares---------------------- bool Sim808Manager::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 Sim808Manager::iniciaSIM() { if (simIniciada) return true; Utiles::printCOM("inicia sim"); //verifica que no este configurado el pin envia("AT+CPIN?"); char* res = recibe(); if (!strstr(res, "+CPIN: READY")) { Utiles::printCOM("Sim Necesita Pin"); return false; } //configura sms en modo texto envia("AT+CMGF=1"); if (!reciveOK()) return false; simIniciada = true; return true; } char* Sim808Manager::recibeDatos() { return recibe(); } char* Sim808Manager::recibe() { unsigned long start = millis(); char d; char *buff = buffer; char *buf = buffer; int len = 0; while (millis() - start < 100) { while (pSeria->available() > 0 && len< (LEN_BUFFER_DATA_SIMMANAGER-3)) { start = millis(); d = pSeria->read(); *buf = d; buf++; len++; } } *buf = 0; //log sim /* if(*buff) Utiles::printCOM(buff); */ return buff; } void Sim808Manager::envia(char* dat) { pSeria->println(dat); //Utiles::printCOM(dat); } void Sim808Manager::enviaSolo(char* dat, int ndata) { for ( int i = 0; i < ndata; i++) { pSeria->write(dat[i]); } //Utiles::printCOM(dat); } bool Sim808Manager::CheckAt() { envia("AT"); bool res = reciveOK(); return res; } void Sim808Manager::enciende() { if (pk < 0) return; digitalWrite(pk, HIGH); delay (2000); digitalWrite (pk, LOW); delay (2000); } bool Sim808Manager::reciveOK() { char* resp = recibe(); if (strstr(resp, "OK")) return true; return false; } //traza nmea gprmc bool Sim808Manager::recibeGPRMC() { bool datoValido = true; char buf[16]; envia("AT+CGPSINF=32"); char *res = recibe(); if (!strstr(res, "+CGPSINF:")) { Utiles::printCOM("info no valido\n"); return false; } StringSplit sp(res, ","); sp.get(); char* res2 = sp.get(); if (!res2 || strlen(res2) < 6) { Utiles::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) { Utiles::printCOM("longitud valido\n"); return false; } if (!strstr(res2, "A")) { //Utiles::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 Sim808Manager::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 Sim808Manager::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 Sim808Manager::checkeaConfig(int baud) { if (Sim808Manager::configBaud(baud)) return true; Utiles::printCOM("reinicia modulo sim"); gpsIniciada = false; simIniciada = false; enciende(); return Sim808Manager::configBaud(baud); } bool Sim808Manager::checkea() { if (!CheckAt()) { Utiles::printCOM("reinicia modulo sim"); gpsIniciada = false; simIniciada = false; enciende(); } else return true; return CheckAt(); } bool Sim808Manager::configBaud(int baud) { const uint32_t baudSIM808[] = { 300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 74880, 115200 }; Utiles::printCOM("configBaud"); pSeria->begin(baud); Utiles::printCOM("configurado p serial"); //envia("AT+GMR"); //reciveOK(); if (CheckAt()) return true; Utiles::printCOM("se intenta configurar baud"); char auxbuf[24]; for (int i = 0; i < 11; i++) { uint32_t baudTest = baudSIM808[i]; sprintf(auxbuf, "prueba: %u", baudTest ); Utiles::printCOM(auxbuf); pSeria->begin(baudTest); if (CheckAt()) { Utiles::printCOM("Conseguido"); sprintf(auxbuf, "AT+IPR=%u", baud ); envia(auxbuf); if (reciveOK()) break; } Utiles::printCOM("fail"); } pSeria->begin(baud); return CheckAt(); } char* Sim808Manager::EnviaComando(char* at_command) { envia(at_command); return recibe(); } bool Sim808Manager::IniciaNetwork(const char* apn = 0, const char* userName = 0, const char* passWord = 0) { if(!iniciaSIM()) return false; char* res; envia("AT+CGATT?"); if (!reciveOK()) return false; envia("AT+CGATT=1"); if (!reciveOK()) return false; if(apn) { strcpy(buffer, "AT+SAPBR=3,1,\"APN\",\""); enviaSolo(buffer, strlen(buffer)); enviaSolo(apn, strlen(apn)); envia("\""); } else envia("AT+SAPBR=3,1,\"APN\",\"\""); if (!reciveOK()) return false; if(userName) { strcpy(buffer, "AT+SAPBR=3,1,\"USER\",\""); enviaSolo(buffer, strlen(buffer)); enviaSolo(userName, strlen(userName)); envia("\""); } else envia("AT+SAPBR=3,1,\"USER\",\"\""); if (!reciveOK()) return false; if(passWord) { strcpy(buffer, "AT+SAPBR=3,1,\"PWD\",\""); enviaSolo(buffer, strlen(buffer)); enviaSolo(passWord, strlen(passWord)); envia("\""); } else envia("AT+SAPBR=3,1,\"PWD\",\"\""); if (!reciveOK()) return false; envia("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\""); if (!reciveOK()) return false; envia("AT+SAPBR=1,1"); reciveOK(); for(int i=0; i<10; i++) { envia("AT+SAPBR=2,1"); res=recibe(); if(res && !strstr(res,"0.0.0.0") && strstr(res,"OK")) { //envia("AT+CIPMUX=0"); return true; } delay(1000); } return false; } uint32_t Sim808Manager::str_to_ip(const char* str) { uint32_t ip = 0; char* p = (char*)str; for (int i = 0; i < 4; i++) { ip |= atoi(p); p = strchr(p, '.'); if (p == NULL) { break; } ip <<= 8; p++; } return ip; } bool Sim808Manager::connect(ProtocolSimManager ptl, const char* host, int port) { //char cmd[64]; char num[4]; char *res; //sim808_clean_buffer(cmd,64); if (ptl == SIM808_TCP) strcpy(buffer, "AT+CIPSTART=\"TCP\",\""); else if (ptl == SIM808_UDP) strcpy(buffer, "AT+CIPSTART=\"UDP\",\""); else return false; enviaSolo(buffer, strlen(buffer)); enviaSolo(host, strlen(host)); enviaSolo("\",",2); itoa(port, num, 10); envia(num); for (int i = 0; i < 70; i++) { res = recibe(); if (strstr(res, "ERROR")) { Utiles::printCOM(res); buffer[0] = (char)0x1B; //enviamos Esc buffer[1] = 0; enviaSolo(buffer, 1); recibe(); return false; } if (strstr(res, "CONNECT")) return true; delay(1000); } return false; } /* * Serial.println(sim808.EnviaComando("AT+HTTPINIT")); Serial.println(sim808.EnviaComando("AT+HTTPPARA=\"CID\",1")); Serial.println(sim808.EnviaComando("AT+HTTPPARA=\"URL\",\"desa.narvaling.com:6265/setcoor/holaArdu\"")); Serial.println(sim808.EnviaComando("AT+HTTPACTION=0")); Serial.println(sim808.EnviaComando("AT+HTTPREAD")); */ bool Sim808Manager::httpGet(char* uri) { envia("AT+HTTPINIT"); if (!reciveOK()) { envia("AT+HTTPTERM"); reciveOK(); return false; } envia("AT+HTTPPARA=\"CID\",1"); if (!reciveOK()) { envia("AT+HTTPTERM"); reciveOK(); return false; } strcpy(buffer, "AT+HTTPPARA=\"URL\",\""); enviaSolo(buffer, strlen(buffer)); enviaSolo(uri, strlen(uri)); envia("\""); if (!reciveOK()) { envia("AT+HTTPTERM"); reciveOK(); return false; } envia("AT+HTTPACTION=0"); bool reciv = 0; for (int i = 0; i < 1200 && !reciv; i++) { char* res = recibe(); if (res) { if (strstr(res, "ERROR")) { Utiles::printCOM("error"); Utiles::printCOM(res); buffer[0] = (char)0x1B; //enviamos Esc buffer[1] = 0; enviaSolo(buffer, 1); recibe(); envia("AT+HTTPTERM"); reciveOK(); return false; } else if (strstr(res, "+HTTPACTION:")) { reciv = 1; } } if(!reciv) delay(100); } if (!reciv) { envia("AT+HTTPTERM"); reciveOK(); return false; } envia("AT+HTTPREAD"); if (!reciveOK()) { envia("AT+HTTPTERM"); reciveOK(); return false; } envia("AT+HTTPTERM"); if (!reciveOK()) return false; return true; } bool Sim808Manager::send(char* strbuf, int len) { Utiles::printCOM(strbuf); envia("AT+CIPQSEND=0"); if(!reciveOK()) return false; if (len <= 0) return false; strcpy(buffer, "AT+CIPSEND="); enviaSolo(buffer, strlen(buffer)); itoa(len, buffer, 12); envia(buffer); char* res = recibe(); if (!res || !strstr(res, ">")) { return false; } enviaSolo(strbuf, len); buffer[0] = (char)26; //0x1A;//(ctrl-z) buffer[1] = 0; enviaSolo(buffer, strlen(buffer)); for (int i = 0; i < 70; i++) { res = recibe(); if(res) { if (strstr(res, "ERROR")) { Utiles::printCOM("error"); Utiles::printCOM(res); buffer[0] = (char)0x1B; //enviamos Esc buffer[1] = 0; enviaSolo(buffer, 1); recibe(); return false; } else if (strstr(res, "OK")) { return true; } } delay(10000); } Utiles::printCOM("Error al enviar datos, envio sale por tiempo"); return false; } bool Sim808Manager::ISConectado(void) { char resp[96]; envia("AT+CIPSTATUS"); char* res = recibe(); if (res && strstr(res, "CONNECT OK")) { //+CIPSTATUS: 1,0,"TCP","216.52.233.120","80","CONNECTED" return true; } else { return false; } } bool Sim808Manager::Cierra() { // if not connected, return if (!ISConectado()) { return true; } envia("AT+CIPCLOSE"); char* res = recibe(); if (!res && NULL != strstr(res, "CLOSE OK")) { //+CIPSTATUS: 1,0,"TCP","216.52.233.120","80","CONNECTED" return true; } else { return false; } } void Sim808Manager::Desconecta() { Cierra(); envia("AT+CIPSHUT"); recibe(); }