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 support@ccsinfo.com

Need help to receive string from modem !

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








Need help to receive string from modem !
PostPosted: Sat Mar 06, 2010 7:05 am     Reply with quote

Hi, I'm working on an SMS controller project. I want to be able to activate an output if a string from the modem is received.

For example if the modem replies "ok" I want to turn an LED on any time this is received. So far I've tried
strstr
strcmp
and gets

I'm using a PIC 16f876...
ANY IDEAS ?
bkamen



Joined: 07 Jan 2004
Posts: 1611
Location: Central Illinois, USA

View user's profile Send private message

PostPosted: Sat Mar 06, 2010 10:14 am     Reply with quote

you also need to post your compiler version and a small example of your code..

In this case, we'd need to see the code that receives the string and then the code that compares it..

-Ben
_________________
Dazed and confused? I don't think so. Just "plain lost" will do. :D
Guest








PostPosted: Sat Mar 06, 2010 1:33 pm     Reply with quote

Hi. This is the code I'm trying with. It's not working as I want though.
Code:

void main() {
char s1[] = ;
char s2[] = "12345";
char ptr;

while(1){
   output_low(pin_B6);
   output_low(pin_B7);
   delay_ms(2000);

   gets(s1);
   ptr = strstr(s1, s2);

   if(ptr)
    {
     output_high(pin_B7);
     break;
    }

   if(ptr==NULL){
     printf("Waiting for string. Press ENT after sending string.");
    }
   else
    {
     output_low(pin_B7);
     output_high(pin_B6);
    }
}
 

The modem returms text messages in PDU format. The last part of the pdu is 12345 for example. Therefore I want to activate output when I recieve 12345.

I'm using CCS C v4.023
Ttelmah
Guest







PostPosted: Sat Mar 06, 2010 2:08 pm     Reply with quote

OK.
First problem is s1.
You need to declare this _with enough space to hold the string you are going to receive_. At present, you are declaring it with no size, so when characters are received, these will overwrite the items in memory after this. Something like:

char s1[32];

Allocates 32 characters of storage to s1.

Second problem. ptr. This wants to be declared as a char _pointer_, not as a char. So:

char *ptr;

Third, get rid of the delay. Gets, _waits_ for a line feed to arrive. In your delay, characters _will_ be missed...

Not in what is shown, but make sure that your RS232 declaration, has 'ERRORS' in it.

Then you would normally want to display the 'waiting' message, before calling gets.

Best Wishes
Guest








PostPosted: Sun Mar 07, 2010 7:29 am     Reply with quote

Thanks a lot guys. The code works ! ........But I still have a problem

The number of characters to be recieved from the modem is 75 but I am only interested in the last 5. If I set

char s1[75]
char s3[75] my memory (RAM) is overloaded !

How can I ignore the first 60-65 characters ???

Here's my code

void main() {
char s1[12]; // I only want 10-15 here
char s2[] = "12345";
char s3[12]; // I only want 10-15 here
char s4[] = "54321";
char *ptr;
char *ptr2;

puts("AT");
delay_ms(1000);

puts("at+cpms=mt,mt,mt");
delay_ms(1000);

puts("at+csms=1");
delay_ms(1000);

resmsgind:
delay_ms(1000);
puts("at+cnmi=1,2,0,0,1");
goto on;



while(true){
on:
gets(s1); // If more than 12 characters are recieved, output pin 7 goes hi for itself.
ptr = strstr(s1, s2); // It can be turned off with "54321" but it doesn't turn back on.
// gets(s1) buffer is full ?
if(ptr) //
{
output_high(pin_B7);
puts("at+cnmi=1,2,0,0,1");
delay_ms(1000);
goto off;
}

if(ptr==NULL){
printf("Invalid Entry #1"); // s2 did not appear in s1
}
}
while(true){

off:
gets(s3);
ptr2 = strstr(s3, s4);

if(ptr2)
{
output_low(pin_B7);
goto resmsgind;
}

if(ptr2==NULL){
printf("Invalid Entry #2"); // s4 did not appear in s3
}
}
}
Sal



Joined: 04 Mar 2010
Posts: 27
Location: Caribbean

View user's profile Send private message

PostPosted: Tue Mar 09, 2010 4:34 am     Reply with quote

Can I use a delay like this to limit the characters read from the input stream ?

getch();
delay_ms(25);
gets(string);

Sal
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Tue Mar 09, 2010 6:19 am     Reply with quote

No you can't use a delay but you can use a loop:-

Code:

int i;

// Skip the first 60 chars
for (i = 0; i < 60; i++)
{
  getc();  // read and ignore char
}
Sal



Joined: 04 Mar 2010
Posts: 27
Location: Caribbean

View user's profile Send private message

PostPosted: Tue Mar 09, 2010 8:05 pm     Reply with quote

@Wayne_

THANKS A LOT IT WORKS !!!
Sal



Joined: 04 Mar 2010
Posts: 27
Location: Caribbean

View user's profile Send private message

PostPosted: Wed Mar 10, 2010 4:42 am     Reply with quote

After some testing I now realise I have another issue. What happens if I ignore the 1st 60 characters but too many are entered after.

E.g I want to recieve 12345 after the first 60 characters. But if the string is 12345678, the program freezes or crashes.

I was trying to use fgets() instead of gets() but the program is not compiling.

In the above code I replaced "gets" with
fgets(s1,5,stdin); // I only wanted to read 5 characters...

This is the error
"Stream must be a constant in the valid range"

Any ideas ? or maybe there is another way ?

Thanks again for all your help
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Wed Mar 10, 2010 5:07 am     Reply with quote

I have just noticed, your code is a bit of a mess in my opinion (before I get slated Smile), sorry for being so blunt but first of all I like a lot of other C programmers do not like the use of goto's in C. I have never found a reason to use them and they make the code very messy when it doesn't have to be. You may also run in to problems when you come to alter your code later on.

Now some programmers are quite happy to use goto's throughout their code in C and that is upto them but they still would not use them just for the sake of it as you do in your code.

In your code you are jumping into and out of while loops. Whilst this may work in your code (due to the fact that they are infinate while(true) loops) if you changed one of the whiles to have a condition then this would not be checked or initialised before entry into the loop.

If you want to exit a while loop, use the "break" instruction.

I have taken the liberty to re-write the main loop according to my programming style. Just have a look Smile

Code:

while (true)  // main loop
  delay_ms(1000);
  puts("at+cnmi=1,2,0,0,1");

  do  {
    gets(s1); // If more than 12 characters are recieved, output pin 7 goes hi for itself.
    ptr = strstr(s1, s2); // It can be turned off with "54321" but it doesn't turn back on.
    // gets(s1) buffer is full ?
    if(ptr) //
    {
      output_high(pin_B7);
      puts("at+cnmi=1,2,0,0,1");
      delay_ms(1000);
    }
    else
      printf("Invalid Entry #1"); // s2 did not appear in s1
  } while (ptr == NULL);

  do {
    gets(s3);
    ptr2 = strstr(s3, s4);

    if(ptr2)
      output_low(pin_B7);
    else
      printf("Invalid Entry #2"); // s4 did not appear in s3
  } while (ptr2 == NULL);
}


I have not tested it so I hope there are no errors.

Sorry if I have come accross a bit high and mighty, and this is a slight diversion from your problem at hand.
ckielstra



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

View user's profile Send private message

PostPosted: Wed Mar 10, 2010 5:20 am     Reply with quote

Quote:
After some testing I now realise I have another issue. What happens if I ignore the 1st 60 characters but too many are entered after.

E.g I want to recieve 12345 after the first 60 characters. But if the string is 12345678, the program freezes or crashes.
What you are now stumbling upon is the difference between a 'quick and dirty prototype program' and a good program.

Writing a program that handles about 80% of the situations is relative easy. Implementing the last 20%, i.e. handling all the exceptions from the normal situation, is what takes the most time. Sometimes this is called the 80-20 rule: it takes 20% of the time to implement 80% of the functionality, but 80% time is required to implement the last 20% functionality.
Cynical people call it a 90-10 rule, or variations on this.

You have written a program that only reads the last 5 characters out of a stream of 75. Problems arise when the number of received characters is different, and as you have noticed, this will happen.

What you should do is write a routine that examines the received data for a known pattern. On recognition of the pattern you can extract your data.

For more help you'll have to provide more details about your data stream.
Sal



Joined: 04 Mar 2010
Posts: 27
Location: Caribbean

View user's profile Send private message

PostPosted: Wed Mar 10, 2010 7:28 pm     Reply with quote

@ ckielstra + Wayne_

Constructive criticism is one of the best tools to make a person improve. Thanks for helping...

@ckielstra

As mentioned in the start of the thread I'm doing an SMS project. My data stream is actually a 5 - digit number sent via an SMS message. The modem does not support text mode so what is recieved by the PIC is a long data stream in the form of a PDU message. Although I only want to send "12345" to activate an output, other data is sent in the PDU message such as service number etc. The total length of the string adds up to about 75 characters.

I know the data I'm sending appears as the last part of the PDU stream

e.g If I send "12345"

In PDU this is 0A07xxxxx8xx820xxxxxxxxxxxxxxxxxxxxx0127560690531D98C5603

Thats why I want to ignore all the characters before this string !
ckielstra



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

View user's profile Send private message

PostPosted: Thu Mar 11, 2010 4:31 pm     Reply with quote

If you know the received text is always 5 digits long, then you could read all incoming data and store the data in a 5 byte buffer. On reception of each new byte you shift the data in the buffer 1 position. When you receive a CR character your value is in the buffer.

Instead of shifting the whole buffer you could use a cyclic buffer, this will be faster.
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