CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

RS232 reception problem

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Arclite



Joined: 02 Jul 2004
Posts: 16
Location: UK

View user's profile Send private message Send e-mail

RS232 reception problem
PostPosted: Tue Dec 07, 2004 8:14 pm     Reply with quote

Hi guys,

I have an RS232 port defined as:

Code:

#USE rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7, bit=8, stream=rsMOD)


and i want to send an AT msg to it like:

Code:

#define AT "AT"

fprintf(rsMOD,AT);
fprintf(rsMOD,"\r");     // the <CR>
// This works!


then i am waiting for the "OK\r" on the receive pin using:

Code:

fgets(InString,rsMOD);
// Then use 'strstr' to compare the returned msg with the expected "OK"
// or use an error handler


I am able to group these instructions several times to set up the modem, when the PIC is connected to a PC (hyper terminal), but i can't get past the first group when connected directly to the modem.

When connected to hyper terminal, if i punch the required responses on the keyboard, the PIC runs through the code with no problem. Do i need to check some flag or set some delay cycles?

I'm thinking of using the kbhit() func, but i'm sure there is a more orthodox method.

I'm not using the interrupt RDA yet as i want to set that up for a different function, so how can i do it?

Regards.
asmallri



Joined: 12 Aug 2004
Posts: 1635
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Tue Dec 07, 2004 8:58 pm     Reply with quote

Are you changing cables when you go from the PC to the modem?

The PC appears as a DTE device, the modem appears as a DCE device. So when the PIC is talking to the PC it must emulate a DCE and when talking to the modem the PIC must emulate a DTE. If you are not using any hardware handshaking and the modem is configured for software only then this means the only signals that need to be transposed are the transmit and receive.

Have you tried communicating between the PC and the modem at 9600 baud? Some modems will autobaud at higher baud rates such as 56K and 115K but will not operate at 9600 unless specifically configured.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
Arclite



Joined: 02 Jul 2004
Posts: 16
Location: UK

View user's profile Send private message Send e-mail

All of the wiring is correct
PostPosted: Wed Dec 08, 2004 9:12 am     Reply with quote

Hi asmallri,
The wires are in the right places, and the comm ports are all the same setting.

The main feature of the problem is that when i type in the "OK" to the PIC-PC link via hyper terminal, everything works. I get the same problem when i type the responses very quickly in the PIC-PC link as the PIC -Modem link would.
So i think i need some sort of delay, what's your opinion?

Regards.
asmallri



Joined: 12 Aug 2004
Posts: 1635
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Wed Dec 08, 2004 9:28 am     Reply with quote

I wouldn't try to solve this with delays. If the PIC you are using has a hardware USART then you should look at using receive interrupts and adding received characters to the a buffer until you get around to processing them. If the PIC does not have a hardware USART then you the use #use rs232 implementation can be transmitting or receiving but not both simultaneously. With a software USART imp[lementation you need to call kbhit() at better than tem times the bit rate to ensure you do not miss characters.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Wed Dec 08, 2004 10:00 am     Reply with quote

So are you saying that the code gets stuck at the fgets() call?

Also, you should add the ERRORS parameter to your #use RS232 statement.
Arclite



Joined: 02 Jul 2004
Posts: 16
Location: UK

View user's profile Send private message Send e-mail

PostPosted: Wed Dec 08, 2004 10:57 am     Reply with quote

Hiya,
Mark : yes the program stops at the fgets(.... I put an LED on before and after the second fgets(.. and the progam halts, illuminating the 1st LED but not the second.

Asmallri: i really need the interrupt for a different job using a larger message string structure. So if i can find different method to get around it, i would be happy with that.



Regards.
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Wed Dec 08, 2004 11:40 am     Reply with quote

Did the ERRORS make any difference? If you get an overflow, the receive is going to stop unless you add ERRORS to the #use.
Arclite



Joined: 02 Jul 2004
Posts: 16
Location: UK

View user's profile Send private message Send e-mail

PostPosted: Wed Dec 08, 2004 4:55 pm     Reply with quote

Hi Mark,

Checked and done what you had said. It doesn't make a difference.
I think it has something to do with the 'fgets()' function. It uses getc() until it reads a 'return' <13> value and puts what it has read into a string.
According to the manual.

The modem returns using <CR><LF> at the start and end of each response.

If that is the case, i'll have to write my own function to process the string modelled on gets(), to avoid the first <13> and read all of the return string.

I am surprised that the prog even got thro' the 1st gets().

I'll inform of the results i get.

Regards.
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Wed Dec 08, 2004 6:19 pm     Reply with quote

Quote:
I am surprised that the prog even got thro' the 1st gets().


I'm not. It read up to the <CR> and then stopped. The receive buf of the UART still had the <LF> in there. Then you sent another command and some more data was sent to the PIC probably overwriting the the <LF> causing a buffer overflow. At that point the receive is going to stop. Now if you put the ERRORS parameter in the #use RS232 it should take care of the overflow. However, if you missed the <13> because of the overflow, then you'll be stuck sitting there waiting for it.
Quote:
I wouldn't try to solve this with delays. If the PIC you are using has a hardware USART then you should look at using receive interrupts and adding received characters to the a buffer until you get around to processing them.


Follow his advice. He knows what he is talking about and I agree with him.

Quote:
Asmallri: i really need the interrupt for a different job using a larger message string structure. So if i can find different method to get around it, i would be happy with that.


This doesn't matter. The INT is for that UART. Receiving data is receiving data. Its up to you to handle it. You only get about 2 bytes of buffing with the hardware. Using the INT, you can create a buffer much larger and avoid missing the data due to the overruns.
Arclite



Joined: 02 Jul 2004
Posts: 16
Location: UK

View user's profile Send private message Send e-mail

Used interrupt RDA, and problem persists.
PostPosted: Sun Dec 12, 2004 3:31 pm     Reply with quote

Hiya,

I have designed my code to use the interrupt RDA for my modem activities as you recommended.

Code:


char InMSG[60];
BYTE next_in=0;
BYTE next_out=0;

#int_RDA
RDA_isr()

{
int t;

    InMSG[next_in]=getc();
    t=next_in;
    next_in=(next_in+1) % sizeof(InMSG);

    if(next_in==next_out)
    {
        next_in=t;

    }

}




When i had altered the rest of the code to accept it, the results were the same. It would hang after sending the 1st command to the modem, ie "AT\r\n"

I had used "ERRORS" in the "#use RS232" line with no improvement. Now i believe that it clears any frame or overrun error in the comms h/w.
Given that there was no change in the performance, i removed the "ERRORS" flag, and used my own function that lights up an LED when either error bit OERR or FERR are thrown, toggling CREN if required to reset the operation. The LED did not light=> no error.

So i think the problem is with the "string" part of the code. I use the comm port to read a response into the InMSG string.

When i first use the InMSG string there will be the response in the first 5 elements, and garbage in the other 55, one might be a Null character.

When i used the "strstr" command to compare to "\r\nOK\r\nNULL", i am supposed to use Null terminated strings, am i correct?

Then i clear the string InMSG (set all elements to Null ie 0), then send my next command, and wait for the next response. I know a response is obtained via a comm port "tap", but still i can't get past the second "strstr" command.

If i don't clear the InMSG string and let it filter through, the device appears to have setup correctly.

In short, my questions are:
How do i clear the InMSG for later reuse in similar strstr checks?

Do i have to reset next_in and next_out when i clear the InMSG string?

Regards
Arclite



Joined: 02 Jul 2004
Posts: 16
Location: UK

View user's profile Send private message Send e-mail

One other thing...
PostPosted: Sun Dec 12, 2004 4:03 pm     Reply with quote

I send "AT\r\n" to the modem, and i get an "\r\nOKr\n" AND an "..AT.." sent back, whats going on here?
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Sun Dec 12, 2004 6:04 pm     Reply with quote

You probably have echo on. There is a command to turn it off.
Arclite



Joined: 02 Jul 2004
Posts: 16
Location: UK

View user's profile Send private message Send e-mail

I think i've cracked this one!
PostPosted: Mon Dec 13, 2004 9:22 am     Reply with quote

Hi Mark,

I have solved most of this stupid problem, and you were correct about the OERR overrun bit. When i had tested the OERR bit earlier, the bit definition was wrong by one byte, so OERR went undetected. Wasn't ERRORS supposed to handle that?

Anyway the code runs through all the modem start-up code with no fault and sends an SMS txt out on completion.


I have code setting up looking like:
Code:


#int_RDA
RDA_isr()
{

InMSG[next_in]=getc();
  if(OERR)
  {
    CREN=0;
    CREN=1;
  }
  else
  {
    if(FERR)
    {

    }
    else
    {
      next_in=(next_in+1) % sizeof(InMSG);
    }
  }
  if(next_in==Next_out)
  {
    next_in=0;   // Circular buffer
  }

}

...
// Send 1st msg
OKd=FALSE;
do{

  fprintf(rsMOD,"AT\r\n");

 // interrupt RDA reads at this point

  if(strstr(InMSG,AuxStr))
  {
   fputs("AT Ok'd",rsCOM);
   OKd=TRUE;
  }
  else
  {
   fputs("AT Failed",rsCOM);
  }
}while(!OKd);
...



Is there a faster/better way to code this to avoid the OERR error?


It took 2 days to do all of this in assembler and ages in CCS. I thought the purpose of having a high level complier was to take out the nitty-gritty, and let you code the app.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Mon Dec 13, 2004 10:00 am     Reply with quote

Quote:
...so OERR went undetected. Wasn't ERRORS supposed to handle that?
The ERRORS directive does reset the OERR-flag, so if this didn't work in your code you probably made a mistake. In all the above posted code samples you never showed a line using the ERRORS directive so we can't check this.

Code:
  if(next_in==Next_out)
  {
    next_in=0;   // Circular buffer
  }
I'm not sure what you want to achieve here, but this certainly is not a circular buffer... Question

Code:
 // interrupt RDA reads at this point
Yes, the RDA interrupt will start reading data, but this takes some time. Between sending the command and receiving the response you should implement some kind of flow control. Your current code will never work the way you expect it to.

Quote:
Is there a faster/better way to code this to avoid the OERR error?
Create a working circular buffer implementation and make sure to calculate the required buffer size.
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Mon Dec 13, 2004 11:22 am     Reply with quote

Quote:
It took 2 days to do all of this in assembler and ages in CCS. I thought the purpose of having a high level complier was to take out the nitty-gritty, and let you code the app.


My answer to this, it would have taken me less than an hour to code and debug a routine for setting up a modem. Why, because I understand the chip and the compiler. C does make it much nicer and easier to maintain the code but a new commer can't expect to be up and running on day one. You can't run until you learn how to walk.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group