Code:
/*
* Made by KinCony IoT: https://www.kincony.com
*
* Make a voice call using SIM7600 AT commands.
* SIM7600 RXD -> ESP32 GPIO16 (TX)
* SIM7600 TXD -> ESP32 GPIO15 (RX)
*/
#include <Arduino.h>
HardwareSerial modem(2);
constexpr int MODEM_RX = 15;
constexpr int MODEM_TX = 16;
constexpr uint32_t MODEM_BAUD = 115200;
// Time from starting the call until automatic hang-up.
constexpr uint32_t CALL_DURATION_MS = 30000;
const char PHONE_NUMBER[] = "+8615381188302";
bool waitFor(const char *expected, uint32_t timeoutMs) {
String response;
uint32_t start = millis();
while (millis() - start < timeoutMs) {
while (modem.available()) {
char c = modem.read();
Serial.write(c);
response += c;
if (response.indexOf(expected) >= 0) {
return true;
}
if (response.indexOf("ERROR") >= 0 ||
response.indexOf("NO CARRIER") >= 0 ||
response.indexOf("BUSY") >= 0 ||
response.indexOf("NO ANSWER") >= 0) {
return false;
}
}
delay(1);
}
Serial.println("\n[Timeout]");
return false;
}
bool sendAT(const String &command,
const char *expected = "OK",
uint32_t timeoutMs = 3000) {
while (modem.available()) {
Serial.write(modem.read());
}
Serial.print("\n>> ");
Serial.println(command);
modem.print(command);
modem.print('\r');
return waitFor(expected, timeoutMs);
}
void setup() {
Serial.begin(115200);
modem.begin(MODEM_BAUD, SERIAL_8N1, MODEM_RX, MODEM_TX);
Serial.println("\nWaiting for SIM7600...");
delay(15000);
bool modemReady = false;
for (int i = 0; i < 10; i++) {
if (sendAT("AT")) {
modemReady = true;
break;
}
delay(1000);
}
if (!modemReady) {
Serial.println("No modem response. Check power, baud rate and UART pins.");
return;
}
if (!sendAT("ATE0")) return;
if (!sendAT("AT+CPIN?", "+CPIN: READY")) {
Serial.println("SIM card is not ready.");
return;
}
// Print signal strength and network registration status.
sendAT("AT+CSQ");
sendAT("AT+CREG?");
sendAT("AT+CEREG?");
// A trailing semicolon requests a voice call.
String dialCommand = String("ATD") + PHONE_NUMBER + ";";
Serial.println("\nDialing...");
uint32_t callStart = millis();
if (!sendAT(dialCommand, "OK", 10000)) {
Serial.println("\nDial command failed or timed out.");
sendAT("ATH");
return;
}
Serial.println("\nDial command accepted; waiting for call events.");
String line;
bool callEnded = false;
while (millis() - callStart < CALL_DURATION_MS && !callEnded) {
while (modem.available()) {
char c = modem.read();
Serial.write(c);
if (c == '\n') {
line.trim();
if (line == "NO CARRIER" ||
line == "BUSY" ||
line == "NO ANSWER" ||
line == "ERROR") {
callEnded = true;
}
line = "";
} else if (c != '\r') {
line += c;
}
}
delay(1);
}
if (callEnded) {
Serial.println("\nCall ended.");
} else {
Serial.println("\nHanging up...");
sendAT("ATH");
}
}
void loop() {
// UART bridge for manual AT-command debugging.
while (modem.available()) {
Serial.write(modem.read());
}
while (Serial.available()) {
modem.write(Serial.read());
}
}