【问题标题】:send English SMS with GSM Modems (D-Link DWM-156)使用 GSM 调制解调器发送英文短信 (D-Link DWM-156)
【发布时间】:2015-04-03 15:41:57
【问题描述】:

我正在使用 AT 命令在 C#.Net 中为 GSM 调制解调器 (D-Link DWM-156) 开发应用程序。我在发送英文短信时遇到问题。 我尝试发送“你好”,但我在手机中收到了□□□□,或者...除了你好。

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);

【问题讨论】:

  • 执行 serialPort1.WriteLine("123456" + "\x1A"); ?
  • WriteLine 输出\r\r\n 无论如何,不​​需要将它们包含在字符串中
  • 乱码文本通常意味着编码/代码页问题。您是否可以使用相同的命令从控制台发送短信?你买4盒还是5盒? 5 表示编码问题,4 表示至少最后一个字符被误解为特殊字符。
  • 如果我做 serialPort1.WriteLine("123456" + "\x1A") 。它显示在我的手机上 s□IF
  • 我做了这段代码,但它也不能正常工作。 serialPort1.WriteLine("AT+CMGF=1\n");线程.睡眠(1000); serialPort1.Write("AT+CMGS=\"09390149196\"\n");Thread.Sleep(1000); serialPort1.Write("Hello" + "\x1A")

标签: c# serial-port sms


【解决方案1】:

一些修复(可能更多,但我没有看到完整代码)。

  • 不要使用WriteLine(),而是使用Write(),因为\r(单独)是命令行和结果代码终止符。
  • SerialPort.WriteLine() 默认情况下会写入一个 usASCII 编码字符串,但您的 GSM 调制解调器需要使用 AT 命令指定的编码字符串。将SerialPort.Encoding 属性设置为特定编码并发送CSCS 命令。您可以使用CSCS=? AT 命令询问支持的编码。即使应该应用默认的 GSM,我也会避免隐含地依赖它。
  • 您不需要在每个命令之后等待,但您必须等待调制解调器应答(检查 OKERROR 字符串)。

来自docs

命令行由三个元素组成:前缀、正文和终止字符。命令行前缀由字符“AT”或“at”组成 [...] 终止字符可以由用户选项(参数 S3)选择,默认为 CR。

在伪代码中:

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

要检查响应(绝对避免任意等待!)你可以从这样的东西开始(未经测试的原始适配,所以你可能需要一些调试,另见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;
}

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

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

如果您遇到问题(但可以连接),您可以将\r 替换为\n。一些调制解调器不正确(假设<CR> 没有映射到除13 之外的任何其他东西,使用S3 参数)默认使用此字符作为命令行终止符(即使它应该出现在输出中仅适用于V1 详细输出)。更改您的代码或发送适当的S3

【讨论】:

  • 谢谢。但是当我使用你的代码时,我遇到了问题。当我发送“h”(一个字符)时,我在手机中正确接收。但是当 2 个或更多字符(例如“你好”)时,我的手机无法正确接收。
  • 一些调制解调器(见更新答案的末尾)处理/接受/要求 \n INSTEAD OF \r (这是他们的默认,您可以使用 S3 指定您想要的范围)。这是错误的(从 standard 的角度来看),但如果是您的情况,您可以尝试。只是不要添加 \n,在 SendCommand() 函数中将 \r 替换为 \n。
  • 嗨。我将 \r 替换为 \n 但我之前遇到过问题。
  • 我用 \n 或 \r 写过这段代码,用 \n 或 \r 写行。但没有一个做错了。
  • 什么是调制解调器响应?您是否尝试使用 \r 并指定 S3=13?
猜你喜欢
  • 1970-01-01
  • 2013-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多