adafruit / Adafruit_FONA

Arduino library for the Adafruit FONA
https://www.adafruit.com/products/1946
211 stars 237 forks source link

getNetworkStatus fails when it receives Call Ready and SMS Ready messages #109

Open garageeks opened 4 years ago

garageeks commented 4 years ago

fona.getNetworkStatus(), used to poll the modem whether it is registered on the network or not, fails if issued right after initialization (fona.begin command). The reason is because the SIM800 modem by itself writes "Call Ready" and "SMS Ready" messages, and getNetworkStatus() doesn't handle the messages properly, therefore it is returning a value of 100, sometimes forever, maybe because the replyBuffer is not cleaned.

This is the outcome with a state machine:

GPRS1 - TRY 1/3 - Modem init... ---> AT <--- ⸮ ---> AT <--- AT ---> AT <--- AT ---> ATE0 <--- ATE0 ---> ATE0 <--- OK Modem OK ---> AT+CSCLK=1 <--- OK ---> AT+CREG? <--- Call Ready GPRS3 - TRY 1/60 - Net status 100: Failed ---> AT+CREG? <--- SMS Ready GPRS3 - TRY 1/60 - Net status 100: Failed ---> AT+CREG? <--- GPRS3 - TRY 1/60 - Net status 100: Failed ---> AT+CREG? <--- GPRS3 - TRY 1/60 - Net status 100: Failed ---> AT+CREG? <--- ---> AT+CREG? <--- +CREG: 0,1 GPRS3 - TRY 1/60 - Net status 1: Registered (home)

Proposed solution: in getNetworkStatus function, use readline(100) command to eat garbage in the buffer before issuing the AT+CREG? command, as this:

` uint8_t Adafruit_FONA::getNetworkStatus(void) { uint16_t status; readline(100); if (! sendParseReply(F("AT+CREG?"), F("+CREG: "), &status, ',', 1)) return 100;

return status; } `

Result: getNetworkStatus always recover when receiving those "Call Ready" messages with a small penalty (timeout of 100ms)