Простой GPS трекер с отправкой HTTP URL координат через sim800l

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

На тему в Проектах не тянет, но вдруг кому пригодится. Собран скетч "на коленке" за пару дней, старый заказчик попросил, часть кода с форума (ссылка есть) а часть с древнего проекта. Фото нет, схемы нет, поддержки и развития не будет, но работает - каждую минуту шлет координаты на сервер, на вопросы по возможности отвечу. Координаты так же выводятся на LCD 1602.

#include <Wire.h>
#include <LiquidCrystal_I2C.h>// include LiquidCrystal library
LiquidCrystal_I2C lcd(0x3F, 16, 2); // initialise the LCD 1602 I2C

char dev_id[] = "Debug_Device";

// Широта и долгота
double lat = 0, lon = 0;

#include <avr\wdt.h>
#include <avr\pgmspace.h>
#include <EEPROM.h>

//#define DEBUG_MODE

#define GPS_RX 4 // пин RX на модуле подключаем к указаному пину на Ардуино TX
#define GPS_TX 3 // пин TX на модуле подключаем к указаному пину на Ардуино RX
#include <SoftwareSerial.h>
SoftwareSerial sgps(GPS_TX, GPS_RX); // установка контактовGPS_TX->RX и GPS_RX->TX для программного порта
// http://arduino.ru/forum/obshchii/kak-postich-nepostizhimoe#comment-388080
// http://arduino.ru/forum/programmirovanie/parsing-nmea?page=1
// test line
// $GPGLL,5511.32245,N,06119.48690,E,171507.00,A,A*7C

char gprs_imei_code[65]; // full string for send
char original_imei_code[20];
#define period_gprs_req 60000UL // 1 min
unsigned long timer_gprs_req = 0;
byte repeat601;
byte firstStart;
byte gprsON;

#define max_size_pgm_buf 252
char pgm_buf[max_size_pgm_buf];

uint8_t mcusr_mirror __attribute__ ((section (".noinit")));
void get_mcusr(void) \
__attribute__((naked)) \
__attribute__((used)) \
__attribute__((section(".init3")));
void get_mcusr(void)
{
  mcusr_mirror = MCUSR;
  MCUSR = 0;
  wdt_disable();
}

#ifdef DEBUG_MODE
#define reset_sim800_pin 4 // pin for reset modem
#else
#define reset_sim800_pin 2 // pin for reset modem
#endif

unsigned long current_millis; // main timer
unsigned long timer_reg_modem = 0; // timer registration modem in net

#define max_size_fixed_resp 16 // in work save 3 response from buf commands
char resp1[max_size_fixed_resp]; char resp2[max_size_fixed_resp]; char resp3[max_size_fixed_resp]; // 3 parts response
byte flresp1, flresp2, flresp3; // found parts of response
#define max_size_resp_buf 248 // max size response buf from modem, then more than goodest
char resp_buf[max_size_resp_buf]; // response buf from modem
byte pos_buf = 0; // current pos response buf
byte modem_step = 100; // current work mode mode in table of command
// static steps:
// 100 - delay 30 sec for registration modem in net
// 101 - not wait response, wait incomming call or other commands

const char at0cmd[] PROGMEM = "AT\r"; const char at1cmd[] PROGMEM = "AT+DDET=1\r"; const char at2cmd[] PROGMEM = "ATE0\r";
const char at3cmd[] PROGMEM = "AT+CLIP=1\r"; const char at4cmd[] PROGMEM = "ATS0=0\r"; const char at5cmd[] PROGMEM = "ATV1\r";
const char at6cmd[] PROGMEM = "AT+CMEE=2\r"; const char at7cmd[] PROGMEM = "AT+CMGF=1\r"; const char at8cmd[] PROGMEM = "AT+CREG?\r";
const char at8resp1[] PROGMEM = "+CREG:"; const char at8resp2[] PROGMEM = ",1";
const char at9cmd[] PROGMEM = "AT+CMGL=\"ALL\"\r"; const char at10cmd[] PROGMEM = "AT+CMGDA=\"DEL ALL\"\r"; const char at11cmd[] PROGMEM = "AT+CMGS=\"";
const char at12cmd[] PROGMEM = "~sender~"; const char at13cmd[] PROGMEM = "\r"; const char at13resp1[] PROGMEM = ">";
const char at14cmd[] PROGMEM = "~textsms~"; const char at15cmd[] PROGMEM = "~ctrlz~"; const char at15resp1[] PROGMEM = "+CMGS:";
const char at16cmd[] PROGMEM = "ATA\r"; const char at16resp2[] PROGMEM = "NO CARRIER";
const char at17cmd[] PROGMEM = "ATH\r"; const char at18cmd[] PROGMEM = "\"";
const char at19cmd[] PROGMEM = "AT+CSQ\r"; const char at19resp1[] PROGMEM = "+CSQ:"; const char at19resp2[] PROGMEM = ",";
const char at20cmd[] PROGMEM = "AT+GSN\r"; // get imei
const char at21cmd[] PROGMEM = "AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"\r"; // gprs options
const char at22cmd[] PROGMEM = "AT+SAPBR=3,1,\"APN\",\"internet\"\r"; // gprs options
const char at23cmd[] PROGMEM = "AT+SAPBR=3,1,\"USER\",\"\"\r"; // gprs options
const char at24cmd[] PROGMEM = "AT+SAPBR=3,1,\"PWD\",\"\"\r"; // gprs options
const char at25cmd[] PROGMEM = "AT+SAPBR=1,1\r"; // start gprs
const char at26cmd[] PROGMEM = "AT+SAPBR=2,1\r"; // get info gprs
const char at26resp1[] PROGMEM = "+SAPBR:"; const char at26resp2[] PROGMEM = ",1,";
const char at27cmd[] PROGMEM = "AT+HTTPINIT\r"; // http init
const char at28cmd[] PROGMEM = "AT+HTTPPARA=\"CID\",1\r"; // cid http
const char at29cmd[] PROGMEM = "AT+HTTPPARA=\"URL\",\"http://mysite.ru:8888/gps/add.php?imei=~imei~"; // link
const char at30cmd[] PROGMEM = "AT+HTTPACTION=0\r"; // get status connection
const char at30resp2[] PROGMEM = "+HTTPACTION"; const char at30resp3[] PROGMEM = ",";
const char at31cmd[] PROGMEM = "AT+HTTPREAD\r"; // load html page
const char at32cmd[] PROGMEM = "AT+HTTPTERM\r"; // close http
const char atOKcmd[] PROGMEM = "OK";
const char atOKRNcmd[] PROGMEM = "OK\r";
const char atNULLcmd[] PROGMEM = "";
const char at1status[] PROGMEM = "1";
const char at2status[] PROGMEM = "2";
const char at1step[] PROGMEM = "1"; const char at2step[] PROGMEM = "2"; const char at3step[] PROGMEM = "3"; const char at4step[] PROGMEM = "4";
const char at5step[] PROGMEM = "5"; const char at6step[] PROGMEM = "6"; const char at7step[] PROGMEM = "7"; const char at8step[] PROGMEM = "8";
const char at9step[] PROGMEM = "9"; const char at10step[] PROGMEM = "10"; const char at11step[] PROGMEM = "11"; const char at12step[] PROGMEM = "12";
const char at13step[] PROGMEM = "13"; const char at14step[] PROGMEM = "14"; const char at15step[] PROGMEM = "15"; const char at16step[] PROGMEM = "16";
const char at17step[] PROGMEM = "17"; const char at18step[] PROGMEM = "18"; const char at19step[] PROGMEM = "19"; const char at101step[] PROGMEM = "101";
const char at20step[] PROGMEM = "20"; const char at21step[] PROGMEM = "21"; const char at22step[] PROGMEM = "22";
const char at23step[] PROGMEM = "23"; const char at24step[] PROGMEM = "24"; const char at25step[] PROGMEM = "25";
const char at26step[] PROGMEM = "26"; const char at27step[] PROGMEM = "27"; const char at28step[] PROGMEM = "28";
const char at29step[] PROGMEM = "29"; const char at30step[] PROGMEM = "30"; const char at31step[] PROGMEM = "31"; const char at32step[] PROGMEM = "32";

const char * const str_at[] PROGMEM = { // record of AT commands
  at0cmd, atOKcmd, atNULLcmd, atNULLcmd, at1status, at1step,
  at1cmd, atOKcmd, atNULLcmd, atNULLcmd, at1status, at2step,
  at2cmd, atOKcmd, atNULLcmd, atNULLcmd, at1status, at3step,
  at3cmd, atOKcmd, atNULLcmd, atNULLcmd, at1status, at4step,
  at4cmd, atOKcmd, atNULLcmd, atNULLcmd, at1status, at5step,
  at5cmd, atOKcmd, atNULLcmd, atNULLcmd, at1status, at6step,
  at6cmd, atOKcmd, atNULLcmd, atNULLcmd, at1status, at7step,
  at7cmd, atOKcmd, atNULLcmd, atNULLcmd, at1status, at8step,
  at8cmd, at8resp1, at8resp2, atOKcmd, at1status, at20step,
  at9cmd, atOKRNcmd, atNULLcmd, atNULLcmd, at1status, at101step,
  at10cmd, atOKcmd, atNULLcmd, atNULLcmd, at1status, at101step,
  at11cmd, atNULLcmd, atNULLcmd, atNULLcmd, at1status, at12step,
  at12cmd, atNULLcmd, atNULLcmd, atNULLcmd, at1status, at18step,
  at13cmd, at13resp1, atNULLcmd, atNULLcmd, at1status, at14step,
  at14cmd, atNULLcmd, atNULLcmd, atNULLcmd, at1status, at15step,
  at15cmd, at15resp1, atOKcmd, atNULLcmd, at1status, at101step,
  at16cmd, atOKRNcmd, at16resp2, atNULLcmd, at2status, at101step,
  at17cmd, atOKRNcmd, atNULLcmd, atNULLcmd, at1status, at101step,
  at18cmd, atNULLcmd, atNULLcmd, atNULLcmd, at1status, at13step,
  at19cmd, at19resp1, at19resp2, atOKcmd, at1status, at101step,
  at20cmd, atOKcmd, atNULLcmd, atNULLcmd, at1status, at21step, // get imei and go to 10 cmd - last cmd for init
  at21cmd, atOKcmd, atNULLcmd, atNULLcmd, at1status, at22step,
  at22cmd, atOKcmd, atNULLcmd, atNULLcmd, at1status, at23step,
  at23cmd, atOKcmd, atNULLcmd, atNULLcmd, at1status, at24step,
  at24cmd, atOKcmd, atNULLcmd, atNULLcmd, at1status, at10step, // end gprs options - go to 10 step - end init
  at25cmd, atOKcmd, atNULLcmd, atNULLcmd, at2status, at26step, // start gprs
  at26cmd, at26resp1, at26resp2, atOKcmd, at1status, at27step,
  at27cmd, atOKcmd, atNULLcmd, atNULLcmd, at1status, at28step,
  at28cmd, atOKcmd, atNULLcmd, atNULLcmd, at1status, at29step,
  at29cmd, atOKcmd, atNULLcmd, atNULLcmd, at1status, at30step,
  at30cmd, atOKcmd, at30resp2, at30resp3, at2status, at31step, // load html page
  at31cmd, atOKcmd, atNULLcmd, atNULLcmd, at1status, at32step,
  at32cmd, atOKcmd, atNULLcmd, atNULLcmd, at1status, at101step,
};

void getPgmBuf(byte idxPgmBuf) {
  const char * addrStroki = pgm_read_word_near((int)(str_at + idxPgmBuf));
  strcpy_P(pgm_buf, addrStroki);
}

byte wait_response = 0; // 0-no wait response, wait ring or other command
// 1-wait fixed response, if time more - reset modem
#define period_fixed_wait 30000UL // max time for type 1 wait response
// 2-wait response data or wait action user, if time more - clear command
#define period_data_wait 30000UL // max time for type 2 wait response

// Эта функция принимает символ из Serial и возвращает
//  указатель на полученную строку или NULL, если строка
//  ещё не получена.
// Строка всегда начинается с $ и заканчивается \r или \n
static const int MAX_LEN = 120; // 120 - максимальная длина строки - надо посмотреть правильное значение в описании протокола!

char * getStrFromSerial(void) {
  static bool waitingForStrBegin = true; // истина, если мы ждём начала строки ($)
  static char strBuf[MAX_LEN];  // буфер для строки
  static int ptr = 0; // индекс свободного байта в буфере
  //  Если буфер переполнился, печатаем сообщение и начинаем ждать новую строку
  if (ptr >= MAX_LEN) {
    ptr = 0;
    waitingForStrBegin = true;
    return NULL;
  }
  //  Если в Serial ничего нет - выходим
  //  А если есть, то читаем 1 символ
  if (!sgps.available()) return NULL;
  const char c = sgps.read();
  //  Если мы ждём начала строки, то сравинваем
  //  прочитанный символ с '$', если равен - начало найдено
  if (waitingForStrBegin) {
    if (c == '$') {
      ptr = 0;
      strBuf[ptr++] = c;
      waitingForStrBegin = false;
    }
    return NULL;
  }
  //  Если прочитанный символ - перевод строки или возврат каретки
  //  то считаем, что строка закончилась. Возвращаем её,
  // а сами готовимся ждать новую.
  if (c == '\r' || c == '\n') {
    strBuf[ptr] = '\0';
    waitingForStrBegin = true;
    return strBuf;
  }
  //  Просто записываем символ в строку
  strBuf[ptr++] = c;
  return NULL;
}

//  Читаeм долготу и широту, складывает в lon и lat
// Возвращает true, если прочитала и false если нет
bool readLatLon(double & lat, double & lon) {
  //  getStrFromSerial() вернёт строку, полученную из Serial
  // или NULL, если строка ещё пока не получена
  const char * str = getStrFromSerial();
  //  Если строка ещё не получена, выходим
  if (str == NULL) return false;
  //  Если строка не начинается с "$GPGLL",
  // то она нам не нужна выходим
  const char * prefix = "$GPGLL";
  if (strncmp(str, prefix, strlen(prefix))) return false;
  //  Ищем первую запятую в строке str
  char * comma = strchr(str, ',');
  //  Если не нашли (строка кривая пришла?) - выходим
  if (!comma) return false;
  //  со следующего символа просле запятой идёт числоа - широта
  lat = atof(comma + 1);
  //  Ищем вторую запятую после начала числа-широты
  comma = strchr(comma + 1, ','); // сначала ищем первую запятую
  if (!comma) return false; // почему-то не нашли :((((
  comma = strchr(comma + 1, ','); // теперь ищем вторую запятую
  if (!comma) return false; // почему-то не нашли :((((
  //  со следующего символа просле запятой идёт числоа - долгота
  lon = atof(comma + 1);
  //  Вроде всё
  return true;
}

void setup() {
  MCUSR = 0;
  wdt_disable();
  lcd.init();
  // put your setup code here, to run once:
  lcd.begin (16, 2); // define the LCD as 16 column by 2 rows
  lcd.backlight(); // switch on the backlight
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("no GPS");
  sgps.begin(9600);
  // start gsm port
  Serial.begin(9600);
  // off led
  pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, LOW);
  pinMode(reset_sim800_pin, INPUT); digitalWrite(reset_sim800_pin, LOW);
  varInit(); // init start variable
  wdt_enable(WDTO_4S); // start WDT by 4 sec
}

void loop() {
  wdt_reset(); // reset WDT, without this, arduino reset after wdt time
  //delay(5000); // test wdt
  current_millis = millis(); // main timer
  // get http page
  if (((current_millis - timer_gprs_req) >= period_gprs_req) && (wait_response == 0) && (modem_step == 101)) {
    timer_gprs_req = current_millis; // reset timer gprs req
    // set mode load http page
    if (gprsON == 1)  modem_step = 26; else modem_step = 25;
  }
  // modem work
  loadDataFromModem(); // load data
  mainLoopModem(); // main actions on modem
  // Читаем широту и долготу и если успешно прочитались, печатаем
  if (readLatLon(lat, lon)) {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print(lat);
    lcd.setCursor(0, 1);
    lcd.print(lon);
  }
}

void varInit() {
  modem_step = 100; // first step = wait modem for registration on net
  wait_response = 0; // no wait response
  gprsON = 0;
  // -
  firstStart = 1;
}

void mainLoopModem() { // main action modem
  switch (modem_step) {
    case 100: {
        if ((current_millis - timer_reg_modem) >= 17000UL) { // wait 17sec registration modem // for test 10sec
          wait_response = 0; // do not response
          modem_step = 0; // go to init modem mode - first command
        }
        break;
      }
    case 101: {
        if (firstStart) {
          firstStart = 0;
        }
        if (pos_buf == 0) break; // no response
        // other find
        break;
      }
    default: {
        switch (wait_response) {
          case 0: {
              sendAtCommand(modem_step); // send command to modem
              break;
            }
          case 1: {
              if ((current_millis - timer_reg_modem) >= period_fixed_wait) { // if end timer wait response
                // we have problem - no correct response from modem
                resetModem();
              } else {
                if (pos_buf == 0) break; // no response
                // action before find response, example long ussd
                if (findRespParts() == 1) { // need fixed response
                  // good response from modem
                  // other action on one item command
                  switch (modem_step) {
                    case 32: { // end http
                        timer_gprs_req = current_millis; // reset timer gprs req
                        // go to next step
                        wait_response = 0; // do not wait response
                        getPgmBuf(6 * modem_step + 5);
                        modem_step = strToByte(pgm_buf); // to next at command or mode
                        pos_buf = 0; // clear response buf
                        break;
                      }
                    case 27: { // httpinit
                        gprsON = 1;
                        repeat601 = 0;
                        // go to next step after actions
                        wait_response = 0; // do not wait response
                        getPgmBuf(6 * modem_step + 5);
                        modem_step = strToByte(pgm_buf); // to next at command or mode
                        pos_buf = 0; // clear response buf
                        break;
                      }
                    case 20: { // get imei
                        byte sp1 = posSubStrFromPos(resp_buf, pos_buf, (char *) "\r\n", 0);
                        if (sp1 > 0) {
                          if ((resp_buf[sp1 + 1] >= 0x30) && (resp_buf[sp1 + 1] <= 0x39)) {
                            byte sp2 = posSubStrFromPos(resp_buf, pos_buf, (char *) "\r\n\r\n", sp1 + 15);
                            if ((sp2 >= (sp1 + 17)) && (sp2 <= (sp1 + 20))) {
                              byte rzn = sp2 - sp1 - 2;
                              for (byte i = 0; i <= rzn; ++i) {
                                gprs_imei_code[i] = resp_buf[i + sp1 + 1];
                              }
                              gprs_imei_code[rzn] = 0;
                              strcpy(original_imei_code, gprs_imei_code);
                              // go to next step
                              wait_response = 0; // do not wait response
                              getPgmBuf(6 * modem_step + 5);
                              modem_step = strToByte(pgm_buf); // to next at command or mode
                              pos_buf = 0; // clear response buf
                              break;
                            }
                          }
                        }
                        gprs_imei_code[0] = 0;
                        // go to next step
                        wait_response = 0; // do not wait response
                        getPgmBuf(6 * modem_step + 5);
                        modem_step = strToByte(pgm_buf); // to next at command or mode
                        pos_buf = 0; // clear response buf
                        break;
                      }
                    default: {
                        // go to next step
                        wait_response = 0; // do not wait response
                        getPgmBuf(6 * modem_step + 5);
                        modem_step = strToByte(pgm_buf); // to next at command or mode
                        pos_buf = 0; // clear response buf
                      }
                  }
                }
              }
              break;
            }
          case 2: {
              if ((current_millis - timer_reg_modem) >= period_data_wait) { // if end timer wait response
                // no data or no user action
                // exit from command
                // go to next step
                wait_response = 0; // do not wait response
                getPgmBuf(6 * modem_step + 5);
                modem_step = strToByte(pgm_buf); // to next at command or mode
              } else {
                if (pos_buf == 0) break; // no response
                // read parts of sms or other commands or DTMF
                switch (modem_step) {
                  case 25: { // start gprs
                      if  ((posSubStrFromPos(resp_buf, pos_buf, (char *) "OK\r\n", 0) > 0)) {
                        gprsON = 1;
                        // go to next step
                        wait_response = 0; // do not wait response
                        getPgmBuf(6 * modem_step + 5);
                        modem_step = strToByte(pgm_buf); // to next at command or mode
                        break;
                      } else if ((posSubStrFromPos(resp_buf, pos_buf, (char *) "operation not allowed\r\n", 0) > 0)) {
                        // go to next step
                        wait_response = 0; // do not wait response
                        getPgmBuf(6 * modem_step + 5);
                        modem_step = strToByte(pgm_buf); // to next at command or mode
                        break;
                      }
                      break;
                    }
                  case 30: { // send http req
                      byte p1 = posSubStrFromPos(resp_buf, pos_buf, (char *) "+HTTPACTION:", 0);
                      if (p1 > 0) {
                        if (posSubStrFromPos(resp_buf, pos_buf, (char *) "\r\n", (p1 + 16)) > 0) {
                          if (posSubStrFromPos(resp_buf, pos_buf, (char *) ",601,", (p1 + 12)) > 0) {
                            ++repeat601;
                            if (repeat601 < 2) {
                              // repeat send
                              wait_response = 0; // do not wait response
                              modem_step = 29;
                              pos_buf = 0; // clear response buf
                              break;
                            } else {
                              // go to next step
                              wait_response = 0; // do not wait response
                              getPgmBuf(6 * modem_step + 5);
                              modem_step = strToByte(pgm_buf); // to next at command or mode
                              pos_buf = 0; // clear response buf
                              break;
                            }
                          } else if (posSubStrFromPos(resp_buf, pos_buf, (char *) ",200,", (p1 + 12)) > 0) {
                            // go to next step
                            wait_response = 0; // do not wait response
                            getPgmBuf(6 * modem_step + 5);
                            modem_step = strToByte(pgm_buf); // to next at command or mode
                            pos_buf = 0; // clear response buf
                            break;
                          }
                        }
                      }
                      break;
                    }
                  default: {
                      // go to next step after actions
                      wait_response = 0; // do not wait response
                      getPgmBuf(6 * modem_step + 5);
                      modem_step = strToByte(pgm_buf); // to next at command or mode
                      pos_buf = 0; // clear response buf
                    }
                }
              }
              break;
            }
          default: {
              // go to next step after actions
              wait_response = 0; // do not wait response
              getPgmBuf(6 * modem_step + 5);
              modem_step = strToByte(pgm_buf); // to next at command or mode
              pos_buf = 0; // clear response buf
            }
        }
      }
  }
  if (pos_buf >= (max_size_resp_buf - 1)) {
    pos_buf = 0; // clear response buf
    resp_buf[pos_buf] = 0;
  }
}

void loadDataFromModem() {
  // load data from modem to buf - only one line (string)
  if (Serial.available()) {
    byte br;
    while (Serial.available()) {
      br = Serial.read();
      if (br) {
        if (pos_buf >= (max_size_resp_buf - 1)) pos_buf = 0;
        resp_buf[pos_buf] = br; ++pos_buf;
      }
    }
    resp_buf[pos_buf] = 0; // stop byte of string
  }
}

byte findRespParts() { // find response parts in response buf
  byte countresp = 0, countgood = 0;
  if (resp1[0] > 0) { // exist response 1
    ++countresp;
    if (strPos(resp_buf, resp1) >= 0) {
      flresp1 = 1; // found response 1
    }
    if (resp2[0] > 0) { // exist response 2
      ++countresp;
      if (strPos(resp_buf, resp2 ) >= 0) {
        flresp2 = 1; // found response 2
      }
      if (resp3[0] > 0) { // exist response 3
        ++countresp;
        if (strPos(resp_buf, resp3) >= 0) {
          flresp3 = 1; // found response 3
        }
      }
    }
  }
  if (flresp1 == 1) {
    ++countgood;
  }
  if (flresp2 == 1) {
    ++countgood;
  }
  if (flresp3 == 1) {
    ++countgood; // calculate good response
  }
  if ((countresp > 0) && (countresp == countgood)) return 1; else return 0;
}

void sendAtCommand(byte numcmd) { // send at command if modem not busy
  // find key worlds
  getPgmBuf(6 * numcmd);
  if (posSubStrFromPos(pgm_buf, strlen(pgm_buf), (char *) "~imei~", 0) > 0) {
    pgm_buf[strlen(pgm_buf) - 6] = 0; // delete text ~imei~
    strcpy(gprs_imei_code, original_imei_code);
    strcat(pgm_buf, dev_id);
    //strcat(pgm_buf, gprs_imei_code);
    // add other data
#define len_str 11 // 5 до точки + 5 после точки + сама точка
    strcat(pgm_buf, "&ln=");
    char xxx[len_str + 1];
    memset(xxx, 0, len_str + 1);
    dtostrf(lat, len_str, 5, xxx);
    strcat(pgm_buf, xxx);
    strcat(pgm_buf, "&lt=");
    memset(xxx, 0, len_str + 1);
    dtostrf(lon, len_str, 5, xxx);
    strcat(pgm_buf, xxx);
    // end line link
    strcat(pgm_buf, "\"\r\n");
    Serial.print(pgm_buf);
  } else {
    Serial.print(pgm_buf); // send cmd from cmd buf by number cmd
  }
  timer_reg_modem = current_millis; // reset wait response timer
  // load response from command to buf
  getPgmBuf(6 * numcmd + 1);
  if (pgm_buf[0] == 0) { // no response
    resp1[0] = 0; resp2[0] = 0; resp3[0] = 0; // no response
    wait_response = 0;
    getPgmBuf(6 * numcmd + 5);
    modem_step = strToByte(pgm_buf); // go to next step or mode
    pos_buf = 0; // clear response buf
    return; // next loop
  } else {
    getPgmBuf(6 * numcmd + 1);
    byte i = 0; while ((resp1[i] = pgm_buf[i]) > 0) ++i; resp1[i] = 0; // save first response from buf at cmd
    getPgmBuf(6 * numcmd + 2);
    if (pgm_buf[0] == 0) { // no second response
      resp2[0] = 0; resp3[0] = 0; // no response 2 and 3
    } else {
      byte i = 0; while ((resp2[i] = pgm_buf[i]) > 0) ++i; resp2[i] = 0; // save secont response from buf at cmd
      getPgmBuf(6 * numcmd + 3);
      if (pgm_buf[0] == 0) { // no thr response
        resp3[0] = 0; // no response 3
      } else {
        byte i = 0; while ((resp3[i] = pgm_buf[i]) > 0) ++i; resp3[i] = 0; // save thr response from buf at cmd
      }
    }
  }
  getPgmBuf(6 * numcmd + 4);
  wait_response = strToByte(pgm_buf); // set wait resp from command buf
  flresp1 = 0; flresp2 = 0; flresp3 = 0; // clear result response
  pos_buf = 0; // clear response buf
}

char* LastPos(char *str1, char *str2) { // find substring in string
  int L1 = strlen(str1);
  int L2 = strlen(str2);
  for (int i = L1 - L2; i >= 0; i--)
  {
    int j = 0;
    for (; j < L2; j++)
      if ((str1[i + j] != str2[j]))
        break;
    if (j == L2)
      return str1 + i;
  }
  return 0;
}

int strPos(char *str11, char *str22) { // find position substring in string
  char*p = LastPos(str11, str22);
  int n = p - str11;
  return n;
}

byte strToByte(char *instr) {
  byte sl = strlen(instr);
  if (sl < 1) return 0;
  byte res = 0, i = 0;
  while (instr[i] > 0) {
    res += ((instr[i] - '0') * pow(10, (sl - i - 1)));
    ++i;
  }
  if (sl > 2) ++res;
  return res;
}

byte posSubStrFromPos(char *inBuf, byte maxPosBuf, char *subStr, byte resPos) {
  if (resPos >= maxPosBuf) return 0;
  while ((resPos < maxPosBuf) && (inBuf[resPos] > 0)) {
    byte isub = 0;
    if (inBuf[resPos] == subStr[isub]) {
      byte sslen = strlen(subStr);
      while (((resPos + isub) < maxPosBuf) && (inBuf[resPos + isub] > 0) && (isub < sslen)) {
        if (subStr[isub] != inBuf[resPos + isub]) break;
        ++isub;
      }
      if (isub >= sslen)   {
        ++resPos;
        return resPos;
      }
    }
    ++resPos;
  }
  return 0;
}

void resetModem() {
  // reset modem
  pinMode(reset_sim800_pin, OUTPUT);
  digitalWrite(reset_sim800_pin, LOW);
  delay(115);
  //digitalWrite(reset_sim800_pin, HIGH);
  pinMode(reset_sim800_pin, INPUT); digitalWrite(reset_sim800_pin, LOW);
  // new init modem and start new main loop
  timer_reg_modem = current_millis; // reset registration modem timer
  varInit(); // init - like first start device
}

---

 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Строка 88 URL

Модем подключается к HW UART пины 0 и 1 МК

GPS модуль 3 и 4 пины

строка 5 идентификатор устройства - идет первым в параметрах URL, потом координаты