3

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);
Jehof
  • 34,674
  • 10
  • 123
  • 155
sm k
  • 37
  • 1
  • 8
  • What it shows on phone if you do serialPort1.WriteLine("123456" + "\x1A"); ? – Amit Feb 04 '15 at 07:56
  • `WriteLine` outputs `\r` or `\r\n` anyway, no need to include them in the string – Panagiotis Kanavos Feb 04 '15 at 08:07
  • 1
    Garbled text usually means encoding/codepage problems. Are you able to send an SMS from the console using the same commands? Do you get 4 boxes or 5? 5 means an encoding problem, 4 means at least the last character was misinterpreted as a special character. – Panagiotis Kanavos Feb 04 '15 at 08:13
  • if I do serialPort1.WriteLine("123456" + "\x1A") .it shows on my phone s□IF< – sm k Feb 04 '15 at 09:01
  • I do this code but it does'nt work correct too. serialPort1.WriteLine("AT+CMGF=1\n"); Thread.Sleep(1000); serialPort1.Write("AT+CMGS=\"09390149196\"\n");Thread.Sleep(1000); serialPort1.Write("Hello" + "\x1A") – sm k Feb 04 '15 at 09:03
  • I send SMS with sim900. and I don't have any problem. but when I use D-Link DWM-156 I have this problem. plese help me! – sm k Feb 04 '15 at 09:09
  • Where are the sleep times taken from? Is there another way of knowing when we are ready to send another command? – Ignacio Soler Garcia Feb 04 '15 at 10:59

1 Answers1

1

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.

Community
  • 1
  • 1
Adriano Repetti
  • 65,416
  • 20
  • 137
  • 208
  • thank you.but when I use your code I have before problem.when I send "h"(one character) ,I receive correctly in my phone. but when 2 or more character for example "hello", ,I don't receive correctly in my phone. – sm k Feb 04 '15 at 12:20
  • Some modems (see at the end of updated answers) handle/accept/require \n INSTEAD OF \r (it's their _default_, you may specify what you want with S3 parameter). It's wrong (from _standard_ point of view) but you can try if it's your case. Just do not add \n, replace \r with \n in SendCommand() function. – Adriano Repetti Feb 04 '15 at 12:48
  • Hi.i replace \r with \n but I have before problem. – sm k Feb 06 '15 at 14:58
  • I do this code ever type.write with \n or \r and writeline with \n or \r. but none of them didn't do correctly. – sm k Feb 06 '15 at 15:06
  • What's modem response? Did you try to use \r and also specify S3=13? – Adriano Repetti Feb 06 '15 at 15:10
  • yes.but when send "hello"( for example ) .it shows on my phone "e2□y". when I try this code with sim900 .it shows correct on my phone,but for GSM Modems (D-Link DWM-156) it does'nt show correct:-( – sm k Feb 07 '15 at 06:20