vshymanskyy / TinyGSM

A small Arduino library for GSM modules, that just works
GNU Lesser General Public License v3.0
1.91k stars 708 forks source link

A7670E gsm modem #734

Open Blackhoody12 opened 1 year ago

Blackhoody12 commented 1 year ago

Hello, I have one question about this library. Does it support A7670E gsm module? I have shield for raspberry (which can be used with esp32 aswell) with this modem. And problem is I cant make it work (i need https protocol). I can communicate with module, get modem info, signal, etc. etc. But when it comes to https request (post), nothing happen. Here is code Im using:

#define TINY_GSM_MODEM_SIM7600
#define SerialMon Serial
#define SerialAT Serial1
#define TINY_GSM_DEBUG SerialMon
#define TINY_GSM_TEST_GPRS true
#define TINY_GSM_TEST_TCP true
#define GSM_PIN ""

// Your GPRS credentials, if any
const char apn[] = ""; 
const char gprsUser[] = "";
const char gprsPass[] = "";
const char sn[] = "12345678";
// Server details to test TCP/SSL
const char server[] = "xxx.xxxxxxxxxx.pl";
const char resource[] = "/api/get_power_status";
const int port = 443;

#include <TinyGsmClient.h>
#include <HTTPClient.h>
#include "SSLClient.h"
#include "utilities.h"
#include "certs.h"

TinyGsm modem(SerialAT);

// HTTPS Transport
TinyGsmClient base_client(modem, 0);
SSLClient secure_layer(&base_client);
HttpClient client = HttpClient(secure_layer, server, port);

void setup()
{
    SerialMon.begin(115200);
    delay(5000);
    SerialAT.begin(UART_BAUD, SERIAL_8N1, MODEM_RX, MODEM_TX);

    secure_layer.setCACert(root_ca);
}

void loop()
{
    bool res;
    Serial.println("Initializing modem...");
    if (!modem.init())
    {
        if (!modem.restart())
        {
            Serial.println("Failed to restart modem, delaying 10s and retrying");
            return;
        }
    }

#if TINY_GSM_TEST_GPRS
    String ret;
    do
    {
        ret = modem.setNetworkMode(54);
        delay(500);
    } while (!ret);

    String name = modem.getModemName();
    Serial.print("Modem Name: ");
    Serial.println(name);

    String modemInfo = modem.getModemInfo();
    Serial.print("Modem Info: ");
    Serial.println(modemInfo);

    if (GSM_PIN && modem.getSimStatus() != 3)
    {
        modem.simUnlock(GSM_PIN);
    }

    Serial.println("Waiting for network...");
    if (!modem.waitForNetwork(600000L))
    {
        return;
    }

    if (modem.isNetworkConnected())
    {
        Serial.println("Network connected");
    }
#endif

#if TINY_GSM_TEST_GPRS
    Serial.print("Connecting to ");
    Serial.println(apn);
    if (!modem.gprsConnect(apn, gprsUser, gprsPass))
    {
        return;
    }
    modem.sendAT(GF("+CNSMOD?"));
    if (modem.waitResponse(GF(GSM_NL "+CNSMOD:")) != 1)
    {
    }
    int nmodec = modem.stream.readStringUntil(',').toInt() != 0;
    int nmode = modem.stream.readStringUntil('\n').toInt();
    modem.waitResponse();

    res = modem.isGprsConnected();
    Serial.print("GPRS status: ");
    Serial.println(res);
    String ccid = modem.getSimCCID();
    Serial.print("CCID: ");
    Serial.println(ccid);
    String imei = modem.getIMEI();
    Serial.print("IMEI:");
    Serial.println(imei);
    String imsi = modem.getIMSI();
    Serial.print("IMSI: ");
    Serial.println(imsi);
    String cop = modem.getOperator();
    Serial.print("Operator : ");
    Serial.println(cop);
    IPAddress local = modem.localIP();
    Serial.print("Local IP: ");
    Serial.println(local);
#endif

#if TINY_GSM_TEST_TCP && defined TINY_GSM_MODEM_HAS_TCP

    if (!modem.isGprsConnected())
    {
        Serial.println("... not connected");
    }
    else
    {
        Serial.print("Connecting to ");
        Serial.println(server);
        Serial.println("Making POST request securely");
        String contentType = "Content-Type: application/x-www-form-urlencoded";
        String postData = "sn=" + String(sn);
        client.post(resource, contentType, postData);
        int status_code = client.responseStatusCode();
        String response = client.responseBody();

        Serial.print("Status code: ");
        Serial.println(status_code);
        Serial.print("Response: ");
        Serial.println(response);

        client.stop();
    }
#endif

#if TINY_GSM_TEST_GPRS
    modem.gprsDisconnect();
    if (!modem.isGprsConnected())
    {
        Serial.println("GPRS disconnected");
    }
    else
    {
        Serial.println("GPRS disconnect: Failed.");
    }
#endif
    delay(2000);
}

So, communication works as wrote ealier, I get all info from modem but when it comes to make https POST I get error code -2 which in HttpClient library states:

// This call was made when the HttpClient class wasn't expecting it
// to be called.  Usually indicates your code is using the class
// incorrectly
static const int HTTP_ERROR_API =-2;

Any idea how to fix it?

deeja commented 11 months ago

@Blackhoody12
I'm using the A7670SA on a Lilygo board and this is working for me, so maybe it will work for you?

/*
  FILE: AllFunctions.ino
  https://github.com/Xinyuan-LilyGO/T-A7670X/blob/main/examples/TinyGSM_Net_GNSS/TinyGSM_Net_GNSS.ino
  AUTHOR: Koby Hale
  PURPOSE: Test functionality
*/

#include <Arduino.h>
#define TINY_GSM_MODEM_SIM7600
#define TINY_GSM_RX_BUFFER 1024 // Set RX buffer to 1Kb
#define SerialMon Serial
#define SerialAT Serial1

// See all AT commands, if wanted
#define DUMP_AT_COMMANDS

/*
   Tests enabled
*/
#define TINY_GSM_TEST_GPRS true
#define TINY_GSM_TEST_GPS true
#define TINY_GSM_POWERDOWN true
#define TINY_GSM_TEST_TCP true

// set GSM PIN, if any
#define GSM_PIN ""

// Your GPRS credentials, if any
const char apn[] = "YOUR APN";
const char gprsUser[] = "";
const char gprsPass[] = "";

// Server details to test TCP/SSL
const char server[] = "vsh.pp.ua";
const char resource[] = "/TinyGSM/logo.txt";

float lat = 0;
float lon = 0;
float speed = 0;
float alt = 0;
int vsat = 0;
int usat = 0;
float accuracy = 0;
int year = 0;
int month = 0;
int day = 0;
int hour = 0;
int minute = 0;
int second = 0;

#include <TinyGsmClient.h>
#include <SPI.h>
#include <SD.h>
#include <Ticker.h>

#ifdef DUMP_AT_COMMANDS // if enabled it requires the streamDebugger lib
#include <StreamDebugger.h>
StreamDebugger debugger(SerialAT, Serial);
TinyGsm modem(debugger);
#else
TinyGsm modem(SerialAT);
#endif

#define uS_TO_S_FACTOR 1000000ULL // Conversion factor for micro seconds to seconds
#define TIME_TO_SLEEP 60          // Time ESP32 will go to sleep (in seconds)

#define UART_BAUD 115200
#define PIN_DTR 25
#define PIN_TX 26
#define PIN_RX 27
#define PWR_PIN 4
#define BAT_ADC 35
#define BAT_EN 12
#define PIN_RI 33
#define RESET 5

#define SD_MISO 2
#define SD_MOSI 15
#define SD_SCLK 14
#define SD_CS 13

int counter, lastIndex, numberOfPieces = 24;
String pieces[24], input;

void setup()
{
  // Set console baud rate
  Serial.begin(115200);
  delay(10);

  Serial.println("setup...");

  pinMode(BAT_EN, OUTPUT);
  digitalWrite(BAT_EN, HIGH);

  // A7608 Reset
  pinMode(RESET, OUTPUT);
  digitalWrite(RESET, LOW);
  delay(100);
  digitalWrite(RESET, HIGH);
  delay(3000);
  digitalWrite(RESET, LOW);

  pinMode(PWR_PIN, OUTPUT);
  digitalWrite(PWR_PIN, LOW);
  delay(100);
  digitalWrite(PWR_PIN, HIGH);
  delay(1000);
  digitalWrite(PWR_PIN, LOW);

  SPI.begin(SD_SCLK, SD_MISO, SD_MOSI, SD_CS);
  if (!SD.begin(SD_CS))
  {
    Serial.println("SDCard MOUNT FAIL");
  }
  else
  {
    uint32_t cardSize = SD.cardSize() / (1024 * 1024);
    String str = "SDCard Size: " + String(cardSize) + "MB";
    Serial.println(str);
  }

  Serial.println("\nWait...");

  delay(1000);

  SerialAT.begin(UART_BAUD, SERIAL_8N1, PIN_RX, PIN_TX);

  // Restart takes quite some time
  // To skip it, call init() instead of restart()
  Serial.println("Initializing modem...");
  if (!modem.init())
  {
    Serial.println("Failed to restart modem, attempting to continue without restarting");
    return;
  }

  String name = modem.getModemName();
  delay(500);
  Serial.println("Modem Name: " + name);

  String modemInfo = modem.getModemInfo();
  delay(500);
}

void loop()
{

  Serial.println("Initializing modem...");
  if (!modem.init())
  {
    Serial.println("Failed to restart modem, attempting to continue without restarting");
  }

  String name = modem.getModemName();
  delay(500);
  Serial.println("Modem Name: " + name);

  String modemInfo = modem.getModemInfo();
  delay(500);

#if TINY_GSM_TEST_GPRS
  // Unlock your SIM card with a PIN if needed
  if (GSM_PIN && modem.getSimStatus() != 3)
  {
    modem.simUnlock(GSM_PIN);
  }
#endif

#if TINY_GSM_TEST_GPRS && defined TINY_GSM_MODEM_XBEE
  // The XBee must run the gprsConnect function BEFORE waiting for network!
  modem.gprsConnect(apn, gprsUser, gprsPass);
#endif

#if TINY_GSM_TEST_GPRS
  DBG("Waiting for network...");
  if (!modem.waitForNetwork())
  {
    delay(10000);
    return;
  }

  if (modem.isNetworkConnected())
  {
    DBG("Network connected");
  }
#endif

#if TINY_GSM_TEST_GPRS
  DBG("Connecting to", apn);
  if (!modem.gprsConnect(apn, gprsUser, gprsPass))
  {
    delay(10000);
    return;
  }

  bool res = modem.isGprsConnected();
  DBG("GPRS status:", res ? "connected" : "not connected");

  String ccid = modem.getSimCCID();
  DBG("CCID:", ccid);

  String imei = modem.getIMEI();
  DBG("IMEI:", imei);

  String cop = modem.getOperator();
  DBG("Operator:", cop);

  IPAddress local = modem.localIP();
  DBG("Local IP:", local);

  int csq = modem.getSignalQuality();
  DBG("Signal quality:", csq);

#endif
#if TINY_GSM_TEST_TCP
  TinyGsmClient client(modem, 0);
  const int port = 80;
  DBG("Connecting to", server);
  if (!client.connect(server, port))
  {
    DBG("... failed");
  }
  else
  {
    // Make a HTTP GET request:
    client.print(String("GET ") + resource + " HTTP/1.0\r\n");
    client.print(String("Host: ") + server + "\r\n");
    client.print("Connection: close\r\n\r\n");

    // Wait for data to arrive
    uint32_t start = millis();
    while (client.connected() && !client.available() &&
           millis() - start < 30000L)
    {
      delay(100);
    };

    // Read data
    start = millis();
    char logo[1204] = {
        '\0',
    };
    int read_chars = 0;
    while (client.connected() && millis() - start < 10000L)
    {
      while (client.available())
      {
        logo[read_chars] = client.read();
        logo[read_chars + 1] = '\0';
        read_chars++;
        start = millis();
      }
    }

    // Serial.println(logo);
    DBG("#####  RECEIVED:", strlen(logo), "CHARACTERS");
    client.stop();
  }
#endif

#if TINY_GSM_TEST_GPS

  // Disable gnss
  modem.sendAT("+CGNSSPWR=0,1");
  modem.waitResponse(10000L);

  modem.sendAT("+CGDRT=4,1");
  modem.waitResponse(10000L);
  modem.sendAT("+CGSETV=4,0");
  modem.waitResponse(10000L);

  // Enable gnss - Use this rather than modem.enableGPS();
  modem.sendAT("+CGNSSPWR=1,1");
  modem.waitResponse(10000L);

   //

  // Wait gnss start.
  SerialMon.print("\tWait for GPS to be ready.");
  while (modem.waitResponse(10000UL, "+CGNSSPWR: READY!") != 1)
  {
    SerialMon.print(".");
  }
  SerialMon.println();

  SerialMon.println("Attempt to get AGPS data from server");
  modem.sendAT("+CAGPS");
  modem.waitResponse(10000L);

  // Set gnss mode use GPS.
  /*
1GPS
2BDS
3GPS + BDS
4GLONASS
5GPS + GLONASS
6BDS + GLONASS
7GPS + BDS + GLONASS
*/
  modem.sendAT("+CGNSSMODE=7");
  modem.waitResponse(10000L);
  modem.sendAT("+CGNSSNMEA=1,1,1,1,1,1,0,0");
  modem.waitResponse(10000L);
  modem.sendAT("+CGPSNMEARATE=2");

  // GPS DEBUG
  // modem.waitResponse(10000L);
  // modem.sendAT("+CGNSSTST=1");
  // modem.waitResponse(10000L);
  // modem.sendAT("+CGNSSPORTSWITCH=0,1");
  // modem.waitResponse(10000L);

  float parameter1, parameter2;
  char buf[16];

  // possibly do this as an alternative to the one below

  // while (1)
  // {

  //   Serial.print("Getting location - ");
  //   if (modem.getGPS(&lat, &lon, &speed, &alt, &vsat, &usat, &accuracy, &year, &month, &day, &hour, &minute, &second))
  //   {
  //     Serial.printf("GPS  lat %f | lon %f | speed %f | alt %f | vsat %d | usat %d | accuracy %f  %d-%d-%d %d:%d:%f", &lat, &lon, &speed, &alt, &vsat, &usat, &accuracy, &year, &month, &day, &hour, &minute, &second);
  //     Serial.println();

  //     break;
  //   }
  //   Serial.println("Failed");

  //   delay(5000);
  // }

  while (1)
  {
    if (modem.getGPS(&parameter1, &parameter2))
    {
      modem.sendAT(GF("+CGNSSINFO"));
      if (modem.waitResponse(GF(GSM_NL "+CGNSSINFO:")) == 1)
      {
        String res = modem.stream.readStringUntil('\n');
        String lat = "";
        String n_s = "";
        String lon = "";
        String e_w = "";
        res.trim();
        lat = res.substring(8, res.indexOf(',', 8));
        n_s = res.substring(19, res.indexOf(',', res.indexOf(',', 19)));
        lon = res.substring(21, res.indexOf(',', res.indexOf(',', 21)));
        e_w = res.substring(33, res.indexOf(',', res.indexOf(',', 33)));
        delay(100);
        Serial.println("****************GNSS********************");
        Serial.printf("lat:%s %s\n", lat, n_s);
        Serial.printf("lon:%s %s\n", lon, e_w);
        float flat = atof(lat.c_str());
        float flon = atof(lon.c_str());
        flat = (floor(flat / 100) + fmod(flat, 100.) / 60) *
               (n_s == "N" ? 1 : -1);
        flon = (floor(flon / 100) + fmod(flon, 100.) / 60) *
               (e_w == "E" ? 1 : -1);
        Serial.print("Latitude:");
        Serial.println(flat);
        Serial.print("Longitude:");
        Serial.println(flon);
      }
      break;
    }
    else
    {
      Serial.print("getGPS ");
      Serial.println(millis());
    }
    delay(2000);
  }

  // Disable gnss
  modem.sendAT("+CGNSSPWR=0,1"); // 0 (off), 1 (hotstart save postition)
  modem.waitResponse(10000L);

#endif

#if TINY_GSM_TEST_GPRS
  modem.gprsDisconnect();
  if (!modem.isGprsConnected())
  {
    DBG("GPRS disconnected");
  }
  else
  {
    DBG("GPRS disconnect: Failed.");
  }
#endif

#if TINY_GSM_POWERDOWN
  // Try to power-off (modem may decide to restart automatically)
  // To turn off modem completely, please use Reset/Enable pins
  Serial.println("Poweroff.");
  DBG("Poweroff.");
  modem.poweroff();

#endif

  // Test is complete Set it to sleep mode
  esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
  delay(200);
  esp_deep_sleep_start();

  // Do nothing forevermore
  while (true)
  {
    modem.maintain();
  }
}