PPP: Add burst of AT commands to lock autobaudrate on begin#12314
Conversation
👋 Hello gonzabrusco, we appreciate your contribution to this project! 📘 Please review the project's Contributions Guide for key guidelines on code, documentation, testing, and more. 🖊️ Please also make sure you have read and signed the Contributor License Agreement for this project. Click to see more instructions ...
Review and merge process you can expect ...
|
Memory usage test (comparing PR against master branch)The table below shows the summary of memory usage change (decrease - increase) in bytes and percentage for each target.
Click to expand the detailed deltas report [usage change in BYTES]
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Test Results 91 files 91 suites 31m 35s ⏱️ Results for commit 1f6eb93. ♻️ This comment has been updated with latest results. |
| // Send burst of AT to lock auto baurate on modem | ||
| for (int i = 0; i < 50; i++) { | ||
| esp_modem_at(_dce, "AT", NULL, 10); | ||
| } |
There was a problem hiding this comment.
IMO this should be only enabled if an argument of the constructor is set. @me-no-dev What do you think ?
There was a problem hiding this comment.
@lucasssvaz Just to add a data point: sending a short burst of "AT" commands is safe and has no side effects on modems that do not rely on autobaud.
In practice, this acts as a no-op for fixed-baud devices while greatly improving initialization reliability for autobaud-based modems, so I don’t think it needs to be gated behind an additional constructor option.
There was a problem hiding this comment.
Can you please give models of modems that do require such burst?
I also agree that this should be optional or at least connected to the models that need it
There was a problem hiding this comment.
One more argument for making it optional.
When using flow-control the UART buffer may fill up and at some point may become blocking until it is able to flush its data.
There was a problem hiding this comment.
My modem is SIM7070
|
I took the time to capture a few traces so you can verify this behavior yourself. I’m using a SIM7070, and this is the exact test sketch I used: #include "Arduino.h"
#include "PPP.h"
#define UART_NUMBER 0
#define UART_RX 3
#define UART_TX 1
#define MODEM_PWRKEY 2 // IO2
#define PWRKEY_PULSE_MS 1200
#define MODEM_TURN_OFF_WAIT_MS 3300
#define MODEM_BOOT_WAIT_MS 7000
void setup() {
pinMode(MODEM_PWRKEY, OUTPUT);
digitalWrite(MODEM_PWRKEY, HIGH);
// === WAIT TO BOOT ===
delay(MODEM_BOOT_WAIT_MS);
// === TURN OFF MODEM ===
digitalWrite(MODEM_PWRKEY, LOW);
delay(PWRKEY_PULSE_MS);
digitalWrite(MODEM_PWRKEY, HIGH);
// === WAIT TO OFF ===
delay(MODEM_TURN_OFF_WAIT_MS);
// === TURN ON MODEM ===
digitalWrite(MODEM_PWRKEY, LOW);
delay(PWRKEY_PULSE_MS);
digitalWrite(MODEM_PWRKEY, HIGH);
// === WAIT TO BOOT ===
delay(MODEM_BOOT_WAIT_MS);
PPP.setPins(UART_TX, UART_RX); // Not using control flow
PPP.setApn("");
PPP.setPin("");
PPP.begin(PPP_MODEM_SIM7070, UART_NUMBER, 115200);
}
void loop() {
// Nothing
}The first capture shows the behavior without sending an initial burst of AT commands. As you can see, PPPClass struggles to synchronize with the modem because the modem does not respond until AT+CMUX=0 is issued. Most likely, the modem is still trying to lock the autobaud rate at that point.
The second capture shows the behavior with an AT burst sent prior to synchronization. In this case, the modem synchronizes immediately, and
For reference, here are the Saleae Logic capture files in case you want to dig deeper into this: |
|
we agree with all. We are just asking that this is made optional :) |
How would you suggest implementing this as an optional feature? At construction time, as an argument to begin(), or enabled by default for SIMCom modules? I would like to emphasize that sending an initial AT command is effectively a no-op and should not have any negative impact on other modems. That said, if you prefer to keep this behavior optional, I’m happy to implement it accordingly—just let me know how you envision the option and I can update this PR. |
class PPPClass {
public:
void sendAtBurst(bool en) {
_sendAtBurst = en;
}
private:
bool _sendAtBurst;
}Then check in begin if |
And don't forget to initialize at false. |
|
@me-no-dev PTAL |


Description of Change
This Pull Request improves the robustness of PPPClass::begin() when used with cellular modems that boot in autobaud mode, such as SIMCom modules.
After a power-on reset, these modems often require multiple "AT\r" commands before they can lock onto the host UART baud rate. The current implementation attempts to synchronize immediately using esp_modem_sync(), which may fail if the modem is still determining the baud rate, leading to unnecessary retries and mode switching.
This change introduces a short burst of "AT\r" commands before calling esp_modem_sync(), allowing the modem to reliably lock the baud rate first. In practice, this significantly improves synchronization reliability without affecting modems that do not use autobaud.
Test Scenarios
I tested this change on a custom ESP32-based board equipped with a SIM7070 modem. Using a logic analyzer on the UART interface, I verified that the added AT command burst improves baud-rate locking and results in a more reliable initialization sequence.