|
|
View previous topic :: View next topic |
Author |
Message |
umutso
Joined: 23 Jan 2013 Posts: 39 Location: turkey
|
SIM900R with 16F877A Communication Problem |
Posted: Mon Mar 25, 2013 3:02 am |
|
|
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: 19511
|
|
Posted: Mon Mar 25, 2013 4:28 am |
|
|
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
|
|
Posted: Mon Mar 25, 2013 5:07 am |
|
|
Hi
The SIM900 module is 3V max right? |
|
|
umutso
Joined: 23 Jan 2013 Posts: 39 Location: turkey
|
|
Posted: Mon Mar 25, 2013 6:05 am |
|
|
@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
|
|
Posted: Mon Mar 25, 2013 2:18 pm |
|
|
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:
_________________ Umut Sonkurt |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9226 Location: Greensville,Ontario
|
|
Posted: Mon Mar 25, 2013 2:33 pm |
|
|
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: 19511
|
|
Posted: Mon Mar 25, 2013 2:48 pm |
|
|
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
|
|
Posted: Tue Mar 26, 2013 12:50 am |
|
|
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
|
|
Posted: Tue Mar 26, 2013 1:09 am |
|
|
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: 19511
|
|
Posted: Tue Mar 26, 2013 1:37 am |
|
|
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
|
|
Posted: Tue Mar 26, 2013 1:52 am |
|
|
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
|
Help with the Ex_SISR.c sampe |
Posted: Thu Mar 28, 2013 12:11 am |
|
|
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: 19511
|
|
Posted: Thu Mar 28, 2013 2:27 am |
|
|
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
|
|
Posted: Thu Mar 28, 2013 2:38 am |
|
|
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: 19511
|
|
Posted: Thu Mar 28, 2013 3:16 am |
|
|
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.... |
|
|
|
|
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
|