|
|
View previous topic :: View next topic |
Author |
Message |
henyhollar
Joined: 09 Aug 2009 Posts: 10 Location: Nigeria
|
pls help |
Posted: Sat Nov 20, 2010 9:28 pm |
|
|
I want to capture the response of my Sagem phone when it is called or any other activity comes through. In the particular case of the code that follows, I want to capture the response "ring" with my get_string function but nothing is happening. Pls help me.
[email protected]
Code: |
#include <18f4525.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP,NOPUT
#use delay (clock=20000000)
#use rs232(baud=19200, xmit=PIN_C6,rcv=PIN_C7)// confirm the pins for trx and rxv
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
const char calltest[] = "ATD08137474080;"; // test if it will make call
char reply[] = "OK";
char ring[] = "RING";
char carrier[] = "NO CARRIER";
/*Storage structure*/
struct storage
{
char datastore[100];
char msgstore[25];
int digitflag :1;
int alphaflag :1;
int smsflag :1;
int errorflag :1;
// int amtflag;
int pickflag :1;
int allflag :1;
int rdaflag :1;
int16 number;
}serialdata,flag,error,smsreceived,amt,bssextract;
struct storage *psd = &serialdata;
/*Prototype*/
int call_test(void);
void get_string(char holder[],int size);
/*test call function*/
int call_test(void)
{
puts(calltest);
return(1);
}
/*Gets rs232 character*/
void get_string(char holder[],int size)
{
char serial_data;
int length,width = 0;
int i;
long timeout;
while(!kbhit() && ++timeout<5000)
;
if(timeout==5000)
{flag.allflag=1; error.number=0;//error_sorter(psd);}// this will happen due to the fallout of timeout overflow.
do
{
serial_data = getc();
++length;
if((serial_data==13||serial_data==10)&&length<3)//done to remove CR and LF. ESC is based on length
{
serial_data = 0;
}
if(serial_data!=13&&serial_data!=10)//once they are removed...ESC is based on CR and LF
{
holder[width++]= serial_data;
}
}while(serial_data!=13);
for(i=0;i==size;i++)
serialdata.datastore[i] = holder[i];
holder[size] = 0;// this is necessary to clean up the buffer for contiguos issues.
//return(serialdata);
}
}
void main()
{
int i;
char holder1[];
set_tris_A(100000);
//output_bit(PIN_A5,1);
while(1)
{
output_bit(PIN_A4,0);
delay_ms(1000);
// i = call_test();
// delay_ms(1000);
// output_bit(PIN_A4,i);
// delay_ms(1000);
get_string(holder1,6);
//printf(serialdata.datastore);
delay_ms(2000);
if (strcmp(serialdata.datastore,carrier)==0)
{ output_bit(PIN_A4,1);
delay_ms(1000);
//reset_cpu();
}
}
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Nov 20, 2010 11:06 pm |
|
|
Please use a more descriptive title for the thread.
Quote: | set_tris_A(100000); |
Bug. However, since you're not using #fast_io, it doesn't matter.
The CCS output functions will set the correct TRIS for you.
Quote: | get_string(holder1, 6);
for(i=0;i==size;i++)
serialdata.datastore[i] = holder[i];
|
The for() loop will only execute if the middle statement is true.
But i = 0 is not equal to 6. Therefore, the for() loop will never execute.
Example. The test program shown below gives the following output:
Code: | #include <16F877.h>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
//============================
void main()
{
int8 i;
int8 size;
size = 6;
printf("Start\r");
for(i=0; i==size; i++)
printf("i = %u\r", i);
printf("End\r");
while(1);
} |
Quote: | char holder1[];
get_string(holder1,6); |
Bug. The 'holder1' array doesn't have any space allocated for it.
It's just an uninitialized pointer. Therefore, get_string() will write
to ram that is likely allocated to some other variables, and clobber them. |
|
|
henyhollar
Joined: 09 Aug 2009 Posts: 10 Location: Nigeria
|
gets,getc do not work properly |
Posted: Sun Nov 21, 2010 5:21 pm |
|
|
Sir what of the construction of the function get_string itself, what is wrong with it.
On the other hand, I tried using the compiler defined gets and getc functions but I am still not getting anything on my virtual terminal. Instead of getting a string sometimes I get a fragment of the string not in any particular order.
For example I call the sagem phone, it responds normally with a RING but what I get sometimes is I, R I, etc.
But on the contrary, I could make call through the phone from the PIC successfully. I am using the compim of proteus. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Nov 21, 2010 5:46 pm |
|
|
1. Your program is too complicated. If you can't understand it, then
it's too complicated. Re-write the program with only a few lines of code.
2. How you do know that Proteus works correctly with a Sagem simulation ? |
|
|
henyhollar
Joined: 09 Aug 2009 Posts: 10 Location: Nigeria
|
|
Posted: Mon Nov 22, 2010 5:42 pm |
|
|
Thanks for the response and understanding.
sir i got it working but not perfectly though. I found out that gets() did not work because sagem always responds with <CR><LF>RING<CR><LF> and from the definition of its function, it will always return the value gotten at every point it encounters \r. That settled!
But i got it to work using getc(); taking it one by one into an array. But the problem is that i dont get <CR><LF>RING<CR><LF> everytime because it is in a while loop. On the second iteration it gives something like RING<CR><LF><CR><LF> and distorting it further on subsequent iteration. My suspicion is the hardware buffer of USART. Now is there a way of clearing the buffer on my way out of every loop in oder to get <CR><LF>RING<CR><LF> everytime or what?
Sagem work with Proteus using compim |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Nov 22, 2010 6:16 pm |
|
|
Quote: |
Now is there a way of clearing the buffer on my way out of every loop. |
There is code in the forum archives to clear the UART's receive buffer.
I made a universal version of it below, so you don't have to look up the
address of RCREG. The compiler will do it for you.
Call this function to clear the UART's hardware receive buffer:
Code: |
void clear_uart_receiver(void)
{
int8 c;
#byte RCREG = getenv("SFR:RCREG");
c = RCREG;
c = RCREG;
c = RCREG;
} |
|
|
|
henyhollar
Joined: 09 Aug 2009 Posts: 10 Location: Nigeria
|
reply |
Posted: Tue Nov 23, 2010 9:02 pm |
|
|
But how does the buffer clearing code work? I have looked at it but I found no value being passed into the buffer to clear it.
I also want to say a big thank you for your help. The code is now working and I have included it here. But I want to ask if I can specify the size of the holder[] in the get_string() function at run time, such that if I need to get something like RING. I will only need 5 bytes while I will need a somewhat bigger byte array like 100 for an SMS. I don't want to make a static array where obviously I have to set it at 100 when actually I might not need such frequently.
Code: |
#include <18f4525.h>
//#fuses HS,NOWDT,NOPROTECT,NOLVP,NOPUT
#use delay (clock=20000000)
#use rs232(baud=19200, xmit=PIN_C6,rcv=PIN_C7)// confirm the pins for trx and rxv
//#include <ctype.h>
#include <string.h>
//#include <stdlib.h>
char ring[] = {"RING"};
void clear_uart_receiver(void);
void get_string(char holder[],int size);
/*Storage structure*/
struct storage
{
char datastore[100];//reduce size later
char msgstore[25];
int digitflag :1;
int alphaflag :1;
int smsflag :1;
int errorflag :1;
// int amtflag;
int pickflag :1;
int allflag :1;
int rdaflag :1;
int16 number;
}serialdata,flag,error,smsreceived,amt,bssextract;
struct storage *psd = &serialdata;
void clear_uart_receiver(void)
{
int8 c;
#byte RCREG = getenv("SFR:RCREG");
c = RCREG;
c = RCREG;
c = RCREG;
}
/*Gets rs232 character*/
void get_string(char holder[],int size)
{
int width = 0;
long timeout;
/* while(!kbhit() && ++timeout<5000)
;
if(timeout==5000)
{flag.allflag=1; error.number=0;error_sorter(psd);}// this will happen due to the fallout of timeout overflow.*/
clear_uart_receiver();
FOR (width = 0; width <= size;) // Note for loop doe not increament width until printable character is gotten
{
holder[width] = getc();
if(holder[width]=='\r'||holder[width]=='\n')//done to remove CR and LF.
{
//holder1[i] = '\0';
}
else
{
serialdata.datastore[width] = holder[width];
width++;
}
}
}
void main()
{
char holder1[4];
set_tris_A(100000);
//output_bit(PIN_A5,1);
output_bit(PIN_A4,0);
delay_ms(1000);
get_string(holder1,3);
printf("%s"holder1);
//printf("i am here!");
if (strncmp(serialdata.datastore,ring,4)==0)
{
output_bit(PIN_A4,1);
delay_ms(1000);
}
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Nov 24, 2010 1:52 pm |
|
|
Quote: | But how does the buffer clearing code work? I have looked at it but I found no value being passed into the buffer to clear it. |
It's cleared by reading the UART's hardware buffer enough times so that
it's guaranteed to be empty. The reading is destructive.
Quote: | I will only need 5 bytes while I will need a somewhat bigger byte array like 100 for an SMS. I don't want to make a static array where obviously I have to set it at 100 when actually I might not need such frequently. |
Try to re-write your code so the holder array is a local array inside a
function. And don't declare it as 'static' inside the function. CCS will
re-use RAM that is allocated for local variables, when the function exits.
So maybe get the string and then parse it, doing both operations inside
the same function. Then the array can be local to the function. |
|
|
|
|
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
|