我正在使用GSM调制解调器“SIM900” 我用超级终端测试了它,主命令没问题。
然后我烧掉代码发送AT命令,使用UART将微控制器上的号码拨到GSM调制解调器,工作正常。
但是我的回答有问题。 GSM以字符流回复,但不以Null'\ 0'结束!
如何在数组中获取整个响应以便稍后解析?而且,我怎样才能检测到响应的结束?
AT \ r \ n响应是==>行
AT + CMGR = 1响应是==> + CMGR:“REC UNREAD”,“+ 2347060580383”,“10/10 / 27,18:54:32 + 04”
提前致谢。
答案 0 :(得分:1)
测试新行,通常为\n
或\r\n
。
NUL
(0
或'\0'
)仅在C中用于终止字符数组,即“字符串”。
答案 1 :(得分:1)
您可以使用\r\nOK
作为结尾,因为手机仅对NewLine使用\n
。但是有一种更可靠的方法(我做过一次)以确保你没有得到错误的结局,例如当传入的短信中有确切的\r\nOK
时。为了做到这一点,我建议您将字符集更改为UCS2,这样您将获得UnicodeArray中的消息文本和发件人编号(就像它被转义一样。)
这是我用于我的目的的类(额外的检查模块(AT \ r \ n命令)用于防止卡在错误中,以防出现意外错误或类似的事情!而且我有时没有响应的模块,所以有了这个,我可以让它再次响应!看起来不合逻辑,但救了我!现在对我来说很完美!):
public class SMSController
{
public event EventHandler StatusChanged;
protected virtual void OnStatusChanged()
{
if (StatusChanged != null)
{
StatusChanged(this, EventArgs.Empty);
}
}
SerialPort serial;
public SMSController(SerialPort serialPort)
{
this.serial = serialPort;
}
string readLine(int timeout = -1)
{
int oldTo = serial.ReadTimeout;
serial.ReadTimeout = timeout;
string str = serial.ReadTo("\n").Replace("\n", "").Replace("\r", "");
serial.ReadTimeout = oldTo;
return str;
}
void writeLine(string str)
{
serial.Write(str + "\r\n");
}
bool waitForString(string str, int timeout = -1)
{
if (readLine(timeout).Contains(str))
{
return true;
}
return false;
}
bool waitForOK(int timeout = -1, bool repeat = true)
{
if (repeat)
{
readUntilFind("OK", timeout);
return true;
}
else
return waitForString("OK", timeout);
}
void readUntilFind(string str, int timeout = -1)
{
while (!waitForString(str, timeout)) ;
}
void writeCommand(string command)
{
serial.DiscardInBuffer();
writeLine(command);
}
bool applyCommand(string command, int timeout = -1)
{
writeCommand(command);
return waitForOK(timeout);
}
private string lastStatus = "Ready";
public string LastStatus
{
get { return lastStatus; }
private set
{
lastStatus = value;
OnStatusChanged();
}
}
public void InitModule()
{
try
{
LastStatus = "Checking SIM900...";
applyCommand("ATE0", 2000); //Disable echo
applyCommand("AT", 5000); //Check module
LastStatus = "Initializing SIM900...";
applyCommand("AT+CMGF=1", 1000); //Set SMS format to text mode
LastStatus = "Operation successful!";
}
catch (TimeoutException)
{
LastStatus = "Operation timed-out";
}
catch (Exception ex)
{
LastStatus = ex.Message;
}
}
public static string ConvertToUnicodeArray(string str)
{
byte[] byt = Encoding.Unicode.GetBytes(str);
string res = "";
for (int i = 0; i < byt.Length; i+=2)
{
res += byt[i + 1].ToString("X2");
res += byt[i].ToString("X2");
}
return res;
}
public void SendMessage(string destinationNumber, string text, bool isUnicode = false)
{
try
{
LastStatus = "Initiating to send...";
applyCommand("AT+CSMP=17,167,2,25", 1000);
if (isUnicode)
{
if (!applyCommand("AT+CSCS=\"UCS2\"", 5000))
throw new Exception("Operation failed!");
writeCommand("AT+CMGS=\"" + ConvertToUnicodeArray(destinationNumber) + "\"");
}
else
{
if (!applyCommand("AT+CSCS=\"GSM\"", 5000))
throw new Exception("Operation failed!");
writeCommand("AT+CMGS=\"" + destinationNumber + "\"");
}
waitForString("> ", 5000);
LastStatus = "Sending...";
serial.DiscardInBuffer();
serial.Write(isUnicode ? ConvertToUnicodeArray(text) : text);
serial.Write(new byte[] { 0x1A }, 0, 1);
if (waitForOK(30000))
{
LastStatus = "Message sent!";
}
else
LastStatus = "Sending failed!";
}
catch (TimeoutException)
{
LastStatus = "Operation timed-out";
}
catch (Exception ex)
{
LastStatus = ex.Message;
}
}
private string readTo(string str, int timeout)
{
int to = serial.ReadTimeout;
serial.ReadTimeout = timeout;
string strread = serial.ReadTo(str);
serial.ReadTimeout = to;
return strread;
}
public static byte[] StringToByteArray(string hex)
{
return Enumerable.Range(0, hex.Length)
.Where(x => x % 2 == 0)
.Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
.ToArray();
}
public static string ConvertUnicodeToText(string bytes)
{
byte[] bt = StringToByteArray(bytes);
for (int i = 0; i < bt.Length; i+=2)
{
byte swap = bt[i];
bt[i] = bt[i + 1];
bt[i + 1] = swap;
}
return Encoding.Unicode.GetString(bt);
}
public SMS[] GetUnreadMessages()
{
List<SMS> lst = new List<SMS>();
try
{
LastStatus = "Initializing...";
applyCommand("AT+CSMP=17,167,2,25", 1000);
applyCommand("AT+CSCS=\"UCS2\"", 2000);
LastStatus = "Fetching text messages...";
writeCommand("AT+CMGL=\"REC UNREAD\"");
string texts = readTo("OK\r\n", 10000);
string[] packets = texts.Split(new string[] { "\r\n\r\n" }, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < packets.Length; i++)
{
if (!packets[i].Contains("+CMGL"))
continue;
string num = packets[i].Split(new string[] { "," },
StringSplitOptions.RemoveEmptyEntries)[2].Replace("\"", "");
string txt = packets[i].Split(new string[] { "\r\n" },
StringSplitOptions.RemoveEmptyEntries)[1].Replace("\"", "");
lst.Add(new SMS(ConvertUnicodeToText(num), ConvertUnicodeToText(txt)));
}
applyCommand("AT+CMGDA=\"DEL READ\"", 10000);
LastStatus = "Operation successful!";
}
catch (TimeoutException)
{
LastStatus = "Operation timed-out";
}
catch (Exception ex)
{
LastStatus = ex.Message;
}
return lst.ToArray();
}
}