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

SIM900R with 16F877A Communication Problem
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
umutso



Joined: 23 Jan 2013
Posts: 39
Location: turkey

View user's profile Send private message MSN Messenger

SIM900R with 16F877A Communication Problem
PostPosted: Mon Mar 25, 2013 3:02 am     Reply with quote

Dear All,

Trying to complete a GPRS only solutşon with PIC16F877A and SIM900R module. I have problems with the communication over the UART between the MCU and the GPRS module.

Before you ask ;
1. When I connect GPRS module to a MAX3232 and connect to the PC, via Hyperterminal I can see the module is UP (After pulling the PWRKEY pin to low for at least 2 seconds) and I can see the RDY... status indicators + I can send AT commands and can make a GPRS connection without no problem.
2. When I put the MCU to MAX3232, I can upgrade firmware, test some printf, puts, fputs, fgets etc... can work well without problems.

When I directly connect the module to MCU, nothing happens since the module is powered on and status is up.

I wrote a test program and create a second RS232 connection on MCU PINs B1 and B2 to check whats happening between the MCU and Module with a baud rate of 2400.(via MAX3232 on hyperterminal) Please see the code with remarks below ;

Need some help here since dont know if I m doing a critical missing or mistake ?

Thanks in advance,

PS : I checked the Tx-Rx pin conections and try vice versa but did not helped.


Code:
#include <16f877a.h>
#device ADC=10
#fuses XT,NOWRT,NOPROTECT,NOWDT,NOLVP,NOCPD,NODEBUG,NOPUT,NOBROWNOUT
#use delay(clock=4000000)           
#use rs232(baud=9600, xmit=PIN_C6,rcv=pin_C7, parity=N, stop=1, STREAM=connection_1)
#use rs232(baud=2400, xmit=PIN_B1,rcv=pin_B2, parity=N, stop=1, STREAM=connection_2 )
#include <string.h>
char keya[40];
char s[40];
void main()
{
output_high(PIN_B4); //connected to PWRKEY

delay_ms(2500);//initialize wait

//Power Up the module
output_low(PIN_B4);
delay_ms(2500);
output_high(PIN_B4);


delay_ms(3000); // Wait for status messages comes from the module
while(true);
{
fgets(keya,connection_2); //From Hyperterminal with my second conn, I send AT\r\n
delay_ms(1000);
fputs("Tx : ",connection_2);//Return to hyperterminal what I sent
fputs(keya,connection_2);//Return to hyperterminal what I sent
fputs("\n\r",connection_2);//Return to hyperterminal what I sent
fputs(keya,connection_1);//put the command to UART from MCU to the module
fputs("\r\n",connection_1);//put <CR> to UART from MCU to the module
//delay_ms(1000);
fgets(s,connection_1);//UART Waits for the "OK" or "ERROR" from the Module
delay_ms(1000);
fputs("Rx : ",connection_2);//I get this
fputs(s,connection_2);//Noting here
fputs("\n\r",connection_2);//Nothing here
delay_ms(1000);
keya="";//Reset the vars
s="";//Reset the vars
}

//nothing ....
}

_________________
Umut Sonkurt
Ttelmah



Joined: 11 Mar 2010
Posts: 19326

View user's profile Send private message

PostPosted: Mon Mar 25, 2013 4:28 am     Reply with quote

Big thing is to remember how small the buffer is in the PIC UART. Just two characters. You 'wait for status messages to comes from the module'. At this point, many more than two characters will have arrived, and UART _will_ be hung. The compiler has the option to add code to 'unhang' the UART, when this happens (add ERRORS to the UART declaration - this should always be present when using the hardware UART).
Other comments, you can't transfer strings to strings with '='. The only place you can transfer strings like this is in their initialisation.

Best Wishes
hmmpic



Joined: 09 Mar 2010
Posts: 314
Location: Denmark

View user's profile Send private message

PostPosted: Mon Mar 25, 2013 5:07 am     Reply with quote

Hi

The SIM900 module is 3V max right?
umutso



Joined: 23 Jan 2013
Posts: 39
Location: turkey

View user's profile Send private message MSN Messenger

PostPosted: Mon Mar 25, 2013 6:05 am     Reply with quote

@Ttelmah;

So if I just add ERRORS on the UART declaration I can get the status messages or I have to do something more?
_________________
Umut Sonkurt
umutso



Joined: 23 Jan 2013
Posts: 39
Location: turkey

View user's profile Send private message MSN Messenger

PostPosted: Mon Mar 25, 2013 2:18 pm     Reply with quote

I have build a test program to monitor what is happening between the MCU and the GPRS module, like the following. The idea is to send a command from Hyperterminal, receive it back to my connection_2 to check, receive this command on the MCU, shift the message with MAX232, send it to the second port of MAX232 then reshift it to TTL level and send it to the module. Then wait for the response on UART from the module, and write this response to my hypertrm connection as well to monitor what is received. Here is the code and schematic (PIN layout are correct since I can only pass through fgets() with this pin connections means receive something from the module). Everything goes well I can also receive from the module (means fgets() detects the <CR> and something probable before the <CR>. I think if I do not receive something from the module program will stuck on fgets()) the main problem is I receive EMPTY something with a <CR>. Here are the code, schema and the hypertrm output:

Sorry for bothering but I need really help on this. (I tried direct UART connection on TTL level as well since the module and UART levels are the same but the same).
Code:
 #include <16f877a.h>
#device ADC=10
#fuses XT,NOWRT,NOPROTECT,NOWDT,NOLVP,NOCPD,NODEBUG,NOPUT,NOBROWNOUT
#use delay(clock=4000000)           
#use rs232(baud=9600, xmit=PIN_C6,rcv=pin_C7, parity=N, stop=1, STREAM=connection_1, ERRORS)
#use rs232(baud=9600, xmit=PIN_B1,rcv=pin_B2, parity=N, stop=1, STREAM=connection_2, ERRORS)

#include <string.h>

char keya[40];
char s[40];
char k;

void main()
{
output_high(PIN_B4); //connected to PWRKEY to power up the module

delay_ms(2500);//initialize

//Power Up the module
output_low(PIN_B4);
delay_ms(2500);
output_high(PIN_B4);
delay_ms(3000); // Wait for power up status messages comes from the module

while(true)
{
fgets(keya,connection_2); //From Hyperterminal with my second conn, I send AT\r\n
delay_ms(1000);
fputs("Tx : ",connection_2);//Return to hyperterminal what I sent to check
fputs(keya,connection_2);//Return to hyperterminal what I sent
delay_ms(1000);
fputs(keya,connection_1);//put the same command on UART from MCU to the module
fputs("\r\n",connection_1);//put <CR> to UART from MCU to the module
delay_ms(900);
fgets(s,connection_1);//UART Waits for the "OK" or "ERROR" from the Module
delay_ms(900);
fputs("Rx : ",connection_2);//Put the received message to my second connection via Hypertrm
fputs(s,connection_2);// I get only <CR> with EMPTY something
delay_ms(1000);
keya="";//Reset the vars
s="";//Reset the vars
}

}


Schematic:



Output of Hypertrm:
Quote:

AT
Tx : AT
Rx :

_________________
Umut Sonkurt
temtronic



Joined: 01 Jul 2010
Posts: 9160
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Mon Mar 25, 2013 2:33 pm     Reply with quote

You should look at the interrupt driver serial example program in the 'examples' folder, 'ex_sisr.c'. It will allow you to 'buffer' the data from the GPS unit attached to the hardware serial port(C6,C7).

When needing more than 1 serial port, use a different PIC, like the 18F46K22, or other PIC that has 2 hardware serial ports. It makes life a LOT easier. I'm using the 18F46K22 for 99% of my applications as it has a lot of onboard peripherals.
The 877 is now 'obsolete', the 877 is the current, dropin replacement at 1/3 the cost.

hth
jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19326

View user's profile Send private message

PostPosted: Mon Mar 25, 2013 2:48 pm     Reply with quote

The status messages have already been lost. They were sent while you were not listening, so 'gone'.
Adding errors will stop the chip getting locked though.
To have the status messages available you need to look at buffering the data like EX_SISR.c (as Temtronic says). This way they will be available for you to read if you want them.

Best Wishes
umutso



Joined: 23 Jan 2013
Posts: 39
Location: turkey

View user's profile Send private message MSN Messenger

PostPosted: Tue Mar 26, 2013 12:50 am     Reply with quote

Hi again,

I got the sample code in CCS and just change it a little bit as follows in order to put my check routine as well. But at the end (the code compiles well without errors) prints the Buffered Data ==> but there is nothing inside.

Quote:
Output
Running...


Buffered data =>
Buffered data =>
Buffered data =>
Buffered data =>
Buffered data =>
Buffered data =>
Buffered data =>
Buffered data =>
Buffered data =>





Code:
#include <16f877a.h>
#device ADC=10
#fuses XT,NOWRT,NOPROTECT,NOWDT,NOLVP,NOCPD,NODEBUG,NOPUT,NOBROWNOUT
#use delay(clock=4000000)           
#use rs232(baud=9600, xmit=PIN_C6,rcv=pin_C7, parity=N, stop=1, STREAM=connection_1, ERRORS)
#use rs232(baud=9600, xmit=PIN_B1,rcv=pin_B2, parity=N, stop=1, STREAM=connection_2, ERRORS)
#include <string.h>
#define BUFFER_SIZE 32
BYTE buffer[BUFFER_SIZE];
BYTE next_in = 0;
BYTE next_out = 0;


#int_rda
void serial_isr() {
   int t;

   buffer[next_in]=fgetc(connection_1);
   t=next_in;
   next_in=(next_in+1) % BUFFER_SIZE;
   if(next_in==next_out)
     next_in=t;           // Buffer full !!
}

#define bkbhit (next_in!=next_out)

BYTE bgetc() {
   BYTE c;

   while(!bkbhit) ;
   c=buffer[next_out];
   next_out=(next_out+1) % BUFFER_SIZE;
   return(c);
}

void main() {

   enable_interrupts(int_rda);
   

   fputs("\r\n\Running...\r\n",connection_2);

               // The program will delay for 10 seconds and then display
               // any data that came in during the 10 second delay

   do {
      delay_ms(10000);
      fprintf(connection_2, "\r\nBuffered data => ");
      while(bkbhit)
        fputc( bgetc(),connection_2 );
   } while (TRUE);
}


Guys really need help here. Please assist.

Thanks,
_________________
Umut Sonkurt
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Mar 26, 2013 1:09 am     Reply with quote

Quote:
I got the sample code in CCS and just change it a little bit as follows

void main() {

enable_interrupts(int_rda);

The little bit that you changed it (ex_sisr.c) made it fail to work.
Don't ask us to help. You will never learn that way. Compare
ex_sisr.c to your code and discover the line that you left out.
Ttelmah



Joined: 11 Mar 2010
Posts: 19326

View user's profile Send private message

PostPosted: Tue Mar 26, 2013 1:37 am     Reply with quote

As a 'clue' if you can't see it, paragraph 14-11 of the data sheet.

Best Wishes
umutso



Joined: 23 Jan 2013
Posts: 39
Location: turkey

View user's profile Send private message MSN Messenger

PostPosted: Tue Mar 26, 2013 1:52 am     Reply with quote

Got it!! Thanks guys. It worked. I was stuck with this issue for a time so my attention was weakened I suppose.

That was really help for me. Now I totally understand the routine.

THanks to all guys for great help.

Regards,
_________________
Umut Sonkurt
umutso



Joined: 23 Jan 2013
Posts: 39
Location: turkey

View user's profile Send private message MSN Messenger

Help with the Ex_SISR.c sampe
PostPosted: Thu Mar 28, 2013 12:11 am     Reply with quote

Dear All,

I'm using EX_SISR.c example to read the buffer from 16F877A UART. It works perfect. But what I need is: I receive data 16 characters long and I need the first 8 characters of this data. I need to assign it to a variable and use or store etc.

Since bgetc() and c variables and function is declared as BYTES, when I try to equalize the bgetc() value to anything int8, char or else, program stops working.

Need help on this:
Code:

while(bkbhit)
     fputc( bgetc(),connection_2 );

This end line of the code works fine until I assign the bgetc() to any other variable.

BR,
_________________
Umut Sonkurt
Ttelmah



Joined: 11 Mar 2010
Posts: 19326

View user's profile Send private message

PostPosted: Thu Mar 28, 2013 2:27 am     Reply with quote

Take a deep breath, and start to think.
You say 'I receive data 16 characters long'. What marks the end of this?. Is this repeated, or just once?.

Now, normally, this will be a 'line' or 'packet' of data, so will be marked by the line feed character.

So, the sequence becomes (psuedo code):

count=0 to 7
read character, add to an array
terminate array

You now have a character array, which you can do what you want with

Then (if the data repeats):

Look for line feed or whatever the end of line marker is.
If you have a marker, loop back to the count.

The sequence (in C) to build the array, would be:
Code:

    char received_data[9]; //remember this always needs to be one
    //character larger than what you are going to receive
    int count;

    for (count=0;count<8;)
    {
        received_data[count++]=bgetc();
    }
    received_data[count]='\0'; //C string terminator character


The array is then a 'string', containing the eight required characters.

Best Wishes
umutso



Joined: 23 Jan 2013
Posts: 39
Location: turkey

View user's profile Send private message MSN Messenger

PostPosted: Thu Mar 28, 2013 2:38 am     Reply with quote

THanks for the help.

Just 1 thing more after your post; the data comes normally like ;

12345678912345<CR>
asdfgh<CR>

so I need here only "12345678"

So for seeking a CR will be the soluton right? And for this what I have to use instead of "\0"?
_________________
Umut Sonkurt
Ttelmah



Joined: 11 Mar 2010
Posts: 19326

View user's profile Send private message

PostPosted: Thu Mar 28, 2013 3:16 am     Reply with quote

No......

'\0', is the C terminator character. A string _must_ have this character at the end.

What I posted, is the part:
Quote:

count=0 to 7
read character, add to an array
terminate array

The '\0', is the 'terminate array' line.

It is not the part:
Quote:

Look for line feed or whatever the end of line marker is.
If you have a marker, loop back to the count.

You need to do this yourself....
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 1, 2  Next
Page 1 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