如何显示/保存返回AT命令的值
how can I display/save the value of what return an AT command
大家好!我正在与Arduino UNO和SIM908一起进行一个项目。我正在努力理解AT命令。当我进入时
Serial.print("AT")
Serial.println("AT+CGPSSTATUS?");
Serial返回一个值,我想将该值保存到缓冲区中
char buffer[size]
除了AT命令的返回值之外,我不希望有其他字符串。
我还把那个文件涂红了SIM908 AT命令手册_V1.01
在第13页,你可以阅读(NB.< CR>< LF>
:我在第一个<
后面加了一个空格,其他没有显示)
必须在每个命令的开头设置"AT"或"AT"前缀线要终止命令行,请输入<CR>。命令通常随后是包括的响应。"<CR><LF><在整个文档中,仅呈现了响应,<CR><LF>有意省略
然后,我询问如何"提取"< CR>< LF>
和< CR>< LF>
之间的响应
看看这个例子(如果我错了,请告诉我),我如何检测< CR>< LF>
void setup()
{
char buffer[200];
Serial.println("AT+CGPSSTATUS?");
}
void loop()
{
if (Serial.available())
{
// HERE I SHOULD CHECK IF CR ANF LF
Serial.write(Serial.read());
// AND SAVE IT IN buffer. IS'T NOT?
}
}
}
你明白我的意思了吗?你怎么能帮我在缓冲区中只存储AT命令的返回值?
非常感谢您的帮助
你给我看的东西很有趣。下面是我如何调整我的代码
我修改了我的代码,顺便创建了一个文件,用于在发送AT命令时测试Serail。关注函数是loop()和read_AT_string()。(我将read_String重命名为read_AT_String()。
在这里,我和我的代码解释,在问题之后,根据你的建议
#include <SoftwareSerial.h>
int baud_rate = 9600;
int pin_gsm = 3;
int pin_gps = 4;
int pin_power = 5;
//int pin_dtr = 6;
boolean debug = true;
boolean raedy_to_go = false;
// Reading String
#define BUFFERSIZE 200
char buffer[BUFFERSIZE];
char inChar;
int index;
void setup()
{
Serial.begin(baud_rate);
delay(5000); // Wait for 5sec after begin
if(debug)
{
Serial.println(F("n****************************"));
Serial.println(F("STARTING SYSTEM Read AT stream"));
Serial.println(F("******************************"));
}
pinMode(pin_gsm,OUTPUT); // Set the pins
pinMode(pin_gps,OUTPUT);
pinMode(pin_power,OUTPUT);
powerUpSim908:
if(powerUpSim908())
{
delay(1000);
if(gps_power()){
gsm_enable();
raedy_to_go = true;
if(debug)
{
Serial.println(F("n****************************"));
Serial.println(F("READY TO GOn"));
Serial.println(F("****************************n"));
}
}
else
{
raedy_to_go = false;
if(debug)
{
Serial.println(F("nNOT READY TO GO.nGPS could not be powernRestart the modulenor/and check the battery level.n"));
}
goto powerUpSim908;
}
}
else
{
raedy_to_go = false;
if(debug)
{
Serial.println(F("nNOT READY TO GO.nCheck the battery level.n"));
}
};
}
void loop()
{
/*
if (Serial.available())
{
Serial.print("Character received: ");
Serial.write(Serial.read());
Serial.println("");
}
*/
if(raedy_to_go)
{
read_AT_string("AT",5000);
delay(10000);
}
}
char read_AT_string(char* command, int timeout)
{
unsigned long previous;
previous = millis();
Serial.println(F("nDISPLAY BUFFER:"));
index=0;
Serial.println(command);
do
{
if(Serial.available() > 0) // Don't read unless
// there you know there is data
{
Serial.println("1");
if (Serial.peek() == 13) // check if CR (without reading)
{
Serial.println("13");
if(Serial.available() > 0)
{
Serial.read(); // read and ignore
if (Serial.peek()==10) // then check if LF (without reading)
{
Serial.println("10");
if(index < Serial.readBytesUntil(13, buffer, BUFFERSIZE-1)) // One less than the size of the buffer array
{
Serial.println("b");
inChar = Serial.read(); // Read a character
buffer[index] = inChar; // Store it
index++; // Increment where to write next
buffer[index] = ' '; // Null terminate the string
}
}
}
}
}
}while(((millis() - previous) < timeout));
Serial.println(buffer);
buffer[0]=' ';
Serial.println(F("END DISPLAY BUFFER"));
}
/* FUNCTION */
boolean powerUpSim908(void)
{
if(debug)
{
Serial.println(F("Powering up SIM908"));
}
boolean turnedON = false;
//uint8_t answer=0;
int cont;
for (cont=0; cont<3; cont++)
{
digitalWrite(pin_power,HIGH);
delay(1500);
digitalWrite(pin_power,LOW);
Serial.println(F("Checking if the module is up"));
if(sendATcommand("AT", "OK", 5000))
{
cont = 4; // Leave the loop
turnedON = true;
}
else
{
turnedON = false;
if(debug)
{
Serial.println(F("nTrying agin to turn on SIM908"));
}
};
}
if(turnedON)
{
if(debug)
{
Serial.println(F("Module is tunrned upn"));
}
}
else
{
if(debug)
{
Serial.println(F("Module is NOT tunrned ONn"));
}
}
return turnedON;
}
boolean sendATcommand(char* ATcommand, char* expected_answer, unsigned int timeout)
{
uint8_t x=0;
bool answer=false;
//åchar response[100];
//buffer[0]=' ';
unsigned long previous;
//memset(response, ' ', 100); // Initialice the string
//Serial.println(response);
delay(100);
while( Serial.available() > 0) Serial.read(); // Clean the input buffer
if (ATcommand[0] != ' ')
{
Serial.println(ATcommand); // Send the AT command
}
x = 0;
previous = millis();
index=0;
do
{
if(Serial.available() > 0)
// there you know there is data
{
if(index < BUFFERSIZE-1) // One less than the size of the array // Same as buffer size
{
inChar = Serial.read(); // Read a character
buffer[index] = inChar; // Store it
index++; // Increment where to write next
//Serial.println(index);
buffer[index] = ' '; // Null terminate the string
}
}
}while(((millis() - previous) < timeout));
if(strstr(buffer,"NORMAL POWER DOWN") != NULL)
{
answer = false;
}
else if (strstr(buffer, expected_answer) != NULL) // check if the desired answer (OK) is in the response of the module
{
/*
Serial.println(F("### BUFFER"));
Serial.println(buffer);
Serial.println(F("### END BUFFER"));
*/
answer = true;
}
else
{
answer = false;
}
if(debug)
{
if(answer)
{
//Serial.println(F("Expected answer : OK!n"));
}
else
{
//Serial.println(F("Expected answer : KO!n"));
};
}
return answer;
}
void gps_enable(void)
{
if(debug)
{
Serial.println(F("nEnabling GPS ..."));
}
digitalWrite(pin_gps,LOW); //Enable GPS mode
digitalWrite(pin_gsm,HIGH); //Disable GSM mode
delay(2000);
}
void gsm_enable(void)
{
if(debug)
{
Serial.println(F("nEnabling GSM ..."));
}
digitalWrite(pin_gsm,LOW); //Enable GSM mode
digitalWrite(pin_gps,HIGH); //Disable GPS mode
delay(2000);
}
/* UTILISTIES */
/* GPS */
boolean gps_power(void) //turn on GPS power supply
{
/*
Serial.println("AT");
delay(2000);
*/
boolean gpspwr = false;
boolean gpsrst = false;
if(sendATcommand("AT+CGPSPWR=1","OK",2000))
{
gpspwr = true;
if(debug)
{
Serial.println("turn on GPS power supply => OK");
}
}
else
{
if(debug)
{
Serial.println("turn on GPS power supply => KO");
}
};
//delay(1000);
if(sendATcommand("AT+CGPSRST=1","OK",2000))
{
gpsrst = true;
if(debug)
{
Serial.println("reset GPS in autonomy mode => OK");
}
}
else
{
if(debug)
{
Serial.println("reset GPS in autonomy mode => KO");
}
}; //reset GPS in autonomy mode
delay(1000);
if(gpspwr && gpsrst)
{
return true;
}else
{
return false;
}
}
在read_At_string中,第一个if(Serial.peek()==13)总是返回false。
1是打印的,但"13"不是,那么我应该是
if(Serial.peek()==13)
返回错误
以下是在5秒内打印的
AT DISPLAY BUFFER:
1
1
1
1
1
1
1
1
1
[...] // It prints 1 until now
1
END DISPLAY BUFFER
这里有一段检测和删除CR+LF的代码(注意:如果读取了CR,但后面没有LF,它也会被删除):
if (Serial.peek()==13) { // check if CR (without reading)
Serial.read(); // read and ignore
if (Serial.peek()==10) // then check if LF (without reading)
Serial.read();
}
要读取Serial的其余响应,您可以使用:
buffer[Serial.readBytesUntil(13, buffer, 199)]=0; // readbytes returns the number of bytes read
然后您必须放弃结束CRLF(与上面相同)。
编辑
您在另一个答案中发布的代码有几个问题。
当您powerUpSim908()
时,您必须注意gsm模块可能会发送未请求的数据(请参阅文档,第1.4章):
注:将发送一个十六进制字符串,如"00 49 49 49 FF FF FF FF"之后立即以115200的波特率通过串行端口输出SIM908已通电。该字符串应被忽略,因为它用于与PC工具同步。只能通过串行输入AT命令SIM908通电后的端口,未经请求的结果代码"RDY"为从串行端口接收。
这意味着在你发送任何东西之前,你必须通过读取来丢弃这些数据。我想这就是为什么你在读取响应时没有得到CRLF的原因:你首先得到HEX字符串或"RDY"。
然后readBytesUntil()
读取尽可能多的字节(在我上面的例子中是maxi 199),并将它们存储在缓冲区中。当遇到字节13(即CR)时,它停止读取。不需要在索引上循环。该函数返回可以读取的字符数,并且不会在缓冲区的末尾加上0结尾(即没有有效的C字符串)。如果你想以我建议的其他方式使用函数,你必须存储返回的长度,因为你以后没有其他方法可以找到它。
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- 什么时候在C++中返回常量引用是个好主意
- 你能重载对象变量名本身返回的内容吗
- 为什么 Serial.println(<char[]>);返回随机字符?
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 如何获取std::result_of函数的返回类型
- QueryWorkingSet总是返回false
- (C++)分析树以计算返回错误值的简单算术表达式
- 为什么向量的.at()成员函数返回引用而不是迭代器
- 在 vector::at 返回引用后进行更改
- C++所有 AT 命令的短信返回错误 |PC<->通过蓝牙和winsocket的移动连接
- string.at if 语句不返回任何内容
- QList::at() 返回对常量的引用
- String.at() 返回时髦的数字
- 映射运算符 [] 的返回值(和"at"方法)
- 链接器返回"relocation has an invalid symbol at symbol index..."
- 如何显示/保存返回AT命令的值
- 当std::map::at超出范围时返回什么
- OpenCV Mat 方法"at" Linux 中返回奇怪的字符
- 为什么 QList::at() 不检查索引是否存在并返回只读值?