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

sim800c
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
NAVID



Joined: 14 Jun 2017
Posts: 28

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

PostPosted: Sat Dec 01, 2018 10:55 am     Reply with quote

dluu13 wrote:
You are right that unfortunately, the manual does not say much about this.

With the RECEIVE_BUFFER option, the circular buffer and the RDA interrupt for placing characters into the receive buffer are automatically generated. You don't need to declare the buffer, or write the ISR. So all you should need is something like this:

Code:
int main(void)
{
    char a;
    while(1)
    {
        if(kbhit())
        {
            a=getc();
            // do stuff with a. You could even put your loop here.
        }
    }
}


kbhit() evaluates as true if there are new characters in the buffer, and false if there are not.

The main point of this is to move the slow for loop out of the RDA interrupt because interrupt routines are meant to be fast.

Also, I just noticed you might not have found "bkhit()" because it is actually "kbhit()". It is in the manual along with the rest of the built-in functions.


Hi, its work but i have 1 problem...its not work properly.
i dont know how to explain (((:
When i send characters it dont show them and wait until to receive a number!!
like this:
kjasdjcnasjdlfkasjdcnsjn :it dont show anything on lcd but when i send '1'
after all these characters its show " kjasdjcnasjdlfkasjdcnsjn1" Shocked Shocked

and rs232 option:
#use rs232(baud=9600,parity=N,xmit=PIN_c6,rcv=PIN_c7,bits=8,stream=PORT1,timeout=100,RECEIVE_BUFFER=64)

and its my code:
Code:

   while(TRUE)
   { 
   lcd_gotoxy(1,1);
    if(kbhit())
        {
            a=getc();
         
             lcd_gotoxy(1,1);
             printf(lcd_putc,"%s                         ",a);
         
        }}
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Sat Dec 01, 2018 11:28 am     Reply with quote

Suite of things:

First, though the buffering is automatic, you do need to have
'enable_interrupts(GLOBAL);' at the start of your main, or the buffering will
not be enabled.

Then you don't show the declaration of 'a', but as shown it should be a char. As such it is _not_ a string, which you try to print. It is just a
single character, which needs to be printed with %c. As with INT_RDA, you need to create a string by writing the characters to an array, and adding the null terminator. The garbage you are seeing displayed is the contents of the memory after where 'a' is stored, until a 0 character is hit.

This latter is really basic programming. You need to get a C textbook, and
read it....

Now you can filter as I describe, with a basic flag. Read the characters. Have a flag set to FALSE, and set it TRUE when you see the line feed after the CMT. While it is FALSE, just throw the characters away and keep looping. Once the flag is set write the characters to an array, until another line feed is seen, then add the NULL termiator, and display.
NAVID



Joined: 14 Jun 2017
Posts: 28

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

PostPosted: Sat Dec 01, 2018 3:14 pm     Reply with quote

Ttelmah wrote:
Suite of things:

First, though the buffering is automatic, you do need to have
'enable_interrupts(GLOBAL);' at the start of your main, or the buffering will
not be enabled.


i did that before ...
Ttelmah wrote:

Then you don't show the declaration of 'a', but as shown it should be a char. As such it is _not_ a string, which you try to print. It is just a
single character, which needs to be printed with %c. As with INT_RDA, you need to create a string by writing the characters to an array, and adding the null terminator. The garbage you are seeing displayed is the contents of the memory after where 'a' is stored, until a 0 character is hit.


yes its char a[32].and i change the %s to %c and its work good.very very tnx.just can you tell me how i can find line feed in the a[32]??
i need to find it and show the characters after line feed ...

Ttelmah wrote:

This latter is really basic programming. You need to get a C textbook, and
read it....

i will but i dont have good source to read...can u Introduction some book??
Ttelmah wrote:

Now you can filter as I describe, with a basic flag. Read the characters. Have a flag set to FALSE, and set it TRUE when you see the line feed after the CMT. While it is FALSE, just throw the characters away and keep looping. Once the flag is set write the characters to an array, until another line feed is seen, then add the NULL termiator, and display.

line feed Razz Razz
i need to find it...help me Very Happy Very Happy [/quote]
dluu13



Joined: 28 Sep 2018
Posts: 395
Location: Toronto, ON

View user's profile Send private message Visit poster's website

PostPosted: Sat Dec 01, 2018 3:23 pm     Reply with quote

oops... I had forgotten to mention that you need the enable_interrupts(GLOBAL)

i use this site a lot as basic reference: https://www.tutorialspoint.com/cprogramming/

As for the newline character, it is denoted as '\n' so

if (a[i] == '\n') evaluates as true, then you've found the newline character at index i. If you are storing the entire incoming message, then you can loop through that array until you find '\n' and then print all characters after that.
NAVID



Joined: 14 Jun 2017
Posts: 28

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

PostPosted: Wed Dec 05, 2018 12:51 pm     Reply with quote

dluu13 wrote:
You are right that unfortunately, the manual does not say much about this.

With the RECEIVE_BUFFER option, the circular buffer and the RDA interrupt for placing characters into the receive buffer are automatically generated. You don't need to declare the buffer, or write the ISR. So all you should need is something like this:

Code:
int main(void)
{
    char a;
    while(1)
    {
        if(kbhit())
        {
            a=getc();
            // do stuff with a. You could even put your loop here.
        }
    }
}


kbhit() evaluates as true if there are new characters in the buffer, and false if there are not.

The main point of this is to move the slow for loop out of the RDA interrupt because interrupt routines are meant to be fast.

Also, I just noticed you might not have found "bkhit()" because it is actually "kbhit()". It is in the manual along with the rest of the built-in functions.

hi again...
its helped me so much...but i have 1 question
how i can clear RECEIVE_BUFFER ?? and make it empty?
dluu13



Joined: 28 Sep 2018
Posts: 395
Location: Toronto, ON

View user's profile Send private message Visit poster's website

PostPosted: Wed Dec 05, 2018 12:59 pm     Reply with quote

To make the circular buffer empty, you can just read from it using getc or similar. Once the character is read, then it is considered to be "gone" and the memory space that the character once held is freed.

kbhit() returns true if there are contents in the circular buffer and false if there are not. So if you just want to purge the buffer you can do something like:

char garbage;
while(kbhit()) garbage=getc();
PrinceNai



Joined: 31 Oct 2016
Posts: 452
Location: Montenegro

View user's profile Send private message

PostPosted: Thu Dec 13, 2018 11:27 am     Reply with quote

First I defined a buffer like this:

#define BUFFER_SIZE 64 //create buffer
char buffer[BUFFER_SIZE];

To get the characters from the GSM module into the buffer I use this inside RDA interrupt:


Code:

   char tmp;
   tmp=getc();                      // get received char and thus also clear interrupt flag 

   buffer[next_in]= tmp;            // move received char to the appropriate place in buffer
   ++next_in;                       // increment IN pointer                                                                                                                                                   
   if(next_in==BUFFER_SIZE) {       // go back to 0         
      next_in=0;                           
      }; 


To clear this buffer:

Code:

void Clear_UART_Buffer() {          //
   next_in=0;
   while (next_in < BUFFER_SIZE){
      buffer[next_in] = '\0';
      next_in++;
   }
}
PrinceNai



Joined: 31 Oct 2016
Posts: 452
Location: Montenegro

View user's profile Send private message

PostPosted: Thu Dec 13, 2018 11:32 am     Reply with quote

One next_in fell out. It should be:
Code:

void Clear_UART_Buffer() {          //
   next_in=0;
   while (next_in < BUFFER_SIZE){
      buffer[next_in] = '\0';
      next_in++;                                             
   }
   next_in=0;
}


and next_in is initialized to zero when it is declared.
PrinceNai



Joined: 31 Oct 2016
Posts: 452
Location: Montenegro

View user's profile Send private message

PostPosted: Fri Dec 14, 2018 7:02 am     Reply with quote

To get only your message to the buffer:

Code:

#define BUFFER_SIZE 64                       //create buffer, change to your size
char buffer[BUFFER_SIZE];
int8 gsm_state = 0;
int1 MESSAGE = 0;
int1 buffer_to_small = 0;
int8 next_in = 0;
char tmp;
// this is in your init


Inside your INT_RDA:

Code:

// put this inside RDA interrupt
// looking for a message that looks like this
// +CMT: "+989375091182","","18/11/28,17:21:07+14"
// Hello
// it always begins with "+CMT"   
   tmp=getc();                     // get the character
   switch (gsm_state) {       
// ----------------------------------------------------------------------
// wait the initial '+'           
   case 0:{
      if(tmp == '+'){              //we have "+", could be "+CMT"
         gsm_state = 1;                //expecting "C"
        }
      else{
         gsm_state = 0;            // wrong character
      }
   break;
   }
// ----------------------------------------------------------------------
   case 1:{
      if(tmp == 'C'){              //we have "C", could be "+CMT"
         gsm_state = 2;                //expecting "M"
        }
      else{
         gsm_state = 0;            // wrong character came, reset state machine
      }
   break;
   }   
// ---------------------------------------------------------------------
   case 2:{
      if(tmp == 'M'){              //we have "M", could be "+CMT"
         gsm_state = 3;                //expecting "T"
        }
      else{
         gsm_state = 0;            // wrong character came, reset state machine
      }
   break;
   }   
// -------------------------------------------------------------------
   case 3:{
      if(tmp == 'T'){              //we have "T", could be "+CMT"
         gsm_state = 4;                //expecting ":"
        }
      else{
         gsm_state = 0;            // wrong character came, reset state machine
         }
   break;
   }
// --------------------------------------------------------------------   
   case 4:{
      if(tmp == ':'){              //we have ":", so it is "+CMT:"
         gsm_state = 5;                //expecting line feed
        }
      else{
         gsm_state = 0;            // wrong character came, reset state machine
      }
   break;
   }
// -------------------------------------------------------------------   
   case 5:{
      if(tmp != '\n'){              // just wait here for the first new line, where your message begins
         gsm_state = 5;                //
        }
      else{
         gsm_state = 6;            // got new line, next characters will be your message
      }
   break;
   }
// ------------------------------------------------------------------
   case 6:{
      if(tmp != '\n'){              // until you see the second new line,
         buffer[next_in]= tmp;       // move received char to the buffer
         next_in++;                  // increment IN pointer
            if(next_in == BUFFER_SIZE + 1) {       // not enough space left in the buffer for the trailing null, even if this was the last character of the message
               next_in = 0;      // the message will most likely be incorrect
               gsm_state = 0;      // you should never come here
               buffer_to_small = 1;         // maybe inform main that the buffer wasn't large enough?
            }            
        }
   
      else{                     // got the second new line, your message should be in the buffer
         gsm_state = 0;            // reset state machine
         strcat(buffer, "\0");      // add null at the end of the message
         MESSAGE = 1;            // inform main that there is a message in the buffer
         next_in = 0;
      }
   break;      
   }
}                              // switch brace
// ----------------------------------------------------------------------   


Best regards
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Fri Dec 14, 2018 1:01 pm     Reply with quote

This can overflow the buffer before it decides it has overflowed the buffer.

Remember with a buffer size of '64', you can only store data from 0 to 63.

Testing for 'next_in' being equal to 65, is too late....
PrinceNai



Joined: 31 Oct 2016
Posts: 452
Location: Montenegro

View user's profile Send private message

PostPosted: Fri Dec 14, 2018 5:04 pm     Reply with quote

True. I started counting from 1, not 0 :-).

Thanks
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Sat Dec 15, 2018 4:29 am     Reply with quote

I think we have all done that sometimes... Sad
NAVID



Joined: 14 Jun 2017
Posts: 28

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

PostPosted: Mon Dec 17, 2018 9:29 am     Reply with quote

PrinceNai wrote:
True. I started counting from 1, not 0 :-).

Thanks

thank you
its helped me a lot
PrinceNai



Joined: 31 Oct 2016
Posts: 452
Location: Montenegro

View user's profile Send private message

PostPosted: Mon Dec 17, 2018 1:04 pm     Reply with quote

Quote:

else{ // got the second new line, your message should be in the buffer
gsm_state = 0; // reset state machine
strcat(buffer, "\0"); // add null at the end of the message
MESSAGE = 1; // inform main that there is a message in the buffer
next_in = 0;
}
break;
}
} // switch brace


I just noticed another mistake. If the second message is shorter than the first one or the buffer wasn't empty, the bolded line doesn't add NULL to the correct position. You should use:

Code:
 buffer[next_in] = '\0';


instead.

Please correct me if I'm wrong.
Best regards,
Samo
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2
Page 2 of 2

 
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