Sending Basic AT commands to Cellular/GNSS Modem

I have a ESP32 datasheet that I have hooked up to a cell modem (Quectel BG95) and I am trying to send the most basic AT command possible just to see if everything is hooked up properly... The two modules are connected via UART ESP32's RX (GPIO 16) and TX (GPIO 17).

I am referring to reference to write my basic code in the Arduino IDE. I also downloaded the "espsoftwareserial" library.


#include <SoftwareSerial.h>

SoftwareSerial Quectel(16, 17);

int greenpower = 32;
int led = 33;


void setup() {

  Serial.begin(115200);  // Open serial communications and wait for port to open:
  while (!Serial) { // wait for serial port to connect. Needed for native USB port only
 
  }
  pinMode(led, OUTPUT); //for verifying power to the board
  pinMode(greenpower, OUTPUT); //for allowing power to auxillary processes
  digitalWrite(greenpower, HIGH); //allow power to aux devices
  digitalWrite(led, HIGH);  //apply power to verification circuit
  delay(1000);
  Serial.println("Started");

  // set the data rate for the SoftwareSerial port
  Quectel.begin(115200);
  Quectel.write("AT\r\n");
}

When I run this though I am not getting any information back. Does anyone know why this could be?

Because you are not reading the software serial port!

1 Like

SoftwareSerial on any platform is going to struggle at 115200

1 Like

Looks like I didn't paste all of the code! My mistake, I have uploaded the full version.

#include <SoftwareSerial.h>

SoftwareSerial Quectel(16, 17);

int greenpower = 32;
int led = 33;


void setup() {

  Serial.begin(115200);  // Open serial communications and wait for port to open:
  while (!Serial) { // wait for serial port to connect. Needed for native USB port only
 
  }
  pinMode(led, OUTPUT); //for verifying power to the board
  pinMode(greenpower, OUTPUT); //for allowing power to auxillary processes
  digitalWrite(greenpower, HIGH); //allow power to aux devices
  digitalWrite(led, HIGH);  //apply power to verification circuit
  delay(1000);
  Serial.println("Started");

  // set the data rate for the SoftwareSerial port
  Quectel.begin(115200);
  Quectel.write("AT\r\n");
}

void loop() {
  if (Quectel.available()) {
    Serial.write(Quectel.read());
  }
  if (Serial.available()) {
    Quectel.write(Serial.read());
  }
  delay(1000);
}

Also I have heard that softwareserial struggles at the higher baud rates. But the example given for the espsoftwareserial uses 115200 baud and my cell module defaults to 115200. This was the reason for this choice.

Also the espsoftwareserial library gives the example below. Although we are trying to accomplish pretty different things their initial set-up is quite different and it has me worried that I may be going wrong here.

// On ESP8266:
// At 80MHz runs up 57600ps, and at 160MHz CPU frequency up to 115200bps with only negligible errors.
// Connect pin 13 to 15.
// For verification and as a example for how to use SW serial on the USB to PC connection,
// which allows the use of HW Serial on GPIO13 and GPIO15 instead, #define SWAPSERIAL below.
// Notice how the bitrates are also swapped then between RX/TX and GPIO13/GPIO15.
// Builtin debug output etc. must be stopped on HW Serial in this case, as it would interfere with the
// external communication on GPIO13/GPIO15.

#include <SoftwareSerial.h>

#ifndef D5
#if defined(ESP8266)
#define D8 (15)
#define D5 (14)
#define D7 (13)
#define D6 (12)
#define RX (3)
#define TX (1)
#elif defined(ESP32)
#define D8 (5)
#define D5 (18)
#define D7 (23)
#define D6 (19)
#define RX (3)
#define TX (1)
#endif
#endif

#ifdef ESP32
#define BAUD_RATE 57600
#else
#define BAUD_RATE 57600
#endif

#undef SWAPSERIAL

#ifndef SWAPSERIAL
auto& usbSerial = Serial;
SoftwareSerial testSerial;
#else
SoftwareSerial usbSerial;
auto& testSerial = Serial;
#endif

void setup() {
#ifndef SWAPSERIAL
    usbSerial.begin(115200);
    // Important: the buffer size optimizations here, in particular the isrBufSize (11) that is only sufficiently
    // large to hold a single word (up to start - 8 data - parity - stop), are on the basis that any char written
    // to the loopback SoftwareSerial adapter gets read before another write is performed.
    // Block writes with a size greater than 1 would usually fail. Do not copy this into your own project without
    // reading the documentation.
    testSerial.begin(BAUD_RATE, SWSERIAL_8N1, D7, D8, false, 95, 11);
#else
    testSerial.begin(115200);
    testSerial.setDebugOutput(false);
    testSerial.swap();
    usbSerial.begin(BAUD_RATE, SWSERIAL_8N1, RX, TX, false, 95);
#endif

    usbSerial.println(PSTR("\nSoftware serial test started"));

    for (char ch = ' '; ch <= 'z'; ch++) {
        testSerial.write(ch);
    }
    testSerial.println();
}

void loop() {
    while (testSerial.available() > 0) {
        usbSerial.write(testSerial.read());
        yield();
    }
    while (usbSerial.available() > 0) {
        testSerial.write(usbSerial.read());
        yield();
    }
}

Wait I am using the correct hardware pins for RXD and TXD so do I even need software serial. After doing some more reading, I have tried:

#include <HardwareSerial.h>
int greenpower = 32;
int led = 33;


void setup() {

  Serial.begin(115200);  // Open serial communications and wait for port to open:
  Serial2.begin(115200,SERIAL_8N1,16,17);
  pinMode(led, OUTPUT); //for verifying power to the board
  pinMode(greenpower, OUTPUT); //for allowing power to auxillary processes
  digitalWrite(greenpower, HIGH); //allow power to aux devices
  digitalWrite(led, HIGH);  //apply power to verification circuit
  delay(1000);

}

void loop() {
  Serial.println("Started");
  Serial2.write("AT");
  while (Serial2.available()) {
    int g = Serial2.read();
    Serial.write(g);
    Serial.println(g);
  }
  delay(1000);
}

And I receive a 0 about every 15-20s but according to the AT command manual I should be receiving OK.