- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi All !
I am quite near to complete the GSM Project. I am not getting desired results as of now. The project which I designed, sends message to Cellular Phone when a push button is pressed. It receives message from Celllular Phone also. It displays it on LCD. Currently I am facing a problem in which I am able to send the message as many times as I press the pushbutton, but not able to receive it and display it on LCD once I send a message priorly. Please find attached my project. I request all to contribute, so we can make a GSM Module for PSoC4.
Regards
Shaunak
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There is one thing I would do differently: You reset the interrupt and then you remove the cause by reading off the character in your handler
I would first remove the cause and then the symptom.(Rocky Hooror Picture Show Theorem)
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Well,not just for the cosmetics: in the default branch of your switch(fsm) set the variable fsm to a legal value or you would loop forever.
A de-bouncing of your pushbutton would be a suggestion. You will always get more than one pulse within a few ms. Easiest is a delay (in main, not in the handler!!!).
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You need to set the UART ISR to level triggered, from datasheet of
UART SCB -
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you for the suggestions. I just came to know that if the received data is greater than 4 bytes, an internal UART interrupt gets activated. In my project, when I receive the message on GSM Modem from a phone and read it using UART interrupt, the number of characters read are beyond the count 32, means it goes beyond 4 bytes. Perhaps that is why I am able to read the message on LCD only once even if I am clearing the UART Rx Buffer in the interrupt with the API UART_GSM_SpiUartClearRxBuffer();. After that I can see that the control of code goes in the UART interrupt, but it does not SET the read_message_status FLAG as the LCD does not show the message. Please find attached the project modified as per the suggestions of Bob and Dana (the solutions improved the code and I thank them for that).
Regards
Shaunak
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Its probably reading more chars because the buffer is not null terminated ? This
problem occurs when trying to print using a stirng API and the string is not NULL
terminated.
So whenever you clear/init the string buffer fill it with '\0' (NULL) chars, then as
you read from UART you will simply overwrite the NULLS and as long as you
do not read a total of chars > ( bufferlen - 1 ) it will always be a NULL terminated
string. Each time you use string and want to get ready for next string reload
the buffer with NULLS.
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@Dana: I tried with your suggestion of clearing the buffer array after reading it, but I am still getting the same output.
As per GSM message rule, every message that GSM module sends to UART, starts with <CR><LF> and ends with <CR><LF> where CR is "Carriage Return" and LF is "New Line Feed". So I have set code according to this standard in my UART Receiver ISR where I am extracting the message from the received data. I am programming the project with below mentioned steps:
1. Setting GSM Module in Text mode (SIM300sendcommand(CMGF1)).
2. Deleting the message at Slot number 1 of GSM (SIM300DeleteMsg()).
3. Clearing the receiver and transmitter buffers (UART_GSM_SpiUartClearRxBuffer(), UART_GSM_SpiUartClearTxBuffer())
4. If(pushbutton is pressed) -> Set the mobile number (SIM300sendcommand(CMGS1)) -> send the message (SIM300sendcommand(MESSAGE1)).
5. If(message from phone is received on GSM Module) -> Send command from PSoC4 to GSM Module to read it (the message is stored on Slot 1) (SIM300ReadMsg()) -> Put the received message on LCD (DisplayOnLCD(1u, 0u, (char *)message)) -> Delete the message at slot 1 (SIM300DeleteMsg())
Currently I am facing a problem in which I have 2 things to get solved:
(A) If after power up, I press the pushbutton and send message from GSM Modem to phone, I get the message on phone. But after that if I send message from phone to GSM Modem, I am not able to read it on LCD despite getting the successful message delivery on phone as well as being able to see through LED blink that it has been received on UART. I can send message successfully from GSM Modem to phone as many times as I wish.
(B) If after power up, I send message from phone to GSM Modem, I am able to see it on LCD. I am also able to send the message from GSM Modem to phone through push button press afterwards. But here, I can not get the same message on GSM Modem through phone afterwards. The point is I am not able to get message on GSM Modem multiple times though I can send message successfully from GSM Modem to phone as many times as I wish.
Please find attached the above stated functioning fulfilling project.
Regards
Shaunak
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Shaunak,
I think, best will be to do a hand-simulation of your rx-handler to see that it will not behave as you want.
Write down two or three messages with 0x0d and 0x0a in the corresponding positions and your (shortened) text in between. Write down the changed value of fsm and use it at the next cycle.
You cannot do that with breakpoints in debug mode, because the modem keeps on sending bytes while the PSoC is halted.
A way out could be
Not using the interrupt, increasing the rx-buffer of the component to two times the message length.
Poll in main() the Rx_BufferSize() which will not return the buffer's size but the number of characters in the buffer. When there is a complete message in the buffer start to read off the characters using ch = (uint8)(UART_GSM_GetByte() & 0x00ff) and handle that as you did in your interrupt handler before.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This is just a minor observation, this code line (30) is doubly terminated -
volatile char message[512];;
should be -
volatile char message[512];
Also noticed on system tab of .cydwr file your heap size is 128 bytes, you might want
to increase that.
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Here you do not terminate these with NULL, so when you use strglen() to
determine length of message to send you will get indeterminate results.
You will have to increase array sizes by +1 to accomidate the NULL character.
www.gnu.org/software/libc/manual/html_node/String-Length.html
char CMGF1[10] = {'A','T','+','C','M','G','F','=','1',0x0D}; /* Command: AT+CMGF=1 'Carriage Return' */
char CMGS1[21] = {'A','T','+','C','M','G','S','=','"','0','0','0','0','0','0','0','0','0','0','"',0x0D}; /* Command: AT+CMGS="0000000000" 'Carriage Return'. Here 0000000000 refers to the 10-digit phone number */
char MESSAGE1[25] = {'B','I','G',' ','H','E','L','L','O',' ','F','R','O','M',' ','P','S','o','C',' ','4',' ','!','!',0x1A}; /* "MESSAGE SENT FROM MODEM" '^Z'. This is the message sent */
char CMGD1[10] = {'A','T','+','C','M','G','D','=','1',0x0D};/* Delete Message at Slot 1 of GSM Modem*/
char CMGR1[10] = {'A','T','+','C','M','G','R','=','1',0x0D};/* Read Message at Slot 1 of GSM Modem*/
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I think it's more convenient: (0x0d = \015 oct or \x0d in hex)
char AT1[3] = "AT\015 ;
char CMGF1[10] = "AT+KMGF=1\x0d";
char CMGS1[21] = "AT+KMGS=0000000000\015";
char MESSAGE1[25] = "BIG HELLO FROM PSoC 4!!\032";
char CMGD1[10] = "AT+KMGD=1\015";
char CMGR1[10] = "AT+KMGR=1\015";
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@Pav, I did not realize you could use the backslash in a string
like that. I kept looking at his strings thinking the same, way too
much typing.
Thanks for the post.
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Your module says that it is a SIM900 but your code states that it is a SIM300 in the top part of the main.c but later it has code for a SIM900. Are the commands the same between them? Also where did you get the module? I would like to check out the program and see how it works.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@Bob: I will try your suggested method of not using interrupt asap and let you know the results.
@Dana: I removed the doubly termination, but the result is same. I even increased the heap size, not getting the desired result yet. As far as terminating the strings with NULL, I do not think that is the reason for failure, as these all are "AT" commands of GSM SIM900 and they work quite good as of now also.
@pavloven: I tried with your method to declared the character strings in " ", but it did not work for GSM SIM900 and SIM300. That is why I adopted the current method.
@bobgoar: I have tested this code on both SIM300 and SIM900. The commands are same for both. You have seen SIM300 in comments because I tested with SIM300 previously. I am sorry for not replacing it with SIM900 in comments which confused you guys a bit. I purchased this module online from India.
Regards
Shaunak
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Shaunak,
there is a common way to interpret the input-stream that consists of different "words" usually ás part of a compiler:
The stream is broken up into "Tokens" that are delimited by "Delimiters" as ";",",","." etc.
The "Tokens" are checked for beeing a "Symbol" which are known words or numbers or whatever you define to be a symbol.
You can find a lot of information, have a look at (google for) unix-programs "lex" and "yacc", the latter is able to write the program for you ;-))
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I also made a small alarm device project with SIM900 and PSoC4
Maybe you will be interested