首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何检测GSM调制解调器响应的最后一个字符?

如何检测GSM调制解调器响应的最后一个字符?
EN

Stack Overflow用户
提问于 2014-02-09 22:15:51
回答 2查看 3.7K关注 0票数 0

我正在使用GSM调制解调器"SIM900“,我已经用超级终端测试过它,主命令也可以。

然后,我使用UART将代码发送给AT命令,在单片机上拨一个号码给GSM调制解调器,它工作得很好。

但我的反应有点问题。GSM回复的字符流,但它不以空'\0‘结束!

如何获得数组中的整个响应,以便稍后解析它?我怎样才能检测到回应的结束呢?

AT\r\n响应为==> OK

AT+CMGR=1响应为==> +CMGR:"REC“、"+2347060580383”、“10/10/27、18:54:32+04”

提前谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-02-14 15:44:57

您可以使用\r\nOK作为结尾,因为手机只对NewLine使用\n。但是有一种更可靠的方法(我做过一次)来确保您不会得到错误的结尾,例如当传入的文本消息中包含了确切的\r\nOK时。为了做到这一点,我建议您将字符集更改为UCS2,这样就可以在UnicodeArray中获得消息文本和发件人号(就像被转义了一样)。

下面是我使用的类(额外的检查模块(AT\r命令)用于防止陷入错误,以防出现意外错误或类似的情况!)我的模块有时没有响应,所以我可以让它再次响应!似乎不符合逻辑,但救了我!现在对我来说是完美的!)

代码语言:javascript
复制
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();
    }
}
票数 2
EN

Stack Overflow用户

发布于 2014-02-09 22:21:08

测试一个新行,典型的是\n\r\n.

NUL (0'\0')仅在C中用于终止字符数组,即“字符串”。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21665789

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档