"SoftwareSerial.h not available" in LilyGo T-Call SIM800

Hello, I'm currently programming a code that will send GPS data to the server using MQTT. The device that I use for program is LilyGo T-Call SIM800 (BLYNK V1.4). The program all went okay until I update my Arduino IDE to the latest version, and the error "fatal error: SoftwareSerial.h: No such file or directory" appear. Is there any suggestion for me so I can make my code work again in the latest version of Arduino IDE?

(Note that, it is such a hassle to use another UART because I have to disconnect it before uploading the code to the board)

the code :

// Select your modem:
#define TINY_GSM_MODEM_SIM800 // Modem is SIM800L

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

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

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

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

// SIM card PIN (leave empty, if not defined)
const char simPIN[]   = ""; 

// MQTT details
const char* broker = "test.mosquitto.org"; // Public IP address or domain name
const char* mqttUsername = "";  // MQTT username
const char* mqttPassword = "";  // MQTT password


const char* topicGPS = "things/product/2g/94E686DFA95C/osd";


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

#include <Wire.h>
#include <TinyGsmClient.h>
#include <TinyGPS++.h>
#include <SoftwareSerial.h>

int RXPin = 35;
int TXPin = 34;

int GPSBaud = 9600;

TinyGPSPlus gps;

SoftwareSerial gpsSerial(RXPin, TXPin);

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

#include <PubSubClient.h>

TinyGsmClient client(modem);
PubSubClient mqtt(client);

// TTGO T-Call pins
#define MODEM_RST            5
#define MODEM_PWKEY          4
#define MODEM_POWER_ON       23
#define MODEM_TX             27
#define MODEM_RX             26
#define I2C_SDA              21
#define I2C_SCL              22


uint32_t lastReconnectAttempt = 0;

// I2C for SIM800 (to keep it running when powered from battery)
// TwoWire I2CPower = TwoWire(0);

// #define IP5306_ADDR          0x75
// #define IP5306_REG_SYS_CTL0  0x00

long lastMsg = 0;

// bool setPowerBoostKeepOn(int en){
//   I2CPower.beginTransmission(IP5306_ADDR);
//   I2CPower.write(IP5306_REG_SYS_CTL0);
//   if (en) {
//     I2CPower.write(0x37); // Set bit1: 1 enable 0 disable boost keep on
//   } else {
//     I2CPower.write(0x35); // 0x37 is default reg value
//   }
//   return I2CPower.endTransmission() == 0;
// }

void mqttCallback(char* topic, byte* message, unsigned int len) {
  Serial.print("Message arrived on topic: ");
  Serial.print(topic);
  Serial.print(". Message: ");
  String messageTemp;
  
  for (int i = 0; i < len; i++) {
    Serial.print((char)message[i]);
    messageTemp += (char)message[i];
  }
  Serial.println();

  // Feel free to add more if statements to control more GPIOs with MQTT

  // If a message is received on the topic esp/output1, you check if the message is either "true" or "false". 
  // Changes the output state according to the message
}

boolean mqttConnect() {
  SerialMon.print("Connecting to ");
  SerialMon.print(broker);

  // Connect to MQTT Broker without username and password
  boolean status = mqtt.connect(broker);

  // Or, if you want to authenticate MQTT:
  //boolean status = mqtt.connect("GsmClientN", mqttUsername, mqttPassword);

  if (status == false) {
    SerialMon.println(" fail");
    ESP.restart();
    return false;
  }
  SerialMon.println(" success");

  return mqtt.connected();
}


void setup() {
  // Set console baud rate
  SerialMon.begin(9600);
  gpsSerial.begin(GPSBaud);
  delay(10);
  
  // // Start I2C communication
  // I2CPower.begin(I2C_SDA, I2C_SCL, 400000);
  
  // // Keep power when running from battery
  // bool isOk = setPowerBoostKeepOn(1);
  // SerialMon.println(String("IP5306 KeepOn ") + (isOk ? "OK" : "FAIL"));

  // Set modem reset, enable, power pins
  pinMode(MODEM_PWKEY, OUTPUT);
  pinMode(MODEM_RST, OUTPUT);
  pinMode(MODEM_POWER_ON, OUTPUT);
  digitalWrite(MODEM_PWKEY, LOW);
  digitalWrite(MODEM_RST, HIGH);
  digitalWrite(MODEM_POWER_ON, HIGH);

  
  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 if needed
  if ( GSM_PIN && modem.getSimStatus() != 3 ) {
    modem.simUnlock(GSM_PIN);
  }

  SerialMon.print("Connecting to APN: ");
  SerialMon.print(apn);
  if (!modem.gprsConnect(apn, gprsUser, gprsPass)) {
    SerialMon.println(" fail");
    ESP.restart();
  }
  else {
    SerialMon.println(" OK");
  }
  
  if (modem.isGprsConnected()) {
    SerialMon.println("GPRS connected");
  }

  // MQTT Broker setup
  mqtt.setServer(broker, 1883);
  mqtt.setCallback(mqttCallback);
}

void loop() {
  if (!mqtt.connected()) {
    SerialMon.println("=== MQTT NOT CONNECTED ===");
    // Reconnect every 10 seconds
    uint32_t t = millis();
    if (t - lastReconnectAttempt > 10000L) {
      lastReconnectAttempt = t;
      if (mqttConnect()) {
        lastReconnectAttempt = 0;
      }
    }
    delay(100);
    return;
  }

  long now = millis();
  while (gpsSerial.available() > 0)
    if (gps.encode(gpsSerial.read()))
       if (gps.location.isValid())
  {
        String json = "{";
    json += "\"satellite\": " + String(gps.satellites.value());
    json += ", \"latitude\": " + String(gps.location.lat(), 6);
    json += ", \"longitude\": " + String(gps.location.lng(), 6);
    json += ", \"altitude\": " + String(gps.altitude.meters());
    json += "}";

    // Publish JSON string to MQTT broker
    char payload[json.length() + 1];
    json.toCharArray(payload, sizeof(payload));
    mqtt.publish(topicGPS, payload);
    Serial.println(payload);
  }
  else
  {
    Serial.println("Location: Not Available");
  }

  // If 5000 milliseconds pass and there are no characters coming in
  // over the software serial port, show a "No GPS detected" error
  if (millis() > 5000 && gps.charsProcessed() < 10)
  {
    Serial.println("No GPS detected");
    while(true);
  }
  mqtt.loop();
}

If any other questions, feel free to ask. Thanks!

As you can set a hardware serial on any IO pin on the ESP32 you don't need a software emulation on that system. You have 3 hardware UARTs on an ESP32.

I don't see the reason for this.

I do know ESP32 have 3 hardware UARTs. The problem is, LilyGo T-Call SIM800 are build using ESP Wrover E as its brain, which is have two UART, UART0 and UART1. Unfortunately, UART0 are used for serial communication and UART1 are used for SIM800 communication. I have to assign another GPIO to be external UART for GPS module (Neo 6M GPS). I have try HardwareSerial.h and assign it to another GPIO, but it seems error shows pin interruption error.

Update : I have success in implementing the SoftwareSerial.h using the same code, and not disturb any line in the code. New problem came out : connecting to MQTT public server (test.mosquitto.org) fail but that is another topic to discuss

Where did you find that information that the WroverE does contain a special version of the ESP32 with less UARTs? The datasheet doesn't mention such an exception. So I think you can use the third serial interface (Serial2) and just define the pins you want to use. Have you tried that?

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.