- Joined
- Jul 4, 2009
- Messages
- 16,474
- Helped
- 5,156
- Reputation
- 10,345
- Reaction score
- 5,202
- Trophy points
- 1,393
- Location
- Aberdyfi, West Wales, UK
- Activity points
- 139,397
Consider what happens when a message has been received, you need to do something with it and also reset 'j' back to zero or it will hit maximum value and stop storing anything else.I suggest you modify the code inside the while() loop so it looks for the terminator at the end of the message.
It seems you are only seeing the final character at the end of each message. That implies you are not incrementing 'j' each time a character arrives OR you are not resetting 'J' to zero at the end of each message. Quoting myself from post #14:
Consider what happens when a message has been received, you need to do something with it and also reset 'j' back to zero or it will hit maximum value and stop storing anything else.
It will work, I have similar PIC devices here that receive similar strings to your GSM messages several times a second and have been doing so 24/7 for many years.
Brian.
_interrupt() void ISR(void)
{
if(RCIF)
{
if(RCIE == 0)
{
RCIE = 1;
j = 0;
}
data[j] = RCREG; // Read The Received Data Buffer and clears RCIF flag
j++;
if(data[j] > length)
j=0;
RCIF = 0;
}
}
UART_str(a);
while(RCIF == 0);
CopyBuff();
ClearRxBuff();
__delay_ms(2);
void CopyBuff()
{
unsigned char tempcount, tempcount1;
tempcount = tempcount1 = 0;
for (tempcount = 0; tempcount < 63; tempcount++)
{
if ((data[tempcount] != 0X0D) & (data[tempcount] != 0X0A))
{
MyBuff[tempcount1] = data[tempcount];
tempcount1++;
}
}
}
void ClearRxBuff()
{
unsigned char tempcount;
tempcount = 0;
for (tempcount = 0; tempcount < 63; tempcount++)
{
data[tempcount] = 0;
}
RCIE = 0;
}
#define BUS_RXBUFFER_SIZE 61
char data[BUS_RXBUFFER_SIZE + 1];
void __interrupt() ISR(void)
{
if(PIR1bits.RCIF)
{
PIR1 &= ~(1 << RCIF); //clear UART interrupt flag
buf = RCREG; //save the received character
if(buf == '\r) //check for end of packet
{
PacketReceived = 1; // terminator was found
*data[] = 0; // see my note after the code
j = 0;
}
else if(j < BUS_RXBUFFER_SIZE) //check for space to store byte
{
data[j++] = buf;
data[j] = 0; //add terminator
}
}
}
/*************************************************************************/
void main(void)
{
while(1)
{
if(PacketReceived)
{
PacketReceived = 0; //clear the flag
// your code to process the string goes here
// data[] contains the string.
*data[] = 0;
j = 0;
}
}
}
Golden rule of ISR, never change the interrupt enable bits inside the ISR
ISR Interrupt_x_Handler()
{
iCounterInterruptX++;
// Do required stuffs
iCounterInterruptX--;
}
Code C - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 __interrupt() void ISR(void) { if(RCIF) { if(RxSTatus == 0) { RxSTatus = 1; j = 0; } data[j] = RCREG; // Read The Received Data Buffer and clears RCIF flag j++; if(data[j] > 61) j=0; RCIF = 0; } }
if(data[j] > 61)
j=0;
if(j >= 61)
j = 0;
#include <xc.h>
#include<string.h>
#define _XTAL_FREQ 20000000
char a[]="AT\r";
char echo[]="ATE0\r";
char sim[]="AT+CPIN?\r"; // To Check sim status
char mode_text[]="AT+CMGF=1\r"; // to set text mode
char message_rec[]="AT+CNMI=1,2,0,0,0\r"; // use to set recipient number and mesg
char buf,data[62];
char MyBuff[62];
char RxSTatus = 0;
unsigned int i,j;
void UART_Init(int baudRate)
{
BRGH=0;
SYNC=0;
TXSTA = 0X20; // Asynchronous mode, 8-bit data & enable transmitter
RCSTA = 0X90; // Enable Serial Port and 8-bit continuous receive
SPBRG = 31; // baud rate @20MHz Clock
}
void UART_TxChar(char ch)
{
while(TXIF == 0); // Wait till the transmitter register becomes empty
TXIF = 0; // Clear transmitter flag
TXREG = ch; // load the char to be transmitted into transmit reg
}
void UART_str(char *ch) // to write data continously
{
for(i=0;ch[i]!=0;i++)
{
UART_TxChar(ch[i]);
}
}
__interrupt() void ISR(void)
{
if(RCIF)
{
if(RxSTatus == 0)
{
RxSTatus = 1;
j = 0;
}
data[j] = RCREG; // Read The Received Data Buffer and clears RCIF flag
j++;
if(data[j ]> 60)
j=0;
RCIF = 0;
}
}
void CopyBuff()
{
unsigned char tempcount, tempcount1;
tempcount = tempcount1 = 0;
for (tempcount = 0; tempcount < 61; tempcount++)
{
if ((data[tempcount] != 0X0D) & (data[tempcount] != 0X0A) & (data[tempcount] != '\0'))
{
MyBuff[tempcount1] = data[tempcount];
tempcount1++;
}
}
}
void ClearRxBuff()
{
unsigned char tempcount;
tempcount = 0;
for (tempcount = 0; tempcount < 61; tempcount++)
{
data[tempcount] = 0;
}
RxSTatus = 0;
}
void main(void)
{
char res,res1,res2,res3,res4,res5,res6,res7,res8,res9,res10,res11,res12,res13,res14,res15;
char ch;
TRISD = 0X00;
PORTD = 0X00;
TRISC = 0x80; // Configure Rx pin(rc7) as input and Tx(rc6) as output
RCIE = 1; // UART RecIeving Interrupt Enable Bit
PEIE = 1; // Peripherals Interrupt Enable Bit
GIE = 1; // Global Interrupt Enable Bit
UART_Init(9600); // Initialize the UART module with 9600 baud rate
UART_str(a);
while(RCIF == 0);
CopyBuff();
ClearRxBuff();
__delay_ms(2);
UART_str(echo);
while(RCIF == 0);
CopyBuff();
ClearRxBuff();
__delay_ms(2);
UART_str(sim);
while(RCIF == 0);
CopyBuff();
ClearRxBuff();
__delay_ms(2);
UART_str(mode_text);
while(RCIF == 0);
CopyBuff();
ClearRxBuff();
__delay_ms(2);
UART_str(message_rec);
while(RCIF == 0);
CopyBuff();
ClearRxBuff();
__delay_ms(2);
while(1)
{
res = strstr(data,"LOAD1 ON");
if(res)
{
RD0 = 1;
}
res1 = strstr(data,"LOAD1 OFF");
if(res)
{
RD0 = 0;
}
}
}
__interrupt() void ISR(void)
{
if(RCIF)
{
if(RxSTatus == 0)
{
RxSTatus = 1;
j = 0;
}
data[j] = RCREG; // Read The Received Data Buffer and clears RCIF flag
j++;
if(j > 60)
j=0;
RCIF = 0;
}
}
while(1)
{
res = strstr(data,"LOAD1 ON");
if(res)
{
RD0 = 1;
}
res1 = strstr(data,"LOAD1 OFF");
if(res)
{
RD0 = 0;
}
}
Please comply with Andre's request for code tags around sections of program otherwise the forum software removes all the formatting.
The reason for your problem is that you keep storing characters until there are 61 in the data[] array, what you need to do is look for something in the message you can use as a terminator and use that instead. In the code I posted, it looks for '\r' but it could be '\n' or a zero at the end of the message, you need to see your GSM module specification to see which yours uses.
There is still a need to check the message length so there is no chance of 'j' becoming so big that 'data[j]' doesn't overwrite whatever is stored after it but under normal use, I doubt you will receive messages as long as 60 characters anyway. If you do not do that check and a long string of characters arrives it will crash or corrupt the program.
Incidentally, there is an error in the last code you posted:
I think the last 'if' should refer to 'res1' not 'res'. There are better and smaller ways to compare lots of strings to see if they match a set pattern.Code:while(1) { res = strstr(data,"LOAD1 ON"); if(res) { RD0 = 1; } res1 = strstr(data,"LOAD1 OFF"); if(res) { RD0 = 0; } }
Brian.
Code C - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 __interrupt() void ISR(void) { if(RCIF) { if(RxSTatus == 0) { RxSTatus = 1; j = 0; } buf = RCREG; // Read The Received Data Buffer and clears RCIF flag data[j] = buf; j++; if(buf == '\n') j=0; } if(res) { RD0 = 1; } res1 = strstr(data,"LOAD1 OFF"); if(res1) { RD0 = 0; }
In 'CopyBuff', you transfer characters from the 'data' array to the 'MyBuff' array but skip out any '\r', '\n' or '\0' characters. That means that the string that ends up in MyBuff will NOT have a null terminator (or any standard terminator character) but, if the new message is shorter than the previous message in 'data' will contain the trailing characters of the previous message. Also 'MyBuff' will not have any indication of how long the active string is. If at some later stage you try to use the 'strstr' function on 'MyBuff' (instead of 'data') then it will keep on going until it randomly finds a null character somewhere in your data memory.
Code C - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 void CopyBuff() { unsigned char tempcount, tempcount1; tempcount = tempcount1 = 0; for (tempcount = 0; tempcount < 61; tempcount++) { if ((data[tempcount] != 0X0D) & (data[tempcount] != 0X0A) & (data[tempcount] != '\0')) { MyBuff[tempcount1] = data[tempcount]; tempcount1++; } } }
tempcount=0;
while(data[tempcount])
{
MyBuff[tempcount] = data[tempcount];
tempcount++;
}
Susan and I are approximately 12 hours apart in time zones so I will reply, I hope she doesn't mind.
Firstly, to add code tags, you copy your code to the message window (as you have been doing) then immediately before it, type [ C O D E ] without the spaces and immediately after it type [ / C O D E ] again without the spaces. Note the '/' added inside the brackets to turn code mode off again. I can't show it here without spaces or it will treat this message as code!
The problem with the buffer length is as both of us have explained - the length of 61 characters is just the maximum size you have allocated or storage, what you should aim to do is start filling the storage from the first location at the start of each message and add a terminating zero to the end of the message. Then when you use your Copybuff() routine you can take out the 'for' loop and just keep copying from the first location until a zero is found. You can do that very easily with a routine like:
Note that the while() will keep the loop running until it sees data[tempcount] equals zero. There are alternative string copy commands that will do the same thing.Code:tempcount=0; while(data[tempcount]) { MyBuff[tempcount] = data[tempcount]; tempcount++; }
That termination zero is very important. In 'C' a text string normally ends with a zero. The zero is not a printable ASCII character so it is used as an "end of text" terminator. Most of the 'C' string commands recognize it, for example if you search for a character in a string it will stop when it finds a zero rather than running on forever or until it finds a match. If you look back to my code in post #23 you will see that after storing a character I move the storage pointer to the next place and add a zero there. It ensures that no matter how many characters are stored, a zero is always added to the end.
Brian.
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?