9

ATコマンドを使用してC#.NetでGSMモデム(D-Link DWM-156)用のアプリケーションを開発しています。Unicodeメッセージ(ペルシア語やアラビア語で書かれたメッセージなど)の送信に問題があります。これが私のプログラムの中核です。

SerialPort GSMPort = new SerialPort();

GSMPort.PortName = "COM6";
GSMPort.BaudRate = 9600;
GSMPort.Parity = Parity.None;
GSMPort.DataBits = 8;
GSMPort.StopBits = StopBits.One;
GSMPort.Handshake = HandShake.RequestToSend;
GSMPort.DtrEnable = true;
GSMPort.RtsEnable = true;

GSMPort.Open();

GSMPort.Write("AT\r");
Thread.Sleep(1000);
GSMPort.Write("AT+CMGF=1\r");
Thread.Sleep(1000);
GSMPort.Write("AT+CMGS=\"" + destinationNumber + "\"\r\n");
Thread.Sleep(1000);
GSMPort.Write(shortMessage+ "\x1A");

英語とASCII文字で問題なく動作します。この記事を読み、 ATコマンドを使用してハイパーターミナルでUnicodeメッセージを送信できます。

AT [Enter]
OK
AT+CSCS="UCS2" or AT+CSCS="HEX" [Enter] ---> We have to convert our message to hex 
OK
AT+CMGF=1 [Enter]
OK
AT+CMGS="destinationNumber" [Enter]
> 0633064406270645002006450631062D06280627 ---> The hex format of our message (سلام مرحبا)
+CMGS: 139
OK

このコマンドが正しく機能GSMPort.Write("AT+CSCS=\"UCS2\"\r");したので、アプリケーションに追加して、0645 0631 062D 0628 0627(مرحبا)または0633 0644 0627 0645(سلام)を送信しようとしました。

GSMPort.Write("AT\r");
Thread.Sleep(1000);
GSMPort.Write("AT+CSCS=\"UCS2\"\r");
Thread.Sleep(1000);
GSMPort.Write("AT+CMGF=1\r");
Thread.Sleep(1000);
GSMPort.Write("AT+CMGS=\"" + destinationNumber + "\"\r\n");
Thread.Sleep(1000);
GSMPort.Write("0633064406270645" + "\x1A");

ただし、ハイパーターミナルのATコマンドとは異なり、宛先は正しい文字を受け取りません。C#コードとハイパーターミナルコードのこれらのATコマンドの違いは何ですか?この問題の解決にご協力いただければ幸いです。


追加情報: ご存知のように、ハイパーターミナルでUnicodeメッセージ(ペルシャ文字など)を送信したり、ATコマンドを使用したりしても問題はありません。以下のコードでは、سلامを送信しようとしています。「0633064406270645」は16進形式です。しかし、私は私の電話で□□□□を受け取ります。

GSMPort.Encoding = UnicodeEncoding.GetEncoding(1256);
GSMPort.Write("AT\r");
Thread.Sleep(1000);
GSMPort.Write("AT+CSCS=\"UCS2\"\r");
Thread.Sleep(1000);
GSMPort.Write("AT+CMGF=1\r");
Thread.Sleep(1000);
GSMPort.Write("AT+CMGS=\"" + destinationNumber + "\"\r\n");
Thread.Sleep(1000);
GSMPort.Write("0633064406270645" + "\x1A");

一方、ハイパーターミナル環境では、すべてがうまくいき、私はسلامを受け取ります。

AT [Enter]
OK
AT+CSCS="UCS2"
OK
AT+CMGF=1 [Enter]
OK
AT+CMGS="destinationNumber" [Enter]
> 0633064406270645 [Ctrl+Z]
+CMGS: 139
OK

ハイパーターミナルのプロパティで、「行の終わりを改行で送信」をチェックすると([プロパティ]->[設定]->[ASCII設定]にあります。下の画像を確認してください)、同じ問題が発生することに気付きました。 C#コード。「ラインフィードでラインを送る」はGSMPort.Writeデフォルトで有効になっていると思いますか?はいの場合、どうすれば無効にできますか?

ここに画像の説明を入力してください

4

3 に答える 3

10

私はついにこの問題を解決する方法を見つけました。質問の「追加情報」セクションで述べたSerialPortように、行末を改行で送信すると、Unicodeメッセージを送信するためのハイパーターミナルのC#コマンドとATコマンドの間にこの不一致が発生しました。ラインフィードに置き換えまし\rた。\n変更されたコードは次のとおりです。

GSMPort.Write("AT\n");
Thread.Sleep(1000);
GSMPort.Write("AT+CSCS=\"UCS2\"\n");
Thread.Sleep(1000);
GSMPort.Write("AT+CMGF=1\n");
Thread.Sleep(1000);
GSMPort.Write("AT+CMGS=\"" + destinationNumber + "\"\n");
Thread.Sleep(1000);
GSMPort.Write("0633064406270645" + "\x1A"); 

プロパティは変更SerialPort.EncodingSerialPort.NewLineないでください。デフォルト値を変更する必要はなくAT+CSCS="UCS2"、Unicode形式でメッセージを送信するように設定するだけです。

于 2013-03-16T15:10:18.540 に答える
4

まず、モデムのサポートを確認してunicodeから、コードをこれ
に変更します。Unicodeメッセージの正しいDCS(データコーディングスキーム)を指定する必要があります。これは0x08です。

この値は、AT+CSMPコマンドの4番目のパラメーターを「8」に変更することで設定できます。

AT + CSMP = 1,167,0,8

    GSMPort.Write("AT\r");
    Thread.Sleep(1000);
    GSMPort.Write("AT+CSCS=\"UCS2\"\r");
    Thread.Sleep(1000);
    GSMPort.Write("AT+CMGF=1\r");
    Thread.Sleep(1000);
    GSMPort.Write("AT+CSMP=1,167,0,8\r"); //AT+CSMP=1,167,0,8
    Thread.Sleep(1000);
    GSMPort.WriteLine("AT+CMGS=\"" + destinationNumber + "\"\r\n");
    Thread.Sleep(1000);
    GSMPort.WriteLine("0633064406270645" + "\x1A");
于 2013-03-09T15:48:12.293 に答える
2

のデフォルトのエンコーディングはSerialPortですEncoding.ASCII。使用している文字セット(など)SerialPort.Encodingをサポートするようにエンコーディングに設定するか、Unicode文字列を使用して任意の方法でバイトに変換します。Encoding.UTF32SerialPort.Write(char[], int, int)

于 2013-03-09T15:03:02.477 に答える