发送英文短消息与GSM调制解调器(D-Link的DWM-156) [英] send English SMS with GSM Modems (D-Link DWM-156)

查看:280
本文介绍了发送英文短消息与GSM调制解调器(D-Link的DWM-156)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开发GSM调制解调器(D-Link的DWM-156)在C#.NET中使用AT命令的应用程序。我在发送英文短消息的问题。
我尝试发送你好,但是我收到□□□□在我的手机或... exept打招呼。

  serialPort1.DataBits = 8; 
serialPort1.Parity = Parity.None;
serialPort1.StopBits = StopBits.One;
serialPort1.BaudRate = 9600;

serialPort1.DtrEnable = TRUE;
serialPort1.RtsEnable = TRUE;
serialPort1.DiscardInBuffer();
serialPort1.DiscardOutBuffer();


serialPort1.WriteLine(AT\r);
Thread.sleep代码(2000);

serialPort1.WriteLine(AT + CMGF = 1\r);
Thread.sleep代码(1000);

serialPort1.WriteLine(AT + CMGS = \09390149196\\r)
Thread.sleep代码(2000);

serialPort1.WriteLine(你好+\x1A);
Thread.sleep代码(1000);


解决方案

一些修正(也许更多,但我没有看到全码)。




  • 请不要使用的WriteLine(),但写(),因为 \r (单独)是命令行和结果代码终止符。

  • SerialPort.WriteLine()在默认情况下写一个USASCII编码字符串,但你的GSM调制解调器期待与AT指令指定的编码字符串。设置 SerialPort.Encoding 属性设置为特定的编码并发送 CSCS 命令。你可以的询问的有 CSCS =?支持的编码AT命令。即使默认的GSM应适用我会避免隐含靠这个。

  • 您不需要在每个命令后等待,但你必须等待调制解调器的答案(检查确定错误字符串)。



通过文档




一个命令行是由三个元件组成:前缀,身体,并终止字符。命令行前缀由字符AT或在的[...]的终止字符可以由用户选择(参数S3)中,默认为CR来选择。




在伪代码:

 无效SendCommand(字符串命令){
serialPort.Write(命令+\r);

//不要把这里任意的等待,检查调制解调器的应答
//从串口(使用超时)阅读。
CheckResponse();
}

serialPort.DataBits = 8;
serialPort.Parity = Parity.None;
serialPort.StopBits = StopBits.One;
serialPort.BaudRate = 9600;
serialPort.DtrEnable = TRUE;
serialPort.RtsEnable = TRUE;
serialPort.Encoding = Encoding.GetEncoding(ISO-8859-1);

serialPort.DiscardInBuffer();
serialPort.DiscardOutBuffer();

SendCommand(AT); //平
SendCommand(AT + CMGF = 1); //报文格式
SendCommand(AT + CSCS = \PCCP437\); //字符集

SendCommand(AT + CMGS = \123456\)//电话号码
SendCommand(你好+\x1A); //消息

要检查响应(绝对避免任意等待!),你可以像这样启动(未经检验的原料适应性,所以你可能需要一些调试,也见这个帖子):

 的AutoResetEvent _receive; 

串ReadResponse(INT超时)
{
串响应=的String.Empty;

,而(真)
{
如果(_receive.WaitOne(超时,FALSE))
{
响应+ = _port.ReadExisting();
}
,否则
{
如果(response.Length大于0)
抛出新的InvalidOperationException异常(未完成的回应。);
,否则
抛出新的InvalidOperationException异常(不回应。);
}

//漂亮原始的实现,我甚至不能确定它涵盖
//所有的情况下,更好的分析会在这里感激。
//另请注意,我假定既\r和\\\
详细V1输出。
如果(response.EndsWith(\r\\\
OK\r\\\
))
中断;

如果(response.EndsWith(\r\\\
>))
中断;

如果(response.EndsWith(\r\\\
ERROR\r\\\
))
中断;
}

返回响应;
}



添加 _receive.Reset()您发送的命令,当然还加入之前 OnPortDataReceived 的处理程序 SerialPort.DataReceived 事件:

 无效OnPortDataReceived(对象发件人,
SerialDataReceivedEventArgs E)
{
如果(e.EventType == SerialData.Chars)
_receive.Set();
}

如果你有一些麻烦(但您可以连接),你可以替换 \r \\\
。有些调制解调器的错误的(假设< CR> 尚未映射到任何东西比 13 使用 S3 参数)在默认情况下使用该字符作为命令行结束(即使它应该只对 V1 详细输出)。要么改变你的代码,或发送相应的 S3


I am developing an application for GSM Modems (D-Link DWM-156) in C#.Net using AT commands. I have a problem sending English SMS. I try to send "hello", But I receive □□□□ in my phone or ...exept hello.

serialPort1.DataBits = 8;
serialPort1.Parity = Parity.None;
serialPort1.StopBits = StopBits.One;
serialPort1.BaudRate = 9600;

serialPort1.DtrEnable = true;
serialPort1.RtsEnable = true;
serialPort1.DiscardInBuffer();
serialPort1.DiscardOutBuffer();


serialPort1.WriteLine("AT\r");
Thread.Sleep(2000);

serialPort1.WriteLine("AT+CMGF=1\r");
Thread.Sleep(1000);

serialPort1.WriteLine("AT+CMGS=\"09390149196\"\r")
Thread.Sleep(2000);

serialPort1.WriteLine("hello" + "\x1A");
Thread.Sleep(1000);

解决方案

Few fixes (maybe more but I don't see full-code).

  • Do not use WriteLine() but Write() because for \r (alone) is the command line and result code terminator character.
  • SerialPort.WriteLine() by default writes a usASCII encoded string but your GSM modem expect strings encoded as specified with an AT command. Set SerialPort.Encoding property to a specific encoding and send CSCS command. You can ask supported encodings with CSCS=? AT command. Even if default GSM should apply I'd avoid to rely implicitly on this.
  • You do not need to wait after each command but you have to wait for modem answer (checking for OK or ERROR strings).

From docs:

A command line is made up of three elements: the prefix, the body, and the termination character. The command line prefix consists of the characters "AT" or "at" [...] The termination character may be selected by a user option (parameter S3), the default being CR.

In pseudo-code:

void SendCommand(string command) {
    serialPort.Write(command + "\r");

    // Do not put here an arbitrary wait, check modem's response
    // Reading from serial port (use timeout).
    CheckResponse();
}

serialPort.DataBits = 8;
serialPort.Parity = Parity.None;
serialPort.StopBits = StopBits.One;
serialPort.BaudRate = 9600;
serialPort.DtrEnable = true;
serialPort.RtsEnable = true;
serialPort.Encoding = Encoding.GetEncoding("iso-8859-1");

serialPort.DiscardInBuffer();
serialPort.DiscardOutBuffer();

SendCommand("AT"); // "Ping"
SendCommand("AT+CMGF=1"); // Message format
SendCommand("AT+CSCS=\"PCCP437\""); // Character set

SendCommand("AT+CMGS=\"123456\"") // Phone number
SendCommand("hello" + "\x1A"); // Message

To check response (absolutely avoid arbitrary waits!) you can start with something like this (raw untested adaption so you may need some debugging, see also this post):

AutoResetEvent _receive;

string ReadResponse(int timeout)
{
    string response = string.Empty;

    while (true)
    {
        if (_receive.WaitOne(timeout, false))
        {
            response += _port.ReadExisting();
        }
        else
        {
            if (response.Length > 0)
                throw new InvalidOperationException("Incomplete response.");
            else
                throw new InvalidOperationException("No response.");
        }

        // Pretty raw implementation, I'm not even sure it covers
        // all cases, a better parsing would be appreciated here.
        // Also note I am assuming verbose V1 output with both \r and \n.
        if (response.EndsWith("\r\nOK\r\n"))
            break;

        if (response.EndsWith("\r\n> "))
            break;

        if (response.EndsWith("\r\nERROR\r\n"))
            break;
    }

    return response;
}

Adding _receive.Reset() just before you send your command and of course also adding OnPortDataReceived as handler for SerialPort.DataReceived event:

void OnPortDataReceived(object sender,
    SerialDataReceivedEventArgs e)
{
    if (e.EventType == SerialData.Chars)
        _receive.Set();
}

If you have some trouble (but you can connect) you may replace \r with \n. Some modems incorrectly (assuming <CR> has not been mapped to anything else than 13 using S3 parameter) use this character as command line terminator by default (even if it should be present in output only for V1 verbose output). Either change your code or send appropriate S3.

这篇关于发送英文短消息与GSM调制解调器(D-Link的DWM-156)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆