I tried using many C/C++ libraries trying to coax a 5G modem to respond to my input AT commands for a long time but I was not successful. The command I was trying to send was the Quectel modem command to query for PDN channels:
AT+CGDCONT?
After a while, I figured out I had to simulate a keyboard Enter press in code to actually tell the modem the command is complete. So all I had to do was append the carriage return (\r) and new line (\n) characters to the AT command string, e.g:
string cmd = "AT+CGDCONT?\r\n";
A working C++ code example is shown below:
#include <string> #include <iostream> #include <cstdio> #include <unistd.h> // Using header only library from // https://github.com/karthickai/serial #include "Serial.h" using namespace std; int main ( int argc, char** argv) { string commPort = "/dev/ttyUSB2"; unsigned int baud = 115200; serial::Serial serial; serial.open ( commPort, baud); if ( !serial.isOpen()) { cout << "comm port is not open" << endl; return 1; } // A modem AT query command string cmd = "AT+CGDCONT?\r\n"; vector<uint8_t> cmdVec (cmd.begin(), cmd.end()); // send command to the modem size_t bytesSent = serial.transmitAsync(cmdVec); cout << "Bytes sent " << bytesSent << endl; int received_bytes = -1; while (received_bytes != 0 ) { // read one byte from the modem and timeout if the // there is no response in more than 1 sec. future<vector<uint8_t>> future = serial.receiveAsync(1, 1000); vector<uint8_t> const received_data = future.get(); received_bytes = received_data.size(); string str(received_data.begin(), received_data.end()); cout << "[" << received_data[0] << "] " << endl; } // Close the serial port serial.close(); cout << "End of process" << endl; return 0; }
The example prints out the data sent by the modem to the calling program, as shown below:
Note: this example is using the modern serial header only C++ library from this site: https://github.com/karthickai/serial