473,394 Members | 1,699 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,394 software developers and data experts.

Delayed AT comand response generation

Hi! I'm trying to run a few AT commands on a GSM modem. I'm doing this in C#.Net 2005.

When I run a few commands one after the other, the response generation takes a long time. The response for the 1st command is returned as blank, i.e nothing. And its actual response is returned as the response to the 3rd command.

That is, due to the delayed response generation, the responses are being over-written. When the program ends, the responses to the last 2 or 3 commands are simply lost.

Please help.


Amey
Mar 6 '07 #1
10 4552
horace1
1,510 Expert 1GB
after you send an AT command cannot you wait for a response such as OK or a message from the modem, then send the next command?
Mar 6 '07 #2
Banfa
9,065 Expert Mod 8TB
Personally I would go further than horace1 and say that you really should wait for the response from the first command before you send the second. That is part of what proper communications handshaking is about, you wait to see that 1 message is successful before sending the next, unless the protocol is specified as allowing you to send a more data with the reply to the initial data (like TCP/IP).

You do not know what the modem is doing (or the quality of the software it is running) your command may have caused network action, sending a second command while 1 is already in progress may be causing the modem handling problems or you may have requested that it does something that it can't do until the first command has completed.
Mar 6 '07 #3
Personally I would go further than horace1 and say that you really should wait for the response from the first command before you send the second. That is part of what proper communications handshaking is about, you wait to see that 1 message is successful before sending the next, unless the protocol is specified as allowing you to send a more data with the reply to the initial data (like TCP/IP).

You do not know what the modem is doing (or the quality of the software it is running) your command may have caused network action, sending a second command while 1 is already in progress may be causing the modem handling problems or you may have requested that it does something that it can't do until the first command has completed.


Re:



Thank u for taking interest in my problem. But the real problem lies here.

I'm going exactly the way u said, one command at a time, waiting for its reply before going for the 2nd command. But I don't have any means of computing the time it takes for the response to be generated. For the time being I'm using a delay of abt 7 secs after each command, hoping the required response will b generated within this time. But even after waiting for 7 secs, the responses are being over-written.These are some basic modem query commands. This is how I get their responses :

INFO - AT+GMM :
INFO - AT+FCLASS=? : Nokia N70

INFO - ATI1 : OK

INFO - ATI2 :
INFO - ATI3 : 0

INFO - ATI4 : OK


The "Nokia N70" is actually the output generated by the 1st command. The "0" is actually the output generated by the command At+FCLASS=?. But it comes as the output to the 4th command. The outputs to the last 3 commands are simply lost as the application terminates after running the last command and waiting for its response for 7 seconds. This will cause serious problems when I will send 100 messages at a time.


Please help.

Amey
Mar 7 '07 #4
Banfa
9,065 Expert Mod 8TB
Here is what v.250 has to say about executing commands and receiving replies

5.6 Executing commands
Upon receipt of the termination character, the DCE shall commence execution of the commands in
the command line in the order received from the DTE. Should execution of a command result in an
error, or a character be not recognized as a valid command, execution is terminated, the remainder of
the command line is ignored, and the ERROR result code is issued. Otherwise, if all commands
execute correctly, only the result code associated with the last command shall be issued; result codes
for preceding commands are suppressed. If no commands appear in the command line, the OK result
code is issued.
ITU v250 is the standard specifying the AT command set and operation for a normal or GSM modem/telephone available here. Additionally 3GPP 27.007 may be useful which is the specification of the extra commands used by a GPRS/3G modem/telephone available here (if you want it just get the latest version).


Anyway from the quote you can see that the modem you are using is not conforming to specification (it is not surpressing results from previous commands). This is not surprising I do not think I have ever used a modem that conformed to specification, apparently the modem manufacturers do not seem to think it is important which is why it is so hard to write modem drivers.

7 seconds does sound rather long for a response to a AT+GMM (I know the modems I have worked on responded more quickly) however we don't know what the modem is doing or how much load the modems processor is under. I would recommend a timeout of 30 seconds, 90% of the commands (and 99% of the commands you are likely to use) should respond in this time.

You can afford a long timeout, remember you should only hit it if there is an error of some sort so in normal operation it should not effect speed. However have you also considered the possibility of an error in the code you are using to send/receive data as the cause of the problem?
Mar 7 '07 #5
Here is what v.250 has to say about executing commands and receiving replies



ITU v250 is the standard specifying the AT command set and operation for a normal or GSM modem/telephone available here. Additionally 3GPP 27.007 may be useful which is the specification of the extra commands used by a GPRS/3G modem/telephone available here (if you want it just get the latest version).


Anyway from the quote you can see that the modem you are using is not conforming to specification (it is not surpressing results from previous commands). This is not surprising I do not think I have ever used a modem that conformed to specification, apparently the modem manufacturers do not seem to think it is important which is why it is so hard to write modem drivers.

7 seconds does sound rather long for a response to a AT+GMM (I know the modems I have worked on responded more quickly) however we don't know what the modem is doing or how much load the modems processor is under. I would recommend a timeout of 30 seconds, 90% of the commands (and 99% of the commands you are likely to use) should respond in this time.

You can afford a long timeout, remember you should only hit it if there is an error of some sort so in normal operation it should not effect speed. However have you also considered the possibility of an error in the code you are using to send/receive data as the cause of the problem?






Thanks a lot for replying.

I'm writing all the data being received by th Serial Port instance(ComPort) to a string, and printing it.


ComPort.DataReceived += DataRecievedHandler;
.
.
.
private static void DataRecievedHandler(object sender, SerialDataReceivedEventArgs args)
{
data = ComPort.ReadLine();
//Console.WriteLine("Response : " + data + Environment.NewLine);
}

Please tell me if I'm wrong, or if there's any other way to do this.


Amey
Mar 7 '07 #6
Banfa
9,065 Expert Mod 8TB
I unfortunately do not know C# but I see no obvious error in that and I wouldn't expect there to be. However what is causing DataRecievedHandler to be called?

In my (10 year) experience of Windows there is something wrong in its heart that causes it to not always notify the application of received data as expected.
Mar 7 '07 #7
I unfortunately do not know C# but I see no obvious error in that and I wouldn't expect there to be. However what is causing DataRecievedHandler to be called?

In my (10 year) experience of Windows there is something wrong in its heart that causes it to not always notify the application of received data as expected.



No luck. Even after 30 secs of delay, the output is same.

I'm actually calling the DataReceivedHandler in a method called OpenPort, where I'm initializing the Serial Port instance. In the handler, I'm reading the input(generated responses) to the Port line by line into a string called 'data'.

The 'DataReceived' in "ComPort.DataReceived" represents the method that handles the data received event of ComPort To that I'm simply passing the handler.

Amey
Mar 7 '07 #8
Banfa
9,065 Expert Mod 8TB
No luck. Even after 30 secs of delay, the output is same.
This is indicative of the problem being the program not receiving the data properly rather than the modem not sending the data.

I'm actually calling the DataReceivedHandler in a method called OpenPort, where I'm initializing the Serial Port instance. In the handler, I'm reading the input(generated responses) to the Port line by line into a string called 'data'.

The 'DataReceived' in "ComPort.DataReceived" represents the method that handles the data received event of ComPort To that I'm simply passing the handler.
OK so you are trying to use the receive event handler to get the data received by the serial port. Unfortunately it would appear from your results that this is not working correctly.

There does seem to be any method for your event handler to signal the main thread of execution that data has arrived.

Ideally what your program should be doing is

<indent>
DO
<indent>
Send AT Command
Wait for Response
Read Response
</indent>
WHILE More Comands to Send
</indent>

If you look at the Microsoft help pages they do not use the data received event, they start a thread and poll the serial port.

I have to say that I have no evidence that serial port events generate by the Windows sub-systems ever worked and I have recently had to hack receiving data from a modem using com port events out of a program and replace it with a polled read because the events where unreliable.

So here are 2 alternitive approaches

1. Start a thread to handle the receive. In the thread poll the com port for data just like the MS example.

2. Actually you are lucky, generally you know you will only be receiving responses after you have sent a command and you know the response will end with OK or ERROR or another known error code. You do not need to start a thread, send the command and then just poll for the response in you main thread (with a timeout). This doesn't handle URCs (unsolicited response codes) and I don't know if you need to, if you do this wont work because it only receives in response to a command and a URC can happen at anytime.
Mar 7 '07 #9
This is indicative of the problem being the program not receiving the data properly rather than the modem not sending the data.

OK so you are trying to use the receive event handler to get the data received by the serial port. Unfortunately it would appear from your results that this is not working correctly.

There does seem to be any method for your event handler to signal the main thread of execution that data has arrived.

Ideally what your program should be doing is

<indent>
DO
<indent>
Send AT Command
Wait for Response
Read Response
</indent>
WHILE More Comands to Send
</indent>

If you look at the Microsoft help pages they do not use the data received event, they start a thread and poll the serial port.

I have to say that I have no evidence that serial port events generate by the Windows sub-systems ever worked and I have recently had to hack receiving data from a modem using com port events out of a program and replace it with a polled read because the events where unreliable.

So here are 2 alternitive approaches

1. Start a thread to handle the receive. In the thread poll the com port for data just like the MS example.

2. Actually you are lucky, generally you know you will only be receiving responses after you have sent a command and you know the response will end with OK or ERROR or another known error code. You do not need to start a thread, send the command and then just poll for the response in you main thread (with a timeout). This doesn't handle URCs (unsolicited response codes) and I don't know if you need to, if you do this wont work because it only receives in response to a command and a URC can happen at anytime.






Hi,


I've been trying this using threads, but no luck.

I got this sample code from the web which I modified a bit. Here it is:





Expand|Select|Wrap|Line Numbers
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.IO.Ports;
  5. using System.Diagnostics;
  6.  
  7. namespace SmsManager
  8. {
  9.     class PortUtilities
  10.     {
  11.         public delegate void OnMessageLog(object sender, PortUtilitiesEventArgs e);
  12.         public static event OnMessageLog OnMessageLogged;
  13.  
  14.         public static void Main()
  15.         {
  16.             OpenPort("COM9");
  17.         }
  18.  
  19.  
  20.  
  21.         /// <summary>
  22.         /// Opens the supplied port number if the port is not already open
  23.         /// </summary>
  24.         /// <param name="portName">The Name of the port, "COM?"</param>
  25.         /// <returns>Opened Serial Port Object</returns>
  26.         public static SerialPort OpenPort(string portName)
  27.         {
  28.             SerialPort serialPort = new SerialPort(portName, 9600, Parity.None, 8, StopBits.One);
  29.             try
  30.             {
  31.                 serialPort.Handshake = Handshake.RequestToSend;
  32.                 serialPort.ReadTimeout = 5000;
  33.                 if (!serialPort.IsOpen) { serialPort.Open(); }
  34.                 SendCMGFCommand(serialPort);
  35.                 SendATCommand(serialPort);
  36.                 //SendCPINCommand(serialPort, pinNumber);
  37.             }
  38.             catch (Exception ex)
  39.             {
  40.                 LogMessage(ex.Message, EventLogEntryType.Error);
  41.             }
  42.             return serialPort;
  43.         }
  44.  
  45.  
  46.  
  47.         /// <summary>
  48.         /// Sends an AT Command to the supplied port
  49.         /// </summary>
  50.         /// <param name="serialPort">Port to use to send command</param>
  51.         /// <returns>True if successful</returns>
  52.         private static bool SendATCommand(SerialPort serialPort)
  53.         {
  54.             DateTime timeout = DateTime.Now.AddMinutes(5);
  55.             string buffer = "";
  56.             try
  57.             {
  58.                 serialPort.Write("AT+GMM\r");
  59.                 buffer = "";
  60.                 do
  61.                 {
  62.                     buffer += serialPort.ReadExisting();
  63.                     Console.WriteLine(buffer);
  64.                     if (DateTime.Now > timeout)
  65.                     {
  66.                         throw new Exception("AT Command timed out without receiving 'OK'.");
  67.                     }
  68.                 }
  69.                 while (!buffer.Contains("OK"));
  70.             }
  71.             catch (Exception ex)
  72.             {
  73.                 LogMessage(ex.Message, EventLogEntryType.Error);
  74.                 return false;
  75.             }
  76.             return true;
  77.         }
  78.  
  79.  
  80.  
  81.         /// <summary>
  82.         /// Sends the CMGFCommand to set the input type
  83.         /// </summary>
  84.         /// <param name="serialPort">Port to use to send command</param>
  85.         /// <returns>True if successful</returns>
  86.         private static bool SendCMGFCommand(SerialPort serialPort)
  87.         {
  88.             DateTime timeout = DateTime.Now.AddMinutes(5);
  89.             string buffer = "";
  90.             try
  91.             {
  92.                 serialPort.Write("AT+CMGF=1\r");
  93.                 buffer = "";
  94.                 do
  95.                 {
  96.                     buffer += serialPort.ReadExisting();
  97.                     Console.WriteLine(buffer);
  98.                     if (DateTime.Now > timeout)
  99.                     {
  100.                         throw new Exception("AT+CMGF=1 Command timed out without receiving 'OK'.");
  101.                     }
  102.                 }
  103.                 while (!buffer.Contains("OK"));
  104.             }
  105.             catch (Exception ex)
  106.             {
  107.                 LogMessage(ex.Message, EventLogEntryType.Error);
  108.                 return false;
  109.             }
  110.             return true;
  111.         }
  112.  
  113.  
  114.  
  115.         private static void LogMessage(string message, EventLogEntryType eventLogEntryType)
  116.         {
  117.             PortUtilitiesEventArgs e = new PortUtilitiesEventArgs();
  118.             e.Message = message;
  119.             e.EventLogEntryType = eventLogEntryType;
  120.             if (OnMessageLogged != null)
  121.             {
  122.                 OnMessageLogged(new object(), e);
  123.             }
  124.         }
  125.     }
  126.  
  127.  
  128.  
  129.     public class PortUtilitiesEventArgs : EventArgs
  130.     {
  131.         public string Message;
  132.         public EventLogEntryType EventLogEntryType;
  133.     }
  134. }
  135.  




However even here, "DateTime timeout = DateTime.Now.AddMinutes(5);" a random response time is being assumed. Is there any way to wait till all the responses for a command are received, without using a random response time?
Mar 14 '07 #10
Banfa
9,065 Expert Mod 8TB
However even here, "DateTime timeout = DateTime.Now.AddMinutes(5);" a random response time is being assumed. Is there any way to wait till all the responses for a command are received, without using a random response time?
This is not a random response time, this is a timeout.

That is this is not how long it takes to receive the response, this is how long we are going to wait until we decide we are not going to receive a response.

For robust communications with another system you (nearly always) have to assume that you may not get the expect response and your only option is to select a timeout value and if that amount of time happens without a response perform some error handling/correction code.

If you do not put in a timeout and your program does not get the expected reply because of an error in your program, an error in the remote systems program or noise induced on the line between to 2 systems then your program will stop because it will never see the expected response that it is still waiting for.

Good communication code will always have timeouts in it to handle communication failures.

However this code should not really run into these timeouts as the commands sent are simple and should be replied to immediately so the line

Expand|Select|Wrap|Line Numbers
  1. while (!buffer.Contains("OK"));
Should break it out of the loop once the complete reply has been received without hitting the timeout, i.e. after a few fractions of a second.

You could simplify this further by just sending "AT" which the modem should reply "OK" to.

It is probably worth outputing the contents of buffer at this stage so that you can see what is being received.

It is also worth using a Terminal program (like Hyperterm) to connect to the modem and verify that it is giving the correct responses.
Mar 14 '07 #11

Sign in to post your reply or Sign up for a free account.

Similar topics

7
by: Leo Breebaart | last post by:
Hi all, I have a question about Python and delayed evaluation. Short-circuiting of Boolean expressions implies that in: >>> if a() and b(): any possible side-effects the call to b() might...
0
by: Andreas Suurkuusk | last post by:
Hi, I just noticed your post in the "C# memory problem: no end for our problem?" thread. In the post you implied that I do not how the garbage collector works and that I mislead people. Since...
13
by: Brian | last post by:
Hi all... This question is more for the GURUs out there. It is not a question on how to do something, but why it happens, and I am trying to figure out if there is a pattern. I am using IE, but...
0
by: subi | last post by:
Hi, I don't know where's the best place to post my question. I hope it suits this group. I have created an assembly with a delay sign attribute set to true in the AssemblyInfo.cs. And the key...
3
by: CSharpUser | last post by:
How do I pass in command line parameters to the program at startup in Visual Studio. This is similar to doing csc program arg1 arg2. I want to achieve the same effect running the program in...
2
by: Amey Agnihotri | last post by:
Hi! I'm trying to run a few AT commands on a GSM modem. I'm doing this in C#.Net 2005. When I run a few commands one after the other, the response generation takes a long time. The response for...
3
by: Andy | last post by:
I have an ASP.NET webpage that allows a user to upload a file from the client browser. I want to display an animated gif and report on the progress of the upload. The <INPUTtag used for uploading...
3
by: MJP | last post by:
I have a button which kicks off the generation of a report after which the file will be downloaded. The report generation can take a long time, so client side onclick event of the button also...
4
by: jx2 | last post by:
can any1 give me a good example for cli or CGI or comand line usage i've read the description on php.net but i just dont understand whats going on what do you use it for and how - i managed to run...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.