I'm looking for a way to wait for a response from an AT command to return OK or CONNECTED or whatever the command returns when it's true.
I can check if the serial is available, but that means I have to manually guess what time between commands to give them time to connect or start.
Function:
void ModemCommand(String command) {
//Send command to modem
mySerial.println(command);
Serial.println(command);
delay(100);
while (!mySerial.available()) {
//Wait for Response from modem
Serial.println(F("No response yet"));
delay(1000);
}
while (mySerial.available()) {
Serial.write(mySerial.read());
//Print response from modem
}
Serial.println("");
//Linefeed after reponse
delay(10);
}
Code example:
ModemCommand(F("ATE0"));
//Turn on echo
ModemCommand(F("AT+CFUN=1"));
//Turn modem functions on
waitSec(8,F("turning on Modem functions"));
ModemCommand(F("AT+CGREG?"));
//GSM attached?
ModemCommand(F("AT+CSQ"));
//Signal Quality
ModemCommand(F("AT+CSTT=\"internet\""));
//Set APN
ModemCommand(F("AT+CIICR"));
//Connect to APN GPRS
waitSec(8,F("connecting to APN GPRS"));
ModemCommand(F("AT+CIFSR"));
//Get IP
Does anybody know how to do this?
-
You first need to understand how serial on the Arduino works. Read this first: hacking.majenko.co.uk/reading-serial-on-the-arduinoMajenko– Majenko2015年09月23日 15:54:00 +00:00Commented Sep 23, 2015 at 15:54
2 Answers 2
The most you can do is define a certain amount of time between received characters, after which you can decide that there's nothing more to be read from the modem. Of course, the time taken for processing is longer for certain commands (and some provide no response at all, until you've completed entering their payload, like TCPSEND, in which case you should simply use mySerial.write()
to send said payload, and not your function), but once a response is ready and its first character is available, a timeout of 1 second between characters should be sufficient, for any reasonable baud rate. Something like this:
#define TIMEOUT 1000
void modem_command(String command){
mySerial.println(command);
Serial.println(command);
while (mySerial.available() == 0); // wait for first char
unsigned long lastRead = millis(); // last time a char was available
while (millis() - lastRead < TIMEOUT){
while (mySerial.available()){
Serial.write(mySerial.read());
lastRead = millis(); // update the lastRead timestamp
}
}
// No need for extra line feed since most responses contain them anyways
}
Of course, you can always alter TIMEOUT
based on your findings.
-
Just looking for a response, and not interpreting it seems like a fairly weak solution.Chris Stratton– Chris Stratton2016年03月11日 16:45:20 +00:00Commented Mar 11, 2016 at 16:45
-
@ChrisStratton But thats what he's asking for: a way to send a command, wait 'efficiently' and view the response with minimum fuss. I assume he'll be monitoring the responses from the serial monitor (given his code example) so thats okay. Besides, anything extra would require a lot of parsing and there are whole libraries for that.SoreDakeNoKoto– SoreDakeNoKoto2016年03月11日 17:02:01 +00:00Commented Mar 11, 2016 at 17:02
-
If the response is being monitored externally, there's no need to internally decide when it has been completely received. Proxying between two serial devices can be entirely stateless. Rather it sure looks like echoing back to the PC is only there for debug monitoring - the shown program automatically executes a lot of commands without waiting for any external confirmation that the echoed response is positive and not an error. If this system is going to be actually useful, internal parsing will be required - an answer already posted last fall.Chris Stratton– Chris Stratton2016年03月11日 17:05:18 +00:00Commented Mar 11, 2016 at 17:05
-
@ChrisStratton yeah...thats exactly what his code is doing. While its not the best practice, it does have a lot of simplicity especially for prototyping. If you want me to correct his mistakes though, thats something else...SoreDakeNoKoto– SoreDakeNoKoto2016年03月11日 17:28:32 +00:00Commented Mar 11, 2016 at 17:28
-
Someone else already did address those mistakes, months before you posted, which is part of what makes an answer that perpetuates them less than satisfying.Chris Stratton– Chris Stratton2016年03月11日 18:13:26 +00:00Commented Mar 11, 2016 at 18:13
You would need to create a buffer which will populate over each loop so you dont block the main loop while waiting the all string.
When you get the string or your buffer is full, just check whatever is the response, and based on that you can make your decision.
-
Yes - though it's not actually necessary to buffer the response, as one can also compare character by character as they are received and keep a persistent count of how many matching ones have been found. Buffering may be best for short responses like this though.Chris Stratton– Chris Stratton2016年03月11日 16:46:35 +00:00Commented Mar 11, 2016 at 16:46