備忘錄_20160105(定位) 修改 回首頁

程式 2026-05-13 15:25:48 1778657148 100
temp3


#define iModemRx 26
#define iModemTx 27
#define iCharArrayMax 1024

#include <ctype.h>

HardwareSerial SerialAT(1);

char caATCmd[]="AT+CGPSINFO";
char caATKeyword[]="+CGPSINFO:";
char caPhp[]="cgpsinfo.php";

/*
char caATCmd[]="AT+CGNSINF";
char caATKeyword[]="+CGNSINF:";
char caPhp[]="cgnsinf.php";
*/

void qa(const char caQuestion[], char caAnswer[])
{
  while(SerialAT.available()) { SerialAT.read(); } // clear leftover data
  
  SerialAT.write(caQuestion);
  SerialAT.write("\r\n");
  
  delay(50);
  
  int iLen=0;
  unsigned long ulLast=millis();
  
  // maybe multi lines
  while((millis()-ulLast)<10000)
  {
    while(SerialAT.available())
    {
      char c1=SerialAT.read();
      ulLast=millis();
      if(iLen<(iCharArrayMax-1))
      {
        caAnswer[iLen]=c1;
        iLen++;
        caAnswer[iLen]='\0';
      }
    }
    
    if(strstr(caAnswer, "OK") || strstr(caAnswer, "ERROR")) { break; }
  }
  
  delay(50);
}

bool getBooQA(const char caQuestion[], const char caKeyword[])
{
  char caAnswerBuffer[iCharArrayMax];
  qa(caQuestion, caAnswerBuffer);
  
  if(strstr(caAnswerBuffer, caKeyword)!=NULL) { return true; }
  return false;
}

void setup()
{
  char caAnswer[iCharArrayMax];
  
  Serial.begin(115200); // esp32
  SerialAT.begin(115200, SERIAL_8N1, iModemRx, iModemTx); // sim7600g-h
  pinMode(4, OUTPUT);
  digitalWrite(4, HIGH);
  delay(3000);
  
  while(getBooQA("AT", "OK")==false) { delay(1000); } // wait until AT is OK
  
  // enable GPS via AT+CGPS=1
  qa("AT+CGPS=0", caAnswer);
  delay(3000);
  qa("AT+CGPS=1", caAnswer);
  
  while(getBooQA("AT+CGDCONT=1,\"IP\",\"internet\"", "OK")==false) { delay(1000); } // network registration
}

bool getBooExtractGPSDataOk(char caInput[], char caOutput[], int iOutputMax, const char caKeyword[])
{
  int iIdxInput=0;
  int iIdxOutput=0;
  bool booFound=false;

  while(true)
  {
    if(caInput[iIdxInput]=='\0') { break; }
    if(strncmp(&caInput[iIdxInput], caKeyword, strlen(caKeyword))==0)
    {
      booFound=true;
      iIdxInput+=strlen(caKeyword);
      while(caInput[iIdxInput]==' ') { iIdxInput++; } // remove spaces
      break;
    }
    iIdxInput++;
  }
  if(booFound==false) { return false; }
  
  while(true)
  {
    if(caInput[iIdxInput]=='\0') { break; }
    if(caInput[iIdxInput]=='\r' || caInput[iIdxInput]=='\n') { break; }
    if(iIdxOutput<(iOutputMax-1))
    {
      caOutput[iIdxOutput]=caInput[iIdxInput];
      iIdxOutput++;
    }
    iIdxInput++;
  }
  caOutput[iIdxOutput]='\0';
  
  if(iIdxOutput<=28) { return false; }
  if(caOutput[11]!=',' || caOutput[13]!=',' || caOutput[26]!=',' || caOutput[28]!=',') { return false; }
  
  return true;
  //return (iIdxOutput>0);
}

bool getBooSafeChar(char c1)
{
  if ((c1 >= 'a' && c1 <= 'z') ||
      (c1 >= 'A' && c1 <= 'Z') ||
      (c1 >= '0' && c1 <= '9'))
  {
    return true;
  }

  if (c1 == '-' || 
      c1 == '_' || 
      c1 == '.' || 
      c1 == '~')
  {
    return true;
  }

  return false;
}

void encodeURIComponent(const char caInput[], char caOutput[], int iOutputMax)
{
  int iIdxInput=0;
  int iIdxOutput=0;

  while(caInput[iIdxInput]!='\0' && iIdxOutput<(iOutputMax-1))
  {
    char c1=caInput[iIdxInput];
    
    if(c1=='\r' || c1=='\n')
    {
    }
    else if(getBooSafeChar(c1)==true)
    {
      caOutput[iIdxOutput]=c1;
      iIdxOutput++;
    }
    else
    {
      if((iIdxOutput+3)>=iOutputMax) { break; }
      sprintf(&caOutput[iIdxOutput], "%%%02X", (unsigned char)c1);
      iIdxOutput+=3;
    }
    
    iIdxInput++;
  }
  
  caOutput[iIdxOutput]='\0';
}

void sendGpsData(const char caPhp[], const char caGpsData[])
{
  char caEncodedGpsData[iCharArrayMax];
  
  while(true)
  {
    if(getBooQA("AT+CPIN?", "+CPIN: READY")==false) { break; }
    if(getBooQA("AT+CGATT=1", "OK")==false) { break; }
    if(getBooQA("AT+CGATT?", "+CGATT: 1")==false) { break; }
    if(getBooQA("AT+HTTPINIT", "OK")==false) { break; }
    
    // parameters
    encodeURIComponent(caGpsData, caEncodedGpsData, iCharArrayMax);
    char caCommand[1024];
    snprintf(
      caCommand,
      sizeof(caCommand),
      "AT+HTTPPARA=\"URL\",\"http://liujiaje.com/resources/20260513_lilygo_t_sim7600g_h/%s?id=%s&data=%s\"",
      caPhp, "lilygo1", caEncodedGpsData);
    if(getBooQA(caCommand, "OK")==false) { break; }
    
    if(getBooQA("AT+HTTPACTION=0", "OK")==true)
    {
      delay(50);
      getBooQA("AT+HTTPREAD=0,200", "."); // read 200 bytes
      delay(50);
    }
    
    while(getBooQA("AT+HTTPTERM", "OK")==false) { delay(1000); }
    // delay(500);
    
    break;
  }

}

void loop() 
{
  char caAnswer[iCharArrayMax];
  char caGpsData[iCharArrayMax];
  
  while(true)
  {
    if(getBooQA("AT+CGPS?", "+CGPS: 1,1")==false) { break; }
    delay(10);
    
    qa(caATCmd, caAnswer);
    if(getBooExtractGPSDataOk(caAnswer, caGpsData, sizeof(caGpsData), caATKeyword)==false) { break; }
    if(strlen(caGpsData)<=14) { break; }
    
    sendGpsData(caPhp, caGpsData);
    // delay(4000);
    break;
  }
  
  delay(1000);
  
  /*
  while (Serial.available()) { SerialAT.write(Serial.read()); }
  while (SerialAT.available()) { Serial.write(SerialAT.read()); }
  */  
}