TTGO T-Call ESP32 SIM800L cannot be connected with the Cayenne dashboard

Hello everybody in the Cayenne Community,

I am currently using the TTGO T-Call ESP32 SIM800L device and it can’t seem to be connected to the Cayenne dashboard.

The coding, fortunately, can be uploaded into the device but the site is still waiting for the device to be connected.

I have used the Cayenne-MQTT-GSM library < Cayenne-MQTT-Arduino/GSM.ino at master · myDevicesIoT/Cayenne-MQTT-Arduino · GitHub >

This is my coding:

/*
This example shows how to connect to Cayenne using a GSM device and send/receive sample data.

The CayenneMQTT Library is required to run this sketch. If you have not already done so you can install it from the Arduino IDE Library Manager.

Steps:
1. Install the TinyGSM library (https://github.com/vshymanskyy/TinyGSM) from the Arduino Library Manager.
2. Set the Cayenne authentication info to match the authentication info from the Dashboard.
3. Uncomment the correct GSM modem type and set the GSM connection info, if needed.
4. Compile and upload the sketch.
5. A temporary widget will be automatically generated in the Cayenne Dashboard. To make the widget permanent click the plus sign on the widget.
*/

//  #define CAYENNE_DEBUG         // Uncomment to show debug messages
#define CAYENNE_PRINT Serial  // Comment this out to disable prints and save space

// Uncomment your modem type:
#define TINY_GSM_MODEM_SIM800
#define SIM800L_IP5306_VERSION_20200811

#include <CayenneMQTTGSM.h>
#include "utilities.h"

// This sketch uses a software serial connection.
// #include <SoftwareSerial.h>
// SoftwareSerial gsmSerial(2, 3); // RX, TX
// If you are using a device that supports a hardware serial (Mega, Leonardo, etc.) and prefer to use
// that you can comment out the above lines and uncomment the one below.
 #define gsmSerial Serial1

// GSM connection info.
char apn[] = "celcom.net.my"; // Access point name. Leave empty if it is not needed.
char gprsLogin[] = ""; // GPRS username. Leave empty if it is not needed.
char gprsPassword[] = ""; // GPRS password. Leave empty if it is not needed.
char pin[] = "1234"; // SIM pin number. Leave empty if it is not needed.

// Cayenne authentication info. This should be obtained from the Cayenne Dashboard.
char username[] = "-fc0a-11eb-be09-";
char password[] = "";
char clientID[] = "-fc0b-11eb-be09-";

void setup() {
  Serial.begin(115200);
  // Auto-detect the GSM serial baud rate. You can manually set it instead if you want to save a bit of space.
  TinyGsmAutoBaud(gsmSerial);
  Cayenne.begin(username, password, clientID, gsmSerial, apn, gprsLogin, gprsPassword, pin);
  
  pinMode(18, OUTPUT);
  pinMode(14, OUTPUT);
  pinMode(15, OUTPUT);
  pinMode(19, OUTPUT);

  digitalWrite(18, HIGH);
  digitalWrite(14, HIGH);
  digitalWrite(15, HIGH);
  digitalWrite(19, HIGH);
}

void loop() 
{
  Cayenne.loop();
}

CAYENNE_IN(V1) 
{
  digitalWrite(18, !getValue.asInt());
  // process received value
}

CAYENNE_IN(V2)
{
  digitalWrite(14, !getValue.asInt());
  // process received value
}

CAYENNE_IN(V3)
{
   digitalWrite(15, !getValue.asInt());
  // process received value
}

CAYENNE_IN(V4)
{
  digitalWrite(19, !getValue.asInt());
  // process received value
}

CAYENNE_OUT_DEFAULT()
{
  // Write data to Cayenne here. This example just sends the current uptime in milliseconds on virtual channel 0.
  Cayenne.virtualWrite(0, millis());
}
// Default function for processing actuator commands from the Cayenne Dashboard.
// You can also use functions for specific channels, e.g CAYENNE_IN(1) for channel 1 commands.
CAYENNE_IN_DEFAULT()
{
  CAYENNE_LOG("Channel %u, value %s", request.channel, getValue.asString());
  //Process message here. If there is an error set an error message using getValue.setError(), e.g getValue.setError("Error message");
}

utilities.h coding:

#include <Wire.h>

#if defined(SIM800L_IP5306_VERSION_20190610)

#define MODEM_RST             5
#define MODEM_PWRKEY          4
#define MODEM_POWER_ON       23
#define MODEM_TX             27
#define MODEM_RX             26

#define I2C_SDA              21
#define I2C_SCL              22
#define LED_GPIO             13
#define LED_ON               HIGH
#define LED_OFF              LOW

#define IP5306_ADDR          0x75
#define IP5306_REG_SYS_CTL0  0x00

// setPowerBoostKeepOn
bool setupPMU()
{
    bool en = true;
    Wire.begin(I2C_SDA, I2C_SCL);
    Wire.beginTransmission(IP5306_ADDR);
    Wire.write(IP5306_REG_SYS_CTL0);
    if (en) {
        Wire.write(0x37); // Set bit1: 1 enable 0 disable boost keep on
    } else {
        Wire.write(0x35); // 0x37 is default reg value
    }
    return Wire.endTransmission() == 0;
}


#elif defined(SIM800L_AXP192_VERSION_20200327)

#define MODEM_RST            5
#define MODEM_PWRKEY          4
#define MODEM_POWER_ON       23
#define MODEM_TX             27
#define MODEM_RX             26
#define MODEM_DTR            32
#define MODEM_RI             33

#define I2C_SDA              21
#define I2C_SCL              22
#define LED_GPIO             13
#define LED_ON               HIGH
#define LED_OFF              LOW


#elif defined(SIM800C_AXP192_VERSION_20200609)
// pin definitions
#define MODEM_PWRKEY          4
#define MODEM_POWER_ON       25
#define MODEM_TX             27
#define MODEM_RX             26
#define MODEM_DTR            32
#define MODEM_RI             33

#define I2C_SDA              21
#define I2C_SCL              22
#define LED_GPIO             12
#define LED_ON               LOW
#define LED_OFF              HIGH

#elif defined(SIM800L_IP5306_VERSION_20200811)


#define MODEM_RST             5
#define MODEM_PWRKEY          4
#define MODEM_POWER_ON       23
#define MODEM_TX             27
#define MODEM_RX             26

#define MODEM_DTR            32
#define MODEM_RI             33

#define I2C_SDA              21
#define I2C_SCL              22
#define LED_GPIO             13
#define LED_ON               HIGH
#define LED_OFF              LOW

#define IP5306_ADDR          0x75
#define IP5306_REG_SYS_CTL0  0x00

// setPowerBoostKeepOn
bool setupPMU()
{
    bool en = true;
    Wire.begin(I2C_SDA, I2C_SCL);
    Wire.beginTransmission(IP5306_ADDR);
    Wire.write(IP5306_REG_SYS_CTL0);
    if (en) {
        Wire.write(0x37); // Set bit1: 1 enable 0 disable boost keep on
    } else {
        Wire.write(0x35); // 0x37 is default reg value
    }
    return Wire.endTransmission() == 0;
}

#else

#error "Please select the corresponding model"

#endif


#if defined(SIM800L_AXP192_VERSION_20200327) || defined(SIM800C_AXP192_VERSION_20200609)
#include <axp20x.h>         //https://github.com/lewisxhe/AXP202X_Library

AXP20X_Class axp;

bool setupPMU()
{
// For more information about the use of AXP192, please refer to AXP202X_Library https://github.com/lewisxhe/AXP202X_Library
    Wire.begin(I2C_SDA, I2C_SCL);
    int ret = axp.begin(Wire, AXP192_SLAVE_ADDRESS);

    if (ret == AXP_FAIL) {
        Serial.println("AXP Power begin failed");
        return false;
    }

    //! Turn off unused power
    axp.setPowerOutPut(AXP192_DCDC1, AXP202_OFF);
    axp.setPowerOutPut(AXP192_LDO2, AXP202_OFF);
    axp.setPowerOutPut(AXP192_LDO3, AXP202_OFF);
    axp.setPowerOutPut(AXP192_DCDC2, AXP202_OFF);
    axp.setPowerOutPut(AXP192_EXTEN, AXP202_OFF);

    //! Do not turn off DC3, it is powered by esp32
    // axp.setPowerOutPut(AXP192_DCDC3, AXP202_ON);

    // Set the charging indicator to turn off
    // Turn it off to save current consumption
    // axp.setChgLEDMode(AXP20X_LED_OFF);

    // Set the charging indicator to flash once per second
    // axp.setChgLEDMode(AXP20X_LED_BLINK_1HZ);


    //! Use axp192 adc get voltage info
    axp.adc1Enable(AXP202_VBUS_VOL_ADC1 | AXP202_VBUS_CUR_ADC1 | AXP202_BATT_CUR_ADC1 | AXP202_BATT_VOL_ADC1, true);

    float vbus_v = axp.getVbusVoltage();
    float vbus_c = axp.getVbusCurrent();
    float batt_v = axp.getBattVoltage();
    // axp.getBattPercentage();   // axp192 is not support percentage
    Serial.printf("VBUS:%.2f mV %.2f mA ,BATTERY: %.2f\n", vbus_v, vbus_c, batt_v);

    return true;
}

#endif



void setupModem()
{

    // Start power management
    if (setupPMU() == false) {
        Serial.println("Setting power error");
    }

#ifdef MODEM_RST
    // Keep reset high
    pinMode(MODEM_RST, OUTPUT);
    digitalWrite(MODEM_RST, HIGH);
#endif

    pinMode(MODEM_PWRKEY, OUTPUT);
    pinMode(MODEM_POWER_ON, OUTPUT);

    // Turn on the Modem power first
    digitalWrite(MODEM_POWER_ON, HIGH);

    // Pull down PWRKEY for more than 1 second according to manual requirements
    digitalWrite(MODEM_PWRKEY, HIGH);
    delay(100);
    digitalWrite(MODEM_PWRKEY, LOW);
    delay(1000);
    digitalWrite(MODEM_PWRKEY, HIGH);

    // Initialize the indicator as an output
    pinMode(LED_GPIO, OUTPUT);
    digitalWrite(LED_GPIO, LED_OFF);
}

And this is what is being displayed in the serial monitor:

I would like to know what can I do to be able to connect this device with the Cayenne dashboard.

Thank you so much for your time and considerations.

I’m having trouble finding the example right now but you can always manually send the mqtt values using pubsubclient GitHub - knolleary/pubsubclient: A client library for the Arduino Ethernet Shield that provides support for MQTT.

I’ll have a look on my other computer tomorrow to see if I can find it there.

Thank you @adam for your response and your time in looking into my codes. I will look into the link that you have sent and see what I can do.

Please do let me know if you have found anything there.

Hello @adam, I was able to connect my TTGO T-Call device to the Cayenne dashboard using WiFi but I still could not do it using GSM. I was wondering whether you have found any solution to my problem.

Now, my coding could not even read my device.

My coding:

#define CAYENNE_DEBUG         // Uncomment to show debug messages
#define CAYENNE_PRINT Serial  // Comment this out to disable prints and save space

// Please select the corresponding model
#define SIM800L_IP5306_VERSION_20200811

// Uncomment your modem type:
#define TINY_GSM_MODEM_SIM800

#include "utilities.h"

#include <CayenneMQTTGSM.h>
#include <TinyGsmClient.h>

// This sketch uses a software serial connection.
// #include <SoftwareSerial.h>
// SoftwareSerial gsmSerial(2, 3); // RX, TX

// If you are using a device that supports a hardware serial (Mega, Leonardo, etc.) and prefer to use
// that you can comment out the above lines and uncomment the one below.
#define gsmSerial Serial1

#define relay1 18
#define relay2 14
#define relay3 15
#define relay4 19

// Hardware Serial on Mega, Leonardo, Micro
#define SerialAT Serial1

// Set serial for debug console (to the Serial Monitor, default speed 115200)
#define SerialMon Serial

// Define the serial console for debug prints, if needed
#define TINY_GSM_DEBUG SerialMon

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

// GSM connection info.
char apn[] = "celcom.net.my"; // Access point name. Leave empty if it is not needed.
char gprsLogin[] = ""; // GPRS username. Leave empty if it is not needed.
char gprsPassword[] = ""; // GPRS password. Leave empty if it is not needed.
char pin[] = "1234"; // SIM pin number. Leave empty if it is not needed.

// Cayenne authentication info. This should be obtained from the Cayenne Dashboard.
char username[] = "01ec54b0-fc0a-11eb-be09-83394739073b";
char password[] = "ae99534def0a65bcc41963e2887dfc880a0728d0";
char clientID[] = "a0a484a0-1b9b-11ec-9f5b-45181495093e";

#ifdef DUMP_AT_COMMANDS
#include <StreamDebugger.h>
StreamDebugger debugger(SerialAT, SerialMon);
TinyGsm modem(debugger);
#else
TinyGsm modem(SerialAT);
#endif
TinyGsmClient client(modem);

void setup() 
{
  Serial.begin(115200);
  // Auto-detect the GSM serial baud rate. You can manually set it instead if you want to save a bit of space.

  pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);
  pinMode(relay3, OUTPUT);
  pinMode(relay4, OUTPUT);

  digitalWrite(relay1, HIGH);
  digitalWrite(relay2, HIGH);
  digitalWrite(relay3, HIGH);
  digitalWrite(relay4, HIGH);

  delay(10);

  setupModem();

  SerialMon.println("Wait...");

  //Set GSM module baud rate and UART pins
  SerialAT.begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX);

  delay(6000);

  // Restart takes quite some time
  // To skip it, call init() instead of restart()
  SerialMon.println("Initializing modem...");
  modem.restart();
   //modem.init();

  String modemInfo = modem.getModemInfo();
  SerialMon.print("Modem Info: ");
  SerialMon.println(modemInfo);
  
  // Unlock your SIM card with a PIN
  // modem.simUnlock("1234");

  TinyGsmAutoBaud(gsmSerial);
  Cayenne.begin(username, password, clientID, gsmSerial, apn, gprsLogin, gprsPassword, pin);
}

void loop() 
{
  Cayenne.loop();
}

CAYENNE_IN(0) 
{
  int pinValue = getValue.asInt();
  digitalWrite(relay1, !pinValue);
  // process received value
}

CAYENNE_IN(1)
{
  int pinValue = getValue.asInt();
  digitalWrite(relay2, !pinValue);
  // process received value
}

CAYENNE_IN(3)
{
   int pinValue = getValue.asInt();
   digitalWrite(relay3, !pinValue);
  // process received value
}

CAYENNE_IN(3)
{
  int pinValue = getValue.asInt();
  digitalWrite(relay4, !pinValue);
  // process received value
}

// Default function for sending sensor data at intervals to Cayenne.
CAYENNE_OUT_DEFAULT()
{
  // Write data to Cayenne here. This example just sends the current uptime in milliseconds on virtual channel 0.
  Cayenne.virtualWrite(0, millis());
}

// You can also use functions for specific channels, e.g CAYENNE_IN(1) for channel 1 commands.
CAYENNE_IN_DEFAULT()
{
  CAYENNE_LOG("Channel %u, value %s", request.channel, getValue.asString());
  //Process message here. If there is an error set an error message using getValue.setError(), e.g getValue.setError("Error message");
}

utilities.h coding

#include <Wire.h>

#if defined(SIM800L_IP5306_VERSION_20190610)

#define MODEM_RST             5
#define MODEM_PWRKEY          4
#define MODEM_POWER_ON       23
#define MODEM_TX             27
#define MODEM_RX             26

#define I2C_SDA              21
#define I2C_SCL              22
#define LED_GPIO             13
#define LED_ON               HIGH
#define LED_OFF              LOW

#define IP5306_ADDR          0x75
#define IP5306_REG_SYS_CTL0  0x00

// setPowerBoostKeepOn
bool setupPMU()
{
    bool en = true;
    Wire.begin(I2C_SDA, I2C_SCL);
    Wire.beginTransmission(IP5306_ADDR);
    Wire.write(IP5306_REG_SYS_CTL0);
    if (en) {
        Wire.write(0x37); // Set bit1: 1 enable 0 disable boost keep on
    } else {
        Wire.write(0x35); // 0x37 is default reg value
    }
    return Wire.endTransmission() == 0;
}


#elif defined(SIM800L_AXP192_VERSION_20200327)

#define MODEM_RST            5
#define MODEM_PWRKEY          4
#define MODEM_POWER_ON       23
#define MODEM_TX             27
#define MODEM_RX             26
#define MODEM_DTR            32
#define MODEM_RI             33

#define I2C_SDA              21
#define I2C_SCL              22
#define LED_GPIO             13
#define LED_ON               HIGH
#define LED_OFF              LOW


#elif defined(SIM800C_AXP192_VERSION_20200609)
// pin definitions
#define MODEM_PWRKEY          4
#define MODEM_POWER_ON       25
#define MODEM_TX             27
#define MODEM_RX             26
#define MODEM_DTR            32
#define MODEM_RI             33

#define I2C_SDA              21
#define I2C_SCL              22
#define LED_GPIO             12
#define LED_ON               LOW
#define LED_OFF              HIGH

#elif defined(SIM800L_IP5306_VERSION_20200811)


#define MODEM_RST             5
#define MODEM_PWRKEY          4
#define MODEM_POWER_ON       23
#define MODEM_TX             27
#define MODEM_RX             26

#define MODEM_DTR            32
#define MODEM_RI             33

#define I2C_SDA              21
#define I2C_SCL              22
#define LED_GPIO             13
#define LED_ON               HIGH
#define LED_OFF              LOW

#define IP5306_ADDR          0x75
#define IP5306_REG_SYS_CTL0  0x00

// setPowerBoostKeepOn
bool setupPMU()
{
    bool en = true;
    Wire.begin(I2C_SDA, I2C_SCL);
    Wire.beginTransmission(IP5306_ADDR);
    Wire.write(IP5306_REG_SYS_CTL0);
    if (en) {
        Wire.write(0x37); // Set bit1: 1 enable 0 disable boost keep on
    } else {
        Wire.write(0x35); // 0x37 is default reg value
    }
    return Wire.endTransmission() == 0;
}

#else

#error "Please select the corresponding model"

#endif


#if defined(SIM800L_AXP192_VERSION_20200327) || defined(SIM800C_AXP192_VERSION_20200609)
#include <axp20x.h>         //https://github.com/lewisxhe/AXP202X_Library

AXP20X_Class axp;

bool setupPMU()
{
// For more information about the use of AXP192, please refer to AXP202X_Library https://github.com/lewisxhe/AXP202X_Library
    Wire.begin(I2C_SDA, I2C_SCL);
    int ret = axp.begin(Wire, AXP192_SLAVE_ADDRESS);

    if (ret == AXP_FAIL) {
        Serial.println("AXP Power begin failed");
        return false;
    }

    //! Turn off unused power
    axp.setPowerOutPut(AXP192_DCDC1, AXP202_OFF);
    axp.setPowerOutPut(AXP192_LDO2, AXP202_OFF);
    axp.setPowerOutPut(AXP192_LDO3, AXP202_OFF);
    axp.setPowerOutPut(AXP192_DCDC2, AXP202_OFF);
    axp.setPowerOutPut(AXP192_EXTEN, AXP202_OFF);

    //! Do not turn off DC3, it is powered by esp32
    // axp.setPowerOutPut(AXP192_DCDC3, AXP202_ON);

    // Set the charging indicator to turn off
    // Turn it off to save current consumption
    // axp.setChgLEDMode(AXP20X_LED_OFF);

    // Set the charging indicator to flash once per second
    // axp.setChgLEDMode(AXP20X_LED_BLINK_1HZ);


    //! Use axp192 adc get voltage info
    axp.adc1Enable(AXP202_VBUS_VOL_ADC1 | AXP202_VBUS_CUR_ADC1 | AXP202_BATT_CUR_ADC1 | AXP202_BATT_VOL_ADC1, true);

    float vbus_v = axp.getVbusVoltage();
    float vbus_c = axp.getVbusCurrent();
    float batt_v = axp.getBattVoltage();
    // axp.getBattPercentage();   // axp192 is not support percentage
    Serial.printf("VBUS:%.2f mV %.2f mA ,BATTERY: %.2f\n", vbus_v, vbus_c, batt_v);

    return true;
}

#endif



void setupModem()
{

    // Start power management
    if (setupPMU() == false) {
        Serial.println("Setting power error");
    }

#ifdef MODEM_RST
    // Keep reset high
    pinMode(MODEM_RST, OUTPUT);
    digitalWrite(MODEM_RST, HIGH);
#endif

    pinMode(MODEM_PWRKEY, OUTPUT);
    pinMode(MODEM_POWER_ON, OUTPUT);

    // Turn on the Modem power first
    digitalWrite(MODEM_POWER_ON, HIGH);

    // Pull down PWRKEY for more than 1 second according to manual requirements
    digitalWrite(MODEM_PWRKEY, HIGH);
    delay(100);
    digitalWrite(MODEM_PWRKEY, LOW);
    delay(1000);
    digitalWrite(MODEM_PWRKEY, HIGH);

    // Initialize the indicator as an output
    pinMode(LED_GPIO, OUTPUT);
    digitalWrite(LED_GPIO, LED_OFF);
}

Screenshot (526)
This is the type of board and the upload speed that I am using.

Screenshot (525)
This is the error that has kept on showing.

I would like to know what can I do.

can you share the entire error.

Hello @shramik_salgaonkar, I managed to upload my coding into my device. However, the Cayenne dashboard still could not connect with my device through GSM.

The display on the serial monitor:

What can I do?

the serial monitor shows only re rst and rebooting of the device. There is no message of connection established.

Are you certain these values are correct in your sketch?

// GSM connection info.
char apn[] = "celcom.net.my"; // Access point name. Leave empty if it is not needed.
char gprsLogin[] = ""; // GPRS username. Leave empty if it is not needed.
char gprsPassword[] = ""; // GPRS password. Leave empty if it is not needed.
char pin[] = "1234"; // SIM pin number. Leave empty if it is not needed.

The domain for their website is https://www.celcom.com.my

Like I said a few up you can use pubsubclient (GitHub - knolleary/pubsubclient: A client library for the Arduino Ethernet Shield that provides support for MQTT.) to manually send and process your mqtt messages. Unfortunately I was not able to find any examples of this. I thought I had some but I either deleted or was mistaken. If you give me a couple days I can try to

I also just noticed that your file doesn’t match the example here: Cayenne-MQTT-Arduino/GSM.ino at master · myDevicesIoT/Cayenne-MQTT-Arduino · GitHub

Copy the example and see if you get any connection, then start adding your code in one thing at a time.

The website of the SIM card that I am using is https://www.celcom.com.my, however the apn that I should us is “celcom.net.my”. I was not sure what I was suppose to do at this website (GitHub - knolleary/pubsubclient: A client library for the Arduino Ethernet Shield that provides support for MQTT.). Sure you can take your time with it, thank you so much :smiley:

I will use the example that you have sent and see whether I could get connected with the Cayenne dashboard. Thank you.

Hello @adam, I have used the coding that you have sent to me and I still could not be able to connect to the Cayenne dashboard.

@joeljacob98 let check whether you can get the connection established with the GSM. You can use this tutorial and see if you can send data ESP32 SIM800L: Publish Data to Cloud without Wi-Fi | Random Nerd Tutorials

Thank you @shramik_salgaonkar, I will have a look at this tutorial and other tutorials similar to this and will let you know what I get.