LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

[rs232.h] ComRd(,,) slow execution

Solved!
Go to solution

Dear users,

I'm an electronic engineering student approaching to his graduation with a thesis on absolute error in gsm positioning.

I'm creating the server application to receive a sms (with AT commands from a rsr232 connected Siemens TC35 gsm module) with cellid informations by the client mobile station, to elaborate them in way to send them (with apis) to Google to retrieve the position with a given cellid.

 

I'm experiencing many problem with ComRd which is absolutely slow, e.g. in the connection setup, i need six blocks like this (one for each setting) and the total execution takes over 15 seconds:

**********************************************************************

                    FlushInQ (ComPort);
                    strcpy(writeBuf,"AT+CLIP=1\r"); // Caller-id Presentation
                    ComWrt (ComPort, writeBuf, strlen(writeBuf));
                    Delay (0.2);
                    ComRd(ComPort, readbuf, 10); // ATTENTION! Slow execution, same with "ComRdTerm (ComPort, readBuf, 10, 0);"
                    if ( !findstr(readBuf,"OK",&indexBuf) ) setErr=0; //check if OK was answered

**********************************************************************

 

Breakpointed to first istruction, and following with step to step execution, if all the other istructions are immediately executed, on ComRd it takes seconds; even if reading just 10 bytes. The same if I use ComRdTerm waiting for the 0 (null).

I can't explain to me why, reading only ten bytes from the rs232 buffer, it takes so much time; there are no timeout issue, command does not pend to something else!

 

Can someone, please, help me?

 

Thanks,

Luca Gallucci

 

LG
Electronic Engineering student @ Università degli Studi di Napoli "Federico II"
Some of my creations here
0 Kudos
Message 1 of 20
(5,784 Views)
Solution
Accepted by Spaghetto

Hi Luca,

 

You don't need the 0.2 second delay after calling ComWrt.

 

You can directly call ComRd, the time it takes for the GSM modem to process your command and answer is actually tolerated by the timeout value of the port, which you can set by SetCommTime function.

 

It is possible that you are missing the reply during that 0.2 second wait.

 

I strongly recommend you use ComRdTerm, because you may not exactly know how many bytes will arrive after an AT command and this may cause problems since you have to give the number of bytes to read from the port when you use ComRd.

But it is guaranteed that a AT command reply will end with a CR and/or LF.

 

The way you call ComRdTerm is wrong. You should use CR or LF as terminating character, not NULL.

The GSM modem will never send you a NULL character, so function will wait until the read operation times out (because it cannot terminate on a NULL), hence the slowing down behavior you are complaining.

 

I hope I could make myself clear.

S. Eren BALCI
IMESTEK
Message 2 of 20
(5,781 Views)

Dear ebalci,

thanks for the prompt reply.

 

Since ate0 needs 50ms (receiving-setting-answering), at+clip above 150, and at+cmgr needs sometimes about a second to retrieve sms from memory; the delay was the smarted option I used to program my pic24f mcu on the client side; I assumed that was the same over here. I tried to remove this delay, even if setcomtime was set on higher time it didn't catch the answer!

 

For ComRdTerm, the problem is that, e.g. to an ATE0 command, the answer is "<cr><lf>OK<cr><lf>", if I wait for an LF, the output string captured from comrdterm will be a null one! The problem is that LF comes ahead and at the end of each command, so there is no real terminator string; i tought that the input buffer was something alike <cr><lf>OK<cr><lf>000000000.... , so I tried to wait the 0 (filling the buffer, not sent by the modem) but nothing changed.

 

So, I modified my code this way:

********************************************************************************

                    SetComTime (ComPort, 0.2);
    
                // Inizializzazione Modulo
                    FlushInQ (ComPort);
                    strcpy(writeBuf,"ATE0\r"); // Echo off-presenza
                    ComWrt (ComPort, writeBuf, strlen(writeBuf));
                    Delay (0.2);
                    ComRd(ComPort, readBuf, GetInQLen(ComPort));
                    if ( findstr(readBuf,"OK",&indexBuf) ) SetCtrlVal (mainPanel, MAIN_PANEL_GSM_ON, 1);

********************************************************************************

 

In this way (getinqlen) I read all the answer in the buffer, hoping that there will not be other messages since I've just flushed it.

 

It works this way, even if I can't remove the delay func; maybe I haven't understand completely your already helpfull answer.

 

Thank you very muck, you saved me, my professor wanted to use interrupt that are the worst way to approach this part complicating this already complicated part (i use interrupt for unsolicited codes in another part of the program)!

 

(sorry for my broken english - "it's-a-me...")

 

LG

LG
Electronic Engineering student @ Università degli Studi di Napoli "Federico II"
Some of my creations here
0 Kudos
Message 3 of 20
(5,779 Views)

I would give a timeout of 1 second and remove the Delay (0.2) line, if I were you.

 

Anyway, to handle the "<cr><lf>OK<cr><lf>" reply, you can call ComRdTerm twice.

 

You can verify that you got an "OK" after this second ComRdTerm.

S. Eren BALCI
IMESTEK
0 Kudos
Message 4 of 20
(5,771 Views)

The twice ComRdTerm call is a clever, and working, solution!

I've perfectly understood the question, and your tought are logically correct, but the solution with 1sec timeout (also with 2-5s) is still not working (and don't know why)!

 

************************************************************************************

                    SetComTime (ComPort, 1);

                    ...

                    FlushInQ (ComPort);
                    strcpy(writeBuf,"AT+CMGF=1\r"); // SMS in text mode
                    ComWrt (ComPort, writeBuf, strlen(writeBuf));
                    //Delay (0.2);
                    ComRdTerm (ComPort, readBuf, GetInQLen(ComPort), '\r');
                    ComRdTerm (ComPort, readBuf, GetInQLen(ComPort), '\r');
                    if ( !findstr(readBuf,"OK",&indexBuf) ) setErr=0;

************************************************************************************

 

Thanks for you support,

LG

LG
Electronic Engineering student @ Università degli Studi di Napoli "Federico II"
Some of my creations here
0 Kudos
Message 5 of 20
(5,767 Views)

Are you aware that the modem might be echoing the characters you are sending?

 

This means when you send "AT+CMGF=1\r", you first receive the exact command in your input buffer and then you can read the "OK" response.

 

You wouldn't be able to see what you type in HyperTerminal if it weren't for this echo.

Hence you have to take it into consideration when using the modem programmatically.

 

This echo was turned on by default in a Telit modem I have used, but don't know if it is the same for your hardware.

S. Eren BALCI
IMESTEK
0 Kudos
Message 6 of 20
(5,756 Views)

ATE0 is the first command sent in setting function (immediately after com port opening) to disable echo!

Also disabling echo manually and starting the program, the problem persist.

Echo is always on as default on a modem startup.

 

LG

 

LG
Electronic Engineering student @ Università degli Studi di Napoli "Federico II"
Some of my creations here
0 Kudos
Message 7 of 20
(5,755 Views)

Hi,

    Using modem by AT can be litle painfull. It is long time when i work on this, but there is some tips:

    1)calling Delay() is not good idea because its lockup your CPU to 100%. Because of this manner, Windows has less time/chance to receive data on serial port and deliver it to your application

       if you like use some delay function try loop with ProcessSystemEvents() to give more chance to windows deliver data and Sleep();//Windows.h  to wait without lockup your CPU

    2)using GetInQLen(ComPort) before ComRd (not inline)is good idea (in combination with wait (1*))

      however if number of lines(end with CRLF) is not known, the only way is wait(to timeout) and check for incoming data (after last received character)

    3)most AT command has simple response with known number of lines(or recognisable end of response)

       so it is possible to detect if whoole response is received (so not need to wait if there is next line (2*))

       according to used AT commands it can be good idea to create function which detect if whole AT Response is received(and possibly get its result(OK/ERROR/OTHER)).

       there is some rules from my memory 🙂

          blank line can be removed from response  "CRLF"

          most simple command return Data+"\CR\LF" + "OK\CR\LF","ERROR\CR\LF" so this can be used to detect if whole reponse is received.

          sometimes modem send unsolicited message before Response to AT command.It is not mixed with response,it is simply send from modem to pc before AT command is send(or in meantime)

            This can be detected because starts with "+TEXT:"  (for example incomming SMS "+CMTI:xxxxxxx" )

            (but some commands returns this as part of response so this must be handled according to used commands, ie allowing some specific strings when need)

          When read SMS message, first read line with header,which contains length of message,Which start after CR/CRLF (not sure if one or both).

            This can prevent some errors when SMS can contain text like "OKCRLF" or when contain only one CR(or LF) character to line break.

    4)I think(not sure) that some modems not send CLRF but only one character LF / CR  on some/all commands/response

       so before change our modem or put application public, try modify your code to handle this. Test it on several modems if you can.

    5)some modems has been reconfigured after Of/On, so be prepared to handle this

       for example:

       to use echo

       to send unsolicited messages:like SMS is received.

       to store SMS on Modem / SMS / Combined

       work with sms in nonasci format(not remember the name) but text and header is totaly diferent

      

P.S. sorry for my bad english

Message 8 of 20
(5,740 Views)

Dear OVR_CZ,

thanks for the reply, I've taken time to answer because I tried to apply all your tips to my code.

1-2) I'm trying to delete delay routines, setting timeout to 1 sec, as you can read in last posts, but I cant, if I delete delays, the read instructions start before timeout, and nothing is received, can you explain me why?

3) For setup, i send command and wait for an answer, you can read above how I've solved the <cr><lf>answer<cr><lf> problem, after your tip I've create a function unsigned char sendat(command,delay); that return 1/0 if OK is/isn't received; for the unsolicited code i use interrupts enabling ConfigComCallback(,,...); waiting for the "+" and switching to the corretc answer eg. in message +CNMI.... +RING.... (after having setted them previously)

4) my application is only for TC35 modem, is a gratuating thesis, i don't need to make an universal application, is just for researching purpose on gsm posizioning error.

5) Once COM is connected, many routines start setting up the modem, like disabling echo, sms in text mode, deleting a slot in memory for an sms...etc

 

Can you help me with (2) ?

 

Thanks, and don't care about your english, It's perfect.

LG

LG
Electronic Engineering student @ Università degli Studi di Napoli "Federico II"
Some of my creations here
0 Kudos
Message 9 of 20
(5,724 Views)

Hello Luca,

OVR_CZ was not suggesting you to avoid waits but to avoid using Delay () command! If you are using CVI release 9 or later you can use DelayWithEventProcessing () instruction from the Programmer's Toolbox, which does not blocks the process: since this tool is distributed in source format you can see in its code how it is implemented.

 

 

PS Ciao! Mi sono laureato nella tua stessa università... un po' di anni fa Smiley Happy



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 10 of 20
(5,715 Views)